Bootstrap

QT OpenGL使用示例

QT OpenGL使用示例

  • CMakeLists.txt
cmake_minimum_required(VERSION 3.5)

project(opengl_demo1 VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets OpenGL)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets OpenGL)


FILE(GLOB PROJECT_SOURCES "./*.cpp" "./*.h" "./*qrc")

add_executable(opengl_demo1
    ${PROJECT_SOURCES}
)

target_link_libraries(opengl_demo1 PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::OpenGL)
  • ccwidget.h
#ifndef CCWIDGET_H
#define CCWIDGET_H

#include <QWidget>
#include <QOpenGLWidget>
#include <QOpenGLFunctions_4_5_Core>
#include <QOpenGLShaderProgram>

class CCWidget : public QOpenGLWidget, QOpenGLFunctions_4_5_Core
{
    Q_OBJECT

public:
    CCWidget(QWidget *parent = nullptr);
    ~CCWidget();

protected:
    virtual void initializeGL() override;
    virtual void paintGL() override;

private:
    class QOpenGLTexture * textureWall;
    QOpenGLTexture * textureSmile;
    QOpenGLShaderProgram shaderProgram;
};
#endif // CCWIDGET_H
  • ccwidget.cpp
#include "ccwidget.h"
#include <QOpenGLShaderProgram>
#include <QTimer>
#include <QTime>
#include <QOpenGLTexture>

unsigned int VBO, VAO, EBO;
float vertices[] =
{
    //位置                  颜色                    纹理坐标
    0.5f, 0.5f, 0.0f,       1.0f, 0.0f, 0.0f,       1.0f, 1.0f,
    0.5f, -0.5f, 0.0f,      0.0f, 1.0f, 0.0f,       1.0f, 0.0f,
    -0.5f, -0.5f, 0.0f,     0.0f, 0.0f, 1.0f,       0.0f, 0.0f,
    -0.5f, 0.5f, 0.0f,      1.0f, 1.0f, 0.0f,       0.0f, 1.0f
};

unsigned int indices[] =
{
    0, 1, 3,
    1, 2, 3
};

CCWidget::CCWidget(QWidget *parent) : QOpenGLWidget(parent)
{

}

CCWidget::~CCWidget()
{
    makeCurrent();
    glDeleteBuffers(1,&VBO);
    glDeleteBuffers(1,&EBO);
    glDeleteVertexArrays(1,&VAO);
    doneCurrent();
}

void CCWidget::initializeGL()
{
    bool ret = initializeOpenGLFunctions();
    qDebug() << "ret = " << ret;
    glClearColor(0.5f, 0.0f, 1.0f, 1.0f);

    glEnable(GL_DEPTH_TEST);
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), nullptr);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float),  (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shapes.vert");
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,":/shapes.frag");
    if(!shaderProgram.link())
        qDebug()<<"shader program error:"<<shaderProgram.log();

    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    textureWall = new QOpenGLTexture(QImage(":/images/test1.png").mirrored());
    textureSmile = new QOpenGLTexture(QImage(":/images/test2.png").mirrored());

    shaderProgram.bind();
    shaderProgram.setUniformValue("textureWall",0);//纹理单元0
    shaderProgram.setUniformValue("textureSmile",1);//纹理单元1

    glBindVertexArray(0);
}

void CCWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    shaderProgram.bind();
    glBindVertexArray(VAO);

    textureWall->bind(0);
    textureSmile->bind(1);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
}
  • main.cpp
#include "ccwidget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    CCWidget w;
    w.show();
    return a.exec();
}
  • shapes.frag
#version 450 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCord;
uniform sampler2D textureWall;
uniform sampler2D textureSmile;
void main()
{
    FragColor = mix(texture(textureWall,TexCord),texture(textureSmile,TexCord),0.5);
}
  • shapes.vert
#version 450 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
layout(location = 2) in vec2 aTexCord;
out vec3 ourColor;
out vec2 TexCord;
void main()
{
    gl_Position = vec4(aPos, 1.0f);
    ourColor=aColor;
    TexCord=aTexCord;
}

;