//draw a frame void RenderFrame() { //Clear buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); //reset modelview matrix glEnable(GL_LIGHTING); glTranslatef(0.0f, 0.0f, -30.0f); glRotatef((float)timer.GetTime()/30, 1.0f, 0.0f, 1.0f); cubeGrid.DrawSurface(threshold); glDisable(GL_LIGHTING); fpsCounter.Update(); //update frames per second counter glColor4f(0.0f, 0.0f, 1.0f, 1.0f); window.StartTextMode(); window.Print(0, 28, "FPS: %.2f", fpsCounter.GetFps()); //print the fps glColor4f(1.0f, 1.0f, 0.0f, 1.0f); window.Print(0, 48, "Grid Size: %d", gridSize); window.Print(0, 68, "%d triangles drawn", cubeGrid.numFacesDrawn); window.EndTextMode(); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); if(window.isKeyPressed(VK_F1)) { window.SaveScreenshot(); window.SetKeyReleased(VK_F1); } window.SwapBuffers(); //swap buffers //check for any opengl errors window.CheckGLError(); //quit if necessary if(window.isKeyPressed(VK_ESCAPE)) PostQuitMessage(0); }
void drawMetaball(int numMetaballs,const vector< vector<float> >& balls) { const int minGridSize = 10; int gridSize = 30; float threshold = 1.0f; CUBE_GRID cubeGrid; METABALL* metaballs = new METABALL[numMetaballs]; for (int i = 0; i<numMetaballs; i++) metaballs[i].Init(VECTOR3D(balls[i][0], balls[i][1], balls[i][2]), balls[i][3] * balls[i][3]); //init marching cube cubeGrid.CreateMemory(); cubeGrid.Init(gridSize); for (int i = 0; i<cubeGrid.numVertices; i++) { cubeGrid.vertices[i].value = 0.0f; cubeGrid.vertices[i].normal.LoadZero(); } VECTOR3D ballToPoint; float squaredRadius; VECTOR3D ballPosition; float normalScale; for (int i = 0; i<numMetaballs; i++) { squaredRadius = metaballs[i].squaredRadius; ballPosition = metaballs[i].position; //VC++6 standard does not inline functions //by inlining these maually, in this performance-critical area, //almost a 100% increase in speed is found for (int j = 0; j<cubeGrid.numVertices; j++) { //ballToPoint=cubeGrid.vertices[j].position-ballPosition; ballToPoint.x = cubeGrid.vertices[j].position.x - ballPosition.x; ballToPoint.y = cubeGrid.vertices[j].position.y - ballPosition.y; ballToPoint.z = cubeGrid.vertices[j].position.z - ballPosition.z; //get squared distance from ball to point //float squaredDistance=ballToPoint.GetSquaredLength(); float squaredDistance = ballToPoint.x*ballToPoint.x + ballToPoint.y*ballToPoint.y + ballToPoint.z*ballToPoint.z; if (squaredDistance == 0.0f) squaredDistance = 0.0001f; //value = r^2/d^2 cubeGrid.vertices[j].value += squaredRadius / squaredDistance; //normal = (r^2 * v)/d^4 normalScale = squaredRadius / (squaredDistance*squaredDistance); //cubeGrid.vertices[j].normal+=ballToPoint*normalScale; cubeGrid.vertices[j].normal.x += ballToPoint.x*normalScale; cubeGrid.vertices[j].normal.y += ballToPoint.y*normalScale; cubeGrid.vertices[j].normal.z += ballToPoint.z*normalScale; } } //hints glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //need to normalize! glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); cubeGrid.DrawSurface(threshold); glDisable(GL_CULL_FACE); cubeGrid.FreeMemory(); delete[] metaballs; }