MFC对话框程序中使用OpenGL

18 篇文章 9 订阅

        在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函数是在窗口改变时重新设置透视投影的宽和高,如果没有这个消息处理当窗口大小改变时图形的位置不会变化,看起来就会很奇怪。

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



        

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值