MFC+OpenGL单文档制作三维图像

原创 2015年08月07日 19:55:38

GDI:图形设备接口

DC:设备描述表

RC:着色描述表

OpenGL:专业图形程序接口

画图原理:每个GDI命令需要传给它一个DC,OpenGL需要绘制环境(RC),

RC与特定的DC联系起来,完成绘图工作。

产生OpenGL并使之成为当前的RC步骤:

1.设置窗口像素格式

2.产生RC

3.设置当前RC


1.创建一个MFC单文档项目命名为VCOpenGL2

   在stdafx里面添加OpenGL的头文件

    #include<GL\glut.h>

2.设置窗口显示风格

    窗口创建之前我们必须设置窗口风格包含

    WS_CLIPCHILDREN(创建父窗口使用的Windows风格,用于重绘时裁剪子窗口所覆盖的区域)和WS_CLIPSIBLINGS(创建子窗口使用Windows风格,用于重绘时裁剪其他子窗口覆盖的区域),从而避免OpenGL绘制到其他窗口中去。这些应该放在PreCreateWindow()中。

3.设置窗口像素格式

首先向VCOpenGL2View类中添加几个保护的成员和公共的成员函数。如下:

protected:
HGLRC m_hRC;//Rendering Context着色描述表
CClientDC *m_pDC; //Device Context设备描述表

intm_wide; //视口的宽度
int m_heigth;//视口的高度
BOOL InitializeOpenGL();//初始化OpenGL
BOOL SetupPixelFormat();//设置像素格式
void RenderScene();//绘制场景

VCOpenGL2View的构造函数中初始化m_hRC,m_pDC ;

CVCOpenGL2View::CVCOpenGL2View()
{
// TODO:  在此处添加构造代码
m_hRC = NULL;
m_pDC = NULL;
}

产生一个RC的第一步是定义窗口的像素格式。像素格式决定窗口所显示的图形在内存中 是如何表示的。由像素格式控制的参数包括:颜色深度、缓冲模式和所支持的绘画接口。在下面将在SetupPixelFormat();函数中对这些参数的设置。代码如下:

BOOL CVCOpenGL2View::SetupPixelFormat()
{
static 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, 0, 0, //忽略累计位
32, //32位深度缓存
0, //无模板缓存
0, //无辅助缓存
PFD_MAIN_PLANE,//主层
0, //保留
0, 0, 0 //忽略层,可见性和损毁掩模
};
int pixelFormat;
//为设备描述表得到最匹配的像素格式
if ((pixelFormat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0)
{
MessageBox(L"ChoosePixelFormat failed");
return FALSE;
}
//设置最匹配的像素格式为当前的像素格式
if (SetPixelFormat(m_pDC->GetSafeHdc(),pixelFormat,&pfd)==FALSE)
{
MessageBox(L"SetPixelFormat failed");
return FALSE;
}
return TRUE;
}


5.产生RC,设置为当前RC。

现在像素格式已经设定,我们下一步工作是产生绘制环境(RC)并使之成为当前绘制环境,即编写InitializeOpenGL()。代码如下:

BOOL CVCOpenGL2View::InitializeOpenGL()
{
PIXELFORMATDESCRIPTORpfd;
int n;
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
//设置当前的绘图像素格式
if (!SetupPixelFormat())
{
return FALSE;
}
n = ::GetPixelFormat(m_pDC->GetSafeHdc());
::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd);
//创建绘图描述表
m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
if (m_hRC==NULL)
{
return FALSE;
}
//使绘图描述表为当前调用线程的当前绘图描述表
if (wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE)
{
return FALSE;
}
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
return TRUE;
}


在OnCreate()函数(用类向导添加)中调用InitializeOpenGL()函数。如下所示:

int CVCOpenGL2View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;


// TODO:  在此添加您专用的创建代码
if (InitializeOpenGL())
{
return 0;
}


return 0;
}

6.设置视口

在OnSize()中一般用来设置视口和窗口大小相关的。代码如下:

void CVCOpenGL2View::RenderScene()
{
//设置清平颜色为黑色
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//清除颜色缓冲区和深度缓冲区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//透视投影变换
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(80, (double)m_wide / (double)m_heigth, 1.5, 0);/*视角80度,纵横比,进裁剪面,远裁剪面*/
//视角变换
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(2, 2, 2, 0, 0, 0, 0, 1, 0);/*前三个参数是眼睛的位置,中间三个参数是物体所在的位置,后面三个参数表示向量,头顶朝上的方向*/
//矩阵堆栈函数,和glPopMatrix()相对应
glPushMatrix();
glBegin(GL_LINES);
glColor3d(1.0, 0.0, 0.0);//X轴 红色
glVertex3d(0.0, 0.0, 0.0);
glVertex3d(2.0, 0.0, 0.0);
glColor3d(0.0, 1.0, 0.0);//Y轴 绿色
glVertex3d(0.0, 0.0, 0.0);
glVertex3d(0.0, 2.0, 0.0);
glColor3d(0.0, 0.0, 1.0);//Z轴 蓝色
glVertex3d(0.0, 0.0, 0.0);
glVertex3d(0.0, 0.0, 2.0);
glEnd();
glColor3f(1.0, 1.0, 1.0);
glutWireCube(0.5);


glPopMatrix();
glFinish();
SwapBuffers(wglGetCurrentDC());
}

