MFC下OpenGL绘图框架

MFCOpenGL入门

源文件

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_CLIPCHILDREN WS_CLIPSIBLINGS,从而避免OpenGL绘制到其他窗口中去。这些应该放在PreCreateWindow()中。

 

代码

 

 

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着色描述表

    CDCm_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 nTypeint cxint cy)

{

 CView::OnSize(nTypecxcy);

 

 // TODO: 在此处添加消息处理程序代码

 GLdouble aspect_ratio// width/height ratio

 

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

 {

      return;

 }

 // select the full client area

 ::glViewport(0, 0, cxcy);

 // 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)绘制场景。3Flush掉渲染流水线。4)若设置了双缓冲,则交换前后台缓冲区。

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

{

 CfirstDocpDoc = GetDocument();

 ASSERT_VALID(pDoc);

 if (!pDoc)

      return;

 

 // TODO: 在此处为本机数据添加绘制代码

 // Clear out the color & depth buffers

 ::glClearGL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

 RenderScene();//绘图都放在这

 // Tell OpenGL to flush its pipeline

 ::glFinish();

 // Now Swap the buffers

 ::SwapBuffersm_pDC->GetSafeHdc() );

}

 

10,              为了使改变窗口大小时严重的闪烁,在OnEraseBkgnd里做一些操作,避免windows自己的窗口刷新闪烁。

BOOL CfirstView::OnEraseBkgnd(CDCpDC)

{

// 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

}

  

 

 

 

 

 

 

附,坐标交互操作的实现:

    //控制旋转和位置的变量

    GLfloat m_xAngle;//

    GLfloat m_yAngle;

    GLfloat m_xPos;

    GLfloat m_yPos;

    CPoint m_MouseDownPoint;

 

 

旋转的关键操作:

        m_xAngle+=(point.y-m_MouseDownPoint.y)/3.6;

        m_yAngle+=(point.x-m_MouseDownPoint.x)/3.6;

        //Set the mouse point

        m_MouseDownPoint=point;

        InvalidateRect(NULL,FALSE); 

 

绘图:

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

    glLoadIdentity();

    glTranslatef(m_xPosm_yPos, -5.0f);

    glRotatef(m_xAngle, 1.0f,0.0f,0.0f);

    glRotatef(m_yAngle, 0.0f,1.0f,0.0f);

绘图操作......

原文链接:http://www.cnblogs.com/yanhuiw/articles/1794462.html

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MFC (Microsoft Foundation Class) 是 Microsoft Windows 操作系统的一个应用程序框架,它提供了一组类库和函数,使得开发者可以快速开发 Windows 应用程序。而 OpenGL 是一个图形库,可以用于创建精美的二维和三维图形。 要利用 MFC 实现一个画板,可以借助 OpenGL 来绘制图形和处理用户的交互。首先,在 MFC 应用程序中创建一个窗口,可以通过继承 CWnd 类来实现。然后,需要在窗口中集成 OpenGL,可以使用OpenGL的扩展库 (GLEW 或者 GLEW32) 来方便地加载 OpenGL 的函数。 接下来,需要处理用户的鼠标和键盘交互。通过重写窗口类中的 OnLButtonDown、OnMouseMove、OnLButtonUp、OnKeyDown、OnKeyUp 等消息处理函数,可以实现画画板上的交互操作。比如,当用户按下鼠标左键并拖动时,可以利用 OpenGL 的绘制函数来绘制相应的图形。 为了实现绘制功能,可以利用 OpenGL 的基本绘制函数,例如 glPointSize、glLineWidth、glBegin、glVertex 等。可以根据用户的输入,计算出相应的坐标,并调用这些 OpenGL 函数来绘制图形。当用户拖动鼠标或按下键盘时,可以更新坐标,并调用 Invalidate 函数来触发窗口重绘。 当然,还可以添加更多的功能,比如绘制不同类型的图形、填充颜色、撤销操作、保存和加载绘图等。通过在 MFC 应用程序中使用OpenGL,可以实现一个功能强大且具有良好交互性的画板。 总之,利用 MFC 结合 OpenGL 可以实现一个高效、灵活且具有交互性的画板应用程序,开发者可以根据需求进一步扩展和完善这个应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值