制作一个基于MFC对话框的OpenGL类

今天写了个基于MFC对话框的OpenGL类:COpenGL,可以在对话框程序中使用OpenGL了,并且提供了全屏与非全屏转换的两个函数,很容易使用,速度快。

使用方法:在对话框上加一个Static控件(或者其他的也可以),在OnInitDialog()中加人下面这段代码(假设控件ID为IDC_OPENGL,m_openGL是类COpenGL的对象):

Code: CRect rect;

GetDlgItem(IDC_OPENGL)->GetWindowRect(rect);

ScreenToClient(rect);

m_openGL.Create(rect, this);

然后在适当的地方调用m_openGL.RenderGLScene()就可以了。

以下是类代码(OpenGL.h和OpenGL.cpp):

Code:#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

//

/

// COpenGL window

class COpenGL : public CWnd

{

// Construction

public:

COpenGL();

// Attributes

public:

// Operations

public:

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(COpenGL)

//}}AFX_VIRTUAL

// Implementation

public:

BOOL SetNormScreen();

BOOL SetFullScreen(int width, int height, int depth);

virtual void RenderGLScene();

void Create(CRect rect, CWnd *parent);

virtual ~COpenGL();

// Generated message map functions

protected:

CRect m_rect;

CWnd* m_parent;

BOOL m_bFullScreen;

DEVMODE m_DMsaved;

BOOL m_bInit;

int InitGL();

void KillGLWindow();

HDC m_hDC;

HGLRC m_hRC;

//{{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_)

Code:// OpenGL.cpp : implementation file

//

#include "stdafx.h"

#include "DialogOpenGL.h"

#include "OpenGL.h"

#include <gl/gl.h>

#include <gl/glu.h>

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/

// COpenGL

COpenGL::COpenGL():m_bInit(FALSE),m_bFullScreen(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()

ON_WM_KEYDOWN()

//}}AFX_MSG_MAP

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(0,className,"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_bFullScreen) // Are We In Fullscreen Mode?

{

if (!ChangeDisplaySettings(NULL,CDS_TEST)) { // if the shortcut doesn't work

ChangeDisplaySettings(NULL,CDS_RESET); // Do it anyway (to get the values out of the registry)

ChangeDisplaySettings(&m_DMsaved,CDS_RESET); // change it to the saved settings

} else {

ChangeDisplaySettings(NULL,CDS_RESET);

}

ShowCursor(TRUE); // Show Mouse Pointer

}

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.5f); // 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); // Clear Screen And Depth Buffer

glLoadIdentity();

// EXAMPLE OPENGL CODE START

//

static GLfloat xrot; // X Rotation

static GLfloat yrot; // Y Rotation

static GLfloat zrot; // Z Rotation

glPushMatrix(); // Push Matrix Onto Stack (Copy The Current Matrix)

glLoadIdentity(); // Reset The Current Modelview Matrix

glTranslatef(0.0f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0

glRotatef(xrot,1.0f,0.0f,0.0f);

glRotatef(yrot,0.0f,1.0f,0.0f);

glRotatef(zrot,0.0f,0.0f,1.0f);

glBegin(GL_QUADS);

// Front Face

glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, 1.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, -1.0f, 1.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, 1.0f);

glColor3f(0.0f,0.0f,1.0f);glVertex3f(-1.0f, 1.0f, 1.0f);

// Back Face

glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, -1.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex3f(-1.0f, 1.0f, -1.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, -1.0f);

glColor3f(0.0f,0.0f,1.0f);glVertex3f( 1.0f, -1.0f, -1.0f);

// Top Face

glColor3f(0.0f,1.0f,0.0f);glVertex3f(-1.0f, 1.0f, -1.0f);

glColor3f(0.0f,0.0f,1.0f);glVertex3f(-1.0f, 1.0f, 1.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, 1.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, -1.0f);

// Bottom Face

glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, -1.0f);

glColor3f(0.0f,0.0f,1.0f);glVertex3f( 1.0f, -1.0f, -1.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, -1.0f, 1.0f);

glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, 1.0f);

// Right face

glColor3f(0.0f,0.0f,1.0f);glVertex3f( 1.0f, -1.0f, -1.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, -1.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, 1.0f, 1.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex3f( 1.0f, -1.0f, 1.0f);

// Left Face

glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, -1.0f);

glColor3f(1.0f,0.0f,0.0f);glVertex3f(-1.0f, -1.0f, 1.0f);

glColor3f(0.0f,0.0f,1.0f);glVertex3f(-1.0f, 1.0f, 1.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex3f(-1.0f, 1.0f, -1.0f);

glEnd();

glPopMatrix(); // Pop Matrix Off The Stack

xrot+=1.3f;

yrot+=1.2f;

zrot+=1.4f; // Decrease The Rotation Variable For The Quad

//

// EXAMPLE OPENGL CODE END //

// Swap our scene to the front

SwapBuffers(m_hDC);

Invalidate(FALSE);

}

void COpenGL::OnPaint()

{

CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here

::ValidateRect ( m_hWnd, NULL );

// 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); // Select The Projection Matrix

glLoadIdentity(); // Reset The Projection Matrix

gluPerspective(45.0f,(GLfloat)cx/(GLfloat)cy,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window

glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix

glLoadIdentity(); // Reset The Modelview Matrix

}

BOOL COpenGL::SetFullScreen(int width, int height, int depth)

{

if(!m_bInit) return FALSE;

if (m_bFullScreen) return TRUE;

DEVMODE dmScreenSettings; // Device Mode

memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared

dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure

dmScreenSettings.dmPelsWidth = width; // Selected Screen Width

dmScreenSettings.dmPelsHeight = height; // Selected Screen Height

dmScreenSettings.dmBitsPerPel = depth; // Selected Bits Per Pixel

dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.

if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)

{

return m_bFullScreen = FALSE;

}

SetParent(NULL);

SetWindowPos(&CWnd::wndTop,0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_SHOWWINDOW);

ShowCursor(FALSE);

SetFocus();

return m_bFullScreen = TRUE;

}

BOOL COpenGL::SetNormScreen()

{

if(!m_bInit) return FALSE;

if (m_bFullScreen) // Are We In Fullscreen Mode?

{

if (!ChangeDisplaySettings(NULL,CDS_TEST)) { // if the shortcut doesn't work

ChangeDisplaySettings(NULL,CDS_RESET); // Do it anyway (to get the values out of the registry)

ChangeDisplaySettings(&m_DMsaved,CDS_RESET); // change it to the saved settings

} else {

ChangeDisplaySettings(NULL,CDS_RESET);

}

SetParent(m_parent);

SetWindowPos(&CWnd::wndTop,m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), SWP_SHOWWINDOW);

ShowCursor(TRUE); // Show Mouse Pointer

m_bFullScreen = FALSE;

}

return TRUE;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值