VC++下的OpenGL编程

    xiaoxiao2021-04-14  104

    1.值得记住的约定

    一般情况下,VC++下进行OpenGL应用程序开发步骤如下: 1.通过PIXELFORMATDESCRIPTOR结构设置备注描述表DC的像素格式属性。 2.创建渲染描述表RC,并与设备描述表DC建立联系。 3.使用OpenGL作图 4.释放所占用的资源,包括解除DC和RC的联系、删除RC及其关联的DC。 在这里,应该先为应用程序添加所需的变量和函数,对相关变量进行初始化,然后在相应函数中实现DC像素格式设置、RC的创建及其和DC的关联、图形绘制以及资源释放等功能。

    2.一个典型实例

    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关联的RC void 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及其绑定的设备描述表DC void 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); }

    3.输出结果

    转载请注明原文地址: https://ju.6miu.com/read-670643.html

    最新回复(0)