MFC中初始化opengl的类3D视图

原创 2013年07月31日 17:37:27


#pragma once

class InitOpenGL3D
{
public:
    InitOpenGL3D(void);
    virtual ~InitOpenGL3D(void);
public:
    // 在OnCreate函数中调用此函数:
    int InitOpenGL3D::OnCreate(LPCREATESTRUCT lpCreateStruct, CClientDC* pDC);
    // 在Ondestroy()中调用 
    void InitOpenGL3D::OnDestroy();
    // 在OnSize()调用
    void InitOpenGL3D::OnSize(UINT nType, int cx, int cy);
    // 在OnPaint()中调用,窗口框架重绘
    void InitOpenGL3D::OnPaint();
private:
    // InitOpenGL3D 消息处理程序
    BOOL InitOpenGL3D::PreCreateWindow(CREATESTRUCT& cs);
    // 定义窗口的像素格式。像素格式决定窗口着所显示的图形在内存中是如何表示的。
    BOOL InitOpenGL3D::SetWindowPixelFormat(HDC hDC);
    // 创建像素格式的View
    BOOL InitOpenGL3D::CreateViewGLContext(HDC hDC);
private:
    // 记录像素格式
    int m_GLPixelIndex; 
    // HGLRC是一个指向 rendering context 的句柄 
    HGLRC m_hGLContext;
    // 
    BOOL DrawCuboid(double x, double y, double z); 
    int m_xSize;
    int m_ySize; 
    CDC* m_pDC; 
    double m_aspect; 
    double unit_pixel;
};

#include "StdAfx.h"

#include "gl\gl.h"
#include "gl\glu.h"
#include "GL\GLUT.H"
#include "GL\glaux.h"

#include "InitOpenGL3D.h"

#include "math.h"
InitOpenGL3D::InitOpenGL3D(void)
{
}

InitOpenGL3D::~InitOpenGL3D(void)
{
}
// InitOpenGL3D 消息处理程序

BOOL InitOpenGL3D::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs
    cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
    // WS_CLIPCHILDREN(创建父窗口使用的Windows风格,用于重绘时裁剪子窗口所覆盖的区域)
    // WS_CLIPSIBLINGS(创建子窗口使用的Windows风格,用于重绘时剪裁其他子窗口所覆盖的区域)
    return TRUE;//CView::PreCreateWindow(cs);
}

// 定义窗口的像素格式。像素格式决定窗口着所显示的图形在内存中是如何表示的。
BOOL InitOpenGL3D::SetWindowPixelFormat(HDC hDC)
{// 定义窗口的像素格式
    PIXELFORMATDESCRIPTOR pixelDesc;

    pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    pixelDesc.nVersion = 1;
    pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
        PFD_DOUBLEBUFFER | PFD_STEREO_DONTCARE;

    pixelDesc.iPixelType = PFD_TYPE_RGBA;
    pixelDesc.cColorBits = 32;
    pixelDesc.cRedBits = 8;
    pixelDesc.cRedShift = 16;
    pixelDesc.cGreenBits = 8;
    pixelDesc.cGreenShift = 8;
    pixelDesc.cBlueBits = 8;
    pixelDesc.cBlueShift = 0;
    pixelDesc.cAlphaBits = 0;
    pixelDesc.cAlphaShift = 0;
    pixelDesc.cAccumBits = 64;
    pixelDesc.cAccumRedBits = 16;
    pixelDesc.cAccumGreenBits = 16;
    pixelDesc.cAccumBlueBits = 16;
    pixelDesc.cAccumAlphaBits = 0;
    pixelDesc.cDepthBits = 32;
    pixelDesc.cStencilBits = 8;
    pixelDesc.cAuxBuffers = 0;
    pixelDesc.iLayerType = PFD_MAIN_PLANE;
    pixelDesc.bReserved = 0;
    pixelDesc.dwLayerMask = 0;
    pixelDesc.dwVisibleMask = 0;
    pixelDesc.dwDamageMask = 0;

    this->m_GLPixelIndex = ChoosePixelFormat(hDC, &pixelDesc);
    if(this->m_GLPixelIndex==0)
    {
        this->m_GLPixelIndex = 1;
        if(DescribePixelFormat(hDC,this->m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR), &pixelDesc)==0)
        {
            return FALSE;
        }
    }

    if(SetPixelFormat(hDC,this->m_GLPixelIndex, &pixelDesc)==FALSE)
    {
        return FALSE;
    }

    return TRUE;
}

