MFC+Glew+Opengl环境配置:并用shader绘制四边形

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配置完成,可以点击菜单栏【调试】–【开始执行】效果如图所示

四、工程代码下载

整个工程代码都可以下载,如果有疑惑可以留言,谢谢。

社交账号快速登录