OpenGL在MFC中的使用总结(二)

有些时候用到OpenGL需要每次进行配置,有点麻烦,可以直接基于CWND派生一个OpenGL类,在需要的时候直接用就可以了。下面附赠上这样一个类,其中删掉了我项目具体绘制的一些东西,如有错误不能用请联系我~~~

h文件:

#if !defined(AFX_OPENGL_H__38B5D1C8_2DFF_4A7D_9A99_3AC401C19D72__INCLUDED_)
#define AFX_OPENGL_H__38B5D1C8_2DFF_4A7D_9A99_3AC401C19D72__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// OpenGL.h : header file
#include <gl/glu.h>
#inclede <gl/gl.h>
/////////////////////////////////////////////////////////////////////////////

// COpenGL window
class COpenGL : public CWnd
{
	// Construction
public:
	COpenGL();

	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(COpenGL)
	//}}AFX_VIRTUAL

	// Implementation
public:
	virtual void RenderGLScene();
	void Create(CRect rect, CWnd *parent);
	virtual ~COpenGL();

	// Generated message map functions
protected:
	CRect m_rect;
	CWnd* m_parent;
	DEVMODE m_DMsaved;

public:
	// 根据需要增、删
	BOOL m_bInit;

	HDC m_hDC;
	HGLRC m_hRC;

	// 读取数据
	int DrawXXX();
	int InitGL();
	void KillGLWindow();

	//{{AFX_MSG(COpenGL)
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnPaint();
	afx_msg void OnSize(UINT nType, int cx, int cy);

	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_OPENGL_H__38B5D1C8_2DFF_4A7D_9A99_3AC401C19D72__INCLUDED_)

CPP文件:

#include "stdafx.h"
#include "OpenGL.h"
#include "math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
COpenGL::COpenGL():m_bInit(FALSE),m_hDC(NULL),m_hRC(NULL),m_parent(NULL)
{

}

COpenGL::~COpenGL()
{
	KillGLWindow(); // Shutdown
}

BEGIN_MESSAGE_MAP(COpenGL, CWnd)
	//{{AFX_MSG_MAP(COpenGL)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
	ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COpenGL message handlers

void COpenGL::Create(CRect rect, CWnd *parent)
{
	if (m_bInit) return;
	ASSERT(rect);
	ASSERT(parent);
	m_rect = rect;
	m_parent = parent;

	CString className = AfxRegisterWndClass(
		CS_HREDRAW | CS_VREDRAW | CS_OWNDC,NULL,(HBRUSH)GetStockObject(BLACK_BRUSH),NULL);

	CreateEx(WS_EX_CLIENTEDGE,className,_T("OpenGL"),WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,rect,parent,0);

}

int COpenGL::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO: Add your specialized creation code here
	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &m_DMsaved);

	GLuint PixelFormat; // Holds The Results After Searching For A Match
	static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
	{
		sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
		1, // Version Number
		PFD_DRAW_TO_WINDOW | // Format Must Support Window
		PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
		PFD_DOUBLEBUFFER, // Must Support Double Buffering
		PFD_TYPE_RGBA, // Request An RGBA Format
		m_DMsaved.dmBitsPerPel, // Select Our Color Depth
		0, 0, 0, 0, 0, 0, // Color Bits Ignored
		0, // No Alpha Buffer
		0, // Shift Bit Ignored
		0, // No Accumulation Buffer
		0, 0, 0, 0, // Accumulation Bits Ignored
		16, // 16Bit Z-Buffer (Depth Buffer)
		0, // No Stencil Buffer
		0, // No Auxiliary Buffer
		PFD_MAIN_PLANE, // Main Drawing Layer
		0, // Reserved
		0, 0, 0 // Layer Masks Ignored
	}; 

	if ( !( m_hDC = ::GetDC ( m_hWnd ) ) )
	{ // Did We Get A Device Context?
		KillGLWindow (); // Reset The Display
		TRACE ( "Can't Create A GL Device Context." );
		return FALSE;
	}

	if ( !( PixelFormat = ChoosePixelFormat ( m_hDC, &pfd ) ) )
	{ // Did Windows Find A Matching Pixel Format?
		KillGLWindow (); // Reset The Display
		TRACE ( "Can't Find A Suitable PixelFormat." );
		return FALSE;
	}

	if ( !SetPixelFormat ( m_hDC, PixelFormat, &pfd ) )
	{ // Are We Able To Set The Pixel Format?
		KillGLWindow (); // Reset The Display
		TRACE ( "Can't Set The PixelFormat." );
		return FALSE;
	}

	if ( !( m_hRC = wglCreateContext ( m_hDC ) ) )
	{ // Are We Able To Get A Rendering Context?
		KillGLWindow (); // Reset The Display
		TRACE( " Can't Create A GL Rendering Context." );
		return FALSE;
	}

	if ( !wglMakeCurrent ( m_hDC, m_hRC ) ) { // Try To Activate The Rendering Context
		KillGLWindow (); // Reset The Display
		TRACE ( "Can't Activate The GL Rendering Context." );
		return FALSE;
	}

	if ( !InitGL () )
	{ // Initialize Our Newly Created GL Window
		KillGLWindow (); // Reset The Display
		TRACE ( "Initialization Failed." );
		return FALSE;
	}
	m_bInit = TRUE;
	return 0;
}

