工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > VC > 正文
制作一个基于MFC对话框的OpenGL类
[文章信息]
作者:Passants
时间:2005-03-04
出处:blog
责任编辑:方舟
[文章导读]
今天写了个基于MFC对话框的OpenGL类:COpenGL,可以在对话框程序中使用OpenGL了
advertisement
专题教程宝典
【软件应用】
【办公软件】
【图形图像】
【网页制作】
【操作系统】
【网络安全】
【程序开发】
【日报周刊】
【多媒体教程】
· 天极软件应用多媒体教程
· Windows开机关机故障分析及排除
· 图解PS按比例自动批量裁剪照片
· Visual FoxPro9.0构建管理系统图解
· 体验面对面的网络视频通讯
· 对付网页恶意代码
· Word动画教程:表格操作全接触
· JBuilder 2005开发Applet游戏全接触
· WinRAR操作技巧与另类应用
· 用VMware 5实现多系统同时运行
[正文]
  今天写了个基于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;
}


天极社区邀请您:写博客日记  上传相片   论坛聊天  订阅电子杂志  推荐网摘   免费图铃工具
笔名:   请您注意:

 遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。

 天极网拥有管理笔名和留言的一切权利。
评论:
 
发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • MFC六大关键技术之运行时类型识别
  • 轻松实现Visual C++源代码规范整理
  • 用Visual C++实现CPU特权指令操作
  • VC下用串口与电台通信需注意的问题
  • 剖析MFC六大关键技术之初始化过程
  • 全球手机排名出炉 诺基亚第一 摩托罗拉第二
  • 明基挖走三星笔记本总代理 三星转战直接零售
  • 协同软件市场广阔 国内厂商面临重重挑战
  • 加强银行市场风险管理 建设信息系统是关键
  • 证监会出台《办法》 规范信息安全信息通报
  • 搜狐首席财务官“倾囊”回购股票表信心
  • 中国DVD不买6C联盟账 称降价幅度杯水车薪
  • 柳传志称联想正积极交涉 乐观看待并购前景
  • Advertisement

    天极无线


    奇妙科幻|美好风光|清风车影|漫画卡通|星座生肖|明星写真|动物世界
    老鼠爱大米
    挥着翅膀的女孩
    女人味
    栀子花开
    白月光
    刚刚好
    江南
    快乐崇拜
    亲爱的你怎么不在我身边
    小薇
    2002年的第一场雪
    有多少爱可以重来
    我的地盘
    七里香
    情人
     
    老鼠爱大米 老板电话
    冲动的惩罚 七里香
    我不是黄蓉 女生撒娇
    盛夏的果实 坚持到底
    孤单北半球 眉飞色舞
    挪威的森林 可爱女人
    最浪漫的事 老板电话

    CSEEK搜索