源代码下载:OpenGL_ch2.rar
WGL – Windows的 OpenGL扩展层
The WGL extension consists of a set of functions (wglCreateContext, wglDeleteContext etc.) and structures (such as PIXELFORMATDESCRIPTOR, GLYPHMETRICSFLOAT) etc. Thus every OpenGL implementation has a platform-specific portion which has to be set up and used according to the particular platform.
设备上下文
The Windows Graphical Device Interface (GDI) is capable of drawing to screen, to memory, to printers or to any other device that provides a GDI interface layer and that can process GDI calls. GDI accomplishes this by a rendering handle to the currently selected device, which is called the device context, or DC.
绘制上下文
A rendering context is the OpenGL equivalent of the GDI DC. All OpenGL calls are rendered to the device through a RC. The rendering context maintains OpenGL state variables such as current background color, current color etc. just as the DC maintains GDI state variables such as current pen, current brush etc.
像素格式
Pixel formats are the translation layer between OpenGL calls and the rendering operation that Windows performs.
举个例子,若像素格式只支持很少一部分颜色值,则OpenGL在用RGB值(128,120,135)绘制一个像素时,就可能使用转换后的值(128,128,128)来绘制.
The pixel format selected essentially describes such things as how colors are displayed, depth of field resolution and what additional capabilities are supported by the rendering context created.
第一个基于MFC的OpenGL应用程
开发环境:VC6.0
1, 首先下载需要的GLUT头文件,DLL和Lib文件,下载链接: glutdlls37beta.zip (149 kilobytes),解压缩后把gltu.h放到"VC98/Include/GL"下,把glut.lib和glut32.lib放到"VC9/Lib" 下,glut32.dll和glut.dll放到你创建的应用程序的运行目录下
2, 创建一个MFC SDI应用程序,在项目属性中加入所需要链接的库文件
1, 在stdafx.h中加入下列语句:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->//OpenGLHeaders
#include<gl/gl.h>
#include<gl/glu.h>
#include<gl/glut.h>
#include<gl/glaux.h>
2, 打开ClassWizard,选择CCY457OpenGLView类,为下述消息加入消息处理函数:WM_CREATE (for OnCreate), WM_DESTROY (for OnDestroy), WM_SIZE (for OnSize), WM_ERASEBACKGROUND (for OnEraseBkground).
3,在窗口创建之前我们必须设置窗口风格包含WS_CLIPCHILDREN和 WS_CLIPSIBLINGS,从而避免OpenGL绘制到其他窗口中去。这些应该放在PreCreateWindow()中。
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->BOOLCCY457OpenGLView::PreCreateWindow(CREATESTRUCT&cs)
{
//TODO:ModifytheWindowclassorstylesherebymodifying
//theCREATESTRUCTcs
//AnOpenGLWindowmustbecreatedwiththefollowingflags
cs.style|=WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
returnCView::PreCreateWindow(cs);
}
4,在CCY457OpenGLView.h中加入如下语句:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->HGLRCm_hRC;//RenderingContext
CDC*m_pDC;//DeviceContext
BOOLInitializeOpenGL();//InitializeOpenGL
BOOLSetupPixelFormat();//SetupthePixelFormat
voidRenderScene();//RendertheScene
5,在OnCreate中我们将通过建立像素格式和绘制上下文来初始化OpenGL. 在InitializeOpenGL()中会创建一个设备上下文(DC),为这个DC选择一个像素格式,创建和这个DC相关的绘制上下文(RC),然后选择这个RC.这个函数会调用SetupPixelFormat()来建立像素格式。
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->intCCY457OpenGLView::OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if(CView::OnCreate(lpCreateStruct)==-1)
return-1;
//InitializeOpenGLHere
InitializeOpenGL();
return0;
}
BOOLCCY457OpenGLView::InitializeOpenGL()
{
//GetaDCfortheClientArea
m_pDC=newCClientDC(this);
//FailuretoGetDC
if(m_pDC==NULL)
{
MessageBox("ErrorObtainingDC");
returnFALSE;
}
//Failuretosetthepixelformat
if(!SetupPixelFormat())
{
returnFALSE;
}
//CreateRenderingContext
m_hRC=::wglCreateContext(m_pDC->GetSafeHdc());
//FailuretoCreateRenderingContext
if(m_hRC==0)
{
MessageBox("ErrorCreatingRC");
returnFALSE;
}
//MaketheRCCurrent
if(::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC)==FALSE)
{
MessageBox("ErrormakingRCCurrent");
returnFALSE;
}
//SpecifyBlackastheclearcolor
::glClearColor(0.0f,0.0f,0.0f,0.0f);
//Specifythebackofthebufferascleardepth
::glClearDepth(1.0f);
//EnableDepthTesting
::glEnable(GL_DEPTH_TEST);
returnTRUE;
}
//SetupPixelFormat
/////////////////////////////////////////////////////////////////////////////
BOOLCCY457OpenGLView::SetupPixelFormat()
{
staticPIXELFORMATDESCRIPTORpfd=
{
sizeof(PIXELFORMATDESCRIPTOR),//sizeofthispfd
1,//versionnumber
PFD_DRAW_TO_WINDOW|//supportwindow
PFD_SUPPORT_OPENGL|//supportOpenGL
PFD_DOUBLEBUFFER,//doublebuffered
PFD_TYPE_RGBA,//RGBAtype
24,//24-bitcolordepth
0,0,0,0,0,0,//colorbitsignored
0,//noalphabuffer
0,//shiftbitignored
0,//noaccumulationbuffer
0,0,0,0,//accumbitsignored
16,//16-bitz-buffer
0,//nostencilbuffer
0,//noauxiliarybuffer
PFD_MAIN_PLANE,//mainlayer
0,//reserved
0,0,0//layermasksignored
};
intm_nPixelFormat=::ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd);
if(m_nPixelFormat==0)
{
returnFALSE;
}
if(::SetPixelFormat(m_pDC->GetSafeHdc(),m_nPixelFormat,&pfd)==FALSE)
{
returnFALSE;
}
returnTRUE;
}
6,在OnSize()中一般用来设置视口和视锥,因为这些是和窗口大小相关的。基本操作包括设置视口,选择投影矩阵,设置模型视图矩阵。
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->voidCCY457OpenGLView::OnSize(UINTnType,intcx,intcy)
{
CView::OnSize(nType,cx,cy);
GLdoubleaspect_ratio;//width/heightratio
if(0>=cx||0>=cy)
{
return;
}
//selectthefullclientarea
::glViewport(0,0,cx,cy);
//computetheaspectratio
//thiswillkeepalldimensionscalesequal
aspect_ratio=(GLdouble)cx/(GLdouble)cy;
//selecttheprojectionmatrixandclearit
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
//selecttheviewingvolume
::gluPerspective(45.0f,aspect_ratio,.01f,200.0f);
//switchbacktothemodelviewmatrixandclearit
::glMatrixMode(GL_MODELVIEW);
::glLoadIdentity();
}
7,在绘制场景时,一般包括如下步骤:1)清空缓存。2)绘制场景。3)Flush掉渲染流水线。4)若设置了双缓冲,则交换前后台缓冲区。
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
voidCCY457OpenGLView::OnDraw(CDC*pDC)
{
CCY457OpenGLDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//Clearoutthecolor&depthbuffers
::glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
RenderScene();
//TellOpenGLtoflushitspipeline
::glFinish();
//NowSwapthebuffers
::SwapBuffers(m_pDC->GetSafeHdc());
}
voidCCY457OpenGLView::RenderScene()
{//第一个玩具嘛,先空着,后面慢慢填
}
8,试试改变窗口的大小,你会看到很严重的闪烁,并且关闭程序后会报告内存泄露,因此我们这就来解决这两个问题吧。
发生闪烁的原因是Windows先绘制背景,然后再是OpenGL绘制,因为我们已经让OpenGL负责清空背景色,因此我们不需要Windows去清空背景了
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->BOOLCCY457OpenGLView::OnEraseBkgnd(CDC*pDC)
{
//TellWindowsnottoerasethebackground
returnTRUE;
}
内存泄露的原因是我们在SetupPixelFormat()中使用了new运算符来为CClientDC对象分配内存,因此需要显示delete掉。
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->voidCCY457OpenGLView::OnDestroy()
{
CView::OnDestroy();
//MaketheRCnon-current
if(::wglMakeCurrent(0,0)==FALSE)
{
MessageBox("CouldnotmakeRCnon-current");
}
//Deletetherenderingcontext
if(::wglDeleteContext(m_hRC)==FALSE)
{
MessageBox("CouldnotdeleteRC");
}
//DeletetheDC
if(m_pDC)
{
deletem_pDC;
}
//SetittoNULL
m_pDC=NULL;
}
分享到:
相关推荐
基于MFC的OpenGL编程part5源码
基于MFC的OpenGL编程part6源码
基于MFC的OpenGL编程part3源码
基于MFC的OpenGL编程part2
基于MFC的OpenGL编程part7的源码 出处:http://phinecos.cnblogs.com/ 代码被我修改过,可以调试出来。原文中的一些细节地方重新注释了一下,方便理解。 很多地方被我修改过,但是大致的内容不会发生变化。 我自己...
基于MFC的OpenGL编程part4源码
基于MFC的OpenGL编程Part10源码 作者:洞庭散人 出处:http://phinecos.cnblogs.com/
基于MFC的OpenGL编程 基于MFC的OpenGL编程 基于MFC的OpenGL编程 基于MFC的OpenGL编程 基于MFC的OpenGL编程
基于MFC的OpenGL编程part8源码 洞庭散人的博客源码
基于MFC的OpenGL编程Part9源码 作者:洞庭散人 出处:http://phinecos.cnblogs.com/
使用单文档视图框架,解决拖动时产生的抖动问题
《基于MFC的OpenGL编程》Part 7 Colors的源码
C++ openGL库文件,有普通的openGL库资源,主要是基于MFC编程的库文件
本程序是基于基于MFC和OPENGL的编程,希望对大家的学习会有帮助。
对于OpenGL的应用,常常是基于GDI接口来实现的。在Windows下做开发,自然 就需要了解OpenGL在MFC下的开发,本工程是MFC下OpenGL开发的一个简单实例。
基于MFC的OpenGL编程.pdf
在MFC对话框中使用OpenGL编程