把OnPreCreate改写成如下所示:
<span style="font-size:14px;">BOOL COpenGLDemoView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS); return CView::PreCreateWindow(cs); }</span>
2.定义窗口的像素格式
产生一个RC的第一步是定义窗口的像素格式。像素格式决定窗口着所显示的图形在内存中是如何表示的。由像素格式控制的参数包括:颜色深度、缓冲模式和所支持的绘画接口。在下面将有对这些参数的设置。我们先在COpenGLDemoView的类中添加一个保护型的成员函数BOOL SetWindowPixelFormat(HDC hDC)(用鼠标右键添加)和保护型的成员变量:int m_GLPixelIndex;
并编辑其中的代码如下:
<span style="font-size:14px;">BOOL COpenGLDemoView::SetWindowPixelFormat(HDC hDC) { //定义窗口的像素格式 PIXELFORMATDESCRIPTOR pixelDesc= { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| PFD_DOUBLEBUFFER|PFD_SUPPORT_GDI, 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 }; this->m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc); if(this->m_GLPixelIndex==0) { this->m_GLPixelIndex = 1; if(DescribePixelFormat(hDC,this->m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0) { return FALSE; } } if(SetPixelFormat(hDC,this->m_GLPixelIndex,&pixelDesc)==FALSE) { return FALSE; } return TRUE; }</span>代码解释:
通常的OpenGL发行版本并不包括所有的标志(flag)。wFlags能接收以下标志:
PFD_DRAW_TO_WINDOW 使之能在窗口或者其他设备窗口画图;一旦初始化完我们的结构,我们就想知道与要求最相近的系统象素格式。我们可以这样做:
m_hGLPixelIndex = ChoosePixelFormat(hDC, &pixelDesc);<span style="font-size:14px;">BOOL COpenGLDemoView::CreateViewGLContext(HDC hDC) { this->m_hGLContext = wglCreateContext(hDC); if(this->m_hGLContext==NULL) {//创建失败 return FALSE; } if(wglMakeCurrent(hDC,this->m_hGLContext)==FALSE) {//选为当前RC失败 return FALSE; } return TRUE; } </span>4.在OnCreate函数中调用此函数:
<span style="font-size:14px;">int COpenGLDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here HWND hWnd = this->GetSafeHwnd(); HDC hDC = ::GetDC(hWnd); if(this->SetWindowPixelFormat(hDC)==FALSE) { return 0; } if(this->CreateViewGLContext(hDC)==FALSE) { return 0; } return 0; } <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span></span>5.添加WM_DESTROY的消息处理函数Ondestroy( ),使之如下所示:
<span style="font-size:14px;">void COpenGLDemoView::OnDestroy() { CView::OnDestroy(); // TODO: Add your message handler code here if(wglGetCurrentContext()!=NULL) { wglMakeCurrent(NULL,NULL); } if(this->m_hGLContext!=NULL) { wglDeleteContext(this->m_hGLContext); this->m_hGLContext = NULL; } } </span>6.编辑COpenGLDemoView的构造函数,使之如下所示:
<span style="font-size:14px;">COpenGLDemoView::COpenGLDemoView() { // TODO: add construction code here this->m_GLPixelIndex = 0; this->m_hGLContext = NULL; }</span>至此,我们已经构造好了框架,使程序可以利用OpenGL进行画图了。你可能已经注意到了,我们在程序开头产生了一个RC,自始自终都使用它。这与大多数GDI程序不同。在GDI程序中,DC在需要时才产生,并且是画完立刻释放掉。实际上,RC也可以这样做;但要记住,产生一个RC需要很多处理器时间。因此,要想获得高性能流畅的图像和图形,最好只产生RC一次,并始终用它,直到程序结束。
<span style="font-size:14px;">void COpenGLDemoView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // TODO: Add your message handler code here GLsizei width,height; GLdouble aspect; width = cx; height = cy; if(cy==0) { aspect = (GLdouble)width; } else { aspect = (GLdouble)width/(GLdouble)height; } glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0,500.0*aspect,0.0,500.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } </span>用Classwizard为COpenGLDemoView添加WM_PAINT的消息处理函数OnPaint,代码如下:
<span style="font-size:14px;">void COpenGLDemoView::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here // Do not call CView::OnPaint() for painting messages glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON); glColor4f(1.0f,0.0f,0.0f,1.0f); glVertex2f(100.0f,50.0f); glColor4f(0.0f,1.0f,0.0f,1.0f); glVertex2f(450.0f,400.0f); glColor4f(0.0f,0.0f,1.0f,1.0f); glVertex2f(450.0f,50.0f); glEnd(); glFlush(); }</span>
这个程序的运行结果是黑色背景下的一个绚丽多彩的三角形。
(1)
要注意,GDI命令是没有设计双缓存的。我们首先把使用InvalidateRect(null)的地方改成InvalidateRect(NULL,FALSE)。这样做是使GDI的重画命令失效,由OpenGL的命令进行重画;(2)
将像素格式定义成支持双缓存的(注:PFD_DOUBLEBUFFER和PFD_SUPPORT_GDI只能取一个,两者相互冲突)。(3)
我们得告诉OpenGL在后台缓存中画图,在视类的OnSize()的最后一行加入:glDrawBuffer (GL_BACK);
(4)
最后我们得把后台缓存的内容换到前台缓存中,在视类的OnPaint()的最后一行加入:SwapBuffers(dc.m_ ps.hdc)。
7、Z缓冲区的问题:要使三维物体显得更流畅,前后各面的空间关系正确,一定得使用Z缓冲技术;否则,前后各面的位置就会相互重叠,不能正确显示。Z缓冲区存储物体每一个点的值,这个值表明此点离人眼的距离。Z缓冲需要占用大量的内存和CPU时间。启用Z缓冲只需在OnSize()的最后加上glEnable (GL_DEPTH_TEST);要记住:在每次重绘之前,应使用glClear(GL_DEPTH_BUFFER_BIT)语句清空Z缓冲区。OpenGL在MFC中的使用总结(一),布布扣,bubuko.com
原文地址:http://blog.csdn.net/sin_geek/article/details/38731319