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();

 这样就成功了!

 

 

 

 

 

转载于:https://www.cnblogs.com/lydyy/p/4693932.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值