// 创建像素格式的View
BOOL InitOpenGL3D::CreateViewGLContext(HDC hDC)
{
    this->m_hGLContext = wglCreateContext(hDC);
    if(this->m_hGLContext==NULL)
    {// 创建失败
        return FALSE;
    }

    if(wglMakeCurrent(hDC,this->m_hGLContext)==FALSE)
    {// 选为当前RC失败
        return FALSE;
    }

    return TRUE;
}
// 指示正在创建窗口(响应WM_CREATE消息) // 在 原
int InitOpenGL3D::OnCreate(LPCREATESTRUCT lpCreateStruct, CClientDC* pDC)
{
    // TODO: Add your specialized creation code here
    
    m_pDC = pDC;
//     HWND hWnd = this->GetSafeHwnd();    
//     HDC hDC = ::GetDC(hWnd);

    if(this->SetWindowPixelFormat(this->m_pDC->GetSafeHdc())==FALSE)
    {
        return 0;
    }
    if(this->CreateViewGLContext(this->m_pDC->GetSafeHdc())==FALSE)
    {
        return 0;
    }
    
    return 0;
}
// 添加WM_DESTROY的消息处理函数Ondestroy( ) // 销毁窗口
void InitOpenGL3D::OnDestroy()
{
    // TODO: Add your message handler code here

    if(wglGetCurrentContext()!=NULL)
    {
        wglMakeCurrent(NULL,NULL);
    }
    if(this->m_hGLContext!=NULL)
    {
        wglDeleteContext(this->m_hGLContext);
        this->m_hGLContext = NULL;
    }
}
// 响应WM_SIZE消息 
void InitOpenGL3D::OnSize(UINT nType, int cx, int cy)
{
    // TODO: Add your message handler code here
    CSize size(cx,cy);
    m_aspect = (cy == 0) ? (double)size.cx : (double)size.cx/(double)size.cy;
    this->m_xSize = cx;
    this->m_ySize = cy;
    this->unit_pixel = (((double)cy)/2.0) / tan((3.1415926*45/180)/2);  // 记录屏幕像素与OpenGL坐标
}
// WM_PAINT的消息处理函数OnPaint,窗口框架重绘
void InitOpenGL3D::OnPaint()
{
    // TODO: Add your message handler code here
    // Do not call CView::OnPaint() for painting messages
    glViewport(0,0, m_xSize, m_ySize);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, m_aspect, 1, 200.0);
    glMatrixMode(GL_MODELVIEW);
    glEnable(GL_DEPTH_TEST);

    wglMakeCurrent(m_pDC->GetSafeHdc(), m_hGLContext);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glShadeModel(GL_SMOOTH);							// 启用阴影平滑
    

    glTranslated(0, 0, -1);

    glPushMatrix();

    // 以下是绘制代码
    glColor3f(1,0,0);
    DrawCuboid(0.2, 0.2, 0.2);

    glTranslated(0.4, 0, 0);
    glColor3f(1,0,0);
    DrawCuboid(0.2, 0.2, 0.2);

    glTranslated(0, 0.4, 0);
    glColor3f(1,0,0);
    DrawCuboid(0.2, 0.2, 0.2);

    glTranslated(-0.4, 0, 0);
    glColor3f(1,0,0);
    DrawCuboid(0.2, 0.2, 0.2);

    glTranslated(-0.4, 0, 0);
    glColor3f(1,0,0);
    DrawCuboid(0.2, 0.2, 0.2);

    glTranslated(0, -0.4, 0);
    glColor3f(1,0,0);
    DrawCuboid(0.2, 0.2, 0.2);

    glTranslated(0, -0.4, 0);
    glColor3f(1,0,0);
    DrawCuboid(0.2, 0.2, 0.2);

    glTranslated(0.4, 0, 0);
    glColor3f(1,0,0);
    DrawCuboid(0.2, 0.2, 0.2);

    glTranslated(0.4, 0, 0);
    glColor3f(1,0,0);
    DrawCuboid(0.2, 0.2, 0.2);

    // 绘制代码完成
    glPopMatrix();
    ::SwapBuffers(m_pDC->GetSafeHdc());  //交换缓冲区
    glFlush();	 
    glDisable(GL_DEPTH_TEST);
}

