MFC中添加OpenGL
WINDOWS下展示OpenGL有多种形式:
MFC 或 win32,该如何向MFC中添加OpenGL?下面是介绍最简单OpenGL框架。
1、首先通过VS建立MFC应用程序-MyOpenGL,选择单文档结构视图。
2、添加控制台窗体,帮助输出调试信息。
CMyOpenGLView.cpp添加头文件
#include <conio.h>
#include <iostream>
#include <fcntl.h>
#include <io.h>
CMyOpenGLView::CMyOpenGLView()添加如下代码,使标准输入输出流和控制台建立连接。
其中MFC环境下cout和C语言的都可以使用,而WIN32下只能使用C语言的标准输出。
if ( AllocConsole() )
{
int hCrt=_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
*stdout = *(::_fdopen(hCrt, "w"));
::setvbuf(stdout, NULL, _IONBF, 0);
*stderr = *(::_fdopen(hCrt, "w"));
::setvbuf(stderr, NULL, _IONBF, 0);
}
CMyOpenGLView::~CMyOpenGLView()中添加
FreeConsole()
2、规定设备显示时的像素格式,并建立OpenGL上下文,(什么?你不知道什么叫做WINDOWS设备和OpenGL上下文?出门右转 孙鑫VC++和OpenGL红宝书
通过MFC类向导添加CMyOpenGLView类的WM_CREATE消息,生成
int CMyOpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct),在里面添加
PIXELFORMATDESCRIPTOR pfd;
int n;
HGLRC hrc; pmDC=new CClientDC(this);
if(!bSetupPixelFormat(pmDC))
return false; n=::GetPixelFormat(pmDC->GetSafeHdc()); ::DescribePixelFormat(pmDC->GetSafeHdc(), n,sizeof(pfd),&pfd); hrc=wglCreateContext(pmDC->GetSafeHdc());
wglMakeCurrent(pmDC->GetSafeHdc(),hrc);
其中
bSetupPixelFormat()的定义如下:
bool bSetupPixelFormat(CClientDC * pmDC)
{
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((pixelformat = ChoosePixelFormat(pmDC->GetSafeHdc(), &pfd)) == 0)
{
cout<<"ChoosePixelFormat failed"<<endl;
return FALSE;
} if(SetPixelFormat(pmDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
{
cout<<"SetPixelFormat failed"<<endl;
return FALSE;
} return TRUE;
}
还要记得销毁,释放资源。
在OnDestroy中添加
void CMyOpenGLView::OnDestroy()
{
CView::OnDestroy(); // TODO: 在此处添加消息处理程序代码
HGLRC hrc;
hrc = ::wglGetCurrentContext();
::wglMakeCurrent(NULL,NULL);
if(hrc)
::wglDeleteContext(hrc); if(pmDC)
delete pmDC; }
这样 我们的上下文及设备就建立完毕,下面可以专注于OpenGL的事情了
3、OpenGL的初始化
在stdafx.h添加头文件
#include "glew.h"
#include "glut.h"
并通过工程属性设置添加
glew32.lib glut.lib glut32.lib 这些就是OpenGL的函数库了
再次在OnCreate(..)函数中添加 代码初始化 glew和设置OpenGL的环境
GLenum err=glewInit();
if(GLEW_OK!=err)
{
return -1;
} glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( NEW )
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f,0.0f,1.0f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LESS); // The Type Of Depth Testing To Do
//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glDisable(GL_BLEND);
::glDisable( GL_CULL_FACE ); // 开启表面剔除
然后在OnSize函数中添加代码建立投影矩阵和模型矩阵
// TODO: 在此处添加消息处理程序代码
int w=cx;
int h=cy;
if(h==0)
h=1;
//设置视口与窗口匹配
glViewport(0,0,w,h); //重新设置坐标系统
//投影矩阵
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)w/(GLfloat)h,10.0f,100000.0f);
//模型矩阵
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
4、完成DrawScreen的接口
我们希望绘制可以不断被调用,这里运用MFC的OnIdle()函数,(这个函数不懂?详见VC++)
在MyOpenGL.cpp里的CMyOpenGLApp类中用VS的MFC向导添加重载函数,然后在里面添加如下代码
BOOL CMyOpenGLApp::OnIdle(LONG lCount)
{
// TODO: 在此添加专用代码和/或调用基类
CWinApp::OnIdle(lCount); if(CMyOpenGLView::mOpenView)
{
CMyOpenGLView::mOpenView->DrawScene();
}
return true;
}
其中mOPenView是CMyOpenGLView的静态类公共成员
在类CMyOpenGLView中添加
static CMyOpenGLView * mOpenView;
并在MyOpenGLView.cpp的头部添加静态成员变量的初始化语句,详见C++静态成员变量初始化
CMyOpenGLView * CMyOpenGLView::mOpenView=0;
然后在 OnCreate中再次添加代码
mOpenView=this;
这样我们在其他类中就可以调用CMyOpenGLView类的自定义成员函数DrawScreen了
然后在CMyOpenGLApp类的OnIdle()中调用
5、书写DrawScreen()
void CMyOpenGLView::DrawScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glMatrixMode(GL_MODELVIEW);
//glLoadIdentity(); glBegin(GL_TRIANGLES); glVertex3f(-10,10,-30);
glColor3f(1.0,0.0,0.0); glVertex3f(10,10,-30);
glColor3f(0.0,1.0,0.0); glVertex3f(0,0,-30);
glColor3f(0.0,0.0,1.0); glEnd(); SwapBuffers(wglGetCurrentDC());
}
其意义详见 OpenGL NeHe教程,以后的绘制函数都可以写在这里了。
6、是不是大功告成了?但是拖拉窗体时,还会有错误,那是因为MFC默认会用白刷子刷新窗体,
而OpenGL的SwapBuffers已经帮我们刷新了,所以应该把MFC的禁制掉
怎么做呢?
6.1、重载CMyOpenGLView的消息响应函数WM_ERASEBKGND,改为如下形式
BOOL CMyOpenGLView::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return true;
}
6.2、在OnSize中也调用绘制函数,这样窗体在变形时也能绘制
DrawScene();
这样就成功了!
MFC中添加OpenGL的更多相关文章
- 在MFC中添加OpenGL窗口
虽然MFC已经落伍好多年,而且用来做界面非常的不好用...但是我既不会C#也不会QT,又需要使用OpenGL,就只能将就用了... 一.首先介绍Windows图像程序设计中几个重要的概念: G ...
- MFC中添加ToolTip提示框
PART 1 MFC 对话框中的 Buttton添加提示 例如我们想在一个对话框中的一个button控件添加tooltip,实现的方法如下: 1. 在该对话框的类中添加一个CToolTipCtrl类型 ...
- MFC中添加消息响应函数
转自:http://blog.csdn.net/eddy_liu/article/details/8474677 目前,用MFC设计的Windows应用程序几乎都采用文档/视图结构.这种程序框架与简单 ...
- MFC中添加了一个dialog,并创建了相应的类,初始化函数没有怎么办?
1.在头文件中添加 virtual BOOL OnInitDialog();2.在对于的CPP文件中添加 BOOL CXXDlg::OnInitDialog() { return TR ...
- MFC中添加新的对话框
MFC工程中,除了系统自动生成的一些对话框之外,还需要根据自己的需求,添加新的对话框.这里总结下自己最近使用的方法. 首先,找到Resource View中自己新建的工程,然后右键,选择Add Cla ...
- 在MFC中添加用户自定义消息
1.定义一个宏 (用户自定义消息从WM_USER开始) #define WM_XXXXX WM_USER+数值 2.声明一个函数并实现 afx_msg LRESULT OnXXXXX( WPARAM ...
- MFC中添加控制台输出
可以在CWinApp的InitInstance()中调用下面的函数,以生成控制台: #include <io.h> #include <fcntl.h> void InitCo ...
- 如何在MFC中添加对话栏
- MFC中添加用户自定义消息
1.定义一个宏(用户自定义消息从WM_USER开始) #define WM_XXXXX WM_USER+数值 2.声明一个成员函数并实现 afx_msg LRESULT OnXXXXX( WPARAM ...
随机推荐
- Java RandomAccessFile的使用(转载的文章,出处http://www.2cto.com/kf/201208/149816.html)
Java的RandomAccessFile提供对文件的读写功能,与普通的输入输出流不一样的是RamdomAccessFile可以任意的访问文件的任何地方.这就是“Random”的意义所在. Rando ...
- jsp a标签传值到action中,action接收不到传值
因为需求,今天在action中加了一个marker属性,尝试了很多方法 set,get方法也生成了,但是就接收不到值. 这时我注意到action中有我之前使用ajax请求数据返回json格式数据,不以 ...
- IQueryable接口与IEnumberable区别
IEnumerable<T> 泛型类在调用自己的SKip 和 Take 等扩展方法之前数据就已经加载在本地内存里了,而IQueryable<T> 是将Skip ,take 这些 ...
- Web用户自定义控件
在新建项的时候,选择Web用户控件,可用来自定义自己的控件,做好后,直接拖到页面即可使用自定义控件与WEB交互,需要在 自定义控件里面 写 属性,如: public string CityID { g ...
- css3动画使用技巧之—border旋转时的应用。
<html> <head> <title>css3动画border旋转时的应用.</title> <meta charset="UTF- ...
- HTML css面试题
1.对WEB标准以及W3C的理解与认识 标签闭合.标签小写.不乱嵌套.提高搜索机器人搜索几率.使用外链css和js脚本.结构行为表现的分离.文件下载与页面速度更快.内容能被更多的用户所访问.内容能被更 ...
- MySQL在远程访问时非常慢的解决skip-name-resolve 并且出现 Reading from net
转载:http://www.itokit.com/2012/0515/73932.html 服务器放在局域网内进行测试时,数据库的访问速度还是很快.但当服务器放到外网后,数据库的访问速度就变得非常慢. ...
- 已经安装php后,再增加扩展模块(不重新编辑php)
下面以安装curl为例,介绍具体安装步骤. 1.安装crul wget http://curl.haxx.se/download/curl-7.19.6.tar.gz tar -zxvf curl-7 ...
- 【javascript 函数基础知识】
函数实际上是对象,每个函数都是 Function 类型的实例,而且都会与其他引用类型一样具有属性和方法.由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定. [概念标签] ...
- [python][flask][flask-SQLAlchemy]关于flask-SQLAlchemy的初级使用教程
鉴于网上关于flask-SQLAlchemy的实例使用教程参差不齐,于此写下工作学习过程中的使用过程,以便分享交流. 对于python关于flask有一定了解的高端玩家来说,请转至flask官方开发文 ...