我们用glNewList() 命令来开始构造显示列表。第二个参数GL_COMPILE 告诉OpenGL 我们想预先在内存中构造这个列表,这样每次画的时候就不必重新计算怎么构造物体了。GL_COMPILE 类似于编程。在你写程序的时候,把它装载到编译器里,你每次运行程序都需要重新编译。而如果他已经编译成了.exe 文件,那么每次你只需要点击那个.exe 文件就可以运行它了,不需要编译。当OpenGL 编译过显示列表后,就不需要再每次显示的时候重新编译它了。这就是为什么用显示列表可以加快速度。<?xml:namespace prefix = o />
你可以在glNewList() 和glEngList() 中间加上任何你想加上的代码。可以设置颜色,贴图等等。唯一不能加进去的代码就是会改变显示列表的代码。显示列表一旦建立,你就不能改变它。
比如你想加上glColor3ub(rand()%255,rand()%255,rand()%255) ,使得每一次画物体时都会有不同的颜色。但因为显示列表只会建立一次,所以每次画物体的时候颜色都不会改变。物体将会保持第一次建立显示列表时的颜色。 如果你想改变显示列表的颜色,你只有在调用显示列表之前改变颜色。
成员变量区: int m_GLPixelIndex; HGLRCm_hGLContext; // 绘制环境 GLfloatxrot;// 绕x轴旋转量 GLfloatyrot; // 绕y轴旋转量 GLfloatxspeed;// X旋转速度 GLfloatyspeed; // Y旋转速度 GLfloatz;// 深入屏幕的距离 GLuintfilter; GLuinttexture[1 ]; GLfloatLightAmbient[ 4 ]; // 环境光参数 GLfloatLightDiffuse[ 4 ]; // 漫射光参数 GLfloatLightPosition[ 4 ]; // 光源位置 GLbooleanbLighting;// 是否启用光照 bool lPressed; bool fPressed; GLuintbox; // 保存盒子的显示列表 GLuinttop; // 保存盒子顶部的显示列表 GLuintxloop; // X轴循环变量 GLuintyloop; // Y轴循环变量 static GLfloatboxcol[ 5 ][ 3 ]; static GLfloattopcol[ 5 ][ 3 ];
成员函数区: BOOLCOpenGLDemoView::PreTranslateMessage(MSG * pMsg) { // TODO:Addyourspecializedcodehereand/orcallthebaseclass if (pMsg -> message == WM_KEYDOWN) { SendMessage(pMsg -> message,pMsg -> wParam,pMsg -> lParam); return true ; } else { return CView::PreTranslateMessage(pMsg); } }void COpenGLDemoView::OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags) { // TODO:Addyourmessagehandlercodehereand/orcalldefault switch (nChar) { case VK_LEFT: { // 左键 yspeed -= 0.02f ; break ; } case VK_RIGHT: { // 右键 yspeed += 0.02f ; break ; } case VK_NEXT: { // Page_Down键按下 z += 0.2f ; break ; } case VK_PRIOR: { // Page_Up键按下 z -= 0.2f ; break ; } case VK_UP: { // Page_Up键按下 xspeed -= 0.02f ; break ; } case VK_DOWN: { // Page_Up键按下 xspeed += 0.02f ; break ; } case ' F ' : { fPressed = TRUE; break ; } case ' L ' : { lPressed = TRUE; break ; } default : break ; } CView::OnKeyDown(nChar,nRepCnt,nFlags); }void COpenGLDemoView::OnKeyUp(UINTnChar,UINTnRepCnt,UINTnFlags) { // TODO:Addyourmessagehandlercodehereand/orcalldefault switch (nChar) { case ' F ' : { if (fPressed == TRUE) { filter = (filter + 1 ) % 3 ; } fPressed= FALSE; break ; } case ' L ' : { if (lPressed == TRUE) { // 防止长时间按着'L'键而导致光照持续变化 bLighting = ! bLighting; if (bLighting) { glEnable(GL_LIGHTING); } else { glDisable(GL_LIGHTING); } } lPressed= FALSE; break ; } default : break ; } CView::OnKeyUp(nChar,nRepCnt,nFlags); } GLvoidCOpenGLDemoView::BuildLists(){ box = glGenLists( 2 ); // Generate2DifferentLists glNewList(box,GL_COMPILE); // StartWithTheBoxList glBegin(GL_QUADS); // BottomFace glNormal3f( 0.0f , - 1.0f , 0.0f ); glTexCoord2f( 1.0f , 1.0f );glVertex3f( - 1.0f , - 1.0f , - 1.0f ); glTexCoord2f( 0.0f , 1.0f );glVertex3f( 1.0f , - 1.0f , - 1.0f ); glTexCoord2f( 0.0f , 0.0f );glVertex3f( 1.0f , - 1.0f , 1.0f ); glTexCoord2f( 1.0f , 0.0f );glVertex3f( - 1.0f , - 1.0f , 1.0f ); // FrontFace glNormal3f( 0.0f , 0.0f , 1.0f ); glTexCoord2f( 0.0f , 0.0f );glVertex3f( - 1.0f , - 1.0f , 1.0f ); glTexCoord2f( 1.0f , 0.0f );glVertex3f( 1.0f , - 1.0f , 1.0f ); glTexCoord2f( 1.0f , 1.0f );glVertex3f( 1.0f , 1.0f , 1.0f ); glTexCoord2f( 0.0f , 1.0f );glVertex3f( - 1.0f , 1.0f , 1.0f ); // BackFace glNormal3f( 0.0f , 0.0f , - 1.0f ); glTexCoord2f( 1.0f , 0.0f );glVertex3f( - 1.0f , - 1.0f , - 1.0f ); glTexCoord2f( 1.0f , 1.0f );glVertex3f( - 1.0f , 1.0f , - 1.0f ); glTexCoord2f( 0.0f , 1.0f );glVertex3f( 1.0f , 1.0f , - 1.0f ); glTexCoord2f( 0.0f , 0.0f );glVertex3f( 1.0f , - 1.0f , - 1.0f ); // Rightface glNormal3f( 1.0f , 0.0f , 0.0f ); glTexCoord2f( 1.0f , 0.0f );glVertex3f( 1.0f , - 1.0f , - 1.0f ); glTexCoord2f( 1.0f , 1.0f );glVertex3f( 1.0f , 1.0f , - 1.0f ); glTexCoord2f( 0.0f , 1.0f );glVertex3f( 1.0f , 1.0f , 1.0f ); glTexCoord2f( 0.0f , 0.0f );glVertex3f( 1.0f , - 1.0f , 1.0f ); // LeftFace glNormal3f( - 1.0f , 0.0f , 0.0f ); glTexCoord2f( 0.0f , 0.0f );glVertex3f( - 1.0f , - 1.0f , - 1.0f ); glTexCoord2f( 1.0f , 0.0f );glVertex3f( - 1.0f , - 1.0f , 1.0f ); glTexCoord2f( 1.0f , 1.0f );glVertex3f( - 1.0f , 1.0f , 1.0f ); glTexCoord2f( 0.0f , 1.0f );glVertex3f( - 1.0f , 1.0f , - 1.0f ); glEnd(); glEndList(); top = box + 1 ; // StorageFor"Top"Is"Box"PlusOne glNewList(top,GL_COMPILE); // NowThe"Top"DisplayList glBegin(GL_QUADS); // TopFace glNormal3f( 0.0f , 1.0f , 0.0f ); glTexCoord2f( 0.0f , 1.0f );glVertex3f( - 1.0f , 1.0f , - 1.0f ); glTexCoord2f( 0.0f , 0.0f );glVertex3f( - 1.0f , 1.0f , 1.0f ); glTexCoord2f( 1.0f , 0.0f );glVertex3f( 1.0f , 1.0f , 1.0f ); glTexCoord2f( 1.0f , 1.0f );glVertex3f( 1.0f , 1.0f , - 1.0f ); glEnd(); glEndList(); } int COpenGLDemoView::DrawGLScene() { // Here'sWhereWeDoAllTheDrawing glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); // ClearScreenAndDepthBuffer glPushAttrib(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT); glPushMatrix(); glBindTexture(GL_TEXTURE_2D,texture[ this -> filter]); // 绑定到选定的纹理上 for (yloop = 1 ;yloop < 6 ;yloop ++ ) { for (xloop = 0 ;xloop < yloop;xloop ++ ) { glLoadIdentity(); // ResetTheView glTranslatef( 1.4f + ( float (xloop) * 2.8f ) - ( float (yloop) * 1.4f ),(( 6.0f - float (yloop)) * 2.4f ) - 7.0f ,z); glRotatef( 45.0f - ( 2.0f * yloop) + xrot, 1.0f , 0.0f , 0.0f ); glRotatef( 45.0f + yrot, 0.0f , 1.0f , 0.0f ); glColor3fv(boxcol[yloop - 1 ]); glCallList(box); glColor3fv(topcol[yloop - 1 ]); glCallList(top); } } xrot+= this -> xspeed; yrot += this -> yspeed; return TRUE; // EverythingWentOK } BOOLCOpenGLDemoView::InitGL(GLvoid)// AllSetupForOpenGLGoesHere { if ( ! LoadGLTextures()) // JumpToTextureLoadingRoutine(NEW) { return FALSE; // IfTextureDidn'tLoadReturnFALSE } this -> BuildLists(); glEnable(GL_TEXTURE_2D); // EnableTextureMapping(NEW) glLightfv(GL_LIGHT1,GL_AMBIENT,LightAmbient);// 设置环境光 glLightfv(GL_LIGHT1,GL_DIFFUSE,LightDiffuse); // 设置漫射光 glLightfv(GL_LIGHT1,GL_POSITION,LightPosition); // 设置光源位置 glEnable(GL_LIGHT1); // 启用一号光源 glShadeModel(GL_SMOOTH);// EnableSmoothShading COLORREFcolor = ::GetSysColor(COLOR_3DFACE); glClearColor(( float )GetRValue(color) / 255.0f , ( float )GetGValue(color) / 255.0f , ( float )GetBValue(color) / 255.0f , 1.0 ); glClearDepth( 1.0f ); // DepthBufferSetup glEnable(GL_DEPTH_TEST); // EnablesDepthTesting glDepthFunc(GL_LEQUAL); // TheTypeOfDepthTestingToDo glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); // ReallyNicePerspectiveCalculations return TRUE; // InitializationWentOK }
效果如图所示: