关闭

MFC对话框程序中使用OpenGL

1583人阅读 评论(2) 收藏 举报
分类:

        在MFC的对话框程序中需要使用OpenGL在某个对话框中作图,综合了网上的两篇文章的内容(文章一文章二),也有自己的心得体会。

        首先需要配置好opengl的环境,程序中会使用到glaux中的库和函数,这里将它的lib,h,dll文件的下载链接附上。其他的库windows中好像带有。

        先将对OpenGL的操作封装成一个类,这是第一篇文章的主要思想:

头文件OpenGL.h

#pragma once
#include <gl/GL.h>
#include <gl/GLU.h>
#include <GLAUX.H>

class COpenGL
{
public:
	COpenGL(void);
	~COpenGL(void);
	HDC hDC;
	HGLRC hRC;

public:
	/************************************************************************/
	/*    对OpenGL的一些初始化工作,width和height表示窗口的宽和高                                                                  */
	/************************************************************************/
	void Init(int width,int height);

	/************************************************************************/
	/* 设置像素格式                                                                     */
	/************************************************************************/
	bool SetupPixelFormat(HDC hDC0);

	/************************************************************************/
	/* 窗口大小改变时的回调函数                                                                     */
	/************************************************************************/
	void Reshap(int width,int height);

	/************************************************************************/
	/*  具体的渲染操作,窗口中显示的内容是在这个函数中完成的                                                                    */
	/************************************************************************/
	void Render();
};

源文件OpenGL.cpp

#include "StdAfx.h"
#include "OpenGL.h"

COpenGL::COpenGL(void)
{
}

COpenGL::~COpenGL(void)
{
	wglMakeCurrent(hDC,NULL);
	wglDeleteContext(hRC);
}

void COpenGL::Init(int width,int height){
	// openGL的初始化设置
	glClearColor(0.0, 1.0, 1.0, 0.0);
	glShadeModel(GL_SMOOTH);
	//glViewport(0, 0, 200, 200);
	glMatrixMode(GL_PROJECTION);
	gluPerspective(60, (GLfloat)width/(GLfloat)height, 0.1, 100.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

bool COpenGL::SetupPixelFormat(HDC hDC0){
	int nPixelFormat;                 // 象素点格式
	hDC=hDC0;
	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                           // 忽略层,可见性和损毁掩模
	};
	if (!(nPixelFormat = ChoosePixelFormat(hDC, &pfd)))
	{ MessageBox(NULL,L"can not find proper mode",L"Error",MB_OK|MB_ICONEXCLAMATION);
	return FALSE;
	}
	SetPixelFormat(hDC,nPixelFormat,&pfd);
	hRC = wglCreateContext(hDC);         
	wglMakeCurrent(hDC, hRC);            
	return TRUE;
}
void COpenGL::Reshap(int width,int height){
	glViewport(0,0,width,height);         
	glMatrixMode(GL_PROJECTION);          
	glLoadIdentity();                 
	gluPerspective                        
		( 60.0f,                       
		(GLfloat)width/(GLfloat)height,
		0.1f,                      
		100.0f                     
		); 
	//gluLookAt(10,5,10,0,0,0,0,1,0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
void COpenGL::Render(){
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0, 0.0, 0.0);
	glLoadIdentity();
	glTranslatef(0.0, 0.0, -5.0);
	glBegin(GL_TRIANGLES);
	glVertex3f(0.0, 1.0, 0.0);
	glVertex3f(-1.0, -1.0, 0.0);
	glVertex3f(1.0, -1.0, 0.0);
	glEnd();
	SwapBuffers(hDC);    
}

         上面将对OpenGL的操作封装成了一个工具类,但是照第一篇文章的思路实现时由于我的工程是基于MFC的对话框程序,照他上面说的方法显示出的对话框中没有东西。于是使用这个工具类时参照了第二篇文章的方法,也明白了如何在其他的工程中使用这个工具类。

      具体的方法是:

1.在需要绘图的窗口类中添加OpenGL.h头文件,并声明一个COpenGL类型的成员变量。如我想在CDialog4这个类中使用OpenGL绘图,那么在它 的头文件中包含OpenGL.h,并声明一个COpenGL类型的成员变量。

2.添加两个消息响应函数,即WM_SIZE和WM_TIMER消息的处理,重写一个函数OnInitDialog。

这两步操作完成后,CDialog4的头文件如下:

#pragma once
#include "OpenGL.h"

// CDialog4 对话框

class CDialog4 : public CDialog
{
	DECLARE_DYNAMIC(CDialog4)
public:
	COpenGL openGL;

public:
	CDialog4(CWnd* pParent = NULL);   // 标准构造函数
	virtual ~CDialog4();

// 对话框数据
	enum { IDD = IDD_DIALOG4 };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnSize(UINT nType, int cx, int cy);
	virtual BOOL OnInitDialog();
	afx_msg void OnTimer(UINT_PTR nIDEvent);
};

CDialog4的源文件如下:

// Dialog4.cpp : 实现文件
//

#include "stdafx.h"
#include "ComputerGraphic.h"
#include "Dialog4.h"


// CDialog4 对话框

IMPLEMENT_DYNAMIC(CDialog4, CDialog)

CDialog4::CDialog4(CWnd* pParent /*=NULL*/)
	: CDialog(CDialog4::IDD, pParent)
{

}

CDialog4::~CDialog4()
{
}

void CDialog4::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CDialog4, CDialog)
	ON_WM_SIZE()
	ON_WM_TIMER()
END_MESSAGE_MAP()




void CDialog4::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);
	openGL.Reshap(cx,cy);
}

BOOL CDialog4::OnInitDialog()
{
	CDialog::OnInitDialog();

	/************************************************************************/
	/*  传递给SetupPixelFormat的参数是要绘图的对象的DC,可以是窗口中的某一个控件
	这里使用的是窗口的DC,即在窗口中绘图,而不是在窗口的某个控件中绘图*/
	/************************************************************************/
	openGL.SetupPixelFormat(::GetDC(m_hWnd));

	//得到绘图区域对应的长方形
	CRect rect;
	GetClientRect(&rect);

	//设置绘图区域的宽和高
	openGL.Init(rect.right,rect.bottom);
	SetTimer(1,10,0);
	

	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}

void CDialog4::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	openGL.Render();
	CDialog::OnTimer(nIDEvent);
}

        重点是在OnInitDialog中的函数调用,获取不同控件的DC就可以在不同的控件中绘图了。这时使用该方法就很灵活方便了。OnSize函数是在窗口改变时重新设置透视投影的宽和高,如果没有这个消息处理当窗口大小改变时图形的位置不会变化,看起来就会很奇怪。

       程序运行后的效果如下图:



        

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:312118次
    • 积分:5960
    • 等级:
    • 排名:第4217名
    • 原创:261篇
    • 转载:43篇
    • 译文:13篇
    • 评论:42条
    友情链接
    博客专栏
    文章分类
    最新评论