Shader.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <fstream>
  2. #include <iostream>
  3. #include "rendering/Shader.h"
  4. #include "wrapper/GL.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(compile(vertexPath, vertexShader, GL::VERTEX_SHADER) ||
  9. compile(fragmentPath, fragmentShader, GL::FRAGMENT_SHADER)) {
  10. return;
  11. }
  12. if(geometryPath != nullptr &&
  13. compile(geometryPath, geometryShader, GL::GEOMETRY_SHADER)) {
  14. return;
  15. }
  16. program = GL::createProgram();
  17. GL::attachShader(program, vertexShader);
  18. if(geometryPath != nullptr) {
  19. GL::attachShader(program, geometryShader);
  20. }
  21. GL::attachShader(program, fragmentShader);
  22. GL::linkProgram(program);
  23. if(GL::printError("cannot link")) {
  24. return;
  25. }
  26. if(GL::logLinkerError(program)) {
  27. clean();
  28. return;
  29. }
  30. }
  31. Shader::~Shader() {
  32. clean();
  33. }
  34. void Shader::clean() {
  35. GL::deleteShader(vertexShader);
  36. GL::deleteShader(geometryShader);
  37. GL::deleteShader(fragmentShader);
  38. GL::deleteProgram(program);
  39. program = 0;
  40. }
  41. bool Shader::compile(const char* path, GL::Shader& s, GL::ShaderType st) {
  42. std::cout << "shader: " << path << '\n';
  43. List<char> code;
  44. if(readFile(code, path)) {
  45. return true;
  46. }
  47. return compile(s, code, st);
  48. }
  49. bool Shader::readFile(List<char>& code, const char* path) const {
  50. std::ifstream in;
  51. in.open(path);
  52. if(!in.good()) {
  53. std::cout << "cannot read file\n";
  54. return true;
  55. }
  56. while(true) {
  57. int c = in.get();
  58. if(c == EOF) {
  59. break;
  60. }
  61. code.add(c);
  62. }
  63. code.add('\0');
  64. return false;
  65. }
  66. bool Shader::hasError() const {
  67. return vertexShader == 0 || fragmentShader == 0 || program == 0;
  68. }
  69. bool Shader::compile(GL::Shader& s, const List<char>& code, GL::ShaderType st) {
  70. s = GL::createShader(st);
  71. GL::compileShader(s, code.begin());
  72. if(GL::printError("compile error")) {
  73. return true;
  74. }
  75. return GL::logCompileError(s);
  76. }
  77. void Shader::use() const {
  78. GL::useProgram(program);
  79. }
  80. void Shader::setMatrix(const char* name, const float* data) {
  81. GL::setMatrix(program, name, data);
  82. }
  83. void Shader::setInt(const char* name, int data) {
  84. GL::setInt(program, name, data);
  85. }
  86. void Shader::setFloat(const char* name, float data) {
  87. GL::setFloat(program, name, data);
  88. }
  89. void Shader::setVector(const char* name, const Vector2& v) {
  90. GL::set2Float(program, name, &(v[0]));
  91. }
  92. void Shader::setVector(const char* name, const Vector3& v) {
  93. GL::set3Float(program, name, &(v[0]));
  94. }
  95. void Shader::setVector(const char* name, const Vector4& v) {
  96. GL::set4Float(program, name, &(v[0]));
  97. }