别忘了,在OnDraw()函数中调用,代码如下:

记得把/*pDC的注释去掉*/

void CVCOpenGL2View::OnDraw(CDC* pDC)
{
CVCOpenGL2Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;


// TODO:  在此处为本机数据添加绘制代码
RenderScene();
}


8.一些收尾工作

8.1为了使改变窗口大小时严重的闪烁,在OnEraseBkgnd()里做一些操作,避免windows自己的窗口刷新闪烁。OnEraseBkgnd()函数需要重写,代码如下:

BOOL CVCOpenGL2View::OnEraseBkgnd(CDC* pDC)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值
return TRUE;


//return CView::OnEraseBkgnd(pDC);
}

8.2为了避免内存泄露,OnDestroy()函数中加一些代码,如下:

void CVCOpenGL2View::OnDestroy()
{
CView::OnDestroy();


// TODO:  在此处添加消息处理程序代码
m_hRC = ::wglGetCurrentContext();
if (::wglMakeCurrent(0, 0) == FALSE)
{
MessageBox(L"Could not make RC non-current");
}
if (m_hRC)
{
if (::wglDeleteContext(m_hRC) == FALSE)
{
MessageBox(L"Could not delete RC");
}
}
if (m_pDC)
{
delete m_pDC;
}
m_pDC = NULL;
}

运行结果:












基于MFC完整的OpenGL框架步骤

1. 新建一个MEC单文档应用程序,如下各图所示, 2. 更改头文件,双击WelecomView.h,在程序前面加上以下两个头文件(W...
  • u013232740
  • u013232740
  • 2015年01月28日 14:52
  • 1432

MFC单文档程序中搭建OpenGL框架

本博客计算机图形学系列文章索引: 地址:《计算机图形学系列相关文章索引(持续更新)》 一、简介 Windows GDI是通过设备句柄(Device Context(设备描述表)以...
  • zhangkaihang
  • zhangkaihang
  • 2012年04月13日 23:43
  • 9756

直接在MFC的对话框上利用OpenGL绘制图形

借鉴前人的经验,如链接http://www.cnblogs.com/phinecos/archive/2007/07/28/834916.html介绍了如何利用MFC的单文档来使用OpenGL(本文也...
  • hurricanecqj
  • hurricanecqj
  • 2015年05月01日 15:20
  • 1450

MFC的对话框中使用OpenGL绘图

我们在编写软件是总是会有自己的界面,当然利用C++就不得不喝MFC打交道了,那么可视化界面通常就要用MFC的Dialog;OpenGL通常画图时会自己生成一个窗口,就如同OpenCV一样,但现在我想O...
  • u010260855
  • u010260855
  • 2014年03月18日 23:36
  • 3505

基于MFC完整的OpenGL框架步骤

1. 新建一个MEC单文档应用程序,如下各图所示, 2. 更改头文件,双击WelecomView.h,在程序前面加上以下两个头文件(W...
  • u013232740
  • u013232740
  • 2015年01月28日 14:52
  • 1432

OpenGL在MFC中的使用总结(一)——基本框架

项目中要画3D显示的模型,于是要用到OpenGL,加上是在MFC中,而且是在MFC中的ActiveX中使用,再而且鉴于他们程序主框架的设定,常规的方法还不一定能实现。所以还是查过不少资料,在此一一总结...
  • lyh03601
  • lyh03601
  • 2014年08月21日 16:10
  • 3567

VS 2012环境下使用MFC进行OpenGL编程

VS 2012下使用MFC+OpenGL基本步骤 引子:以前一直惧怕MFC感觉它是一个非常复杂的东西,更不用说去用它来和OpenGL结合了,以前是一直羡慕别人用MFC创建一个窗口进行OpenGL绘图...
  • bbppbb
  • bbppbb
  • 2014年04月22日 21:11
  • 6432

MFC 中配置OpenGL环境

MFC为编写Windows应用程序提供了极大的方便,程序员在编写Windows应用程序时,只需要几步就可以把一个程序的框架建立起来.该类极大的提高了编程者的开发效率,是个具有极大实用价值的工具. ...
  • xiaoge132
  • xiaoge132
  • 2016年03月09日 09:45
  • 2451

Opengl与MFC结合显示图像

Opengl与MFC结合显示图像。下面是总结的一个类: //头文件 #if !defined(AFX_OPENGL_H__4D4A8C3F_A907_4A63_B205_B839E456A...
  • xbeinonlinkejidaxue
  • xbeinonlinkejidaxue
  • 2014年11月06日 21:56
  • 1030

MFC 使用Opengl贴图

用opengl库在mfc 对话框程序中创建简单的opengl程序。 步骤: 1.用vs2010创建mfc dialog对话框程序 直接点击完成,创建工程结束。 2.删掉对话框上面...
  • sz76211822
  • sz76211822
  • 2017年02月22日 19:40
  • 629
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MFC+OpenGL单文档制作三维图像
举报原因:
原因补充:

(最多只允许输入30个字)