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;
    }

  • 相关阅读:
    C# GridView点击某列打开新浏览器窗口
    大白话系列之C#委托与事件讲解(二)
    大白话系列之C#委托与事件讲解(一)
    Razor语法大全
    Expression<Func<T,TResult>>和Func<T,TResult>
    C#委托的介绍(delegate、Action、Func、predicate)
    Android--样式经验
    Android--onSaveInstanceState()保存数据
    Android--ActivityLiving生命周期
    android--快捷键
  • 原文地址:https://www.cnblogs.com/lcxu2/p/2004066.html
Copyright © 2011-2022 走看看