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

5 篇文章 1 订阅

MFC中初始化opengl的类3D视图 | 火苗999℃的博客

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值