前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qt5.12 + OpenGL 创建第一个多边形Core版

Qt5.12 + OpenGL 创建第一个多边形Core版

作者头像
用户5908113
发布2020-01-02 17:25:13
1.3K0
发布2020-01-02 17:25:13
举报
文章被收录于专栏:Pou光明Pou光明

原教程地址:

https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/

程序参考地址:

https://blog.csdn.net/z136411501/article/details/79834381

这里介绍第二种方法,使用QOpenGLFunctions_3_3_Core类对象,Core类其实是一种Qt对OpenGL特定版本的包装类对象,可以直接使用该版本OpenGL的所有函数。

效果图如下:

代码和之前比“几乎”没变,只是把所有gl开头的函数都换成了

m_core->gl ******来调用了。

头文件如下:

代码语言:javascript
复制
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>

class MyGLWidget : public QOpenGLWidget
{
    Q_OBJECT

public:
    MyGLWidget();

    ~MyGLWidget();

protected:
    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();

private:
    //顶点缓冲对象 Vertex Buffer Object,VBO,教程中第一个出现的OpenGL对象
    GLuint VBO;               
    GLuint VAO;

    GLuint EBO;

    GLuint m_shaderProgram;    //着色器程序对象
    QOpenGLFunctions_3_3_Core *m_core;

这里我们不再继承 QOpenGLExtraFunctions,对gl相关函数的调用则是通过m_core进行。

源文件如下:

代码语言:javascript
复制
//着色器语言GLSL(OpenGL Shading Language)编写的顶点着色器
static const char *vertexShaderSource =
        "#version 330 core\n"
        "layout(location = 0) in vec3 aPos;\n"
        "void main(){\n"
        "  gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
        "}\n\0";


//着色器语言GLSL(OpenGL Shading Language)编写的片段着色器
static const char *fragmentShaderSource =
        "#version 330 core\n"
        "out vec4 FragColor;\n"
        "void main(){\n"
        "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
        "}\n\0";

#if 0
    #define TRIANGLE
#elif 1
    #define RECTANGLE
#endif

MyGLWidget::MyGLWidget()
{

}

MyGLWidget::~MyGLWidget()
{

}

void MyGLWidget::initializeGL()
{

    m_core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();//获取上下文

    //着色器部分
    GLuint vertexShader = m_core->glCreateShader(GL_VERTEX_SHADER);                //创建顶点着色器对象
    m_core->glShaderSource(GLuint(vertexShader), 1, &vertexShaderSource, nullptr); //着色器源码附加到着色器对象
    m_core->glCompileShader(GLuint(vertexShader));                                 //编译

    int is_success;                                             //检查是否编译成功,未成功则需返回错误
    char infoLog[512];
    m_core->glGetShaderiv(GLuint(vertexShader), GL_COMPILE_STATUS, &is_success);
    if (!is_success)
    {
        m_core->glGetShaderInfoLog(GLuint(vertexShader), 512, nullptr, infoLog);
        qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED" << infoLog ;
    }


    GLuint fragmentShader = m_core->glCreateShader(GL_FRAGMENT_SHADER);  //创建片段着色器对象,与顶点着色器相似
    m_core->glShaderSource(GLuint(fragmentShader), 1, &fragmentShaderSource, nullptr);
    m_core->glCompileShader(GLuint(fragmentShader));

    m_core->glGetShaderiv(GLuint(fragmentShader), GL_COMPILE_STATUS, &is_success);
    if (!is_success)
    {
        m_core->glGetShaderInfoLog(GLuint(fragmentShader), 512, nullptr, infoLog);
        qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED" << infoLog;
    }


    m_shaderProgram = m_core->glCreateProgram();                         //创建着色器程序对象
    m_core->glAttachShader(m_shaderProgram, GLuint(vertexShader));
    m_core->glAttachShader(m_shaderProgram, GLuint(fragmentShader));
    m_core->glLinkProgram(m_shaderProgram);                              //之前编译的着色器附加到程序对象上

    m_core->glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, &is_success);//检查是否编译成功,未成功则需返回错误
    if (!is_success) {
        m_core->glGetProgramInfoLog(m_shaderProgram, 512, nullptr, infoLog);
        qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog ;
    }

    m_core->glDeleteShader(vertexShader);                               //着色器对象链接到程序对象以后,删除着色器对象
    m_core->glDeleteShader(fragmentShader);

    //VAO,VBO数据部分

#ifdef TRIANGLE
    GLfloat vertices[] = {
        -0.5f, -0.5f, 0.0f, // left
        0.5f, -0.5f, 0.0f,  // right
        0.0f,  0.5f, 0.0f   // top
    };
#else                                      //绘制矩形
    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
    };

    unsigned int indices[] = { // 注意索引从0开始!
        0, 1, 3, // 第一个三角形
        1, 2, 3  // 第二个三角形
    };
#endif
//两个参数,第一个为需要创建的缓存数量。第二个为用于存储单一ID或多个ID的GLuint变量或数组的地址
    m_core->glGenVertexArrays(1, &VAO);          
    m_core->glGenBuffers(1, &VBO);               //顶点缓冲对象处理
    m_core->glGenBuffers(1, &EBO);
    m_core->glBindVertexArray(VAO);
    m_core->glBindBuffer(GL_ARRAY_BUFFER, VBO);  //使用glBindBuffer函数把新创建的缓冲绑定到GL_ARRAY_BUFFER目标上
    //之前定义的顶点数据复制到缓冲的内存中
    m_core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);      
#ifdef RECTANGLE
    m_core->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    m_core->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
#endif
//glVertexAttribPointer函数告诉OpenGL该如何解析顶点数据(应用到逐个顶点属性上)
    m_core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);  
    m_core->glEnableVertexAttribArray(0);        //以顶点属性位置值作为参数,启用顶点属性;顶点属性默认是禁用的

    m_core->glBindBuffer(GL_ARRAY_BUFFER, 0);
    m_core->glBindVertexArray(0);

}

void MyGLWidget::resizeGL(int w, int h)
{
    m_core->glViewport(0, 0, w, h);
}

void MyGLWidget::paintGL()
{
    m_core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    m_core->glClear(GL_COLOR_BUFFER_BIT);

    m_core->glUseProgram(m_shaderProgram); //激活程序对象
    m_core->glBindVertexArray(VAO);
#ifdef TRIANGLE
    m_core->glDrawArrays(GL_TRIANGLES, 0, 3);
#else                                         //绘制矩形
    m_core->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
#endif
//    glUseProgram(0);

}
代码语言:javascript
复制

小结:

对于程序中 文字解释的排版欢迎大家多提出宝贵的意见,感谢!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Pou光明 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档