/****************************************************************************** * Renders the modifier's visual representation and computes its bounding box. ******************************************************************************/ Box3 SliceModifier::renderVisual(TimePoint time, ObjectNode* contextNode, SceneRenderer* renderer) { TimeInterval interval; Box3 bb = contextNode->localBoundingBox(time); if(bb.isEmpty()) return Box3(); Plane3 plane = slicingPlane(time, interval); FloatType sliceWidth = 0; if(_widthCtrl) sliceWidth = _widthCtrl->getFloatValue(time, interval); ColorA color(0.8f, 0.3f, 0.3f); if(sliceWidth <= 0) { return renderPlane(renderer, plane, bb, color); } else { plane.dist += sliceWidth / 2; Box3 box = renderPlane(renderer, plane, bb, color); plane.dist -= sliceWidth; box.addBox(renderPlane(renderer, plane, bb, color)); return box; } }
void PlayerModel::render() { TextureManager::getInstance()->enableTexture(); glBindTexture(GL_TEXTURE_2D, TextureManager::getInstance()->getTextures("gold.bmp")); glPushMatrix(); glScalef(0.3f,0.3f,0.3f); glColor3f(1, 1, 0); renderPlane(); glPushMatrix(); glTranslatef(0, 1.0f, 0); renderPlane(); glPopMatrix(); //front renderOneSide(); //right side glPushMatrix(); glTranslatef(3.0f, 0.0f, 0.0f); glRotated(-90.0f, 0, 1.0f, 0); renderOneSide(); glPopMatrix(); //back glPushMatrix(); glTranslatef(3.0f, 0.0f, 3.0f); glRotated(180.0f, 0, 1.0f, 0); renderOneSide(); glPopMatrix(); //left side glPushMatrix(); glTranslatef(0.0f, 0.0f, 3.0f); glRotated(90.0f, 0, 1.0f, 0); renderOneSide(); glPopMatrix(); glPopMatrix(); glDisable(GL_TEXTURE_2D); }
void Planes::render() { if(displaylist_index) glCallList(displaylist_index); else { for(int plane_index=0;plane_index<plane_number;++plane_index) { if(plane_enabled[plane_index]) renderPlane(plane_index); } } }
void renderFn() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); g_program.use(); setPerspective(); glActiveTexture(GL_TEXTURE9); glBindTexture(GL_TEXTURE_2D, omap2); g_program.setUniform("MaxTessLevel", max_tess); g_program.setUniform("ModelView", g_modelview); g_program.setUniform("Projection", g_projection); g_program.setUniform("MVP", g_projection * g_modelview); g_program.setUniform("NormalMatrix", glm::inverseTranspose(mat3(g_modelview))); g_program.setUniform("MousePosition", mouse); g_program.setUniform("Time", elapsed); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); renderLand(); d_program.use(); glUniformSubroutinesuiv(GL_VERTEX_SHADER, 1, &plv); glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &plf); glActiveTexture(GL_TEXTURE9); glBindTexture(GL_TEXTURE_2D, plane); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); renderPlane(scene->mRootNode); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); d_program.setUniform("FrameTime", clockdiff); d_program.setUniform("Elapsed", elapsed); glUniformSubroutinesuiv(GL_VERTEX_SHADER, 1, &pav); glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &paf); renderParticles(); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); }
void Planes::setEnableStatus(bool status,int plane_idx) { if(plane_idx<=0||plane_idx>plane_number) return; plane_enabled[plane_idx-1]=status?1:0; //update display list glDeleteLists(displaylist_index,1); //build display list for the enabled planes displaylist_index=glGenLists(1); if(displaylist_index!=0) { glNewList(displaylist_index,GL_COMPILE); for(int plane_index=0;plane_index<plane_number;++plane_index) { if(plane_enabled[plane_index]) renderPlane(plane_index); } glEndList(); } }
//------------------------------------------------------------------------------ void PlaneAnimation::clockDetected() { if (clockCounter == 0) { if (addingX) { if (xCoefficient >= 0.5) addingX = false; } else { if (xCoefficient <= -0.5) addingX = true; } if (addingY) { if (yCoefficient >= 0.75) addingY = false; } else { if (yCoefficient <= -0.75) addingY = true; } if (addingX) { xCoefficient += 0.25; } else { xCoefficient -= 0.25; } if (addingY) { yCoefficient += 0.25; } else { yCoefficient -= 0.25; } // qDebug() << "xCoeff " << xCoefficient; renderPlane(); } clockCounter++; clockCounter %= NUM_CLOCKS_PER_BEAT / 6; }
void renderPlane(const struct aiNode *nd) { aiMatrix4x4 m = nd->mTransformation; m.Transpose(); GLfloat aux[16]; memcpy(aux, &m, sizeof(GLfloat) * 16); mat4 matrix = mstack.top() * glm::make_mat4(aux); mstack.push(matrix); for (GLuint n = 0; n < nd->mNumMeshes; ++n) { GLuint index = nd->mMeshes[n]; const aiMesh* mesh = scene->mMeshes[index]; d_program.setUniform("ModelView", mstack.top()); d_program.setUniform("Projection", pstack.top()); d_program.setUniform("MVP", pstack.top() * mstack.top()); d_program.setUniform("NormalMatrix", glm::inverseTranspose(mat3(mstack.top()) * mat3(g_modelview))); if (mesh->mPrimitiveTypes == aiPrimitiveType_TRIANGLE) { glBindVertexArray(vaos[index]); glDrawElements(GL_TRIANGLES, index_count[index], GL_UNSIGNED_INT, 0); } else if (mesh->mPrimitiveTypes == aiPrimitiveType_POINT) { glBindVertexArray(vaos[index]); glDrawElements(GL_POINTS, index_count[index], GL_UNSIGNED_INT, 0); } else if (mesh->mPrimitiveTypes == aiPrimitiveType_LINE) { glBindVertexArray(vaos[index]); glDrawElements(GL_LINES, index_count[index], GL_UNSIGNED_INT, 0); } } for (GLuint n = 0; n < nd->mNumChildren; ++n) renderPlane(nd->mChildren[n]); mstack.pop(); }
void ViewWindow::onIdle(const float delta) { if (NULL == getRenderContex()) { return; } // if (!getRenderContex()->isInitialized()) { getRenderContex()->setWaitForVBL(false); int index = 0; bool pf = false; for (int i = 0; i != getRenderContex()->getDevicesNumber(); ++i) { DeviceInfo di = getRenderContex()->getDeviceInfo(i); std::string dp(di.identifier_.Description); if (dp.find("PerfHUD") != std::string::npos) { index = i; pf = true; break; } } getRenderContex()->createDevice(m_hWnd, index, 0, true, true, Vector2::Zero); getGlobal()->create(); camera_.setSpeed(5.0f); Vector3 minBound = -Vector3( 100.5f, 0.f, 100.5f ); Vector3 maxBound = Vector3(10000, 5000.0f, 10000.0f); camera_.limit_ = BoundingBox( minBound, maxBound ); camera_.create(30, MATH_PI*0.75f, MATH_PI_Half*0.5f); // Camera c = getRenderContex()->getCamera(); c.setFarPlane(10000.0f); getRenderContex()->setCamera(c); getRenderContex()->updateProjectionMatrix(); getSceneManager()->setRunType(eRunType_Editor); getSceneManager()->setAllChunksVisible(true); // { font_ = FontManager::getPointer()->createFont(std::string("freetype\\LuYaHeiMb.TTF"), 18, eFontProperty_Normal, "freeNormal"); } } // camera_.update(delta, 0.0f); getSceneManager()->update(delta); { getGlobal()->update(delta); } // getRenderContex()->setViewMatrix(camera_.view_); // u32 clearFlags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER; if ( getRenderContex()->isStencilAvailable() ) clearFlags |= D3DCLEAR_STENCIL; static Vector4 scc(0.5f,0.5f,0.5f, 0.5f); getRenderContex()->getDxDevice()->Clear( 0, NULL, clearFlags, scc.getARGB(), 1, 0 ); getRenderContex()->beginScene(); //plane renderPlane(); //axis renderAxisXYZ(); // if (getSceneManager()) { getSceneManager()->render(); getGlobal()->render(); } //屏幕字,最后画 { std::ostringstream ss; ss<<"FPS = "<<_fps; font_->render(Vector2(10, 10), Vector4(1, 0, 0, 1), ss.str()); } font_->render(); getRenderContex()->endScene(); getRenderContex()->present(); }
int main( void ) { //init bullet initBullet(); // Initialise GLFW if( !glfwInit() ) { fprintf( stderr, "Failed to initialize GLFW\n" ); return -1; } glfwWindowHint(GLFW_SAMPLES, 4); // glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //screen resolution GLFW const GLFWvidmode * mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); int w = mode->width; int h = mode->height; if(MessageBox(NULL, L"Would you like to run in fullscreen?", L"Fullscreen", MB_ICONQUESTION | MB_YESNO) == IDYES) { window = glfwCreateWindow( w, h, "Ray Tracing - Alfonso Oricchio", glfwGetPrimaryMonitor(), NULL); printf("fullscreen\n"); } else { window = glfwCreateWindow( WINDOW_WIDTH, WINDOW_HEIGHT, "Ray Tracing - Alfonso Oricchio", NULL, NULL); printf("window\n"); } // Open a window and create its OpenGL context if( window == NULL ){ fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" ); glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // Initialize GLEW glewExperimental = true; // Needed for core profile if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); return -1; } // Ensure we can capture the escape key being pressed below glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); glfwSetCursorPos(window, WINDOW_WIDTH/2, WINDOW_HEIGHT/2); // Dark blue background glClearColor(0.0f, 0.0f, 0.4f, 0.0f); // Enable depth test glEnable(GL_DEPTH_TEST); // Accept fragment if it closer to the camera than the former one glDepthFunc(GL_LESS); // Cull triangles which normal is not towards the camera //glEnable(GL_CULL_FACE); GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); // Create and compile our GLSL program from the shaders GLuint depthProgramID = LoadShaders( "DepthRTT.vertexshader", "DepthRTT.fragmentshader" ); // Get a handle for our "MVP" uniform GLuint depthMatrixID = glGetUniformLocation(depthProgramID, "depthMVP"); // The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer. GLuint FramebufferName = 0; glGenFramebuffers(1, &FramebufferName); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); // Depth texture. Slower than a depth buffer, but you can sample it later in your shader GLuint depthTexture; glGenTextures(1, &depthTexture); glBindTexture(GL_TEXTURE_2D, depthTexture); glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, 1024, 1024, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0); // No color output in the bound framebuffer, only depth. glDrawBuffer(GL_NONE); // Always check that our framebuffer is ok if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) return false; /***********************************************************/ // The quad's FBO. Used only for visualizing the shadowmap. static const GLfloat g_quad_vertex_buffer_data[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, }; GLuint quad_vertexbuffer; glGenBuffers(1, &quad_vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW); // Create and compile our GLSL program from the shaders GLuint quad_programID = LoadShaders( "Passthrough.vertexshader", "SimpleTexture.fragmentshader" ); GLuint texID = glGetUniformLocation(quad_programID, "texture"); /**********************************************************/ // Create and compile our GLSL program from the shaders GLuint programID = LoadShaders( "TransformVertexShader.vertexshader", "ColorFragmentShader.fragmentshader" ); // Get a handle for our "MVP" uniform GLuint MatrixID = glGetUniformLocation(programID, "MVP"); GLuint ViewMatrixID = glGetUniformLocation(programID, "V"); GLuint ModelMatrixID = glGetUniformLocation(programID, "M"); GLuint DepthBiasID = glGetUniformLocation(programID, "DepthBiasMVP"); GLuint ShadowMapID = glGetUniformLocation(programID, "shadowMap"); // Get a handle for our "LightPosition" uniform GLuint lightInvDirID = glGetUniformLocation(programID, "LightInvDirection_worldspace"); //CUBO1 addBox(2,2,2,0,0,0,1.0); //CUBO2 addBox2(2,2,2,0,6,0,1.0); //FLOOR initFloor(); //WALL initWall(); //BALL addScene(); do{ world->stepSimulation(1/60.f); if (glfwGetKey( window, GLFW_KEY_SPACE ) == GLFW_PRESS){ btRigidBody* ball = addBall(1.0,CamGetPosition().x,CamGetPosition().y,CamGetPosition().z,2.0); ball->setLinearVelocity(btVector3((CamGetDirection().x*50),(CamGetDirection().y*50),(CamGetDirection().z*50))); } // Render to our framebuffer glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); glViewport(0,0,1024,1024); // Render on the whole framebuffer, complete from the lower left corner to the upper right // Clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ////////////////////////////// // Use our shader //SHADOW RENDER glUseProgram(depthProgramID); glm::vec3 lightInvDir = glm::vec3(0.5f,2,2); // Compute the MVP matrix from the light's point of view glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,20); glm::mat4 depthViewMatrix = glm::lookAt(lightInvDir, glm::vec3(0,0,0), glm::vec3(0,1,0)); // or, for spot light : //glm::vec3 lightPos(5, 20, 20); //glm::mat4 depthProjectionMatrix = glm::perspective<float>(45.0f, 1.0f, 2.0f, 50.0f); //glm::mat4 depthViewMatrix = glm::lookAt(lightPos, lightPos-lightInvDir, glm::vec3(0,1,0)); glm::mat4 depthModelMatrix = glm::mat4(1.0); glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix; // Send our transformation to the currently bound shader, // in the "MVP" uniform glUniformMatrix4fv(depthMatrixID, 1, GL_FALSE, &depthMVP[0][0]); // CUBE1 ------------------------------------------------------------------------- renderBox(bodies[0],true); //just a cube not really needed //CUBE2 -------------------------------------------------------------------------- renderBox2(bodies[1],true); //just a cube not really needed //FLOOR -------------------------------------------------------------------------- renderPlane(bodies[2],true); //floor //WALL --------------------------------------------------------------------------- renderWall(bodies[3],true); //back wall //CASTLE ------------------------------------------------------------------------- renderScene(true); //castle, main scene //BALL --------------------------------------------------------------------------- int iv; for(iv = 4; iv < bodies.size();iv++) { renderBall(bodies[iv],(iv - 4),true); //"cannon balls" shooted from the camera } ////////////////////////////// //STANDARD RENDER // Compute the MVP matrix from keyboard and mouse input // Clear the screen // Render to the screen glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0,0,1024,768); // Render on the whole framebuffer, complete from the lower left corner to the upper right glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Use our shader glUseProgram(programID); computeMatricesFromInputs(); glm::mat4 ProjectionMatrix = getProjectionMatrix(); glm::mat4 ViewMatrix = getViewMatrix(); glm::mat4 ModelMatrix = glm::mat4(1.0); glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix; glm::mat4 biasMatrix( 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); glm::mat4 depthBiasMVP = biasMatrix*depthMVP; // Send our transformation to the currently bound shader, // in the "MVP" uniform glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]); glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]); glUniformMatrix4fv(DepthBiasID, 1, GL_FALSE, &depthBiasMVP[0][0]); glUniform3f(lightInvDirID, lightInvDir.x, lightInvDir.y, lightInvDir.z); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, depthTexture); glUniform1i(ShadowMapID, 0); // CUBE1 ------------------------------------------------------------------------- renderBox(bodies[0],false); //just a cube not really needed //CUBE2 -------------------------------------------------------------------------- renderBox2(bodies[1],false); //just a cube not really needed //FLOOR -------------------------------------------------------------------------- renderPlane(bodies[2],false); //floor //WALL --------------------------------------------------------------------------- renderWall(bodies[3],false); //back wall //CASTLE ------------------------------------------------------------------------- renderScene(false); //castle, main scene //BALL --------------------------------------------------------------------------- // int iv; for(iv = 4; iv < bodies.size();iv++) { renderBall(bodies[iv],(iv - 4),false); //"cannon balls" shooted from the camera } /*--------------------------------------------------*/ // Optionally render the shadowmap (for debug only) // Render only on a corner of the window (or we we won't see the real rendering...) glViewport(0,0,512,512); // Use our shader glUseProgram(quad_programID); // Bind our texture in Texture Unit 0 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, depthTexture); // Set our "renderedTexture" sampler to user Texture Unit 0 glUniform1i(texID, 0); // 1rst attribute buffer : vertices glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); glVertexAttribPointer( 0, // attribute 0. No particular reason for 0, but must match the layout in the shader. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); // Draw the triangle ! // You have to disable GL_COMPARE_R_TO_TEXTURE above in order to see anything ! //glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles glDisableVertexAttribArray(0); /*--------------------------------------------------*/ // Swap buffers glfwSwapBuffers(window); glfwPollEvents(); } // Check if the ESC key was pressed or the window was closed while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 ); deleteALL(); glDeleteProgram(programID); glDeleteVertexArrays(1, &VertexArrayID); // Close OpenGL window and terminate GLFW glfwTerminate(); return 0; }
Planes::Planes(const char* config_file_name,unsigned int plane_number):plane_number(plane_number) { ConfigFile config_file; plane_enabled.resize(plane_number); plane_bounce.resize(plane_number); plane_center.resize(plane_number); plane_normal.resize(plane_number); plane_size.resize(plane_number); plane_color.resize(plane_number); plane_ambient.resize(plane_number); plane_diffuse.resize(plane_number); plane_specular.resize(plane_number); plane_shininess.resize(plane_number); for(int plane_index=0;plane_index<plane_number;++plane_index) { char option_name[128]; char plane_index_ch='0'+plane_index; sprintf(option_name,"planeEnabled_%c",plane_index_ch); config_file.addOption(option_name,&plane_enabled[plane_index]); sprintf(option_name,"planeBounce_%c",plane_index_ch); config_file.addOption(option_name,&plane_bounce[plane_index]); sprintf(option_name,"planeCenter_%c_X",plane_index_ch); config_file.addOption(option_name,&plane_center[plane_index][0]); sprintf(option_name,"planeCenter_%c_Y",plane_index_ch); config_file.addOption(option_name,&plane_center[plane_index][1]); sprintf(option_name,"planeCenter_%c_Z",plane_index_ch); config_file.addOption(option_name,&plane_center[plane_index][2]); sprintf(option_name,"planeNormal_%c_X",plane_index_ch); config_file.addOption(option_name,&plane_normal[plane_index][0]); sprintf(option_name,"planeNormal_%c_Y",plane_index_ch); config_file.addOption(option_name,&plane_normal[plane_index][1]); sprintf(option_name,"planeNormal_%c_Z",plane_index_ch); config_file.addOption(option_name,&plane_normal[plane_index][2]); sprintf(option_name,"planeSize_%c",plane_index_ch); config_file.addOption(option_name,&plane_size[plane_index]); sprintf(option_name,"planeColor_%c_X",plane_index_ch); config_file.addOption(option_name,&plane_color[plane_index][0]); sprintf(option_name,"planeColor_%c_Y",plane_index_ch); config_file.addOption(option_name,&plane_color[plane_index][1]); sprintf(option_name,"planeColor_%c_Z",plane_index_ch); config_file.addOption(option_name,&plane_color[plane_index][2]); sprintf(option_name,"planeAmbient_%c",plane_index_ch); config_file.addOption(option_name,&plane_ambient[plane_index]); sprintf(option_name,"planeDiffuse_%c",plane_index_ch); config_file.addOption(option_name,&plane_diffuse[plane_index]); sprintf(option_name,"planeSpecular_%c",plane_index_ch); config_file.addOption(option_name,&plane_specular[plane_index]); sprintf(option_name,"planeShininess_%c",plane_index_ch); config_file.addOption(option_name,&plane_shininess[plane_index]); } printf("Parsing planes from %s...\n",config_file_name); if(config_file.parseOptions(config_file_name)!=0) throw 1; config_file.printOptions(); //build display list for the enabled planes displaylist_index=glGenLists(1); if(displaylist_index!=0) { glNewList(displaylist_index,GL_COMPILE); for(int plane_index=0;plane_index<plane_number;++plane_index) { if(plane_enabled[plane_index]) renderPlane(plane_index); } glEndList(); } else printf("Warning: Failed to create display list for planes.\n"); }