正文

OpenGL基本框架2006-08-05 21:25:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/vfdff/17303.html

分享到:

摘于:http://cracker007.programfan.com           对于windows下的编程,似乎无论是win32 app还是dll,或者mfc,最重要的,也是最难的,都是那个框架。OpenGL也是如此。好在我已经饱经mfc的洗礼,明白如何下手分析框架。不过发现网上的很多程序框架都不是完全一样,不知道这里有没有什么标准?有些代码段去掉之后也仍然没有问题的。这似乎印证了csdn上的一句话:OpenGL出了错,什么都不会做; DirectX出了错,什么都做的出来。^-^ 研究了很多例子之后,我自己总结出了一个最简单、易懂的通用框架,并且给出了重要部分的注释:   /******************************by CRACKER007*******************************/     BOOL CGdlg::InitialPixelFormat()    //此函数被后面的CreateRC调用{ static PIXELFORMATDESCRIPTOR pfd= {  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,0,   32,   0,   0,   PFD_MAIN_PLANE,   0,   0,0,0 }; int pixelformat;  //下面两个if用来选择与pDC最匹配的硬件像素格式 if((pixelformat=ChoosePixelFormat(pDC->GetSafeHdc(),&pfd))==0) {  MessageBox("ChoosePixelFormat failed");  return FALSE; } if(SetPixelFormat(pDC->GetSafeHdc(),pixelformat,&pfd)==FALSE) {  MessageBox("SetPixelFormat failed");  return FALSE; } return TRUE;}----------------------------------------------------------------------------void CGdlg::CreateRC()    //创建RC的一系列操作{ PIXELFORMATDESCRIPTOR pdf;   int n; HGLRC hrc;  //rc句柄 pDC=new CClientDC(this);  //pDC声明于类定义中: CClientDC *pDC ASSERT(pDC!=NULL); if(!InitialPixelFormat())  //调用前面定义的函数设置像素格式 {  return; } n=::GetPixelFormat(pDC->GetSafeHdc()); //这两行用于测试像素格式 ::DescribePixelFormat(pDC->GetSafeHdc(),n,sizeof(pfd),&pfd); hrc=wglCreateContext(pDC->GetSafeHdc());//创建rc wglMakeCurrent(pDC->GetSafeHdc(),hrc); //使rc当前化}---------------------------------------------------------------------------void CGdlg::FirstDraw()   //初始化{        glClearDepth(1.0f);  //设置深度缓存        glEnable(GL_DEPTH_TEST);  //启用深度测试        glDepthFunc(GL_LEQUAL);  //深度测试的类型        glMatrixMode(GL_MODELVIEW); glLoadIdentity();}---------------------------------------------------------------------------void CGdlg::ReleaseRC()    //释放RC{ HGLRC hrc; hrc=::wglGetCurrentContext(); ::wglMakeCurrent(NULL,NULL); if(hrc) {  ::wglDeleteContext(hrc); } if(pDC) {  delete pDC; }}----------------------------------------------------------------------------void CGdlg::ReDraw()    //用于OnDraw/OnPaint{ static BOOL bBusy=FALSE;  if(bBusy) {  return; }        bBusy=TRUE; glClearColor(0.2f,0.2f,0.5f,1.0f);  //设置背景色 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//刷新深度缓存                                                         //以及背景色            glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //DrawOG();       //具体绘图(如果用glClearColor设置了背景色,                          //那么要记得用glClear刷新 glFinish(); SwapBuffers(wglGetCurrentDC()); bBusy=FALSE;}---------------------------------------------------------------------------开始OpenGl操作所对应的消息函数内容应该包含:CreateRC();FirstDraw();Invalidate(); (或者RedrawWindow(),关于两者的区别,请看注)----------------------------------------------------------------------------结束OpenGl操作所对应的消息函数内容应该包含:ReleaseRC();----------------------------------------------------------------------------OnDraw/OnPaint的内容应该包含:ReDraw();----------------------------------------------------------------------------注一:1 使用Invalidate(..)可以触发WM_PAINT,但系统并不立即重绘,这是因为WM_PAINT的2个特性:low priority、Windows combines multiple WM_PAINT messages in the  message queue into a single message, 如果想立即重绘,那么就需要调用UpdateWindow();2 RedrawWindow()可以实现立即重绘;3 如果更新的是一个区域RGN的时候它没法调用Invalidate实现,因为Invalidate只对矩形有效,但是RedrawWindow可以。 注二:如果要使用GDI函数,必须在glFinish()和SwapBuffers(wglGetCurrentDC())函数之后调用,否则会产生闪烁。如果一定要在绘制OpenGL结束之前使用GDI函数,那么想要除去闪烁则只能使用SingleBuffer模式。

阅读(610) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册