天天看點

OpenGL在MFC中的使用總結(二)——派生的OpenGL類

有些時候用到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;
}