| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- #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);
- /* 创建第二个纹理 */
- QImage image2;
- image2.load(":/image/awesomeface.png");
- glGenTextures(1, &m_texture2);
- glBindTexture(GL_TEXTURE_2D, m_texture2);
- /* 设置纹理参数 */
- 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, image2.width(), image2.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image2.bits());
- glGenerateMipmap(GL_TEXTURE_2D);
- /* 设置纹理单元 */
- m_shader->use();
- m_shader->setInt("ourTexture1", 0);
- m_shader->setInt("ourTexture2", 1);
- }
- 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);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, m_texture1);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, m_texture2);
- // 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);
- }
- }
|