我们用glNewList()命令来开始构造显示列表。第二个参数GL_COMPILE告诉OpenGL我们想预先在内存中构造这个列表,这样每次画的时候就不必重新计算怎么构造物体了。GL_COMPILE类似于编程。在你写程序的时候,把它装载到编译器里,你每次运行程序都需要重新编译。而如果他已经编译成了.exe文件,那么每次你只需要点击那个.exe文件就可以运行它了,不需要编译。当OpenGL编译过显示列表后,就不需要再每次显示的时候重新编译它了。这就是为什么用显示列表可以加快速度。
你可以在glNewList()和glEngList()中间加上任何你想加上的代码。可以设置颜色,贴图等等。唯一不能加进去的代码就是会改变显示列表的代码。显示列表一旦建立,你就不能改变它。
比如你想加上glColor3ub(rand()%255,rand()%255,rand()%255),使得每一次画物体时都会有不同的颜色。但因为显示列表只会建立一次,所以每次画物体的时候颜色都不会改变。物体将会保持第一次建立显示列表时的颜色。 如果你想改变显示列表的颜色,你只有在调用显示列表之前改变颜色。
成员变量区:
int m_GLPixelIndex;
HGLRC m_hGLContext;//绘制环境

GLfloat xrot;//绕x轴旋转量
GLfloat yrot;//绕y轴旋转量

GLfloat xspeed; // X 旋转速度
GLfloat yspeed; // Y 旋转速度

GLfloat z; // 深入屏幕的距离

GLuint filter;
GLuint texture[1];
GLfloat LightAmbient[4]; // 环境光参数
GLfloat LightDiffuse[4]; // 漫射光参数
GLfloat LightPosition[4]; // 光源位置

GLboolean bLighting;//是否启用光照
bool lPressed;
bool fPressed;


GLuint box;// 保存盒子的显示列表
GLuint top;// 保存盒子顶部的显示列表
GLuint xloop;// X轴循环变量
GLuint yloop;// Y轴循环变量


static GLfloat boxcol[5][3];

static GLfloat topcol[5][3];
成员函数区:

BOOL COpenGLDemoView::PreTranslateMessage(MSG* pMsg)


{
// TODO: Add your specialized code here and/or call the base class
if(pMsg->message == WM_KEYDOWN)

{
SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
return true;
}
else

{
return CView::PreTranslateMessage(pMsg);
}
}

void COpenGLDemoView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)


{
// TODO: Add your message handler code here and/or call default
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(UINT nChar, UINT nRepCnt, UINT nFlags)


{
// TODO: Add your message handler code here and/or call default
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);
}


GLvoid COpenGLDemoView::BuildLists()


{
box=glGenLists(2); // Generate 2 Different Lists
glNewList(box,GL_COMPILE); // Start With The Box List
glBegin(GL_QUADS);
// Bottom Face
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);
// Front Face
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);
// Back Face
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);
// Right face
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);
// Left Face
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; // Storage For "Top" Is "Box" Plus One
glNewList(top,GL_COMPILE); // Now The "Top" Display List
glBegin(GL_QUADS);
// Top Face
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's Where We Do All The Drawing
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer

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(); // Reset The View
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; // Everything Went OK
}

BOOL COpenGLDemoView::InitGL(GLvoid) // All Setup For OpenGL Goes Here


{
if (!LoadGLTextures()) // Jump To Texture Loading Routine ( NEW )

{
return FALSE; // If Texture Didn't Load Return FALSE
}
this->BuildLists();
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( 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); // Enable Smooth Shading
COLORREF color = ::GetSysColor(COLOR_3DFACE);
glClearColor((float)GetRValue(color)/255.0f,
(float)GetGValue(color)/255.0f,
(float)GetBValue(color)/255.0f,
1.0);

glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations

return TRUE; // Initialization Went OK
} 效果如图所示:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述