MFC单文档程序中搭建OpenGL框架
来源:互联网 发布:安卓连接mysql 编辑:程序博客网 时间:2024/06/05 23:13
一、简介
Windows GDI是通过设备句柄(Device Context(设备描述表)以下简称"DC")来绘图,而OpenGL则需要绘制环境(Rendering Context(着色描述表),以下简称"RC")。每一个GDI命令需要传给它一个DC,但与GDI不同,OpenGL使用当前绘制环境(RC)。但是RC并不能直接完成绘图,只能与特定的DC联系起来,从而完成具体的绘图工作。一旦在一个线程中指定了一个当前RC,在此线程中其后所有的OpenGL命令都使用相同的当前RC。虽然在单一窗口中可以使用多个RC,但在单一线程中只有一个当前RC。下面我将首先产生一个OpenGL RC并使之成为当前RC。这将分为三个步骤:
1、设置窗口像素格式;
2、产生RC;
3、设置为当前RC。
用一个图表示如下所示,图中介绍了需要在各个函数中设置的信息:
二、搭建MFC中的OpenGL基本框架
本文以一个单文档程序为例。新建一个单文档名字为VCOpenGL2 其他的默认。
1、添加链接库。
打开菜单栏下的项目->属性->配置属性->链接器->输入->附加依赖项里加入OpenGL32.lib GLu32.lib GLaux.lib,如图
如果不用这种方法添加链接库的话,可以写上下列代码,也能达到同样的效果:
2、 包含头文件。
在stdafx里面添加opengl的头文件(当然也可以在其他文件中添加,比如绘图一般都是在视图中的,可以在xxxView.cpp文件中包含头文件)。如下代码所示:
#include <GL\glaux.h>#include <GL\glut.h>
有几点说明:
2.1、包含glut.h的同时就把gl.h和glu.h都包括了。因为打开glut.h你可以看到如下图所示的,已经包含了gl.h和glu.h。
2.2、关于这OpenGL中的这几个库的介绍,看一看我的另一篇文章,地址如下:
http://blog.csdn.net/zhangkaihang/article/details/7459629
3、设置窗口显示风格。
窗口创建之前我们必须设置窗口风格包含
WS_CLIPCHILDREN(创建父窗口使用的Windows风格,用于重绘时裁剪子窗口所覆盖的区域)和WS_CLIPSIBLINGS(创建子窗口使用的Windows风格,用于重绘时剪裁其他子窗口所覆盖的区域),
从而避免OpenGL绘制到其他窗口中去。这些应该放在PreCreateWindow()中。代码如下:
CMyVIew中的PreCreateWindow中添加
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
4、设置窗口像素格式
首先向VCOpenGL2View类中添加几个保护的成员变量和公共的成员函数。如下:
别忘了在VCOpenGL2View的构造函数中设置 m_hRC = NULL; m_pDC = NULL;
产生一个RC的第一步是定义窗口的像素格式。像素格式决定窗口着所显示的图形在内存中是如何表示的。由像素格式控制的参数包括:颜色深度、缓冲模式和所支持的绘画接口。在下面将在SetupPixelFormat()函数中对这些参数的设置。代码如下:
5、产生RC,设置为当前RC。
现在像素格式已经设定,我们下一步工作是产生绘制环境(RC)并使之成为当前绘制环境,即编写InitializeOpenGL()函数。代码如下:
别忘了再OnCreate()函数中调用 InitializeOpenGL()函数。如下所示:
6、设置视口
在OnSize()中一般用来设置视口和视锥,因为这些是和窗口大小相关的。代码如下:
7、绘制场景(用OpenGL绘图相关的代码都在这里哦!!)
本文以一个三维正方体为例,代码如下:
别忘了,在OnDraw()函数中调用哦!!!!!如下:8、一些收尾工作。
8.1 为了使改变窗口大小时严重的闪烁,在OnEraseBkgnd()里做一些操作,避免windows自己的窗口刷新闪烁。OnEraseBkgnd()函数需要重写。如下:
8.2 为了避免内存泄露,OnDestroy()函数中加一些代码,如下:至此一个单文档的框架就弄好了。下面贴出所画的立方体,如下图:
在VC6.0中
1、 理论基础
a、在单文档的创建过程中,设置好显示的像素格式,并按OpenGL得要求设置窗口的属性和风格
b、在窗口的绘制过程中,首先获得Windows设备描述表DC,然后将其与事先设置好的OpenGL绘制
表述表RC联系起来;
c、调用OpenGL命令进行图形绘制;
d、退出OpenGL图形窗口时,释放OpenGL绘制描述表RC和Windows设备描述表DC。
2、编程步骤
a、启动vc6.0,选择NEW菜单,在NEW对话框中选择Project标签,选择"MFC AppWizard(exe)",
新建一个基于对话框的工程。名称为MySDOpenGL。
b、利用MFC ClassWizard为CMySDOpenGLView类添加消息WM_CREATE、WM_DESTROY、WM_SIZE、
WM_TIMER得响应函数.
c.在CMySDOpenGLView.h中加入源代码.
////////////////////////////////////////////////
//添加成员函数与成员变量
BOOL InitializeOpenGL(CDC *pDC);
void SetLogicalPalette(void);
BOOL SetupPixelFormat(void);
BOOL RenderScene();
HGLRC m_hRC; //OpenGL绘制描述表
HPALETTE m_hPalette; //OpenGL调色板
CDC* m_pDC; //OpenGL设备描述表
///////////////////////////////////////////////////
d、在文件CMySDOpenGLView.cpp中加入如下代码
BOOL CMySDOpenGLView::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);
}
void CMySDOpenGLView::OnDraw(CDC* pDC)
{
CMySDOpenGLDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
////////////////////////////////////////////////////
RenderScene(); //渲染场景
///////////////////////////////////////////////////
}
int CMySDOpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
////////////////////////////////////////////////////////
//初始化调色板和渲染上下文、定时器
m_pDC = new CClientDC(this);
SetTimer(1,20,NULL);
InitializeOpenGL(m_pDC);
///////////////////////////////////////////////////////
return 0;
}
void CMySDOpenGLView::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
///////////////////////////////////////////////////////
//删除调色板和渲染上下文
::wglMakeCurrent(0,0);
::wglDeleteContext(m_hRC);
if(m_hPalette)
DeleteObject(m_hPalette);
if(m_pDC)
delete m_pDC;
KillTimer(1);
}
void CMySDOpenGLView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
//////////////////////////////////////////////////////
//添加窗口缩放时的变换函数
glViewport(0,0,cx,cy);
//////////////////////////////////////////////////////
}
void CMySDOpenGLView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
///////////////////////////////////////////////////////////
//添加定时器响应函数和场景更新函数
Invalidate(FALSE);
///////////////////////////////////////////////////////////
CView::OnTimer(nIDEvent);
}
//////////////////////////////////////////////////////////
//场景绘制与渲染
///////////////////////////////////////////////////////////
BOOL CMySDOpenGLView::RenderScene()
{
// glClearColor(1.0,0.0,0.0,1.0);
// glClear(GL_COLOR_BUFFER_BIT);
::SwapBuffers(m_pDC->GetSafeHdc()); //交换缓冲区
return TRUE;
}
/////////////////////////////////////////////////////////////
//设置像素格式
////////////////////////////////////////////////////////////
BOOL CMySDOpenGLView::SetupPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), //pfd结构的大小
1, //版本号
PFD_DRAW_TO_WINDOW| //支持在窗口中绘图
PFD_SUPPORT_OPENGL| //支持OPENGL
PFD_DOUBLEBUFFER, //支持双缓冲
PFD_TYPE_RGBA, //RGBA颜色模式
24, //24位颜色深度
0,0,0,0, //忽略颜色位
0, //没有非透明度缓存
0, //忽略移位位
0, //无累加缓存
0,0,0,0, //忽略累加位
32, //32位深度缓存
0, //无模板缓存
PFD_MAIN_PLANE, //主层
0, //保留
0,0,0 //忽略层,可见性和损毁掩模
};
int pixelformat;
pixelformat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd); //选择像素格式
::SetPixelFormat(m_pDC->GetSafeHdc(),pixelformat,&pfd); //设置像素格式
if(pfd.dwFlags &PFD_NEED_PALETTE)
SetLogicalPalette(); //设置调色板
return TRUE;
}
//////////////////////////////////////////////////////////
//设置逻辑调色板
///////////////////////////////////////////////////////////
void CMySDOpenGLView::SetLogicalPalette()
{
struct
{
WORD Vertion;
WORD NumberOfEntries;
PALETTEENTRY aEntries[256];
}logicalPalette = {0x300,256};
BYTE reds[] = {0,36,72,109,145,182,218,255 };
BYTE greens[] = {0,36,72,109,145,182,218,255 };
BYTE blues[] = {0,85,170,255};
for (int colorNum = 0;colorNum < 256; ++colorNum)
{
logicalPalette.aEntries[colorNum].peRed = reds[colorNum & 0x07];
logicalPalette.aEntries[colorNum].peGreen = greens[(colorNum >> 0x03)
&0x07];
logicalPalette.aEntries[colorNum].peBlue =blues[(colorNum >> 0x06) &
0x03];
logicalPalette.aEntries[colorNum].peFlags = 0;
}
m_hPalette = CreatePalette((LOGPALETTE*)&logicalPalette);
}
////////////////////////////////////////////////////////
// 初始化openGL场景
////////////////////////////////////////////////////////
BOOL CMySDOpenGLView::InitializeOpenGL(CDC *pDC)
{
m_pDC = pDC;
SetupPixelFormat();
//生成绘制描述表
m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc());
//设置当前绘制描述表
::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC);
return TRUE;
}
e、在文件StdAfx.h中加入如下源代码。
//////////////////////////////////////////////////////////////////////////
//包含有关OpenGL 函数的头文件
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include <GL/glut.h>
//////////////////////////////////////////////////////////////////////////
最后运行编译。
- MFC单文档程序中搭建OpenGL框架
- MFC单文档程序中搭建OpenGL框架 .
- MFC单文档程序中搭建OpenGL框架
- MFC中单文档程序框架
- MFC中单文档程序框架
- MFC中单文档程序框架
- OpenGL创建MFC单文档框架
- 基于MFC单文档SDI的OpenGL图形程序的基本框架
- MFC--单文档程序(框架)
- 用MFC(单文档)开发OpenGL程序
- MFC中 单文档程序 删除工具栏
- 如何手动写一个MFC单文档程序框架
- MFC搭建OpenGL框架示例
- 搭建OpenGL的MFC框架
- MFC单文档框架理解
- OpenGL在MFC单文档中的应用
- MFC+OpenGL单文档实现图形旋转
- MFC+OpenGL单文档制作三维图像
- 考研英语 - word-list-5
- 文章标题
- 容器(vector)
- 后缀自动机 【Sdoi2016】生成魔咒 bzoj4516
- OpenGL开发库的介绍
- MFC单文档程序中搭建OpenGL框架
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解
- delphi DBgrideh 导出
- 怎么把jqgrid显示的字段设置成超连接
- [NOIP2005][提高组T2]过河
- dubbo、dubbox坑集合
- 详解:数据库名、实例名、ORACLE_SID、数据库域名、全局数据库名、服务名及手工脚本创建oracle数据库
- ythjuk,uili8l;o9;o;o;p';pikil.o;o
- Centos+git+gitolite 安装和部署