MFC下OpenGL入門(可以用)


MFC下OpenGL入門

源文件

1, 建一工程文件,我這里命名為first,現在first工程里面我們沒有添加任何東西,所有的東西都是MFC自動幫我們創建的。

2, 添加鏈接庫。這一步很關鍵。打開菜單欄下的項目->屬性->配置屬性->鏈接器->輸入->附加依賴項里加入OpenGL32.lib GLu32.lib GLaux.lib,如圖

 

3, 加頭文件,在stdafx里面添加opengl的頭文件。如下代碼所示:

 

復制代碼
 //-----------------------Tramp---添加OpenGL庫頭文件----------------------------->

#include "stdio.h"

#include "math.h"

#include "gl\gl.h"

#include "gl\glu.h"

#include "gl\glaux.h"

//---------------------------------------------------------------------------<
 

 

 

 

4, CCY457OpenGLView類的屬性欄,為下述消息加入消息處理函數:WM_CREATE (for OnCreate), WM_DESTROY (for OnDestroy), WM_SIZE (for OnSize), WM_ERASEBACKGROUND (for OnEraseBkground).如下圖:

 

   

5, 設置窗口顯示風格。窗口創建之前我們必須設置窗口風格包含WS_CLIPCHILDRENWS_CLIPSIBLINGS,從而避免OpenGL繪制到其他窗口中去。這些應該放在PreCreateWindow()中。

 

 
BOOL CfirstView::PreCreateWindow(CREATESTRUCT& cs)

{

// TODO: 在此處通過修改

// CREATESTRUCT cs 來修改窗口類或樣式

 cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;//Tramp

return CView::PreCreateWindow(cs);

}
 

 

 

6, 在CfirstView.h中加入如下語句:

 

 

    /************************************************************************/

    /* 設置的變量是Rendering Context(着色描述表)。每一個OpenGL都被連接到一個着

    色描述表上。着色描述表將所有的OpenGL調用命令連接到Device Context(設備描述表)上。

    我將OpenGL的着色描述表定義為hRC 。要讓您的程序能夠繪制窗口的話,還需要創建一個

    設備描述表,也就是第二行的內容。Windows的設備描述表被定義為hDC 。DC將窗口連接到

    GDI(Graphics Device Interface圖形設備接口)。而RC將OpenGL連接到DC                                                                     */

    /************************************************************************/

    HGLRC m_hRC;    //Rendering Context着色描述表

    CDC* m_pDC;        //Device Context設備描述表

    BOOL InitializeOpenGL();    //Initialize OpenGL

    BOOL SetupPixelFormat();    //Set up the Pixel Format

    void RenderScene();            //Render the Scene

 

7, 在OnCreate中我們將通過建立像素格式和繪制上下文來初始化OpenGL. 在InitializeOpenGL()中會創建一個設備上下文(DC),為這個DC選擇一個像素格式,創建和這個DC相關的繪制上下文(RC),然后選擇這個RC.這個函數會調用SetupPixelFormat()來建立像素格式。

int Clesson1View::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

 if (CView::OnCreate(lpCreateStruct) == -1)

      return -1;

 

 // TODO: 在此添加您專用的創建代碼

 InitializeOpenGL();//初始化openGL繪圖

 

 return 0;

}

     //初始化opengl繪制

BOOL CfirstView::InitializeOpenGL()

{

    //Get a DC for the Client Area

    m_pDC = new CClientDC(this);

    //Failure to Get DC

    if(m_pDC == NULL)

    {

        //::MessageBox("Error Obtaining DC");

        return FALSE;

    }

    //Failure to set the pixel format

    if(!SetupPixelFormat())

    {

        return FALSE;

    }

 //Create Rendering Context

 m_hRC = ::wglCreateContext (m_pDC->GetSafeHdc ());

 //Failure to Create Rendering Context

 if(m_hRC == 0)

 {

      // MessageBox("Error Creating RC");

      return FALSE;

 }

 //Make the RC Current

 if(::wglMakeCurrent (m_pDC->GetSafeHdc (), m_hRC)==FALSE)

 {

      // MessageBox("Error making RC Current");

      return FALSE;

 }

 //Specify Black as the clear color

 ::glClearColor(0.0f,0.0f,0.0f,0.0f);

 //Specify the back of the buffer as clear depth

 ::glClearDepth(1.0f);

 //Enable Depth Testing

 ::glEnable(GL_DEPTH_TEST);

 return TRUE;

 

}

//設置像素格式

BOOL CfirstView::SetupPixelFormat()

