VC++下的OpenGL编程:一般情况下,VC++下进行OpenGL应用程序开发步骤如下:1.通过PIXELFORMATDESCRIPTOR结构设置备注描述表DC的像素格式属性。
2.创建渲染描述表RC,并与设备描述表DC建立联系。
3.使用OpenGL作图4.释放所占用的资源,包括解除DC和RC的联系、删除RC及其关联的DC。在这里,应该先为应用程序添加所需的变量和函数,对相关变量进行初始化,然后在相应函数中实现DC像素格式设置、RC的创建及其和DC的关联、图形绘制以及资源释放等功能。
2.1 添加成员变量和成员函数
CClientDC* pDrawDC; // 用于指向当前DC的指针BOOL PixelformatSetting(void); // 用于设置像素格式 void GLSetting(void); // 用于创建渲染描述表RC 并关联RC/DC void DrawGraphics(void); //OpenGL作图2.2 添加消息响应函数
WM_CREATE --- OnCreate(); //该消息响应函数在建立一个窗体前被调用。WM_DESTROY --- OnDestroy(); //窗口撤销时响应此函数,因此在该函数中释放所有被占用的资源。WM_SIZE --- OnSize(); //改变窗口大小时响应此函数,可以调整视场。afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnDestroy(); afx_msg void OnSize(UINT nType, int cx, int cy);2.3 成员函数和消息响应函数添加代码
设置像素格式BOOL CtestGLView::PixelformatSetting(void) { static PIXELFORMATDESCRIPTOR pdf = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW| PFD_SUPPORT_OPENGL| PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 24, 0,0,0,0,0,0,0,0,0,0,0,0, 32, 0,0, PFD_MAIN_PLANE, 0,0,0,0 }; //填充PIXELFORMATDISCRIPTOR int ipixelformat; //获得最佳匹配的像素格式索引 if((ipixelformat = ChoosePixelFormat(pDrawDC->GetSafeHdc(), &pdf))==0) { MessageBox(_T("Choose pixel format failed!")); return FALSE; } //把DC的像素格式设置成由索引值ipixelformat指向的像素格式 if(SetPixelFormat(pDrawDC->GetSafeHdc(),ipixelformat, &pdf) == FALSE) { MessageBox(_T("Set pixel format failed")); return FALSE; } return TRUE; }创建渲染描述表,调用PixelFormatSetting()设置像素格式,创建和DC关联的RCvoid CtestGLView::GLSetting(void) { HGLRC hRC; //渲染描述表句柄 pDrawDC = new CClientDC (this); //使用pDrawDC指向当前DC ASSERT(pDrawDC != NULL); if( !PixelformatSetting()) //设置像素格式 return; //创建和当前DC兼容的RC,并和当前DC关联 hRC = wglCreateContext(pDrawDC->GetSafeHdc()); wglMakeCurrent(pDrawDC->GetSafeHdc(),hRC); }在消息响应函数OnCreate()中调用函数GLSetting(),使得GL环境生效int CtestGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; GLSetting(); return 0; }绘制几何拓扑void CtestGLView::DrawGraphics(void) { //移动物体到显示区 glTranslatef(0.0,0.0,-6.0); //相当于在调整照相机 避免像太大 glRotated(RotateAngle,1,1,1); //以边线的方式绘制三角形 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); //绘制三角形,顺序给出3个三角形的顶点 glBegin(GL_TRIANGLES); glVertex3f(-0.6,0,0); glVertex3f(0.6,0,0); glVertex3f(0.0,0.15,0.6); glVertex3f(-0.6,0,0); glVertex3f(0,0.15,0.6); glVertex3f(0,0.9,0.6); glVertex3f(0,0.9,0.6); glVertex3f(0,0.15,0.6); glVertex3f(0.6,0,0); glEnd(); }OnDraw函数中,图像显示void CtestGLView::OnDraw(CDC* /*pDC*/) { CtestGLDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; static BOOL bBusy = FALSE; //定义开关变量 if(bBusy) //开关 绘制完成后才可以更新缓存 { return; } bBusy = TRUE; glClearColor(0,0,0.5,0.5);//设置背景颜色 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除深度缓存和颜色缓存 glMatrixMode(GL_MODELVIEW); //启动模型视图矩阵 glLoadIdentity(); DrawGraphics(); SwapBuffers(wglGetCurrentDC()); //更新缓存 bBusy = FALSE; }删除渲染描述表RC及其绑定的设备描述表DCvoid CtestGLView::OnDestroy() { CView::OnDestroy(); //删除渲染描述表及其绑定的设备描述表 HGLRC hRC; //OpenGL的渲染描述表 hRC = ::wglGetCurrentContext(); ::wglMakeCurrent(NULL,NULL); //解除当前RC和DC的关联,并把当前RC非当前化 if(hRC) { ::wglDeleteContext(hRC); } if(pDrawDC) { delete pDrawDC; } }2.4 添加人机交互(旋转功能)
采用鼠标左键控制开关,定时旋转方案。WM_BUTTONDOWN --- OnLButtonDown();WM_TIMER --- OnTimer();添加变量:BOOL bRotate; float RotateAngle;void CtestGLView::OnLButtonDown(UINT nFlags, CPoint point) { if (bRotate) { SetTimer(1,100,NULL); } else { KillTimer(1); } bRotate = !bRotate; CView::OnLButtonDown(nFlags, point); } void CtestGLView::OnTimer(UINT_PTR nIDEvent) { //定时器计时达到预定时刻 则旋转角度增加10 if( nIDEvent == 1) { RotateAngle += 10; Invalidate(FALSE); //重新绘制 } CView::OnTimer(nIDEvent); }