shader.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "shader.h"
  2. #include <QFile>
  3. #include <QTextStream>
  4. #include <QDebug>
  5. namespace Render::GL {
  6. Shader::Shader() {
  7. // Defer OpenGL function initialization until a context is current
  8. }
  9. Shader::~Shader() {
  10. if (m_program != 0) {
  11. glDeleteProgram(m_program);
  12. }
  13. }
  14. bool Shader::loadFromFiles(const QString& vertexPath, const QString& fragmentPath) {
  15. QFile vertexFile(vertexPath);
  16. QFile fragmentFile(fragmentPath);
  17. if (!vertexFile.open(QIODevice::ReadOnly) || !fragmentFile.open(QIODevice::ReadOnly)) {
  18. qWarning() << "Failed to open shader files";
  19. return false;
  20. }
  21. QTextStream vertexStream(&vertexFile);
  22. QTextStream fragmentStream(&fragmentFile);
  23. QString vertexSource = vertexStream.readAll();
  24. QString fragmentSource = fragmentStream.readAll();
  25. return loadFromSource(vertexSource, fragmentSource);
  26. }
  27. bool Shader::loadFromSource(const QString& vertexSource, const QString& fragmentSource) {
  28. initializeOpenGLFunctions();
  29. GLuint vertexShader = compileShader(vertexSource, GL_VERTEX_SHADER);
  30. GLuint fragmentShader = compileShader(fragmentSource, GL_FRAGMENT_SHADER);
  31. if (vertexShader == 0 || fragmentShader == 0) {
  32. return false;
  33. }
  34. bool success = linkProgram(vertexShader, fragmentShader);
  35. glDeleteShader(vertexShader);
  36. glDeleteShader(fragmentShader);
  37. return success;
  38. }
  39. void Shader::use() {
  40. initializeOpenGLFunctions();
  41. glUseProgram(m_program);
  42. }
  43. void Shader::release() {
  44. initializeOpenGLFunctions();
  45. glUseProgram(0);
  46. }
  47. void Shader::setUniform(const QString& name, float value) {
  48. GLint location = glGetUniformLocation(m_program, name.toUtf8().constData());
  49. if (location != -1) {
  50. glUniform1f(location, value);
  51. }
  52. }
  53. void Shader::setUniform(const QString& name, const QVector3D& value) {
  54. GLint location = glGetUniformLocation(m_program, name.toUtf8().constData());
  55. if (location != -1) {
  56. glUniform3f(location, value.x(), value.y(), value.z());
  57. }
  58. }
  59. void Shader::setUniform(const QString& name, const QMatrix4x4& value) {
  60. GLint location = glGetUniformLocation(m_program, name.toUtf8().constData());
  61. if (location != -1) {
  62. glUniformMatrix4fv(location, 1, GL_FALSE, value.constData());
  63. }
  64. }
  65. void Shader::setUniform(const QString& name, int value) {
  66. GLint location = glGetUniformLocation(m_program, name.toUtf8().constData());
  67. if (location != -1) {
  68. glUniform1i(location, value);
  69. }
  70. }
  71. void Shader::setUniform(const QString& name, bool value) {
  72. setUniform(name, static_cast<int>(value));
  73. }
  74. GLuint Shader::compileShader(const QString& source, GLenum type) {
  75. initializeOpenGLFunctions();
  76. GLuint shader = glCreateShader(type);
  77. QByteArray sourceBytes = source.toUtf8();
  78. const char* sourcePtr = sourceBytes.constData();
  79. glShaderSource(shader, 1, &sourcePtr, nullptr);
  80. glCompileShader(shader);
  81. GLint success;
  82. glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
  83. if (!success) {
  84. GLchar infoLog[512];
  85. glGetShaderInfoLog(shader, 512, nullptr, infoLog);
  86. qWarning() << "Shader compilation failed:" << infoLog;
  87. glDeleteShader(shader);
  88. return 0;
  89. }
  90. return shader;
  91. }
  92. bool Shader::linkProgram(GLuint vertexShader, GLuint fragmentShader) {
  93. initializeOpenGLFunctions();
  94. m_program = glCreateProgram();
  95. glAttachShader(m_program, vertexShader);
  96. glAttachShader(m_program, fragmentShader);
  97. glLinkProgram(m_program);
  98. GLint success;
  99. glGetProgramiv(m_program, GL_LINK_STATUS, &success);
  100. if (!success) {
  101. GLchar infoLog[512];
  102. glGetProgramInfoLog(m_program, 512, nullptr, infoLog);
  103. qWarning() << "Shader linking failed:" << infoLog;
  104. glDeleteProgram(m_program);
  105. m_program = 0;
  106. return false;
  107. }
  108. return true;
  109. }
  110. } // namespace Render::GL