{

 static PIXELFORMATDESCRIPTOR pfd =

 {

      sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd

      1,                              // version number

      PFD_DRAW_TO_WINDOW |            // support window

      PFD_SUPPORT_OPENGL |            // support OpenGL

      PFD_DOUBLEBUFFER,                // double buffered

      PFD_TYPE_RGBA,                  // RGBA type

      24,                             // 24-bit 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,                     // accum bits ignored

      16,                             // 16-bit z-buffer

      0,                              // no stencil buffer

      0,                              // no auxiliary buffer

      PFD_MAIN_PLANE,                 // main layer

      0,                              // reserved

      0, 0, 0                         // layer masks ignored

 };

 int m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);

 if ( m_nPixelFormat == 0 )

 {

      return FALSE;

 }

 if ( ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd) == FALSE)

 {

      return FALSE;

 }

 return TRUE;

}

 

8, 在OnSize()中一般用來設置視口和視錐,因為這些是和窗口大小相關的。基本操作包括設置視口,選擇投影矩陣,設置模型視圖矩陣。

void CfirstView::OnSize(UINT nType, int cx, int cy)

{

 CView::OnSize(nType, cx, cy);

 

 // TODO: 在此處添加消息處理程序代碼

 GLdouble aspect_ratio; // width/height ratio

 

 if ( 0 >= cx || 0 >= cy )

 {

      return;

 }

 // select the full client area

 ::glViewport(0, 0, cx, cy);

 // compute the aspect ratio

 // this will keep all dimension scales equal

 aspect_ratio = (GLdouble)cx/(GLdouble)cy;

 // select the projection matrix and clear it

 ::glMatrixMode(GL_PROJECTION);

 ::glLoadIdentity();

 // select the viewing volume

 ::gluPerspective(45.0f, aspect_ratio, .01f, 200.0f);//畫三維

 //::gluOrtho2D(-10.0f, 10.0f, -10.0f, 10.0f);    //二維

 

 

 // switch back to the modelview matrix and clear it

 ::glMatrixMode(GL_MODELVIEW);

 ::glLoadIdentity();

}

 

9, 在繪制場景時,一般包括如下步驟:1)清空緩存。2)繪制場景。3)Flush掉渲染流水線。4)若設置了雙緩沖,則交換前后台緩沖區。

void CfirstView::OnDraw(CDC* /*pDC*/)

{

 CfirstDoc* pDoc = GetDocument();

 ASSERT_VALID(pDoc);

 if (!pDoc)

      return;

 

 // TODO: 在此處為本機數據添加繪制代碼

 // Clear out the color & depth buffers

 ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

 RenderScene();//繪圖都放在這

 // Tell OpenGL to flush its pipeline

 ::glFinish();

 // Now Swap the buffers

 ::SwapBuffers( m_pDC->GetSafeHdc() );

}

 

10,              為了使改變窗口大小時嚴重的閃爍,在OnEraseBkgnd里做一些操作,避免windows自己的窗口刷新閃爍。

BOOL CfirstView::OnEraseBkgnd(CDC* pDC)

{

// TODO: 在此添加消息處理程序代碼和/或調用默認值

 

return TRUE;

}

11,              為了避免內存泄露,我們要將在SetupPixelFormat()中使用了new運算符來為CClientDC對象分配的內存在程序關閉時delete掉。

 void CfirstView::OnDestroy()

{

    CView::OnDestroy();

 

    // TODO: 在此處添加消息處理程序代碼

    //Make the RC non-current

    if(::wglMakeCurrent (0,0) == FALSE)

    {

        MessageBox(_T("Could not make RC non-current"));

    }

 

    //Delete the rendering context

    if(::wglDeleteContext (m_hRC)==FALSE)

    {

        MessageBox(_T("Could not delete RC"));

    }

    //Delete the DC

    if(m_pDC)

    {

        delete m_pDC;

    }

    //Set it to NULL

    m_pDC = NULL;

}

 

12,      下面寫主繪圖函數,RenderScene(),在窗口畫了一個正方體、一個四面體。

 void CfirstView::RenderScene()