void COpenGL::KillGLWindow()
{
	if ( m_hRC )
	{ // Do We Have A Rendering Context?
		if ( !wglMakeCurrent ( NULL, NULL ) )
		{ // Are We Able To Release The DC And RC Contexts?
			TRACE ( "Release Of DC And RC Failed." );
		}

		if ( !wglDeleteContext ( m_hRC ) )
		{ // Are We Able To Delete The RC?
			TRACE ( "Release Rendering Context Failed." );
		}
		m_hRC = NULL; // Set RC To NULL
	}

	if ( m_hDC && !::ReleaseDC ( m_hWnd, m_hDC ) )
	{ // Are We Able To Release The DC
		TRACE ( "Release Device Context Failed." );
		m_hDC = NULL; // Set DC To NULL
	}

	if ( m_hWnd && !::DestroyWindow ( m_hWnd ) )
	{ // Are We Able To Destroy The Window?
		TRACE( "Could Not Release m_hWnd." );
		m_hWnd = NULL; // Set m_hWnd To NULL
	}
}

int COpenGL::InitGL()
{
	glShadeModel(GL_SMOOTH); // Enable Smooth Shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
	glClearDepth(1.0f); // Depth Buffer Setup
	glEnable(GL_DEPTH_TEST); // Enables Depth Testing
	glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
	glEnable(GL_TEXTURE_2D); // Enable Texture Mapping

	return TRUE; // Initialization Went OK
}

void COpenGL::RenderGLScene()
{
	if(!m_bInit)
		return;
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//画模型
	DrawXXX();
	SwapBuffers(m_hDC);
}

void COpenGL::OnPaint()
{
	//CPaintDC dc(this); // device context for painting

	// TODO: Add your message handler code here
	::ValidateRect ( m_hWnd, NULL );
	RenderGLScene();

	// Do not call CWnd::OnPaint() for painting messages
}
void COpenGL::OnSize(UINT nType, int cx, int cy)
{
	CWnd::OnSize(nType, cx, cy);

	// TODO: Add your message handler code here
	if ( cy==0)
	{ // Prevent A Divide By Zero By
		cy=1; // Making Height Equal One
	} 

	glViewport(0,0,cx,cy); // Reset The Current Viewport

	glMatrixMode(GL_PROJECTION); //设置投影矩阵
	glLoadIdentity(); // 初始化

	gluPerspective(45.0f,(GLfloat)cx/(GLfloat)cy,0.1f,100.0f); //设置视点

	glMatrixMode(GL_MODELVIEW); //设置模型矩阵
	glLoadIdentity(); // 初始化

}

int COpenGL::DrawXXX()
{
	//具体的绘制

	return 1;
}

OpenGL在MFC中的使用总结(二)

时间: 2024-10-14 03:19:44

OpenGL在MFC中的使用总结(二)的相关文章

OpenGL在MFC中的使用总结(一)

项目中要画3D显示的模型,于是要用到OpenGL,加上是在MFC中,而且是在MFC中的ActiveX中使用,再而且鉴于他们程序主框架的设定,常规的方法还不一定能实现.所以还是查过不少资料,在此一一总结一下.首先总结最基础的一些东西. 一.按照讲课的逻辑,先讲点原理性的东西~ GDI是通过设备描述表(Device Context,以下简称"DC")来绘图,而OpenGL是通过渲染描述表(Rendering Context,以下简称"RC").每一个GDI命令需要传给它