// 跟扩展库的绘制结果相同
BOOL InitOpenGL3D::DrawCuboid(double x, double y, double z) // 测试用
{
    //     glPushMatrix();
    double cx = x/2.0;
    double cy = y/2.0;
    double cz = z/2.0;
    glBegin(GL_QUADS);
    // 左面
    glTexCoord2f(0.0f, 0.0f);  glVertex3f(-cx, -cy, -cz);
    glTexCoord2f(1.0f, 0.0f);  glVertex3f(-cx,  cy, -cz);
    glTexCoord2f(1.0f, 1.0f);  glVertex3f(-cx,  cy,  cz);
    glTexCoord2f(0.0f, 1.0f);  glVertex3f(-cx, -cy,  cz);
    // 右面
    glTexCoord2f(0.0f, 0.0f);  glVertex3f(cx, -cy, -cz);
    glTexCoord2f(1.0f, 0.0f);  glVertex3f(cx,  cy, -cz);
    glTexCoord2f(1.0f, 1.0f);  glVertex3f(cx,  cy,  cz);
    glTexCoord2f(0.0f, 1.0f);  glVertex3f(cx, -cy,  cz);
    // 上面
    glTexCoord2f(0.0f, 0.0f);  glVertex3f(-cx, cy, -cz);
    glTexCoord2f(1.0f, 0.0f);  glVertex3f( cx, cy, -cz);
    glTexCoord2f(1.0f, 1.0f);  glVertex3f( cx, cy,  cz);
    glTexCoord2f(0.0f, 1.0f);  glVertex3f(-cx, cy,  cz);
    // 下面
    glTexCoord2f(0.0f, 0.0f);  glVertex3f(-cx, -cy, -cz);
    glTexCoord2f(1.0f, 0.0f);  glVertex3f( cx, -cy, -cz);
    glTexCoord2f(1.0f, 1.0f);  glVertex3f( cx, -cy,  cz);
    glTexCoord2f(0.0f, 1.0f);  glVertex3f(-cx, -cy,  cz);
    // 前面
    glTexCoord2f(0.0f, 0.0f);  glVertex3f(-cx, -cy, -cz);
    glTexCoord2f(1.0f, 0.0f);  glVertex3f( cx, -cy, -cz);
    glTexCoord2f(1.0f, 1.0f);  glVertex3f( cx,  cy, -cz);
    glTexCoord2f(0.0f, 1.0f);  glVertex3f(-cx,  cy, -cz);
    // 后面
    glTexCoord2f(0.0f, 0.0f);  glVertex3f(-cx, -cy, cz);
    glTexCoord2f(1.0f, 0.0f);  glVertex3f( cx, -cy, cz);
    glTexCoord2f(1.0f, 1.0f);  glVertex3f( cx,  cy, cz);
    glTexCoord2f(0.0f, 1.0f);  glVertex3f(-cx,  cy, cz);
    glEnd();

    //     glPopMatrix();
    return TRUE;
}