{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer

    glLoadIdentity();                                   // Reset The Current Modelview Matrix

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

    glRotatef(30,0.0f,1.0f,0.0f);                       // Rotate The Triangle On The Y axis ( NEW )

    glBegin(GL_TRIANGLES);                              // Start Drawing A Triangle

    glColor3f(1.0f,0.0f,0.0f);                      // Red

    glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Front)

    glColor3f(0.0f,1.0f,0.0f);                      // Green

    glVertex3f(-1.0f,-1.0f, 1.0f);                  // Left Of Triangle (Front)

    glColor3f(0.0f,0.0f,1.0f);                      // Blue

    glVertex3f( 1.0f,-1.0f, 1.0f);                  // Right Of Triangle (Front)

    glColor3f(1.0f,0.0f,0.0f);                      // Red

    glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Right)

    glColor3f(0.0f,0.0f,1.0f);                      // Blue

    glVertex3f( 1.0f,-1.0f, 1.0f);                  // Left Of Triangle (Right)

    glColor3f(0.0f,1.0f,0.0f);                      // Green

    glVertex3f( 1.0f,-1.0f, -1.0f);                 // Right Of Triangle (Right)

    glColor3f(1.0f,0.0f,0.0f);                      // Red

    glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Back)

    glColor3f(0.0f,1.0f,0.0f);                      // Green

    glVertex3f( 1.0f,-1.0f, -1.0f);                 // Left Of Triangle (Back)

    glColor3f(0.0f,0.0f,1.0f);                      // Blue

    glVertex3f(-1.0f,-1.0f, -1.0f);                 // Right Of Triangle (Back)

    glColor3f(1.0f,0.0f,0.0f);                      // Red

    glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Left)

    glColor3f(0.0f,0.0f,1.0f);                      // Blue

    glVertex3f(-1.0f,-1.0f,-1.0f);                  // Left Of Triangle (Left)

    glColor3f(0.0f,1.0f,0.0f);                      // Green

    glVertex3f(-1.0f,-1.0f, 1.0f);                  // Right Of Triangle (Left)

    glEnd();                                            // Done Drawing The Pyramid

 

    glLoadIdentity();                                   // Reset The Current Modelview Matrix

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

    glRotatef(25,1.0f,1.0f,1.0f);                   // Rotate The Quad On The X axis ( NEW )

    glBegin(GL_QUADS);                                  // Draw A Quad

    glColor3f(0.0f,1.0f,0.0f);                      // Set The Color To Green

    glVertex3f( 1.0f, 1.0f,-1.0f);                  // Top Right Of The Quad (Top)

    glVertex3f(-1.0f, 1.0f,-1.0f);                  // Top Left Of The Quad (Top)

    glVertex3f(-1.0f, 1.0f, 1.0f);                  // Bottom Left Of The Quad (Top)

    glVertex3f( 1.0f, 1.0f, 1.0f);                  // Bottom Right Of The Quad (Top)

    glColor3f(1.0f,0.5f,0.0f);                      // Set The Color To Orange

    glVertex3f( 1.0f,-1.0f, 1.0f);                  // Top Right Of The Quad (Bottom)

    glVertex3f(-1.0f,-1.0f, 1.0f);                  // Top Left Of The Quad (Bottom)

    glVertex3f(-1.0f,-1.0f,-1.0f);                  // Bottom Left Of The Quad (Bottom)

    glVertex3f( 1.0f,-1.0f,-1.0f);                  // Bottom Right Of The Quad (Bottom)

    glColor3f(1.0f,0.0f,0.0f);                      // Set The Color To Red

    glVertex3f( 1.0f, 1.0f, 1.0f);                  // Top Right Of The Quad (Front)

    glVertex3f(-1.0f, 1.0f, 1.0f);                  // Top Left Of The Quad (Front)

    glVertex3f(-1.0f,-1.0f, 1.0f);                  // Bottom Left Of The Quad (Front)

    glVertex3f( 1.0f,-1.0f, 1.0f);                  // Bottom Right Of The Quad (Front)

    glColor3f(1.0f,1.0f,0.0f);                      // Set The Color To Yellow

    glVertex3f( 1.0f,-1.0f,-1.0f);                  // Top Right Of The Quad (Back)

    glVertex3f(-1.0f,-1.0f,-1.0f);                  // Top Left Of The Quad (Back)

    glVertex3f(-1.0f, 1.0f,-1.0f);                  // Bottom Left Of The Quad (Back)

    glVertex3f( 1.0f, 1.0f,-1.0f);                  // Bottom Right Of The Quad (Back)

    glColor3f(0.0f,0.0f,1.0f);                      // Set The Color To Blue

    glVertex3f(-1.0f, 1.0f, 1.0f);                  // Top Right Of The Quad (Left)

    glVertex3f(-1.0f, 1.0f,-1.0f);                  // Top Left Of The Quad (Left)

    glVertex3f(-1.0f,-1.0f,-1.0f);                  // Bottom Left Of The Quad (Left)

    glVertex3f(-1.0f,-1.0f, 1.0f);                  // Bottom Right Of The Quad (Left)

    glColor3f(1.0f,0.0f,1.0f);                      // Set The Color To Violet

    glVertex3f( 1.0f, 1.0f,-1.0f);                  // Top Right Of The Quad (Right)

    glVertex3f( 1.0f, 1.0f, 1.0f);                  // Top Left Of The Quad (Right)

    glVertex3f( 1.0f,-1.0f, 1.0f);                  // Bottom Left Of The Quad (Right)

    glVertex3f( 1.0f,-1.0f,-1.0f);                  // Bottom Right Of The Quad (Right)

    glEnd();                                            // Done Drawing The Quad

}

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM