|               
                    今天写了个基于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; 
                    } | 
                 
              
             
             
             
             |