QOpenGLWidget

2023-12-17 11:33:34
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShader>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLFunctions_3_3_Core>

/****************************************************************************************
* OpenGL:Open Graphics Library是一个规范
* OpenGL核心是一个C库,同时也支持多种语言的派生
*
* 1.立即渲染模式(Immediate mode),也就是固定渲染管线
* 2.核心模式(Core-profile),也叫可编程管线(3.2以后的版本,使用到着色器)
*
* QOpenGLWidget 代替GLFW
* QOpenGLFunctions_x_x_Core(Core:核心模式) 代替GLAD
*   提供OpenGLx.x版本核心模式的所有功能,是对OpenGl函数的封装
*   initializeOpenGLFunctions:初始化OpenGL函数,将Qt里的函数指针指向显卡的函数
*
* //顶点着色器会在GPU上创建内存,存储顶点数据,通过VBO管理,VAO存放顶点结构定义
*****************************************************************************************/

class MainWindow : public QOpenGLWidget, protected QOpenGLFunctions_3_3_Core
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

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

#endif // MAINWINDOW_H
#include "mainwindow.h"

unsigned int VBO,VAO,EBO;
unsigned int shaderProgram;

float 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[] = {  // note that we start from 0!
      0, 1, 3,  // first Triangle
      1, 2, 3   // second Triangle
  };
const char *vertexShaderSource = "#version 330 core\n"
      "layout (location = 0) in vec3 aPos;\n"
      "void main()\n"
      "{\n"
      "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
      "}\0";
const char *fragmentShaderSource = "#version 330 core\n"
      "out vec4 FragColor;\n"
      "void main()\n"
      "{\n"
      "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
      "}\n\0";

MainWindow::MainWindow(QWidget *parent)
    :QOpenGLWidget(parent)
{
}

MainWindow::~MainWindow()
{
    makeCurrent();

    glDeleteBuffers(1,&VBO);
    glDeleteBuffers(1, &EBO);
    glDeleteVertexArrays(1,&VAO);
    glDeleteProgram(shaderProgram);

    doneCurrent();
}

void MainWindow::initializeGL()
{
    initializeOpenGLFunctions();

    //创建VBO、EBO和VAO
    glGenBuffers(1,&VBO);
    glGenBuffers(1,&EBO);
    glGenVertexArrays(1,&VAO);

    //绑定VBO,VAO,EBO
    //OpenGL允许同时绑定多个不同类型的缓冲(如:GL_ARRAY_BUFFER...)
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);

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

    //告诉显卡如何解析缓冲里的属性值
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    //开启VAO管理的第一个属性值
    glEnableVertexAttribArray(0);

    //解绑VBO,VAO
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    unsigned int vertexShader;
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

    unsigned int fragmentShader;
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}

void MainWindow::resizeGL(int w,int h)
{
    glViewport(0,0,w,h);
}

void MainWindow::paintGL()
{
    glClearColor(0.0f,0.5f,0.5f,0.5f);
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(shaderProgram);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}

?

文章来源:https://blog.csdn.net/xiaoyao_zhang/article/details/135042378
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。