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