NeHe-OpenGL-Qt5-Lesson02-注释与学习-CreatePolygon

这节,绘画一个三个形和矩形。

效果如下:

这节加入了着色器shader和着色语言GLSL(OpenGL shader language)。

https://doc.qt.io/qt-5/qopenglshaderprogram.html

https://blog.csdn.net/hankern/article/details/85316476

Shader其实就是一段执行在GPU上的程序,此程序使用OpenGL ES SL语言来编写。它是一个描述顶点或像素特性的简单程序。在opengles中常用的shader有两种:vertex shader和fragment shader。Geometry Shader(几何着色器)是继Vertex Shader和Fragment Shader之后,由Shader Model 4引入的新的着色器。还有一个compute Shader由Shader Model 5引入的提供通用计算能力的着色器。

Qt5中着色器为

#include <QOpenGLShaderProgram>

主要代码

polygonwindow.h

#ifndef POLYGONWINDOW_H
#define POLYGONWINDOW_H

#include <QOpenGLShaderProgram>
#include "openglwindow.h"

// QOpenGLShaderProgram
// The QOpenGLShaderProgram class allows OpenGL shader programs to be linked and used.
// Header: #include<QOpenGLShaderProgram>
// QT += gui
// Since Qt5.0
// Inherits: QObject
class PolygonWindow : public OpenGLWindow
{
    Q_OBJECT
public:
    explicit PolygonWindow(QWindow *parent = 0);
    ~PolygonWindow();
protected:
    void initialize();
    void render();
private:
    void initGeometry();
private:
    // 着色器
    QOpenGLShaderProgram *m_program;
    GLuint m_posAttr;

    GLuint m_vboIds[2];
};

#endif // POLYGONWINDOW_H

polygonwindow.cpp

#include "polygonwindow.h"

PolygonWindow::PolygonWindow(QWindow *parent) :
    OpenGLWindow(parent), m_program(NULL)
{
}

PolygonWindow::~PolygonWindow()
{
    glDeleteBuffers(2,&m_vboIds[0]);
}

void PolygonWindow::initialize()
{
    initGeometry();
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepthf(1.0f);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);

    m_program = new QOpenGLShaderProgram(this);
    // Compiles the contents of fileName as a shader of the specified type and adds it to this shader program.
    // Returns true if compilation was successful, false otherwise.
    // The compilation errors and warnings will be made available via log().
    m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/vertshader.glsl");
    m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/fragshader.glsl");
    // Links together the shaders that were added to this program with addShader().
    // Returns true if the link was successful or false otherwise.
    // If the link failed, the error messages can be retrieved with log().
    m_program->link();
    // Returns the location of the attribute name within this shader program's parameter list.
    // Returns -1 if name is not a valid attribute for this shader program.
    m_posAttr = m_program->attributeLocation("posAttr");
}

void PolygonWindow::render()
{
    // GL_COLOR_BUFFER_BIT:    当前可写的颜色缓冲
    // GL_DEPTH_BUFFER_BIT:    深度缓冲
    // GL_ACCUM_BUFFER_BIT:   累积缓冲
    // GL_STENCIL_BUFFER_BIT: 模板缓冲
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // Binds this shader program to the active QOpenGLContext and makes it the current shader program.
    // Any previously bound shader program is released.
    // This is equivalent to calling glUseProgram() on programId().
    // Returns true if the program was successfully bound; false otherwise.
    // If the shader program has not yet been linked, or it needs to be re-linked, this function will call link().
    m_program->bind();
    // Sets this matrix to the identity.
    m_modelView.setToIdentity();
    m_modelView.translate(-1.5f, 0.0f, -6.0f);
    // Sets the uniform variable at location in the current context to value.
    m_program->setUniformValue("mvpMatrix", m_projection * m_modelView);
    glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
    // Enables the vertex array at location in this shader program so that the value set
    // by setAttributeArray() on location will be used by the shader program.
    m_program->enableAttributeArray(m_posAttr);
    // Sets an array of vertex values on the attribute at location in this shader program,
    // starting at a specific offset in the currently bound vertex buffer.
    // The stride indicates the number of bytes between vertices.
    // A default stride value of zero indicates that the vertices are densely packed in the value array.
    m_program->setAttributeBuffer(m_posAttr, GL_FLOAT, 0, 3);
    // 在OpenGl中所有的图形都是通过分解成三角形的方式进行绘制。
    // 1.GL_TRIANGLES:每三个顶之间绘制三角形,之间不连接
    // 2.GL_TRIANGLE_FAN:以V0V1V2,V0V2V3,V0V3V4,……的形式绘制三角形
    // 3.GL_TRIANGLE_STRIP:顺序在每三个顶点之间均绘制三角形。这个方法可以保证从相同的方向上所有三角形均被绘制。以V0V1V2,V1V2V3,V2V3V4……的形式绘制三角形
    glDrawArrays(GL_TRIANGLES, 0, 3);

    m_modelView.translate(3.0f, 0.0f, 0.0f);
    m_program->setUniformValue("mvpMatrix", m_projection * m_modelView);
    glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
    m_program->enableAttributeArray(m_posAttr);
    m_program->setAttributeBuffer(m_posAttr, GL_FLOAT, 0, 3);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    m_program->release();
}

void PolygonWindow::initGeometry()
{
    // https://blog.csdn.net/qq_36383623/article/details/85123077
    // 用来生成缓冲区对象的名称。
    glGenBuffers(2, &m_vboIds[0]);
    GLfloat triangleVertices[] = {
        0.0f, 1.0f, 0.0f,
        -1.0f,-1.0f, 0.0f,
        1.0f,-1.0f, 0.0f,
    };
    // bind a named buffer object
    glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);

    // https://blog.csdn.net/qq_24283329/article/details/75453013
    //void glBufferData(GLenum  	target,
    //        GLsizeiptr  	size,
    //        const GLvoid *  data,
    //        GLenum  	usage);
    //
    //target
    //Specifies the target buffer object.
    //The symbolic constant must be
    //GL_ARRAY_BUFFER,
    //GL_ELEMENT_ARRAY_BUFFER,
    //GL_PIXEL_PACK_BUFFER, or
    //GL_PIXEL_UNPACK_BUFFER.
    glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW);

    GLfloat quadVertices[] = {
         1.0f, 1.0f, 0.0f,
        -1.0f, 1.0f, 0.0f,
         1.0f,-1.0f, 0.0f,
        -1.0f,-1.0f, 0.0f
    };
    glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
}

多谢,亲爱的美美。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值