#include "WidgetGL1.h" #include #include #include "spdlog/spdlog.h" WidgetGL1::WidgetGL1(QWidget *parent) { } WidgetGL1::~WidgetGL1() { } void WidgetGL1::initializeGL() { /* 初始化OpenGL函数 */ initializeOpenGLFunctions(); /* 创建VAO */ glGenVertexArrays(1, &m_VAO); /* 绑定VAO,后面的顶点属性设置和缓冲区绑定都会存储在这个VAO中 */ glBindVertexArray(m_VAO); /* ------------------------------ 设置VBO ------------------------------ */ /* 顶点输入 */ float vertices[] = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f }; GLuint VBO = 0; /* 顶点缓冲对象 */ glGenBuffers(1, &VBO); /* 将VBO绑定到缓冲对象上(其实是用于激活这个VBO对象,可以对这个对象进行操作了) 说明:OpenGL的对象操作都要依赖OpenGL提供的函数,有很多对象类型,这里将VBO绑定在 GL_ARRAY_BUFFER 上,就像放在了对应的操作台上,之后就可以对这个对象进行 操作,后续的一切对 GL_ARRAY_BUFFER 的操作就是对VBO的操作 */ glBindBuffer(GL_ARRAY_BUFFER, VBO); /* 将数据拷贝到VBO中 */ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); /* 设置顶点链接属性 */ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), 0); /* 启用顶点属性,这里是启用位置为0的顶点属性 */ glEnableVertexAttribArray(0); /* 解绑VBO */ glBindBuffer(GL_ARRAY_BUFFER, 0); /* 解绑VAO */ glBindVertexArray(0); /* ------------------------------ 顶点着色器 ------------------------------ */ const char* vertexShaderSource = R"( #version 330 core layout (location = 0) in vec3 aPos; void main() { gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); } )"; /* 创建顶点着色器对象 */ GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); /* 加载顶点着色器源码 */ glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr); /* 编译着色器 */ glCompileShader(vertexShader); printOpenGLCompileError(vertexShader); /* ------------------------------ 片段着色器 ------------------------------ */ const char* fragmentShaderSource = R"( #version 330 core out vec4 FragColor; void main() { FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); } )"; /* 创建片段着色器对象 */ GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); /* 加载片段着色器源码 */ glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr); /* 编译着色器 */ glCompileShader(fragmentShader); printOpenGLCompileError(fragmentShader); /* ------------------------------ 着色器程序对象 ------------------------------ */ m_shaderProgam = glCreateProgram(); /* 将顶点着色器和片段着色器附加到着色器程序对象上 */ glAttachShader(m_shaderProgam, vertexShader); glAttachShader(m_shaderProgam, fragmentShader); /* 链接着色器程序 */ glLinkProgram(m_shaderProgam); /* 销毁顶点着色器和片段着色器 */ glDeleteShader(vertexShader); glDeleteShader(fragmentShader); } void WidgetGL1::resizeGL(int w, int h) { /* 设置视口 */ glViewport(0, 0, w, h); } void WidgetGL1::paintGL() { /* 清屏 */ glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); /* 绘制三角形 */ glUseProgram(m_shaderProgam); glBindVertexArray(m_VAO); glDrawArrays(GL_TRIANGLES, 0, 3); /* 解绑VAO */ glBindVertexArray(0); } /* 打印编译错误 */ void WidgetGL1::printOpenGLCompileError(GLuint errorCode) { int sucess; char infoLog[512]; glGetShaderiv(errorCode, GL_COMPILE_STATUS, &sucess); if (!sucess) { glGetShaderInfoLog(errorCode, 512, nullptr, infoLog); SPDLOG_ERROR("OpenGL编译错误: {}", infoLog); } } /* 打印着色器链接错误 */ void WidgetGL1::printOpenGLLinkError(GLuint errorCode) { int sucess; char infoLog[512]; glGetProgramiv(errorCode, GL_LINK_STATUS, &sucess); if (!sucess) { glGetProgramInfoLog(errorCode, 512, nullptr, infoLog); SPDLOG_ERROR("OpenGL链接错误: {}", infoLog); } }