在这些步骤的执行过程中,OpenGL可能执行其他的一些操作,例如自动消隐处理等。
另外,景物光栅化之后被送入帧缓冲器之前还可以根据需要对像素数据进行操作。
4.2OpenGL程序的框架设计
OpenGL程序框架的创建包括了四个部分:
创建C++Builder6.0项目;定义C++Builder6.0和OpenGL的接口和变量,通过设计C++Builder6.0和OpenGL的接口,将OpenGL指令嵌入到c++Builder6.0中,做到用户用C++Builder6.0发出指令,OpenGL响应绘图;初始化OpenGL环境;定义创建和绘制物体函数。
4.3.1设置C++Builder6.0环境
启动C++Builder6.0后,默认会生成一个名称为project1的项目,包含了一个名称为Form1的窗体,各文件都采用默认生成的文件名。
在生成默认项目和窗体后,在Form1的“ObjectInspector”中选择”Events“添加FormCreate(>、FormResize(>、FormC1ose(>和FormKeyDown(>四个事件函数。
FormCreate(>事件函数是窗口建立事件的处理函数,在事件函数中主要实现OpenGL的初始化工作。
FormResize(>事件函数重新定位窗口,当窗口发生变化时处理此事件函数。
函数完整代码如下:
{
glViewport(0,0,width,height>;
glMatrixMode(GL_PROJECTION>;
glLosdentity(>;
gluPerspective(45.0,(GLfloat>width/height,3.0,7.0>。
glMatrixMode(GL_MODELVIEW>;
}
FormClose(>响应窗口关闭事件,当窗口关闭时,释放系统资源。
事件代码如下:
if(hRC>wgIDeleteContext(hRC>;
if(hDC>ReleaseDC(Handle,hDC>:
FormKeyDown(>响应键盘输入事件,提供一个键盘输入响应接口。
事件代码如下:
if(Key==VK_ESCAPE>Close(>;
if(Key==VK_F4>
{
fullsereen=lfullscreen。
ChangeResolution(DisplayX,DisplayY,fullscreen>;
}
当按下键盘的Esc键时程序结束,按F4键时,在全屏模式和窗口模式之间切换。
函数ChangeResolution(>用Windows自带的API函数来实现,函数代码如下:
void__fastcallTForml:
:
ChangeResolution(GLsizeix,GLsizeiy,boolfullscreenflag>
{
if(fullscreenflag>
{
SetWindowLong(Handle,GWL_STYLE,WS_P0PUP>。
SetWindowPos(Handle,HWND_TOPMOST,0,0,x,y,SWP_SHOWWINDOW>;
ShowCursor(false>;
}.
else’
{
SetWindowLong(Handle,GWL_STYLE,WS_TILEDWINDOW>:
SetWindowPos(Handle,HWND_TOP,0,0,x,Y,SWP_SHOWW-
INDOW>;
ShowCursor(ture>;
}
}
4.3.2定义接口和变量
OpenGL的库函数被封装在Openg132删动态链接库中,要调用OpenGL只需要在C++Builder程序的头文件中声明即可。
在unit1.h代码中加入如下声明:
#include
#include
#include
这里主要设置在头文件unit1.h的类TForm1中声明private变量:
HGLRChRC。
HDChDC。
boolfullscreen。
GLsizeiDisplayX,DisplayY。
设置好项目和OpenGL接口及声明OpenGL所需的变量后,就可以进行初始化OpenGL的工作了。
4.3.3初始化OpenGL环境
在WindowsXP操作系统中采用C++Builder6.0初始化OpenGL程序的步骤包括:
创建设备描述表DC(DeviceContext>、设置像素格式、创建着色描述表RC(RenderingContext>、设置显示模式和窗口位置大小等。
以下代码都在FormCreate(>事件中实现。
首先创建DC:
任何一个Windows程序都必须处理设备描述表DC,DC告诉Windows
怎样在一个窗口中显示图形信息。
和其它Windows程序一样。
OpenGL应用程序也必须应用DC。
DC包含了与图形设备接口GDI(GraphicalDeviceInterface>有关的内容。
在FormCmate(>中用语句hDC=GetDc(Handle>:
可以获得设备描述表。
其次设置像素格式:
在FormCreate(>中添加下面代码。
找到对应与此前选定的像素格式。
如果找不到对应的像素格式,则关闭窗口,退出程序。
if(lSetPixelFormatDescriptor(hDC>>Close(>。
函数SetPixelFormatDescriptor(hDC>的作用就是设置OpenGL的像素格式,下面是该函数代码:
{
intpixelformat:
PIXELFORMATDESCRIPTORpfd={sized(PIXELFORMATDESCRIPTOR>,1,
PFD_DRAW_TO_WINDOWIPFD_SUPPORT_OPENGLIPFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0,0,0,0,0,0,
0,0,0,
0,0,0,0,
32,
0,0,
PFD_MAIN_PLANE,
0,0,0,0,
}
if((pixelformat=ChoosePixelFormat(hDC,&pfd>>==0>
{
MessageBox(NULL,“ChoosePixelFormatfailed”,“Error”,MB_OK>。
returnfalse。
}
if(SetPixdFonnat(hDC,pixelformat,&pfd>==false>
{
MessageBox(NULL,“SetPixelFormatfailed”,"Error",MB_OK>。
Returnfalse。
}
returntrue。
}
再次创建RC:
OpenGL应用程序除了包含普通Windows程序所必须的DC外,还必须使用着色描述表RC,RC包含了与OpenGL系统发生联系的重要信息,应用程序应根据指定的DC创建一个RC,一个OpenGL应用程序必须拥有
一个RC。
hRC=wglCreateContext(hDC>;
wglMakeCurrent(hDC,hRC>;
最后初始化操作:
初始化代码通过函数InitGL(>实现。
(1)设置初始OpenGL窗口大小,并确定是否使用全屏模式:
DisplayX=640。
DisplayY=480。
fullscreen=false。
ChangeResolution(DisphyX,DisplayY,fullse—men>。
(2>图形背景色在计算机上通常指窗体的背景颜色,这里将窗体背景设置为黑色。
glClearColor(0.0f,0.0f,0.0f,0.0f>:
glclear(GL_COLOR_BUFFER_BIT>。
(3>设置深度缓存三维图形绘制时,一个物体的自身遮挡部分或被其他不透明物体的遮挡部分是随着观测角度、方位等参数的变化而变化的,这时候要进行消隐处理。
消隐需要启动深度测试和设置深度缓存:
glClearDepth(1.0f>;
glEnable(GL_DEFrH_TEST>。
glClear(GL_DEFTH_BUFFEB_BIT>。
(4>透视投影使得远离视点(观察点>的物体看起来小,而离视点近的物体看起来大,其视景体为一个台锥。
在调用投影变换函数前,首先要选择操作透视矩阵和初始化透视矩阵:
glMatrixMode(GL_PROJECTION>。
glLoadldentity(>。
然后设置透视模式并选择模型观察矩阵:
gluPerspective(45.0,(GLfloat>width,height,3.0,7.0>。
glMstrixMode(GL_MODELVIEW>。
(5>光照处理是OpenGL中绘制三维图形的一个重要步骤。
目的是实现富有真实感的图形。
光照处理主要步骤是;创建光源、选择光照模型、定义物体材质属性、并创建和定位。
最后激活光源。
程序中光源设置由函数:
SetupLighting(>实现,代码如下:
GLfloatMaterialAmbient[]={0.5,0.5,0.5,1.0}。
GLfloatMaterialDiffuse[]={1.0,1.0,1.0,1.0}。
GLfloatMateriaISpecular[]={1.0,1.0,1.0,1.0}。
GLfloatMaterialShininess[]={50.0}。
GLfloatAmbientLightPosition[]={0.5,1.0,1.0,0.0}。
GLfloatLightAmbient[]={0.5,0.5,0.5,1.0}。
glMaterialfv{GL_FRONT,GL_AMBIENT,MaterialAmbient};
glMaterialfv{GL_FRONT,GL_DIFFUSE,MaterialSpecular};
glMaterlalfv{GL_FRONT,GL_SPECULAR,MaterialSpecalar};
glMaterialfv{GL_FRONT,GL_SHININESS,MatefialShininess}。
glLightfv{GL_LIGHT0,GL_POSITION,AmbientLightPosition};
glLightModelfv{GL_LIGHT_MODEIL_AMBIENT,LightAmbient}。
glEnable