MFC+Glew+Opengl环境配置:并用shader绘制四边形
一、开发环境说明
- 操作系统:windows
- 开发软件:VS2017
- 编程语言:基于MFC对话框下的opengl
- 库 :glew
- 最终效果图:
二、配置操作
配置opengl,并搭建opnegl框架,使在MFC下能显示出绘制的图形
1、打开vs2017软件,依次点击【文件】–【新建】–【项目】,选择“Visual C++”下面的 MFC,如下图所示
2、点击【确定】–【下一步】选择【基于对话框】,点击【完成】。如图所示
3、在左侧【解决方案资源管理器】中,右键单击【project】选择【添加】–【类(C)】 如图所示
4、点击“添加”,填写内容如图所示 ,然后点击完成;
5、下载glew.h,glew32.lib,glew32.dll 放在当前工程所在的文件夹下面,如图所示
6、在类视图下面,右键单击【MyOpengl】,选择类向导,添加如图三个消息函数 ,点击【编辑代码】
7、在“Myopengl.h”添加如图所示代码
8、在【Myopengl.cpp】中函数SetupPixelFormat(HDC hdc) 代码如下
BOOL MyOpengl::SetupPixelFormat(HDC hdc)//设置像素格式
{
PIXELFORMATDESCRIPTOR pfd = //像素格式
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | //绘制到窗口
PFD_SUPPORT_OPENGL |//支持opengl
PFD_DOUBLEBUFFER,//采用双缓冲
PFD_TYPE_RGBA,//像素类型 RGBA
24,//像素位数 4*8- 32
0, 0, 0, 0, 0, 0,//
0,
0,
0,
0, 0, 0, 0,
16,//深度缓冲区位数
0,//模板缓冲
0,
PFD_MAIN_PLANE,//
0,
0, 0, 0
};
int pixelformat;
if (0 == (pixelformat =ChoosePixelFormat(hdc, &pfd)))//匹配像素格式的索引
{return FALSE;
}
if (FALSE == ::SetPixelFormat(hdc,pixelformat, &pfd))//设置像素格式
{return FALSE;
}
return TRUE;
}
9、在【Myopengl.cpp】顶部添加如下代码
//顶点着色程序 字符串
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";
//片段着色程序 字符串
const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
GLuint shaderProgram; //着色器
GLuint VAO;//顶点缓冲
void MyOpengl::InitShaderAndBuffer()//加载shader并创建顶点缓冲
{
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);//创建顶点着色器
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);//绑定着色器程序
glCompileShader(vertexShader);//编译
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);//创建片元着色器
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);///绑定着色器程序
glCompileShader(fragmentShader);//编译
shaderProgram = glCreateProgram();//创建着色器程序
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。【省略】
//四边系三个顶点
GLfloat vertices[] = {
0.5f, 0.5f, 0.0f, // Top Right
0.5f, -0.5f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, // Bottom Left
-0.5f, 0.5f, 0.0f // Top Left
};
GLuint indices[] = { // Note that we start from 0!
0, 1, 3, // First Triangle 第一个三角形索引
1, 2, 3 // Second Triangle 第二个三角形索引
};
GLuint VBO, EBO;
glGenVertexArrays(1, &VAO);//创建顶点缓冲
glGenBuffers(1, &VBO);//创建bufer
glGenBuffers(1, &EBO);//创建buffer
glBindVertexArray(VAO);//绑定
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。【省略】
}
10、在【Myopengl.cpp】中函数OnCreate 实现代码如下
int MyOpengl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
hdc = ::GetDC(m_hWnd);//hdc设备上下文,m_hWnd窗口句柄
SetupPixelFormat(hdc);//设置像素格式
//CPaintDC dc(this);
hglrc = wglCreateContext(hdc);//hglrc :opengl设备上下文
wglMakeCurrent(hdc, hglrc);//hglrc绑定hdc; 绘制到当前设备上下文
glClearDepth(1.0f);//1.0是最大深度([0.0,1.0])
glEnable(GL_DEPTH_TEST);//启动深度检测
InitShaderAndBuffer()//加载shader并创建顶点缓冲
return 0;
}
11、在【Myopengl.cpp】中函数OnSize 实现代码如下
//控件窗口大小改变事件
void MyOpengl::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
GLdouble aspect_ratio;//窗口长宽比
if (0 >= cx || 0 >= cy)//窗口长、宽必须大于0
return;
glViewport(0, 0, cx, cy);//根据窗口的实时变化重绘窗口
}
12、在【Myopengl.cpp】中函数OnPaint 实现代码如下
//刷新绘制事件
void MyOpengl::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CWnd::OnPaint()
wglMakeCurrent(hdc, hglrc);//hglrcopengl设备上下文--》绑定-->hdc当前设备上下文
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);//背景颜色
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除颜色缓冲以及深度缓冲
display();//绘制函数,在这个函数中绘制自己的图形
glFinish();//绘制结束
SwapBuffers(hdc);//交换前后缓冲区
wglMakeCurrent(hdc, NULL);//释放设备上下文
}
13、在【Myopengl.cpp】中函数display 实现代码如下
//在此函数中绘制 图形
void MyOpengl::display()
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//背景颜色
glUseProgram(shaderProgram);//使用着色器
glBindVertexArray(VAO);//绑定顶点缓冲
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//绘制命令
glBindVertexArray(0);//解绑
}
14、在【Myopengl.cpp】中函数reflesh 实现代码如下
//强制刷新重绘控件
void MyOpengl::reflesh()
{
Invalidate(false);//是控件无效
this->UpdateWindow();//更新控件
}
15、在【CprojectDlg.h】文件中添加代码如下
16、在【CprojectDlg.cpp】中函数OnInitDialog添加代码如下
17、 在【资源视图】下双击【Dialog】文件夹下面的【IDD_PROJECT_DIALOG】,删除文本控件和按钮,如图所示
18、 opengl配置完成,可以点击菜单栏【调试】–【开始执行】效果如图所示
四、工程代码下载
整个工程代码都可以下载,如果有疑惑可以留言,谢谢。