科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件制作一个基于MFC对话框的OpenGL类

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

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

今天写了个基于MFC对话框的OpenGL类:COpenGL,可以在对话框程序中使用OpenGL了 .

作者:Passants 来源:blog 2007年10月19日

关键字: 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):

<

查看本文来源

/TABLE>
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章
    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;
    }