基于MFC完整的OpenGL框架步骤

1. 新建一个MEC单文档应用程序,如下各图所示, 2. 更改头文件,双击WelecomView.h,在程序前面加上以下两个头文件(W...
  • u013232740
  • u013232740
  • 2015年01月28日 14:52
  • 1432

MFC 视图类(CView)介绍

视图是程序设计中使用率最高的窗口对象,它是用户的主要操作界面。因为它通常以某种形式表示文档数据,所以称之为视图。一个视图对象只关联一个文档对象;一个文档对象可以关联多个视图,每个视图对象以不同形式表示...
  • u011867581
  • u011867581
  • 2015年01月26日 13:09
  • 2498

OpenGL--3D世界(视图变换,模型变换,投影变换,视口变换)

理论基础 1,OpenGL渲染3D物体到屏幕上的过程其实类似我们平时用照相机拍照的过程,这个步骤大致如下:一,把照相机固定在三脚架并让它对准场景(视图变换)二,把场景中的物体调整摆放好(模型变换)三...
  • u010223072
  • u010223072
  • 2015年03月25日 13:59
  • 4364

MFC 中配置OpenGL环境

MFC为编写Windows应用程序提供了极大的方便,程序员在编写Windows应用程序时,只需要几步就可以把一个程序的框架建立起来.该类极大的提高了编程者的开发效率,是个具有极大实用价值的工具. ...
  • xiaoge132
  • xiaoge132
  • 2016年03月09日 09:45
  • 2451

VS2010-MFC:用OpenGL在对话框中的PictureControl(图片控件)中绘制三维模型,可旋转、平移、缩放,可用于三维模型的预览

由于有这个需求,就是当在对话框设置一些数值的时候,可以在对话框上预览三维图像。 (1)生成一个基于对话框的程序,或者直接在单文档或者多文档上插入一个对话框,生成一个新的对话框类CGridingDlg,...
  • HW140701
  • HW140701
  • 2017年03月21日 17:59
  • 2087

MFC中对话框向视图类的数据发送

最近在做一个界面上的东西:需要在工具栏中点击按钮弹出一个对话框,这个对话框需要根据视图类里面的 变量进行更新对话框里面combox的内容,同时对话框需要将变化的内容发送给视图类,这就涉及到了对话框 和...
  • shlkl99
  • shlkl99
  • 2014年01月17日 15:10
  • 1505

Opengl与MFC结合显示图像

Opengl与MFC结合显示图像。下面是总结的一个类: //头文件 #if !defined(AFX_OPENGL_H__4D4A8C3F_A907_4A63_B205_B839E456A...
  • xbeinonlinkejidaxue
  • xbeinonlinkejidaxue
  • 2014年11月06日 21:56
  • 1030

[MFC]CView视图类、CMainFrame主框架类

1. 视图对象简介以及视图对象何如使用文档来操作数据:     1) 视图的两个重要用途:          i. 鉴于文档的唯一任务就是管理应用程序的数据,那么视图的一个重要用途就是提供文档的可视化...
  • Lirx_Tech
  • Lirx_Tech
  • 2015年09月22日 20:09
  • 1048

MFC的单文档视图结构(摘录)

文档        文档对象用于管理和维护数据,包括保存数据、取出数据以及修改数据等操作,在数据被修改以后,文档可以通知其对应的所有视图更新显示。    视图        视图对象...
  • qqqren
  • qqqren
  • 2016年11月25日 10:52
  • 349

[实例]OpenGL绘制茶壶(光照、三维变换)

#include #ifdef __APPLE__ #include #else #include #endif #include double angle = 0.0; static ...
  • Mahabharata_
  • Mahabharata_
  • 2016年08月25日 22:55
  • 4757
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MFC中初始化opengl的类3D视图
举报原因:
原因补充:

(最多只允许输入30个字)