OpenGL在MFC中的使用总结(三)

有些时候直接创建OpenGL窗口不适合,或者根本不允许再创建窗口,就像我现在的这个项目,创建的窗口显示不出来,被主框架限定,而我只能在ActiveX控件的子类里做一些相关工作,那只能用到OpenGL的离屏渲染技术了~即不直接绘制到窗口上,而是绘制到一张位图上,然后再次调用这张位图实现后续的工作. 下面就总结怎么使用所谓的"离屏渲染". const int WIDTH = 500; const int HEIGHT = 500; // Create a memory DC compati

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

项目中要画3D显示的模型,于是要用到OpenGL,加上是在MFC中,并且是在MFC中的ActiveX中使用.再并且鉴于他们程序主框架的设定.常规的方法还不一定能实现.所以还是查过不少资料,在此一一总结一下.首先总结最基础的一些东西. 一.依照讲课的逻辑,先讲点原理性的东西~ GDI是通过设备描写叙述表(Device Context,下面简称"DC")来画图.而OpenGL是通过渲染描写叙述表(Rendering Context,下面简称"RC").每个GDI命令须要

[iTyran原创]iPhone中OpenGL ES显示3DS MAX模型之二:lib3ds加载模型

[iTyran原创]iPhone中OpenGL ES显示3DS MAX模型之二:lib3ds加载模型 作者:u0u0 - iTyran 在上一节中,我们分析了OBJ格式.OBJ格式优点是文本形式,可读性好,缺点也很明显,计算机解析文本过程会比解析二进制文件慢很多.OBJ还有个问题是各种3D建模工具导出的布局格式还不太一样,face还有多边形(超过三边形),不利于在OpenGL ES里面加载. .3ds文件是OBJ的二进制形式,并且多很多信息.有一个C语言写的开源库可以用来加.3ds文件,这就是l

MFC中模态对话框和非模态对话框

MFC的对话框非为两种,一种叫模态对话框(Modal  Dialog  Box,又叫做模式对话框),一种叫做非模式对话框(Modaless Dialog Box,又叫无模式对话框).两者的区别在于当对话框打开的时候,是否允许用户进行其他对象的操作. 一.模态对话框 模态对话框指,当用户需要对该对话框之外的其他对话框或者模块进行操作时,必须该对话框关闭,才能去编辑其他对话框或者模块. 创建如下: //创建模态对话框 CModalDialog modalDialog; modalDialog.DoM

【转】MFC中调试过程中查看输出信息 -- 不错

原文网址:http://blog.sina.com.cn/s/blog_4e24d9c501014o39.html 笔记&&方便查阅. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MFC的运行机制 以及 MFC中的DC、CDC、HDC、句柄、设备上下文 [转]

在MFC程序中,我们并不经常直接调用Windows API,而是从MFC类创建对象并调用属于这些对象的成员函数.也就是说MFC封装了Windows API.你说你喜欢C++而MFC换一种说法就是一个用C++写的一个函数库 然后你来调用 只不过这个类不是你写的 MFC提供数百个类,最重要的.也是编写任何VC++应用程序都必不可少的两个类CWinApp和CFrameWnd,这两个类是编写复杂庞大应用程序的基石. 1>封装特性:构成MFC框架的是MFC类库而MFC类库又是C++的一个类库.这些类封装W

MFC 中 Tooltip 实现的几种方式

方法一:利用CWnd本身自身支持的tooptip来实现,这种方法适用给控件增加tooltip,非常方便和简单方法如下:1.在窗口中增加消息映射ON_NOTIFY_EX(TTN_NEEDTEXT, 0, SetTipText)SetTipText是个回调函数,名字叫什么无所谓,符合原型就行了,原型下面会说.    2.EnableToolTips(TRUE),使用这个方法调用这个函数是必不可少的.建议在CDialog::OnInitDialog调用. 3.在窗口中增加一个函数用于动态提供显示内容,

MFC中获取命令行参数的几种方法

在MFC程序中,可以用以下几种方法来获取命令行参数.为方便说明,我们假设执行了命令:C:\test\app.exe -1 -2 方法一: ::GetCommandLine();将获取到 "C:\test\app.exe" -1 -2 方法二: for (int i=0;i<__argc;i++){ __argv[i]; 将依次得到C:\test\app.exe -1 -2} 方法三: AfxGetApp()->m_lpCmdLine;将获取到 -1 -2 方法四: 在C**