zoukankan      html  css  js  c++  java
  • 【转】《基于MFC的OpenGL编程》Part 2 Setting up OpenGL on Windows(2)

    5, OnCreate中我们将通过建立像素格式和绘制上下文来初始化OpenGL. InitializeOpenGL()中会创建一个设备上下文(DC),为这个DC选择一个像素格式,创建和这个DC相关的绘制上下文(RC,然后选择这个RC.这个函数会调用SetupPixelFormat()来建立像素格式。

    int CCY457OpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        
    if (CView::OnCreate(lpCreateStruct) == -1
    )
            
    return -1
    ;
        
    //Initialize OpenGL Here

         InitializeOpenGL();
        
    return 0
    ;
    }

    BOOL CCY457OpenGLView::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;
    }
    //Setup Pixel Format

    /////////////////////////////////////////////////////////////////////////////
    BOOL CCY457OpenGLView::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;
    }

    6, OnSize()中一般用来设置视口和视锥,因为这些是和窗口大小相关的。基本操作包括设置视口,选择投影矩阵,设置模型视图矩阵。

    void CCY457OpenGLView::OnSize(UINT nType, int cx, int cy)
    {
         CView::OnSize(nType, cx, cy);
         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);
        
        
    // switch back to the modelview matrix and clear it

         ::glMatrixMode(GL_MODELVIEW);
         ::glLoadIdentity();
    }

    7,在绘制场景时,一般包括如下步骤:1)清空缓存。2)绘制场景。3Flush掉渲染流水线。4)若设置了双缓冲,则交换前后台缓冲区。

    void CCY457OpenGLView::OnDraw(CDC* pDC)
    {
         CCY457OpenGLDoc
    * pDoc =
    GetDocument();
         ASSERT_VALID(pDoc);
        
    // Clear out the color & depth buffers

         ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
         RenderScene();
        
    // Tell OpenGL to flush its pipeline

         ::glFlush();
        
    // Now Swap the buffers

         ::SwapBuffers( m_pDC->GetSafeHdc() );
    }
    void
    CCY457OpenGLView::RenderScene ()
    {
    //第一个玩具嘛,先空着,后面慢慢填

    }

    8,试试改变窗口的大小,你会看到很严重的闪烁,并且关闭程序后会报告内存泄露,因此我们这就来解决这两个问题吧。

    发生闪烁的原因是Windows先绘制背景,然后再是OpenGL绘制,因为我们已经让OpenGL负责清空背景色,因此我们不需要Windows去清空背景了

    BOOL CCY457OpenGLView::OnEraseBkgnd(CDC* pDC)
    {
        
    //Tell Windows not to erase the background

        return TRUE;
    }

          内存泄露的原因是我们在SetupPixelFormat()使用了new运算符来为CClientDC对象分配内存,因此需要显式delete掉。

    void CCY457OpenGLView::OnDestroy()
    {
         CView::OnDestroy();
        
    //Make the RC non-current

        if(::wglMakeCurrent (NULL, NULL) == FALSE)
         {
             MessageBox(
    "Could not make RC non-current"
    );
         }
        
        
    //Delete the rendering context

        if(::wglDeleteContext (m_hRC)==FALSE)
         {
             MessageBox(
    "Could not delete RC"
    );
         }
        
    //Delete the DC

        if(m_pDC)
         {
             delete m_pDC;
         }
        
    //Set it to NULL

         m_pDC = NULL;
    }

  • 相关阅读:
    (转)【web前端培训之前后端的配合(中)】继续昨日的故事
    ural(Timus) 1136. Parliament
    scau Josephus Problem
    ACMICPC Live Archive 6204 Poker End Games
    uva 10391 Compound Words
    ACMICPC Live Archive 3222 Joke with Turtles
    uva 10132 File Fragmentation
    uva 270 Lining Up
    【转】各种字符串哈希函数比较
    uva 10905 Children's Game
  • 原文地址:https://www.cnblogs.com/lcxu2/p/2004066.html
Copyright © 2011-2022 走看看