1.1 第一个OpenGL应用
图1-8显示出来的实际上是一个标准的Windows窗口,和OpenGL好像没有关系,尽管我们已经建立了OpenGL的RC。这是因为我们自己的三个主要的OpenGL函数glInit(),glMain(), glShutdown()都是空函数。
为了真正实现OpenGL的功能,我们还需要将这三个函数进行填充。实际上,前面的部分就是OpenGL程序最基本的框架,当然,如果要输出一些内容,就需要再进行补充。
先来看修改后的OpenGL的初始化函数glInit()主体。在glInit函数中,可以把对OpenGL初始化的一切都放在里面。
首先启动阴影平滑,然后再使用glClearColor清除屏幕,清除屏幕所使用的颜色由其中的前面三个参数(分别表示红、绿、蓝三种颜色的分量)来决定。在OpenGL中,0.0f表示颜色最暗,1.0f表示颜色最亮。
int glInit()
{
//启用阴影平滑(Smooth Shading)。
glShadeModel(GL_SMOOTH);
//使用白色作为底色,实际上也就是使用白色来填充屏幕。
glClearColor(1.0f,1.0f,1.0f,0.0f);
//设置深度缓冲
glClearDepth(1.0f);
//启动深度测试
glEnable(GL_DEPTH_TEST);
//深度测试的类型
glDepthFunc(GL_LEQUAL);
//进行透视修正,GL_NICEST表示修正到最佳效果。
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
return TRUE;
}
对于复杂的程序,glInit()中需要设置的更多。
接下来再看glShutdown()。glShutdown()的所用是在程序退出前释放OpenGL占用的资源,包括渲染描述表、设备描述表、窗口句柄,以及撤注销窗口类。
void glShutdown()
{
if (hRC)
{
//将RC和DC分开
if (!wglMakeCurrent(NULL,NULL))
{
MessageBox(NULL,"Fail to unlink RC and DC!","ERROR",MB_OK);
}
//删除渲染描述表hRC
if (!wglDeleteContext(hRC))
{
MessageBox(NULL,"Fail to delete RC!","ERROR",MB_OK);
}
hRC=NULL;
}
if (hDC)
{
if(!ReleaseDC(hWnd,hDC)) // 释放 DC
{
hDC=NULL;
}
}
if (hWnd)
{
if(!DestroyWindow(hWnd)) // 销毁窗口句柄
{
hWnd=NULL; }
}
//注销窗口类
if (!UnregisterClass(szWindowClass,hInst))
{
MessageBox(NULL,"Fail to Unregister Window Class!","ERROR",MB_OK);
hInst=NULL;
}
}
最后是本程序最重要的部分。glMain()首先以彩色缓冲和深度缓冲清除当前的缓冲区,然后加载单位矩阵,再将当前颜色设置成红色,通过glBegin~glEnd绘制一个三角形。最后交换前后缓冲区,将图形显示出来。如图1-9所示。
void glMain()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//向-Z方向平移5个单位
glTranslatef(0.0f, 0.0f,-5.0f);
//当前绘图颜色为红色
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_TRIANGLES); // 绘制三角形
glVertex3f( 0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd();
SwapBuffers(hDC);
}
图1-9 第一个OpenGL应用
到此为止,一个完整的OpenGL程序就完成了,尽管还有些粗糙,也不够规模。但是只要在这个框架上继续进行补充,发挥你的想象力,任何效果都可以创造出来。