Shader.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. return false;
  60. }
  61. code.add(c);
  62. }
  63. return false;
  64. }
  65. bool Shader::hasError() const {
  66. return vertexShader == 0 || fragmentShader == 0 || program == 0;
  67. }
  68. bool Shader::compile(GL::Shader& s, const List<char>& code, GL::ShaderType st) {
  69. s = GL::createShader(st);
  70. GL::compileShader(s, code.begin());
  71. if(GL::printError("compile error")) {
  72. return true;
  73. }
  74. return GL::logCompileError(s);
  75. }
  76. void Shader::use() const {
  77. GL::useProgram(program);
  78. }
  79. void Shader::setMatrix(const char* name, const float* data) {
  80. GL::setMatrix(program, name, data);
  81. }
  82. void Shader::setInt(const char* name, int data) {
  83. GL::setInt(program, name, data);
  84. }
  85. void Shader::setFloat(const char* name, float data) {
  86. GL::setFloat(program, name, data);
  87. }
  88. void Shader::setVector(const char* name, const Vector2& v) {
  89. GL::set2Float(program, name, &(v[0]));
  90. }
  91. void Shader::setVector(const char* name, const Vector3& v) {
  92. GL::set3Float(program, name, &(v[0]));
  93. }
  94. void Shader::setVector(const char* name, const Vector4& v) {
  95. GL::set4Float(program, name, &(v[0]));
  96. }