王朝网络
分享
 
 
 

基于MFC对话框的OpenGL类

王朝厨房·作者佚名  2007-01-04
宽屏版  字体: |||超大  

今天写了个基于MFC对话框的OpenGL类:COpenGL,可以在对话框程序中使用OpenGL了,并且提供了全屏与非全屏转换的两个函数,很容易使用,速度快。可以到这里下载demo project。有什么意见或问题,请大家给我留言。:)

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

CRect rect;

GetDlgItem(IDC_OPENGL)->GetWindowRect(rect);

ScreenToClient(rect);

m_openGL.Create(rect, this);

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

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

#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_)

// 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;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有