OpenGL基本框架

来源:互联网 发布:金融数据交易平台 编辑:程序博客网 时间:2024/06/11 04:23
/******************************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模式。
原创粉丝点击