WidgetGL1.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #include "WidgetGL1.h"
  2. #include <gl/gl.h>
  3. #include <qopenglext.h>
  4. #include "spdlog/spdlog.h"
  5. WidgetGL1::WidgetGL1(QWidget *parent)
  6. {
  7. }
  8. WidgetGL1::~WidgetGL1()
  9. {
  10. }
  11. void WidgetGL1::initializeGL()
  12. {
  13. /* 初始化OpenGL函数 */
  14. initializeOpenGLFunctions();
  15. /* 创建VAO */
  16. glGenVertexArrays(1, &m_VAO);
  17. /* 绑定VAO,后面的顶点属性设置和缓冲区绑定都会存储在这个VAO中 */
  18. glBindVertexArray(m_VAO);
  19. /* ------------------------------ 设置VBO ------------------------------ */
  20. /* 顶点输入 */
  21. float vertices[] = {
  22. -0.5f, -0.5f, 0.0f,
  23. 0.5f, -0.5f, 0.0f,
  24. 0.0f, 0.5f, 0.0f
  25. };
  26. GLuint VBO = 0;
  27. /* 顶点缓冲对象 */
  28. glGenBuffers(1, &VBO);
  29. /* 将VBO绑定到缓冲对象上(其实是用于激活这个VBO对象,可以对这个对象进行操作了)
  30. 说明:OpenGL的对象操作都要依赖OpenGL提供的函数,有很多对象类型,这里将VBO绑定在 GL_ARRAY_BUFFER 上,就像放在了对应的操作台上,之后就可以对这个对象进行
  31. 操作,后续的一切对 GL_ARRAY_BUFFER 的操作就是对VBO的操作 */
  32. glBindBuffer(GL_ARRAY_BUFFER, VBO);
  33. /* 将数据拷贝到VBO中 */
  34. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  35. /* 设置顶点链接属性 */
  36. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), 0);
  37. /* 启用顶点属性,这里是启用位置为0的顶点属性 */
  38. glEnableVertexAttribArray(0);
  39. /* 解绑VBO */
  40. glBindBuffer(GL_ARRAY_BUFFER, 0);
  41. /* 解绑VAO */
  42. glBindVertexArray(0);
  43. /* ------------------------------ 顶点着色器 ------------------------------ */
  44. const char* vertexShaderSource = R"(
  45. #version 330 core
  46. layout (location = 0) in vec3 aPos;
  47. void main()
  48. {
  49. gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
  50. }
  51. )";
  52. /* 创建顶点着色器对象 */
  53. GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
  54. /* 加载顶点着色器源码 */
  55. glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
  56. /* 编译着色器 */
  57. glCompileShader(vertexShader);
  58. printOpenGLCompileError(vertexShader);
  59. /* ------------------------------ 片段着色器 ------------------------------ */
  60. const char* fragmentShaderSource = R"(
  61. #version 330 core
  62. out vec4 FragColor;
  63. void main()
  64. {
  65. FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
  66. }
  67. )";
  68. /* 创建片段着色器对象 */
  69. GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  70. /* 加载片段着色器源码 */
  71. glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
  72. /* 编译着色器 */
  73. glCompileShader(fragmentShader);
  74. printOpenGLCompileError(fragmentShader);
  75. /* ------------------------------ 着色器程序对象 ------------------------------ */
  76. m_shaderProgam = glCreateProgram();
  77. /* 将顶点着色器和片段着色器附加到着色器程序对象上 */
  78. glAttachShader(m_shaderProgam, vertexShader);
  79. glAttachShader(m_shaderProgam, fragmentShader);
  80. /* 链接着色器程序 */
  81. glLinkProgram(m_shaderProgam);
  82. /* 销毁顶点着色器和片段着色器 */
  83. glDeleteShader(vertexShader);
  84. glDeleteShader(fragmentShader);
  85. }
  86. void WidgetGL1::resizeGL(int w, int h)
  87. {
  88. /* 设置视口 */
  89. glViewport(0, 0, w, h);
  90. }
  91. void WidgetGL1::paintGL()
  92. {
  93. /* 清屏 */
  94. glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
  95. glClear(GL_COLOR_BUFFER_BIT);
  96. /* 绘制三角形 */
  97. glUseProgram(m_shaderProgam);
  98. glBindVertexArray(m_VAO);
  99. glDrawArrays(GL_TRIANGLES, 0, 3);
  100. /* 解绑VAO */
  101. glBindVertexArray(0);
  102. }
  103. /* 打印编译错误 */
  104. void WidgetGL1::printOpenGLCompileError(GLuint errorCode)
  105. {
  106. int sucess;
  107. char infoLog[512];
  108. glGetShaderiv(errorCode, GL_COMPILE_STATUS, &sucess);
  109. if (!sucess)
  110. {
  111. glGetShaderInfoLog(errorCode, 512, nullptr, infoLog);
  112. SPDLOG_ERROR("OpenGL编译错误: {}", infoLog);
  113. }
  114. }
  115. /* 打印着色器链接错误 */
  116. void WidgetGL1::printOpenGLLinkError(GLuint errorCode)
  117. {
  118. int sucess;
  119. char infoLog[512];
  120. glGetProgramiv(errorCode, GL_LINK_STATUS, &sucess);
  121. if (!sucess)
  122. {
  123. glGetProgramInfoLog(errorCode, 512, nullptr, infoLog);
  124. SPDLOG_ERROR("OpenGL链接错误: {}", infoLog);
  125. }
  126. }