|
@@ -0,0 +1,161 @@
|
|
|
|
|
+#include "WidgetGL4.h"
|
|
|
|
|
+#include <gl/gl.h>
|
|
|
|
|
+#include <qimage.h>
|
|
|
|
|
+#include <qopenglext.h>
|
|
|
|
|
+#include <QTime>
|
|
|
|
|
+#include <QImage>
|
|
|
|
|
+#include <setjmp.h>
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#include "spdlog/spdlog.h"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+WidgetGL4::WidgetGL4(QWidget *parent)
|
|
|
|
|
+{
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+WidgetGL4::~WidgetGL4()
|
|
|
|
|
+{
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+void WidgetGL4::initializeGL()
|
|
|
|
|
+{
|
|
|
|
|
+ /* 初始化OpenGL函数 */
|
|
|
|
|
+ initializeOpenGLFunctions();
|
|
|
|
|
+
|
|
|
|
|
+ /* 创建VAO */
|
|
|
|
|
+ glGenVertexArrays(1, &m_VAO);
|
|
|
|
|
+ /* 绑定VAO,后面的顶点属性设置和缓冲区绑定都会存储在这个VAO中 */
|
|
|
|
|
+ glBindVertexArray(m_VAO);
|
|
|
|
|
+
|
|
|
|
|
+ /* ------------------------------ 设置VBO ------------------------------ */
|
|
|
|
|
+ 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开始!
|
|
|
|
|
+ // 此例的索引(0,1,2,3)就是顶点数组vertices的下标,
|
|
|
|
|
+ // 这样可以由下标代表顶点组合成矩形
|
|
|
|
|
+
|
|
|
|
|
+ 0, 1, 3, // 第一个三角形
|
|
|
|
|
+ 1, 2, 3 // 第二个三角形
|
|
|
|
|
+ };
|
|
|
|
|
+ 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);
|
|
|
|
|
+
|
|
|
|
|
+ /* 创建EBO */
|
|
|
|
|
+ GLuint EBO = 0;
|
|
|
|
|
+ glGenBuffers(1, &EBO);
|
|
|
|
|
+ /* 绑定EBO */
|
|
|
|
|
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
|
|
|
|
+ /* 将索引数据拷贝到EBO中 */
|
|
|
|
|
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
|
|
|
|
+
|
|
|
|
|
+ /* 设置顶点链接属性 */
|
|
|
|
|
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), 0);
|
|
|
|
|
+ /* 启用顶点属性,这里是启用位置为0的顶点属性 */
|
|
|
|
|
+ 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);
|
|
|
|
|
+
|
|
|
|
|
+ /* 解绑VBO */
|
|
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
|
+ /* 解绑VAO */
|
|
|
|
|
+ glBindVertexArray(0);
|
|
|
|
|
+
|
|
|
|
|
+ /* 创建着色器对象 */
|
|
|
|
|
+ m_shader = new Shader(":/GLLearning/ShaderSource/vertexShader1.glsl", ":/GLLearning/ShaderSource/fragmentShader1.glsl");
|
|
|
|
|
+ m_shaderProgam = m_shader->getProgramID();
|
|
|
|
|
+
|
|
|
|
|
+ /* 加载纹理图片 */
|
|
|
|
|
+ QImage image;
|
|
|
|
|
+ bool ret = image.load(":/image/1.jpg");
|
|
|
|
|
+ if (!ret)
|
|
|
|
|
+ {
|
|
|
|
|
+ SPDLOG_ERROR("加载纹理图片失败");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ /* 创建纹理 */
|
|
|
|
|
+
|
|
|
|
|
+ glGenTextures(1, &m_texture1);
|
|
|
|
|
+ glBindTexture(GL_TEXTURE_2D, m_texture1);
|
|
|
|
|
+ /* 设置纹理参数 */
|
|
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
+ /* 将纹理图片数据传递给OpenGL */
|
|
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.bits());
|
|
|
|
|
+ glGenerateMipmap(GL_TEXTURE_2D);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void WidgetGL4::resizeGL(int w, int h)
|
|
|
|
|
+{
|
|
|
|
|
+ /* 设置视口 */
|
|
|
|
|
+ glViewport(0, 0, w, h);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void WidgetGL4::paintGL()
|
|
|
|
|
+{
|
|
|
|
|
+ /* 清屏 */
|
|
|
|
|
+ glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
|
|
|
|
+ glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
|
+
|
|
|
|
|
+ /* 绘制四边形 */
|
|
|
|
|
+ m_shader->use();
|
|
|
|
|
+ glBindVertexArray(m_VAO);
|
|
|
|
|
+ glBindTexture(GL_TEXTURE_2D, m_texture1);
|
|
|
|
|
+
|
|
|
|
|
+ // glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
|
|
|
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
|
|
|
|
+ /* 解绑VAO */
|
|
|
|
|
+ glBindVertexArray(0);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 打印编译错误 */
|
|
|
|
|
+void WidgetGL4::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 WidgetGL4::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);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|