void DrawTexturedRect(const Position & tl, const Position & br, const int & textureID, const GLfloat * rgba) { glPushMatrix(); glEnable( GL_TEXTURE_2D ); glColor4fv(rgba); glBindTexture( GL_TEXTURE_2D, textureID ); glBegin( GL_QUADS ); glTexCoord3d(0.0,0.0,.5); glVertex2i(tl.x(),tl.y()); glTexCoord3d(1.0,0.0,.5); glVertex2i(br.x(),tl.y()); glTexCoord3d(1.0,1.0,.5); glVertex2i(br.x(),br.y()); glTexCoord3d(0.0,1.0,.5); glVertex2i(tl.x(),br.y()); glEnd(); glDisable( GL_TEXTURE_2D ); glPopMatrix(); }
void FieldViewerBase::addQuadslice(float zOffset) { glBegin(GL_QUADS); glNormal3f( 0.0f, 1.0f, 0.0f); //lightning normals glTexCoord3d(0.0f, 0.0f, 0.0f+z+zOffset); glVertex3f(0.0f, 0.0f, 0.0f+zOffset); //bottom left glTexCoord3d(1.0f, 0.0f, 0.0f+z+zOffset); glVertex3f(1.0f, 0.0f, 0.0f+zOffset);//bottom right glTexCoord3d(1.0f, 1.0f, 0.0f+z+zOffset); glVertex3f(1.0f, 1.0f, 0.0f+zOffset); //top right glTexCoord3d(0.0f, 1.0f, 0.0f+z+zOffset); glVertex3f(0.0f, 1.0f, 0.0f+zOffset);//top left glEnd(); }
void GimRasterizer::vertex(const Point3d& uvw, const Point3d& xyz) { float wd = static_cast<float>(target_->width()) ; float s = ((float(wd) - 0.99) / float(wd)) ; glTexCoord3d(xyz.x(), xyz.y(), xyz.z()) ; // TODO: setup viewing matrix instead ... float u = s * 2.0 * (uvw.x() - 0.5) ; float v = s * 2.0 * (uvw.y() - 0.5) ; float w = uvw.z() ; glVertex3d(u,v,w) ; }
// Note: we do not use glColor because glColor is clamped to [0,1] // and converted to an int ! void GimRasterizer::vertex(const Point2d& uv, const Point3d& xyz) { float w = static_cast<float>(target_->width()) ; // float s = (float(w) / (float(w) + 1.0)) ; float s = ((float(w) - 0.99) / float(w)) ; glTexCoord3d(xyz.x(), xyz.y(), xyz.z()) ; // TODO: setup viewing matrix instead ... float u = s * 2.0 * (uv.x() - 0.5) ; float v = s * 2.0 * (uv.y() - 0.5) ; glVertex2d(u,v) ; }
void addQuadslice(float zOffset) { float z= 0.0f; glBegin(GL_QUADS); glNormal3f( 0.0f, 1.0f, 0.0f); //lightning glTexCoord3d(0.0f, 0.0f, 0.0f+z+zOffset); glVertex3f(0.0f, 1.0f, 0.0f+zOffset);//top left glTexCoord3d(1.0f, 0.0f, 0.0f+z+zOffset); glVertex3f(1.0f, 1.0f, 0.0f+zOffset); //top right glTexCoord3d(1.0f, 1.0f, 0.0f+z+zOffset); glVertex3f(1.0f, 0.0f, 0.0f+zOffset);//bottom right glTexCoord3d(0.0f, 1.0f, 0.0f+z+zOffset); glVertex3f(0.0f, 0.0f, 0.0f+zOffset); //bottom left glEnd(); }
void NoiseVolumeRenderer::drawImplementation(osg::State& state) const { if(waterVolume() == 0) { return; } Point p; Point o = waterVolume()->origin(); double dx = 1.0 / ((waterVolume()->sizeX() - 1) * waterVolume()->stepX()); double dy = 1.0 / ((waterVolume()->sizeY() - 1) * waterVolume()->stepY()); double dz = 1.0 / ((waterVolume()->sizeZ() - 1) * waterVolume()->stepZ()); glBegin(GL_LINES); // x axis glColor4f(1.0, 0.0, 0.0, 1.0); p = waterVolume()->point(0, 0, 0); glVertex3d(p.x(), p.y(), p.z()); p = waterVolume()->point(waterVolume()->sizeX()-1, 0, 0); glVertex3d(p.x(), p.y(), p.z()); // y axis glColor4f(0.0, 1.0, 0.0, 1.0); p = waterVolume()->point(0, 0, 0); glVertex3d(p.x(), p.y(), p.z()); p = waterVolume()->point(0, waterVolume()->sizeY()-1, 0); glVertex3d(p.x(), p.y(), p.z()); // z axis glColor4f(0.0, 0.0, 1.0, 1.0); p = waterVolume()->point(0, 0, 0); glVertex3d(p.x(), p.y(), p.z()); p = waterVolume()->point(0, 0, waterVolume()->sizeZ()-1); glVertex3d(p.x(), p.y(), p.z()); glEnd(); Locker lock(waterVolume()); // showing velocities /* glBegin(GL_LINES); glColor4d(1.0, 1.0, 1.0, 1.0); for(unsigned i = 0; i < waterVolume()->sizeX(); i++) { for(unsigned j = 0; j < waterVolume()->sizeY(); j++) { for(unsigned k = 0; k < waterVolume()->sizeZ(); k++) { Vector v = waterVolume()->velocity(i, j, k); Point p1 = waterVolume()->point(i, j, k); Point p2 = p1 + v; glVertex3d(p1.x(), p1.y(), p1.z()); glVertex3d(p2.x(), p2.y(), p2.z()); } } } glEnd();*/ double tr = 1.0 / threshold(); // showing densities for(unsigned i = 1; i < waterVolume()->sizeX() - 1; i++) { for(unsigned j = 1; j < waterVolume()->sizeY() - 1; j++) { for(unsigned k = 1; k < waterVolume()->sizeZ() - 1; k++) { Vector n; double x, y, z, t, d; // cube vertices Point p1 = waterVolume()->point( i, j, k); Point p2 = waterVolume()->point(i+1, j, k+1); Point p3 = waterVolume()->point(i+1, j, k); Point p4 = waterVolume()->point(i+1, j+1, k+1); Point p5 = waterVolume()->point(i+1, j+1, k); Point p6 = waterVolume()->point( i, j+1, k+1); Point p7 = waterVolume()->point( i, j+1, k); Point p8 = waterVolume()->point( i, j, k+1); glBegin(GL_TRIANGLE_STRIP); // first face n = ((p3 - p1) ^ (p2 - p1)).normalise(); glNormal3d(n.x(), n.y(), n.z()); x = (p8.x() - o.x()) * dx; y = (p8.y() - o.y()) * dy; z = (p8.z() - o.z()) * dz; t = ImprovedNoise::noise(x, y, z) + 0.5; d = waterVolume()->density(i, j, k+1) * tr; glColor4d(t, t, t, d); glTexCoord3d(x, y, z); glVertex3d(p8.x(), p8.y(), p8.z()); x = (p1.x() - o.x()) * dx; y = (p1.y() - o.y()) * dy; z = (p1.z() - o.z()) * dz; t = ImprovedNoise::noise(x, y, z) + 0.5; d = waterVolume()->density(i, j, k) * tr; glColor4d(t, t, t, d); glTexCoord3d(x, y, z); glVertex3d(p1.x(), p1.y(), p1.z()); x = (p2.x() - o.x()) * dx; y = (p2.y() - o.y()) * dy; z = (p2.z() - o.z()) * dz; t = ImprovedNoise::noise(x, y, z) + 0.5; d = waterVolume()->density(i+1, j, k+1) * tr; glColor4d(t, t, t, d); glTexCoord3d(x, y, z); glVertex3d(p2.x(), p2.y(), p2.z()); x = (p3.x() - o.x()) * dx; y = (p3.y() - o.y()) * dy; z = (p3.z() - o.z()) * dz; t = ImprovedNoise::noise(x, y, z) + 0.5; d = waterVolume()->density(i+1, j, k) * tr; glColor4d(t, t, t, d); glTexCoord3d(x, y, z); glVertex3d(p3.x(), p3.y(), p3.z()); // second face n = ((p5 - p3) ^ (p4 - p3)).normalise(); glNormal3d(n.x(), n.y(), n.z()); x = (p4.x() - o.x()) * dx; y = (p4.y() - o.y()) * dy; z = (p4.z() - o.z()) * dz; t = ImprovedNoise::noise(x, y, z) + 0.5; d = waterVolume()->density(i+1, j+1, k+1) * tr; glColor4d(t, t, t, d); glTexCoord3d(x, y, z); glVertex3d(p4.x(), p4.y(), p4.z()); x = (p5.x() - o.x()) * dx; y = (p5.y() - o.y()) * dy; z = (p5.z() - o.z()) * dz; t = ImprovedNoise::noise(x, y, z) + 0.5; d = waterVolume()->density(i+1, j+1, k) * tr; glColor4d(t, t, t, d); glTexCoord3d(x, y, z); glVertex3d(p5.x(), p5.y(), p5.z()); // third face n = ((p7 - p5) ^ (p6 - p5)).normalise(); glNormal3d(n.x(), n.y(), n.z()); x = (p6.x() - o.x()) * dx; y = (p6.y() - o.y()) * dy; z = (p6.z() - o.z()) * dz; t = ImprovedNoise::noise(x, y, z) + 0.5; d = waterVolume()->density(i, j+1, k+1) * tr; glColor4d(t, t, t, d); glTexCoord3d(x, y, z); glVertex3d(p6.x(), p6.y(), p6.z()); x = (p7.x() - o.x()) * dx; y = (p7.y() - o.y()) * dy; z = (p7.z() - o.z()) * dz; t = ImprovedNoise::noise(x, y, z) + 0.5; d = waterVolume()->density(i, j+1, k) * tr; glColor4d(t, t, t, d); glTexCoord3d(x, y, z); glVertex3d(p7.x(), p7.y(), p7.z()); // fourth face n = ((p1 - p7) ^ (p8 - p7)).normalise(); glNormal3d(n.x(), n.y(), n.z()); x = (p8.x() - o.x()) * dx; y = (p8.y() - o.y()) * dy; z = (p8.z() - o.z()) * dz; t = ImprovedNoise::noise(x, y, z) + 0.5; d = waterVolume()->density(i, j, k+1) * tr; glColor4d(t, t, t, d); glTexCoord3d(x, y, z); glVertex3d(p8.x(), p8.y(), p8.z()); x = (p1.x() - o.x()) * dx; y = (p1.y() - o.y()) * dy; z = (p1.z() - o.z()) * dz; t = ImprovedNoise::noise(x, y, z) + 0.5; d = waterVolume()->density(i, j, k) * tr; glColor4d(t, t, t, d); glTexCoord3d(x, y, z); glVertex3d(p1.x(), p1.y(), p1.z()); glEnd(); } } } }
// This function is responsible for displaying the object. void drawScene(void) { int i; // Clear the rendering window glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Rotate the image glMatrixMode( GL_MODELVIEW ); // Current matrix affects objects positions glLoadIdentity(); // Initialize to the identity // Position the camera at [0,0,5], looking at [0,0,0], // with [0,1,0] as the up direction. gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // Set material properties of object // Here are some colors you might use - feel free to add more GLfloat diffColors[4][4] = { {0.5, 0.5, 0.9, 1.0}, {0.9, 0.5, 0.5, 1.0}, {0.5, 0.9, 0.3, 1.0}, {0.3, 0.8, 0.9, 1.0} }; // Here we use the first color entry as the diffuse color glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, diffColors[c]); // Define specular color and shininess GLfloat specColor[] = {1.0, 1.0, 1.0, 1.0}; GLfloat shininess[] = {100.0}; // Note that the specular color and shininess can stay constant glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess); // Set light properties // Light color (RGBA) GLfloat Lt0diff[] = {1.0,1.0,1.0,1.0}; // Light position GLfloat Lt0pos[] = {1.0f+0.5*p1, 1.0f+0.5*p2, 5.0f, 1.0f}; glLightfv(GL_LIGHT0, GL_DIFFUSE, Lt0diff); glLightfv(GL_LIGHT0, GL_POSITION, Lt0pos); // This GLUT method draws a teapot. You should replace // it with code which draws the object you loaded. //glutSolidTeapot(1.0); glBegin(GL_TRIANGLES); float x0=0.5f*(xmax+xmin); float y0=0.5f*(ymax+ymin); float z0=0.5f*(zmax+zmin); float xl=xmax-xmin; float yl=ymax-ymin; float zl=zmax-zmin; glOrtho(xmin,xmax,ymin,ymax,zmin,zmax); for(int k=0; i < Model.size(); i++){ for(unsigned int x=0; x < Model[i]->vecf.size(); x++) { int a,b,c,d,e,f,g,h,i; a=Model[k]->vecf[x][0]; b=Model[k]->vecf[x][1]; c=Model[k]->vecf[x][2]; d=Model[k]->vecf[x][3]; e=Model[k]->vecf[x][4]; f=Model[k]->vecf[x][5]; g=Model[k]->vecf[x][6]; h=Model[k]->vecf[x][7]; i=Model[k]->vecf[x][8]; //cout << c << "\t in display fn"<< endl; //Normals if(c == 0){ glNormal3d(0, 0,0); } else glNormal3d(vecn[c-1][0], vecn[c-1][1],vecn[c-1][2]); //Textures if(b == 0) glTexCoord3d(0, 0,0); else glTexCoord3f(vec_tex[b-1][0], vec_tex[b-1][1], vec_tex[b-1][2]); //Vertices glVertex3d(vecv[a-1][0]-x0, vecv[a-1][1]-y0, vecv[a-1][2]-z0); //Normals if(f == 0){ glNormal3d(0, 0,0); } else glNormal3d(vecn[f-1][0], vecn[f-1][1], vecn[f-1][2]); //Textures if(e == 0) glTexCoord3d(0, 0,0); else glTexCoord3f( vec_tex[e-1][0], vec_tex[e-1][1], vec_tex[e-1][2]); //Vertices glVertex3d( vecv[d-1][0]-x0, vecv[d-1][1]-y0, vecv[d-1][2]-z0); //Normals if(i == 0){ glNormal3d(0, 0,0); } else glNormal3d( vecn[i-1][0], vecn[i-1][1], vecn[i-1][2]); //Textures if(h == 0) glTexCoord3d(0, 0,0); else glTexCoord3f( vec_tex[h-1][0], vec_tex[h-1][1], vec_tex[h-1][2]); //Vertices glVertex3d( vecv[g-1][0]-x0, vecv[g-1][1]-y0, vecv[g-1][2]-z0); } } glEnd(); // Dump the image to the screen. glutSwapBuffers(); }
template< > inline void glTexCoord3< LDOUBL > ( LDOUBL s,LDOUBL t, LDOUBL r ) { glTexCoord3d((double)s,(double)t,(double)r); };
template< > inline void glTexCoord3< double > ( double s,double t, double r ) { glTexCoord3d(s,t,r); };
void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3], float dx, GPUTexture *tex_shadow) { RegionView3D *rv3d= ar->regiondata; float viewnormal[3]; int i, j, n, good_index; float d /*, d0 */ /* UNUSED */, dd, ds; float *points = NULL; int numpoints = 0; float cor[3] = {1.,1.,1.}; int gl_depth = 0, gl_blend = 0; /* draw slices of smoke is adapted from c++ code authored by: Johannes Schmid and Ingemar Rask, 2006, [email protected] */ float cv[][3] = { {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f}, {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f} }; // edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] float edges[12][2][3] = { {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, {{-1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, {{-1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, {{1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, {{-1.0f, 1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, {{-1.0f, -1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, {{-1.0f, -1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}}, {{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}} }; /* Fragment program to calculate the view3d of smoke */ /* using 2 textures, density and shadow */ const char *text = "!!ARBfp1.0\n" "PARAM dx = program.local[0];\n" "PARAM darkness = program.local[1];\n" "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n" "TEMP temp, shadow, value;\n" "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" "MUL value, temp, darkness;\n" "MUL value, value, dx;\n" "MUL value, value, f;\n" "EX2 temp, -value.r;\n" "SUB temp.a, 1.0, temp.r;\n" "MUL temp.r, temp.r, shadow.r;\n" "MUL temp.g, temp.g, shadow.r;\n" "MUL temp.b, temp.b, shadow.r;\n" "MOV result.color, temp;\n" "END\n"; GLuint prog; float size[3]; if(!tex) { printf("Could not allocate 3D texture for 3D View smoke drawing.\n"); return; } tstart(); sub_v3_v3v3(size, max, min); // maxx, maxy, maxz cv[0][0] = max[0]; cv[0][1] = max[1]; cv[0][2] = max[2]; // minx, maxy, maxz cv[1][0] = min[0]; cv[1][1] = max[1]; cv[1][2] = max[2]; // minx, miny, maxz cv[2][0] = min[0]; cv[2][1] = min[1]; cv[2][2] = max[2]; // maxx, miny, maxz cv[3][0] = max[0]; cv[3][1] = min[1]; cv[3][2] = max[2]; // maxx, maxy, minz cv[4][0] = max[0]; cv[4][1] = max[1]; cv[4][2] = min[2]; // minx, maxy, minz cv[5][0] = min[0]; cv[5][1] = max[1]; cv[5][2] = min[2]; // minx, miny, minz cv[6][0] = min[0]; cv[6][1] = min[1]; cv[6][2] = min[2]; // maxx, miny, minz cv[7][0] = max[0]; cv[7][1] = min[1]; cv[7][2] = min[2]; copy_v3_v3(edges[0][0], cv[4]); // maxx, maxy, minz copy_v3_v3(edges[1][0], cv[5]); // minx, maxy, minz copy_v3_v3(edges[2][0], cv[6]); // minx, miny, minz copy_v3_v3(edges[3][0], cv[7]); // maxx, miny, minz copy_v3_v3(edges[4][0], cv[3]); // maxx, miny, maxz copy_v3_v3(edges[5][0], cv[2]); // minx, miny, maxz copy_v3_v3(edges[6][0], cv[6]); // minx, miny, minz copy_v3_v3(edges[7][0], cv[7]); // maxx, miny, minz copy_v3_v3(edges[8][0], cv[1]); // minx, maxy, maxz copy_v3_v3(edges[9][0], cv[2]); // minx, miny, maxz copy_v3_v3(edges[10][0], cv[6]); // minx, miny, minz copy_v3_v3(edges[11][0], cv[5]); // minx, maxy, minz // printf("size x: %f, y: %f, z: %f\n", size[0], size[1], size[2]); // printf("min[2]: %f, max[2]: %f\n", min[2], max[2]); edges[0][1][2] = size[2]; edges[1][1][2] = size[2]; edges[2][1][2] = size[2]; edges[3][1][2] = size[2]; edges[4][1][1] = size[1]; edges[5][1][1] = size[1]; edges[6][1][1] = size[1]; edges[7][1][1] = size[1]; edges[8][1][0] = size[0]; edges[9][1][0] = size[0]; edges[10][1][0] = size[0]; edges[11][1][0] = size[0]; glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); glLoadMatrixf(rv3d->viewmat); // glMultMatrixf(ob->obmat); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* printf("Viewinv:\n"); printf("%f, %f, %f\n", rv3d->viewinv[0][0], rv3d->viewinv[0][1], rv3d->viewinv[0][2]); printf("%f, %f, %f\n", rv3d->viewinv[1][0], rv3d->viewinv[1][1], rv3d->viewinv[1][2]); printf("%f, %f, %f\n", rv3d->viewinv[2][0], rv3d->viewinv[2][1], rv3d->viewinv[2][2]); */ // get view vector copy_v3_v3(viewnormal, rv3d->viewinv[2]); normalize_v3(viewnormal); // find cube vertex that is closest to the viewer for (i=0; i<8; i++) { float x,y,z; x = cv[i][0] - viewnormal[0]; y = cv[i][1] - viewnormal[1]; z = cv[i][2] - viewnormal[2]; if ((x>=min[0])&&(x<=max[0]) &&(y>=min[1])&&(y<=max[1]) &&(z>=min[2])&&(z<=max[2])) { break; } } if(i >= 8) { /* fallback, avoid using buffer over-run */ i= 0; } // printf("i: %d\n", i); // printf("point %f, %f, %f\n", cv[i][0], cv[i][1], cv[i][2]); if (GL_TRUE == glewIsSupported("GL_ARB_fragment_program")) { glEnable(GL_FRAGMENT_PROGRAM_ARB); glGenProgramsARB(1, &prog); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog); glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(text), text); // cell spacing glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 0, dx, dx, dx, 1.0); // custom parameter for smoke style (higher = thicker) glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 1, 7.0, 7.0, 7.0, 1.0); } else printf("Your gfx card does not support 3D View smoke drawing.\n"); GPU_texture_bind(tex, 0); if(tex_shadow) GPU_texture_bind(tex_shadow, 1); else printf("No volume shadow\n"); if (!GPU_non_power_of_two_support()) { cor[0] = (float)res[0]/(float)larger_pow2(res[0]); cor[1] = (float)res[1]/(float)larger_pow2(res[1]); cor[2] = (float)res[2]/(float)larger_pow2(res[2]); } // our slices are defined by the plane equation a*x + b*y +c*z + d = 0 // (a,b,c), the plane normal, are given by viewdir // d is the parameter along the view direction. the first d is given by // inserting previously found vertex into the plane equation /* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */ ds = (ABS(viewnormal[0])*size[0] + ABS(viewnormal[1])*size[1] + ABS(viewnormal[2])*size[2]); dd = 0.05; // ds/512.0f; n = 0; good_index = i; // printf("d0: %f, dd: %f, ds: %f\n\n", d0, dd, ds); points = MEM_callocN(sizeof(float)*12*3, "smoke_points_preview"); while(1) { float p0[3]; float tmp_point[3], tmp_point2[3]; if(dd*(float)n > ds) break; copy_v3_v3(tmp_point, viewnormal); mul_v3_fl(tmp_point, -dd*((ds/dd)-(float)n)); add_v3_v3v3(tmp_point2, cv[good_index], tmp_point); d = dot_v3v3(tmp_point2, viewnormal); // printf("my d: %f\n", d); // intersect_edges returns the intersection points of all cube edges with // the given plane that lie within the cube numpoints = intersect_edges(points, viewnormal[0], viewnormal[1], viewnormal[2], -d, edges); // printf("points: %d\n", numpoints); if (numpoints > 2) { copy_v3_v3(p0, points); // sort points to get a convex polygon for(i = 1; i < numpoints - 1; i++) { for(j = i + 1; j < numpoints; j++) { if(!convex(p0, viewnormal, &points[j * 3], &points[i * 3])) { float tmp2[3]; copy_v3_v3(tmp2, &points[j * 3]); copy_v3_v3(&points[j * 3], &points[i * 3]); copy_v3_v3(&points[i * 3], tmp2); } } } // printf("numpoints: %d\n", numpoints); glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); for (i = 0; i < numpoints; i++) { glTexCoord3d((points[i * 3 + 0] - min[0] )*cor[0]/size[0], (points[i * 3 + 1] - min[1])*cor[1]/size[1], (points[i * 3 + 2] - min[2])*cor[2]/size[2]); glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]); } glEnd(); } n++; } tend(); // printf ( "Draw Time: %f\n",( float ) tval() ); if(tex_shadow) GPU_texture_unbind(tex_shadow); GPU_texture_unbind(tex); if(GLEW_ARB_fragment_program) { glDisable(GL_FRAGMENT_PROGRAM_ARB); glDeleteProgramsARB(1, &prog); } MEM_freeN(points); if(!gl_blend) glDisable(GL_BLEND); if(gl_depth) { glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); } }
void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, GPUTexture *tex, float min[3], float max[3], int res[3], float dx, float UNUSED(base_scale), float viewnormal[3], GPUTexture *tex_shadow, GPUTexture *tex_flame) { int i, j, k, n, good_index; float d /*, d0 */ /* UNUSED */, dd, ds; float *points = NULL; int numpoints = 0; float cor[3] = {1.0f, 1.0f, 1.0f}; int gl_depth = 0, gl_blend = 0; /* draw slices of smoke is adapted from c++ code authored * by: Johannes Schmid and Ingemar Rask, 2006, [email protected] */ float cv[][3] = { {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f}, {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f} }; /* edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] */ float edges[12][2][3] = { {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, {{-1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, {{-1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, {{1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, {{-1.0f, 1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, {{-1.0f, -1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, {{-1.0f, -1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}}, {{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}} }; unsigned char *spec_data; float *spec_pixels; GPUTexture *tex_spec; /* Fragment program to calculate the view3d of smoke */ /* using 4 textures, density, shadow, flame and flame spectrum */ const char *shader_basic = "!!ARBfp1.0\n" "PARAM dx = program.local[0];\n" "PARAM darkness = program.local[1];\n" "PARAM render = program.local[2];\n" "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n" "TEMP temp, shadow, flame, spec, value;\n" "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" "TEX spec, flame.r, texture[3], 1D;\n" /* calculate shading factor from density */ "MUL value.r, temp.a, darkness.a;\n" "MUL value.r, value.r, dx.r;\n" "MUL value.r, value.r, f.r;\n" "EX2 temp, -value.r;\n" /* alpha */ "SUB temp.a, 1.0, temp.r;\n" /* shade colors */ "MUL temp.r, temp.r, shadow.r;\n" "MUL temp.g, temp.g, shadow.r;\n" "MUL temp.b, temp.b, shadow.r;\n" "MUL temp.r, temp.r, darkness.r;\n" "MUL temp.g, temp.g, darkness.g;\n" "MUL temp.b, temp.b, darkness.b;\n" /* for now this just replace smoke shading if rendering fire */ "CMP result.color, render.r, temp, spec;\n" "END\n"; /* color shader */ const char *shader_color = "!!ARBfp1.0\n" "PARAM dx = program.local[0];\n" "PARAM darkness = program.local[1];\n" "PARAM render = program.local[2];\n" "PARAM f = {1.442695041, 1.442695041, 1.442695041, 1.442695041};\n" "TEMP temp, shadow, flame, spec, value;\n" "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" "TEX spec, flame.r, texture[3], 1D;\n" /* unpremultiply volume texture */ "RCP value.r, temp.a;\n" "MUL temp.r, temp.r, value.r;\n" "MUL temp.g, temp.g, value.r;\n" "MUL temp.b, temp.b, value.r;\n" /* calculate shading factor from density */ "MUL value.r, temp.a, darkness.a;\n" "MUL value.r, value.r, dx.r;\n" "MUL value.r, value.r, f.r;\n" "EX2 value.r, -value.r;\n" /* alpha */ "SUB temp.a, 1.0, value.r;\n" /* shade colors */ "MUL temp.r, temp.r, shadow.r;\n" "MUL temp.g, temp.g, shadow.r;\n" "MUL temp.b, temp.b, shadow.r;\n" "MUL temp.r, temp.r, value.r;\n" "MUL temp.g, temp.g, value.r;\n" "MUL temp.b, temp.b, value.r;\n" /* for now this just replace smoke shading if rendering fire */ "CMP result.color, render.r, temp, spec;\n" "END\n"; GLuint prog; float size[3]; if (!tex) { printf("Could not allocate 3D texture for 3D View smoke drawing.\n"); return; } #ifdef DEBUG_DRAW_TIME TIMEIT_START(draw); #endif /* generate flame spectrum texture */ #define SPEC_WIDTH 256 #define FIRE_THRESH 7 #define MAX_FIRE_ALPHA 0.06f #define FULL_ON_FIRE 100 spec_data = malloc(SPEC_WIDTH * 4 * sizeof(unsigned char)); flame_get_spectrum(spec_data, SPEC_WIDTH, 1500, 3000); spec_pixels = malloc(SPEC_WIDTH * 4 * 16 * 16 * sizeof(float)); for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { for (k = 0; k < SPEC_WIDTH; k++) { int index = (j * SPEC_WIDTH * 16 + i * SPEC_WIDTH + k) * 4; if (k >= FIRE_THRESH) { spec_pixels[index] = ((float)spec_data[k * 4]) / 255.0f; spec_pixels[index + 1] = ((float)spec_data[k * 4 + 1]) / 255.0f; spec_pixels[index + 2] = ((float)spec_data[k * 4 + 2]) / 255.0f; spec_pixels[index + 3] = MAX_FIRE_ALPHA * ( (k > FULL_ON_FIRE) ? 1.0f : (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH)); } else { spec_pixels[index] = spec_pixels[index + 1] = spec_pixels[index + 2] = spec_pixels[index + 3] = 0.0f; } } } } tex_spec = GPU_texture_create_1D(SPEC_WIDTH, spec_pixels, NULL); sub_v3_v3v3(size, max, min); /* maxx, maxy, maxz */ cv[0][0] = max[0]; cv[0][1] = max[1]; cv[0][2] = max[2]; /* minx, maxy, maxz */ cv[1][0] = min[0]; cv[1][1] = max[1]; cv[1][2] = max[2]; /* minx, miny, maxz */ cv[2][0] = min[0]; cv[2][1] = min[1]; cv[2][2] = max[2]; /* maxx, miny, maxz */ cv[3][0] = max[0]; cv[3][1] = min[1]; cv[3][2] = max[2]; /* maxx, maxy, minz */ cv[4][0] = max[0]; cv[4][1] = max[1]; cv[4][2] = min[2]; /* minx, maxy, minz */ cv[5][0] = min[0]; cv[5][1] = max[1]; cv[5][2] = min[2]; /* minx, miny, minz */ cv[6][0] = min[0]; cv[6][1] = min[1]; cv[6][2] = min[2]; /* maxx, miny, minz */ cv[7][0] = max[0]; cv[7][1] = min[1]; cv[7][2] = min[2]; copy_v3_v3(edges[0][0], cv[4]); /* maxx, maxy, minz */ copy_v3_v3(edges[1][0], cv[5]); /* minx, maxy, minz */ copy_v3_v3(edges[2][0], cv[6]); /* minx, miny, minz */ copy_v3_v3(edges[3][0], cv[7]); /* maxx, miny, minz */ copy_v3_v3(edges[4][0], cv[3]); /* maxx, miny, maxz */ copy_v3_v3(edges[5][0], cv[2]); /* minx, miny, maxz */ copy_v3_v3(edges[6][0], cv[6]); /* minx, miny, minz */ copy_v3_v3(edges[7][0], cv[7]); /* maxx, miny, minz */ copy_v3_v3(edges[8][0], cv[1]); /* minx, maxy, maxz */ copy_v3_v3(edges[9][0], cv[2]); /* minx, miny, maxz */ copy_v3_v3(edges[10][0], cv[6]); /* minx, miny, minz */ copy_v3_v3(edges[11][0], cv[5]); /* minx, maxy, minz */ // printf("size x: %f, y: %f, z: %f\n", size[0], size[1], size[2]); // printf("min[2]: %f, max[2]: %f\n", min[2], max[2]); edges[0][1][2] = size[2]; edges[1][1][2] = size[2]; edges[2][1][2] = size[2]; edges[3][1][2] = size[2]; edges[4][1][1] = size[1]; edges[5][1][1] = size[1]; edges[6][1][1] = size[1]; edges[7][1][1] = size[1]; edges[8][1][0] = size[0]; edges[9][1][0] = size[0]; edges[10][1][0] = size[0]; edges[11][1][0] = size[0]; glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); /* find cube vertex that is closest to the viewer */ for (i = 0; i < 8; i++) { float x, y, z; x = cv[i][0] - viewnormal[0] * size[0] * 0.5f; y = cv[i][1] - viewnormal[1] * size[1] * 0.5f; z = cv[i][2] - viewnormal[2] * size[2] * 0.5f; if ((x >= min[0]) && (x <= max[0]) && (y >= min[1]) && (y <= max[1]) && (z >= min[2]) && (z <= max[2])) { break; } } if (i >= 8) { /* fallback, avoid using buffer over-run */ i = 0; } // printf("i: %d\n", i); // printf("point %f, %f, %f\n", cv[i][0], cv[i][1], cv[i][2]); if (GL_TRUE == glewIsSupported("GL_ARB_fragment_program")) { glEnable(GL_FRAGMENT_PROGRAM_ARB); glGenProgramsARB(1, &prog); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog); /* set shader */ if (sds->active_fields & SM_ACTIVE_COLORS) glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_color), shader_color); else glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_basic), shader_basic); /* cell spacing */ glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, dx, dx, dx, 1.0); /* custom parameter for smoke style (higher = thicker) */ if (sds->active_fields & SM_ACTIVE_COLORS) glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 1.0, 1.0, 1.0, 10.0); else glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, sds->active_color[0], sds->active_color[1], sds->active_color[2], 10.0); } else printf("Your gfx card does not support 3D View smoke drawing.\n"); GPU_texture_bind(tex, 0); if (tex_shadow) GPU_texture_bind(tex_shadow, 1); else printf("No volume shadow\n"); if (tex_flame) { GPU_texture_bind(tex_flame, 2); GPU_texture_bind(tex_spec, 3); } if (!GPU_non_power_of_two_support()) { cor[0] = (float)res[0] / (float)power_of_2_max_i(res[0]); cor[1] = (float)res[1] / (float)power_of_2_max_i(res[1]); cor[2] = (float)res[2] / (float)power_of_2_max_i(res[2]); } /* our slices are defined by the plane equation a*x + b*y +c*z + d = 0 * (a,b,c), the plane normal, are given by viewdir * d is the parameter along the view direction. the first d is given by * inserting previously found vertex into the plane equation */ /* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */ ds = (fabsf(viewnormal[0]) * size[0] + fabsf(viewnormal[1]) * size[1] + fabsf(viewnormal[2]) * size[2]); dd = max_fff(sds->global_size[0], sds->global_size[1], sds->global_size[2]) / 128.f; n = 0; good_index = i; // printf("d0: %f, dd: %f, ds: %f\n\n", d0, dd, ds); points = MEM_callocN(sizeof(float) * 12 * 3, "smoke_points_preview"); while (1) { float p0[3]; float tmp_point[3], tmp_point2[3]; if (dd * (float)n > ds) break; copy_v3_v3(tmp_point, viewnormal); mul_v3_fl(tmp_point, -dd * ((ds / dd) - (float)n)); add_v3_v3v3(tmp_point2, cv[good_index], tmp_point); d = dot_v3v3(tmp_point2, viewnormal); // printf("my d: %f\n", d); /* intersect_edges returns the intersection points of all cube edges with * the given plane that lie within the cube */ numpoints = intersect_edges(points, viewnormal[0], viewnormal[1], viewnormal[2], -d, edges); // printf("points: %d\n", numpoints); if (numpoints > 2) { copy_v3_v3(p0, points); /* sort points to get a convex polygon */ for (i = 1; i < numpoints - 1; i++) { for (j = i + 1; j < numpoints; j++) { if (!convex(p0, viewnormal, &points[j * 3], &points[i * 3])) { float tmp2[3]; copy_v3_v3(tmp2, &points[j * 3]); copy_v3_v3(&points[j * 3], &points[i * 3]); copy_v3_v3(&points[i * 3], tmp2); } } } /* render fire slice */ glBlendFunc(GL_SRC_ALPHA, GL_ONE); glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, 1.0, 0.0, 0.0, 0.0); glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); for (i = 0; i < numpoints; i++) { glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], (points[i * 3 + 1] - min[1]) * cor[1] / size[1], (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); glVertex3f(points[i * 3 + 0] / fabsf(ob->size[0]), points[i * 3 + 1] / fabsf(ob->size[1]), points[i * 3 + 2] / fabsf(ob->size[2])); } glEnd(); /* render smoke slice */ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, -1.0, 0.0, 0.0, 0.0); glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); for (i = 0; i < numpoints; i++) { glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], (points[i * 3 + 1] - min[1]) * cor[1] / size[1], (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); glVertex3f(points[i * 3 + 0] / fabsf(ob->size[0]), points[i * 3 + 1] / fabsf(ob->size[1]), points[i * 3 + 2] / fabsf(ob->size[2])); } glEnd(); } n++; } #ifdef DEBUG_DRAW_TIME printf("Draw Time: %f\n", (float)TIMEIT_VALUE(draw)); TIMEIT_END(draw); #endif if (tex_shadow) GPU_texture_unbind(tex_shadow); GPU_texture_unbind(tex); if (tex_flame) { GPU_texture_unbind(tex_flame); GPU_texture_unbind(tex_spec); } GPU_texture_free(tex_spec); free(spec_data); free(spec_pixels); if (GLEW_ARB_fragment_program) { glDisable(GL_FRAGMENT_PROGRAM_ARB); glDeleteProgramsARB(1, &prog); } MEM_freeN(points); if (!gl_blend) { glDisable(GL_BLEND); } if (gl_depth) { glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); } }
inline void glTexCoord( const GLdouble & s, const GLdouble & t, const GLdouble & r ) { glTexCoord3d( s, t, r ); }
M(void, glTexCoord3d, jdouble s, jdouble t, jdouble r) { glTexCoord3d(s, t, r); }
void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, GPUTexture *tex, const float min[3], const float max[3], const int res[3], float dx, float UNUSED(base_scale), const float viewnormal[3], GPUTexture *tex_shadow, GPUTexture *tex_flame) { const float ob_sizei[3] = { 1.0f / fabsf(ob->size[0]), 1.0f / fabsf(ob->size[1]), 1.0f / fabsf(ob->size[2])}; int i, j, k, n, good_index; float d /*, d0 */ /* UNUSED */, dd, ds; float (*points)[3] = NULL; int numpoints = 0; float cor[3] = {1.0f, 1.0f, 1.0f}; int gl_depth = 0, gl_blend = 0; int use_fire = (sds->active_fields & SM_ACTIVE_FIRE); /* draw slices of smoke is adapted from c++ code authored * by: Johannes Schmid and Ingemar Rask, 2006, [email protected] */ float cv[][3] = { {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f}, {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f} }; /* edges have the form edges[n][0][xyz] + t*edges[n][1][xyz] */ float edges[12][2][3] = { {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 2.0f}}, {{1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, {{-1.0f, -1.0f, 1.0f}, {0.0f, 2.0f, 0.0f}}, {{-1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, {{1.0f, -1.0f, -1.0f}, {0.0f, 2.0f, 0.0f}}, {{-1.0f, 1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, {{-1.0f, -1.0f, 1.0f}, {2.0f, 0.0f, 0.0f}}, {{-1.0f, -1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}}, {{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}} }; unsigned char *spec_data; float *spec_pixels; GPUTexture *tex_spec; GPUProgram *smoke_program; int progtype = (sds->active_fields & SM_ACTIVE_COLORS) ? GPU_PROGRAM_SMOKE_COLORED : GPU_PROGRAM_SMOKE; float size[3]; if (!tex) { printf("Could not allocate 3D texture for 3D View smoke drawing.\n"); return; } #ifdef DEBUG_DRAW_TIME TIMEIT_START(draw); #endif /* generate flame spectrum texture */ #define SPEC_WIDTH 256 #define FIRE_THRESH 7 #define MAX_FIRE_ALPHA 0.06f #define FULL_ON_FIRE 100 spec_data = malloc(SPEC_WIDTH * 4 * sizeof(unsigned char)); flame_get_spectrum(spec_data, SPEC_WIDTH, 1500, 3000); spec_pixels = malloc(SPEC_WIDTH * 4 * 16 * 16 * sizeof(float)); for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { for (k = 0; k < SPEC_WIDTH; k++) { int index = (j * SPEC_WIDTH * 16 + i * SPEC_WIDTH + k) * 4; if (k >= FIRE_THRESH) { spec_pixels[index] = ((float)spec_data[k * 4]) / 255.0f; spec_pixels[index + 1] = ((float)spec_data[k * 4 + 1]) / 255.0f; spec_pixels[index + 2] = ((float)spec_data[k * 4 + 2]) / 255.0f; spec_pixels[index + 3] = MAX_FIRE_ALPHA * ( (k > FULL_ON_FIRE) ? 1.0f : (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH)); } else { spec_pixels[index] = spec_pixels[index + 1] = spec_pixels[index + 2] = spec_pixels[index + 3] = 0.0f; } } } } tex_spec = GPU_texture_create_1D(SPEC_WIDTH, spec_pixels, NULL); #undef SPEC_WIDTH #undef FIRE_THRESH #undef MAX_FIRE_ALPHA #undef FULL_ON_FIRE sub_v3_v3v3(size, max, min); /* maxx, maxy, maxz */ cv[0][0] = max[0]; cv[0][1] = max[1]; cv[0][2] = max[2]; /* minx, maxy, maxz */ cv[1][0] = min[0]; cv[1][1] = max[1]; cv[1][2] = max[2]; /* minx, miny, maxz */ cv[2][0] = min[0]; cv[2][1] = min[1]; cv[2][2] = max[2]; /* maxx, miny, maxz */ cv[3][0] = max[0]; cv[3][1] = min[1]; cv[3][2] = max[2]; /* maxx, maxy, minz */ cv[4][0] = max[0]; cv[4][1] = max[1]; cv[4][2] = min[2]; /* minx, maxy, minz */ cv[5][0] = min[0]; cv[5][1] = max[1]; cv[5][2] = min[2]; /* minx, miny, minz */ cv[6][0] = min[0]; cv[6][1] = min[1]; cv[6][2] = min[2]; /* maxx, miny, minz */ cv[7][0] = max[0]; cv[7][1] = min[1]; cv[7][2] = min[2]; copy_v3_v3(edges[0][0], cv[4]); /* maxx, maxy, minz */ copy_v3_v3(edges[1][0], cv[5]); /* minx, maxy, minz */ copy_v3_v3(edges[2][0], cv[6]); /* minx, miny, minz */ copy_v3_v3(edges[3][0], cv[7]); /* maxx, miny, minz */ copy_v3_v3(edges[4][0], cv[3]); /* maxx, miny, maxz */ copy_v3_v3(edges[5][0], cv[2]); /* minx, miny, maxz */ copy_v3_v3(edges[6][0], cv[6]); /* minx, miny, minz */ copy_v3_v3(edges[7][0], cv[7]); /* maxx, miny, minz */ copy_v3_v3(edges[8][0], cv[1]); /* minx, maxy, maxz */ copy_v3_v3(edges[9][0], cv[2]); /* minx, miny, maxz */ copy_v3_v3(edges[10][0], cv[6]); /* minx, miny, minz */ copy_v3_v3(edges[11][0], cv[5]); /* minx, maxy, minz */ // printf("size x: %f, y: %f, z: %f\n", size[0], size[1], size[2]); // printf("min[2]: %f, max[2]: %f\n", min[2], max[2]); edges[0][1][2] = size[2]; edges[1][1][2] = size[2]; edges[2][1][2] = size[2]; edges[3][1][2] = size[2]; edges[4][1][1] = size[1]; edges[5][1][1] = size[1]; edges[6][1][1] = size[1]; edges[7][1][1] = size[1]; edges[8][1][0] = size[0]; edges[9][1][0] = size[0]; edges[10][1][0] = size[0]; edges[11][1][0] = size[0]; glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); /* find cube vertex that is closest to the viewer */ for (i = 0; i < 8; i++) { float x, y, z; x = cv[i][0] - viewnormal[0] * size[0] * 0.5f; y = cv[i][1] - viewnormal[1] * size[1] * 0.5f; z = cv[i][2] - viewnormal[2] * size[2] * 0.5f; if ((x >= min[0]) && (x <= max[0]) && (y >= min[1]) && (y <= max[1]) && (z >= min[2]) && (z <= max[2])) { break; } } if (i >= 8) { /* fallback, avoid using buffer over-run */ i = 0; } // printf("i: %d\n", i); // printf("point %f, %f, %f\n", cv[i][0], cv[i][1], cv[i][2]); smoke_program = GPU_shader_get_builtin_program(progtype); if (smoke_program) { GPU_program_bind(smoke_program); /* cell spacing */ GPU_program_parameter_4f(smoke_program, 0, dx, dx, dx, 1.0); /* custom parameter for smoke style (higher = thicker) */ if (sds->active_fields & SM_ACTIVE_COLORS) GPU_program_parameter_4f(smoke_program, 1, 1.0, 1.0, 1.0, 10.0); else GPU_program_parameter_4f(smoke_program, 1, sds->active_color[0], sds->active_color[1], sds->active_color[2], 10.0); } else printf("Your gfx card does not support 3D View smoke drawing.\n"); GPU_texture_bind(tex, 0); if (tex_shadow) GPU_texture_bind(tex_shadow, 1); else printf("No volume shadow\n"); if (tex_flame) { GPU_texture_bind(tex_flame, 2); GPU_texture_bind(tex_spec, 3); } if (!GPU_non_power_of_two_support()) { cor[0] = (float)res[0] / (float)power_of_2_max_u(res[0]); cor[1] = (float)res[1] / (float)power_of_2_max_u(res[1]); cor[2] = (float)res[2] / (float)power_of_2_max_u(res[2]); } cor[0] /= size[0]; cor[1] /= size[1]; cor[2] /= size[2]; /* our slices are defined by the plane equation a*x + b*y +c*z + d = 0 * (a,b,c), the plane normal, are given by viewdir * d is the parameter along the view direction. the first d is given by * inserting previously found vertex into the plane equation */ /* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */ ds = (fabsf(viewnormal[0]) * size[0] + fabsf(viewnormal[1]) * size[1] + fabsf(viewnormal[2]) * size[2]); dd = max_fff(sds->global_size[0], sds->global_size[1], sds->global_size[2]) / 128.f; n = 0; good_index = i; // printf("d0: %f, dd: %f, ds: %f\n\n", d0, dd, ds); points = MEM_callocN(sizeof(*points) * 12, "smoke_points_preview"); while (1) { float p0[3]; float tmp_point[3], tmp_point2[3]; if (dd * (float)n > ds) break; copy_v3_v3(tmp_point, viewnormal); mul_v3_fl(tmp_point, -dd * ((ds / dd) - (float)n)); add_v3_v3v3(tmp_point2, cv[good_index], tmp_point); d = dot_v3v3(tmp_point2, viewnormal); // printf("my d: %f\n", d); /* intersect_edges returns the intersection points of all cube edges with * the given plane that lie within the cube */ numpoints = intersect_edges(points, viewnormal[0], viewnormal[1], viewnormal[2], -d, edges); // printf("points: %d\n", numpoints); if (numpoints > 2) { copy_v3_v3(p0, points[0]); /* sort points to get a convex polygon */ for (i = 1; i < numpoints - 1; i++) { for (j = i + 1; j < numpoints; j++) { if (!convex(p0, viewnormal, points[j], points[i])) { swap_v3_v3(points[i], points[j]); } } } /* render fire slice */ if (use_fire) { if (GLEW_VERSION_1_4) glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE); else glBlendFunc(GL_SRC_ALPHA, GL_ONE); GPU_program_parameter_4f(smoke_program, 2, 1.0, 0.0, 0.0, 0.0); glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); for (i = 0; i < numpoints; i++) { glTexCoord3d((points[i][0] - min[0]) * cor[0], (points[i][1] - min[1]) * cor[1], (points[i][2] - min[2]) * cor[2]); glVertex3f(points[i][0] * ob_sizei[0], points[i][1] * ob_sizei[1], points[i][2] * ob_sizei[2]); } glEnd(); } /* render smoke slice */ if (GLEW_VERSION_1_4) glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GPU_program_parameter_4f(smoke_program, 2, -1.0, 0.0, 0.0, 0.0); glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); for (i = 0; i < numpoints; i++) { glTexCoord3d((points[i][0] - min[0]) * cor[0], (points[i][1] - min[1]) * cor[1], (points[i][2] - min[2]) * cor[2]); glVertex3f(points[i][0] * ob_sizei[0], points[i][1] * ob_sizei[1], points[i][2] * ob_sizei[2]); } glEnd(); } n++; } #ifdef DEBUG_DRAW_TIME printf("Draw Time: %f\n", (float)TIMEIT_VALUE(draw)); TIMEIT_END(draw); #endif if (tex_shadow) GPU_texture_unbind(tex_shadow); GPU_texture_unbind(tex); if (tex_flame) { GPU_texture_unbind(tex_flame); GPU_texture_unbind(tex_spec); } GPU_texture_free(tex_spec); free(spec_data); free(spec_pixels); if (smoke_program) GPU_program_unbind(smoke_program); MEM_freeN(points); if (!gl_blend) { glDisable(GL_BLEND); } if (gl_depth) { glEnable(GL_DEPTH_TEST); } }
void drawExplosion(Particles_system *partSys){ //glDisable(GL_LIGHTING); glPushAttrib(GL_ALL_ATTRIB_BITS); glPushMatrix(); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHT2); glEnable(GL_BLEND); // abilita blending (superficie traslucida) glBlendFunc(GL_SRC_ALPHA,GL_ONE); // tipo di blending glDisable(GL_CULL_FACE); // disiabilita il taglio delle superfici nascoste glEnable(GL_COLOR_MATERIAL); // abilita il materiale glEnable(GL_TEXTURE_2D); // attiviamo texture glColorMaterial(GL_FRONT, GL_EMISSION); // tipo di materiale //glTranslatef(partSys->pos.x,partSys->pos.y,partSys->pos.z); // ci spostiamo nella posizione della navicella GLfloat lifeRate, moveRate; Particle* part; GLfloat *x,*y,*z; GLboolean allOff=true; for (int i=0;i<MAX_PARTICLES;i++) { part= &(partSys->particle[i]); if(part->active) { allOff=false; x=&(part->pos.x); y=&(part->pos.y); z=&(part->pos.z); // disegnamo la particella glColor4f(part->color[0],part->color[1],part->color[2],part->life); glBindTexture(GL_TEXTURE_2D, g_textureArray[4]); /* glBegin(GL_TRIANGLE_STRIP); // Costruisco un quadrato da una striscia di triangoli glTexCoord3d(1,0,1); glVertex3f(*x+0.05f,*y-0.05f,*z); // inferiore destro glTexCoord3d(0,0,1); glVertex3f(*x-0.05f,*y-0.05f,*z); // inferiore sinistro glTexCoord3d(1,1,1); glVertex3f(*x+0.05f,*y+0.05f,*z); // superiore destro glTexCoord3d(0,1,1); glVertex3f(*x-0.05f,*y+0.05f,*z); // superiore sinistro glEnd(); */ glBegin(GL_TRIANGLE_STRIP); // Costruisco un quadrato da una striscia di triangoli glTexCoord3d(1,0,1); glVertex3f(*x+0.1f,*y-0.1f,*z+0.1f); // inferiore destro glTexCoord3d(0,0,1); glVertex3f(*x-0.1f,*y-0.1f,*z-0.1f); // inferiore sinistro glTexCoord3d(1,1,1); glVertex3f(*x+0.1f,*y+0.1f,*z-0.1f); // superiore destro glTexCoord3d(0,1,1); glVertex3f(*x-0.1f,*y+0.1f,*z+0.1f); // superiore sinistro glEnd(); if(!freezeExpl){ // muoviamo la particella lifeRate = (0.5*dtime)/40; moveRate = pow(dtime,2)/2500; *x +=part->dir.x*moveRate; // muoviamo la particella su X utilizzando anche il framerate *y +=part->dir.y*moveRate; // muoviamo la particella su Y utilizzando anche il framerate *z +=part->dir.z*moveRate; // muoviamo la particella su X utilizzando anche il framerate part->fade=(float)dtime/10000000 + (rand()%100)/1000.0f; part->life-=part->fade; // Riduciamo la vita della particella } //printf("X: %f\tY: %f\tZ: %f, moverate: %f\n", *x,*y,*z, moveRate);fflush(stdout); //printf("\tX: %f\tY: %f\tZ: %f\n", part->pos.x,part->pos.y,part->pos.z);fflush(stdout); // se e' tanto distante dal punto di esplosione non la visualizziamo piu' if(distance(partSys->pos,part->pos)>120){ part->active=false; } } } // se nessuna particella e' attiva disattiviamo il sistema di particelle if(allOff) partSys->active=false; glDisable(GL_COLOR_MATERIAL); // disabilita il materiale glDisable(GL_TEXTURE_2D); glEnable(GL_CULL_FACE); // abilita il taglio delle superfici nascoste glDisable(GL_BLEND); // disabilita blending glDisable(GL_LIGHT2); glDisable(GL_LIGHT1); glDisable(GL_LIGHT0); glPopMatrix(); glPopAttrib(); //glEnable(GL_LIGHTING); }