Shader.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include <fstream>
  2. #include <iostream>
  3. #include "wrapper/GL.h"
  4. #include "wrapper/Shader.h"
  5. Shader::Shader(const char* vertexPath, const char* fragmentPath,
  6. const char* geometryPath)
  7. : vertexShader(0), geometryShader(0), fragmentShader(0), program(0) {
  8. if(readFileAndCompile(vertexPath, vertexShader, GL_VERTEX_SHADER) ||
  9. readFileAndCompile(fragmentPath, fragmentShader, GL_FRAGMENT_SHADER)) {
  10. return;
  11. }
  12. if(geometryPath != nullptr &&
  13. readFileAndCompile(geometryPath, geometryShader, GL_GEOMETRY_SHADER)) {
  14. return;
  15. }
  16. program = glCreateProgram();
  17. glAttachShader(program, vertexShader);
  18. if(geometryPath != nullptr) {
  19. glAttachShader(program, geometryShader);
  20. }
  21. glAttachShader(program, fragmentShader);
  22. glLinkProgram(program);
  23. if(GL::checkAndPrintError("cannot link")) {
  24. return;
  25. }
  26. GLint linked;
  27. glGetProgramiv(program, GL_LINK_STATUS, &linked);
  28. if(!linked) {
  29. ErrorLog log;
  30. glGetProgramInfoLog(program, log.getLength(), nullptr, log.begin());
  31. std::cout << "linker log: " << log.begin() << "\n";
  32. clean();
  33. return;
  34. }
  35. }
  36. Shader::~Shader() {
  37. clean();
  38. }
  39. void Shader::clean() {
  40. glDeleteShader(vertexShader);
  41. glDeleteShader(geometryShader);
  42. glDeleteShader(fragmentShader);
  43. glDeleteProgram(program);
  44. program = 0;
  45. }
  46. bool Shader::readFileAndCompile(const char* path, GLuint& shader,
  47. GLenum shaderType) {
  48. std::cout << "shader: " << path << '\n';
  49. Code code;
  50. if(readFile(code, path)) {
  51. return true;
  52. }
  53. return compile(shader, code, shaderType);
  54. }
  55. bool Shader::readFile(Code& code, const char* path) const {
  56. std::ifstream in;
  57. in.open(path);
  58. if(!in.good()) {
  59. std::cout << "cannot read file\n";
  60. return true;
  61. }
  62. in.get(code.begin(), code.getLength(), EOF);
  63. return false;
  64. }
  65. bool Shader::hasError() const {
  66. return vertexShader == 0 || fragmentShader == 0 || program == 0;
  67. }
  68. bool Shader::compile(GLuint& shader, const Code& code, GLenum shaderType) {
  69. shader = glCreateShader(shaderType);
  70. const GLchar* buffer = code.begin();
  71. glShaderSource(shader, 1, &buffer, nullptr);
  72. glCompileShader(shader);
  73. if(GL::checkAndPrintError("compile error")) {
  74. return true;
  75. }
  76. GLint compiled;
  77. glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
  78. if(!compiled) {
  79. ErrorLog log;
  80. glGetShaderInfoLog(shader, log.getLength(), nullptr, log.begin());
  81. std::cout << "compiler log: " << log.begin() << "\n";
  82. return true;
  83. }
  84. return false;
  85. }
  86. void Shader::use() const {
  87. glUseProgram(program);
  88. }
  89. void Shader::setMatrix(const GLchar* name, const GLfloat* data) {
  90. glUniformMatrix4fv(glGetUniformLocation(program, name), 1, GL_TRUE, data);
  91. }
  92. void Shader::setInt(const GLchar* name, GLint data) {
  93. glUniform1i(glGetUniformLocation(program, name), data);
  94. }
  95. void Shader::setFloat(const GLchar* name, GLfloat data) {
  96. glUniform1f(glGetUniformLocation(program, name), data);
  97. }
  98. void Shader::setVector(const GLchar* name, const Vector2& v) {
  99. glUniform2fv(glGetUniformLocation(program, name), 1, &(v[0]));
  100. }
  101. void Shader::setVector(const GLchar* name, const Vector3& v) {
  102. glUniform3fv(glGetUniformLocation(program, name), 1, &(v[0]));
  103. }
  104. void Shader::setVector(const GLchar* name, const Vector4& v) {
  105. glUniform4fv(glGetUniformLocation(program, name), 1, &(v[0]));
  106. }