MFC框架,OpenGL渲染
1.下载OpenGL的文件配置
百度云链接
提取码:5e7a
2.将文件解压放到你觉得合适的地方,我是直接放在C盘下的。
3.创建一个MFC单文档程序
4.将OpenGL配置到VC中
加入#include,就是你解压的文件中得include文件夹
加入lib库
注意:最好选择所有配置 。所有平台,避免不必要的问题。
添加链接库,不然找不到,opengl32.lib;glu32.lib;
前期工作准备好了
开始搭建OpenGL渲染,所有步骤都是在视口类中完成
1.引用头文件,在视口类中引用
2.在视口类中添加两个变量,两个成员函数
protected:
int m_GLPixelIndex;
HGLRC m_hGLContext;
protected:
BOOL SetWindowPixelFormat(HDC hDC);
BOOL CreateViewGLContext(HDC hDC);
其两个成员函数的实现以及两个成员变量的初始化
COpenGLView::COpenGLView() noexcept
{
// TODO: 在此处添加构造代码
m_GLPixelIndex = 0;
m_hGLContext = NULL;
}
BOOL COpenGLView::SetWindowPixelFormat(HDC hDC)
{
PIXELFORMATDESCRIPTOR pixelDesc =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER | PFD_SUPPORT_GDI,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,
0,
0,
0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,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;
}
BOOL COpenGLView::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;
}
在其PreCreateWindow函数中添加
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
在类向导中分别添加:
WM_CREATE,
WM_DESTROY,
WM_SIZE
WM_ERASEBKGND
WM_PAINT消息映射
int COpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
HWND hWnd = this->GetSafeHwnd();
HDC hDC = ::GetDC(hWnd);
if (this->SetWindowPixelFormat(hDC) == FALSE)
{
return 0;
}
if (this->CreateViewGLContext(hDC) == FALSE)
{
return 0;
}
return 0;
}
void COpenGLView::OnDestroy()
{
CView::OnDestroy();
// TODO: 在此处添加消息处理程序代码
if (wglGetCurrentContext() != NULL)
{
wglMakeCurrent(NULL, NULL);
}
if (this->m_hGLContext != NULL)
{
wglDeleteContext(this->m_hGLContext);
this->m_hGLContext = NULL;
}
}
void COpenGLView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
GLsizei width, height;
GLdouble aspect;
width = cx;
height = cy;
if (cy == 0)
{
aspect = (GLdouble)width;
}
else
{
aspect = (GLdouble)width / (GLdouble)height;
}
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 500.0*aspect, 0.0, 500.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
BOOL COpenGLView::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return true;
}
void COpenGLView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CView::OnPaint()
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
glLineWidth(2);
glColor3d(125, 125, 125);
glBegin(GL_POLYGON);
glVertex2d(100.0f, 50.0f);
glVertex2d(450.0f, 400.0f);
glVertex2d(450.0f, 50.0f);
glEnd();
//glFlush();
SwapBuffers(wglGetCurrentDC());//这个必须有,双缓存要把后台画布加到前台画布中,不然窗口显示是黑黑的一块屏幕而已
}
本人在网上找到资源,但是资源不完整,把资源完善了一下,免得同学们老是被卡在屏幕显示不出东西。
OpenGL的坐标系是坐下角为原点
gluOrtho2D(0.0, 500.0*aspect, 0.0, 500.0);这个函数
第一个参数:指定起点x的坐标
第二个参数:指定起点x的偏移值,相当于终点的x坐标
第三个参数:指定y的起点坐标,
第四个参数:指定起点y的偏移值,相当于终点的y坐标
形成的一个裁剪矩形,就是将渲染的限制-1<x<1,-1<y<1;
放大到在世界坐标轴中裁剪一个那么大的区域放到窗口上。