WidgetGL4.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #include "WidgetGL4.h"
  2. #include <gl/gl.h>
  3. #include <qimage.h>
  4. #include <qopenglext.h>
  5. #include <QTime>
  6. #include <QImage>
  7. #include <setjmp.h>
  8. #include "spdlog/spdlog.h"
  9. WidgetGL4::WidgetGL4(QWidget *parent)
  10. {
  11. }
  12. WidgetGL4::~WidgetGL4()
  13. {
  14. }
  15. void WidgetGL4::initializeGL()
  16. {
  17. /* 初始化OpenGL函数 */
  18. initializeOpenGLFunctions();
  19. /* 创建VAO */
  20. glGenVertexArrays(1, &m_VAO);
  21. /* 绑定VAO,后面的顶点属性设置和缓冲区绑定都会存储在这个VAO中 */
  22. glBindVertexArray(m_VAO);
  23. /* ------------------------------ 设置VBO ------------------------------ */
  24. float vertices[] = {
  25. /* -----位置----- ----颜色----- -----纹理坐标----- */
  26. 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // 右上角
  27. 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 右下角
  28. -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // 左下角
  29. -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // 左上角
  30. };
  31. unsigned int indices[] = {
  32. // 注意索引从0开始!
  33. // 此例的索引(0,1,2,3)就是顶点数组vertices的下标,
  34. // 这样可以由下标代表顶点组合成矩形
  35. 0, 1, 3, // 第一个三角形
  36. 1, 2, 3 // 第二个三角形
  37. };
  38. GLuint VBO = 0;
  39. /* 顶点缓冲对象 */
  40. glGenBuffers(1, &VBO);
  41. /* 将VBO绑定到缓冲对象上(其实是用于激活这个VBO对象,可以对这个对象进行操作了)
  42. 说明:OpenGL的对象操作都要依赖OpenGL提供的函数,有很多对象类型,这里将VBO绑定在 GL_ARRAY_BUFFER 上,就像放在了对应的操作台上,之后就可以对这个对象进行
  43. 操作,后续的一切对 GL_ARRAY_BUFFER 的操作就是对VBO的操作 */
  44. glBindBuffer(GL_ARRAY_BUFFER, VBO);
  45. /* 将数据拷贝到VBO中 */
  46. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  47. /* 创建EBO */
  48. GLuint EBO = 0;
  49. glGenBuffers(1, &EBO);
  50. /* 绑定EBO */
  51. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
  52. /* 将索引数据拷贝到EBO中 */
  53. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
  54. /* 设置顶点链接属性 */
  55. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), 0);
  56. /* 启用顶点属性,这里是启用位置为0的顶点属性 */
  57. glEnableVertexAttribArray(0);
  58. /* 设置颜色属性 */
  59. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(3*sizeof(float)));
  60. glEnableVertexAttribArray(1);
  61. /* 设置纹理坐标属性 */
  62. glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void*)(6*sizeof(float)));
  63. glEnableVertexAttribArray(2);
  64. /* 解绑VBO */
  65. glBindBuffer(GL_ARRAY_BUFFER, 0);
  66. /* 解绑VAO */
  67. glBindVertexArray(0);
  68. /* 创建着色器对象 */
  69. m_shader = new Shader(":/GLLearning/ShaderSource/vertexShader1.glsl", ":/GLLearning/ShaderSource/fragmentShader1.glsl");
  70. m_shaderProgam = m_shader->getProgramID();
  71. /* 加载纹理图片 */
  72. QImage image;
  73. bool ret = image.load(":/image/1.jpg");
  74. if (!ret)
  75. {
  76. SPDLOG_ERROR("加载纹理图片失败");
  77. return;
  78. }
  79. /* 创建纹理 */
  80. glGenTextures(1, &m_texture1);
  81. glBindTexture(GL_TEXTURE_2D, m_texture1);
  82. /* 设置纹理参数 */
  83. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  84. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  85. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  86. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  87. /* 将纹理图片数据传递给OpenGL */
  88. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.bits());
  89. glGenerateMipmap(GL_TEXTURE_2D);
  90. }
  91. void WidgetGL4::resizeGL(int w, int h)
  92. {
  93. /* 设置视口 */
  94. glViewport(0, 0, w, h);
  95. }
  96. void WidgetGL4::paintGL()
  97. {
  98. /* 清屏 */
  99. glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
  100. glClear(GL_COLOR_BUFFER_BIT);
  101. /* 绘制四边形 */
  102. m_shader->use();
  103. glBindVertexArray(m_VAO);
  104. glBindTexture(GL_TEXTURE_2D, m_texture1);
  105. // glDrawArrays(GL_TRIANGLES, 0, 6);
  106. glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
  107. /* 解绑VAO */
  108. glBindVertexArray(0);
  109. }
  110. /* 打印编译错误 */
  111. void WidgetGL4::printOpenGLCompileError(GLuint errorCode)
  112. {
  113. int sucess;
  114. char infoLog[512];
  115. glGetShaderiv(errorCode, GL_COMPILE_STATUS, &sucess);
  116. if (!sucess)
  117. {
  118. glGetShaderInfoLog(errorCode, 512, nullptr, infoLog);
  119. SPDLOG_ERROR("OpenGL编译错误: {}", infoLog);
  120. }
  121. }
  122. /* 打印着色器链接错误 */
  123. void WidgetGL4::printOpenGLLinkError(GLuint errorCode)
  124. {
  125. int sucess;
  126. char infoLog[512];
  127. glGetProgramiv(errorCode, GL_LINK_STATUS, &sucess);
  128. if (!sucess)
  129. {
  130. glGetProgramInfoLog(errorCode, 512, nullptr, infoLog);
  131. SPDLOG_ERROR("OpenGL链接错误: {}", infoLog);
  132. }
  133. }