Shader.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "rendering/Shader.h"
  2. #include <stdio.h>
  3. #include "utils/Logger.h"
  4. Shader::Shader() : shaders(0), program(0) {
  5. }
  6. Shader::~Shader() {
  7. for(GL::Shader shader : shaders) {
  8. GL::deleteShader(shader);
  9. }
  10. GL::deleteProgram(program);
  11. }
  12. static bool endsWith(const char* path, int length, const char* ending) {
  13. int endingLength = static_cast<int>(strlen(ending));
  14. if(length < endingLength) {
  15. return false;
  16. }
  17. return strcmp(path + (length - endingLength), ending) == 0;
  18. }
  19. GL::ShaderType Shader::getShaderType(const char* path) const {
  20. int length = static_cast<int>(strlen(path));
  21. if(endsWith(path, length, ".vs")) {
  22. return GL::ShaderType::VERTEX;
  23. } else if(endsWith(path, length, ".fs")) {
  24. return GL::ShaderType::FRAGMENT;
  25. } else if(endsWith(path, length, ".gs")) {
  26. return GL::ShaderType::GEOMETRY;
  27. } else if(endsWith(path, length, ".tcs")) {
  28. return GL::ShaderType::TESSELATION_CONTROL;
  29. } else if(endsWith(path, length, ".tes")) {
  30. return GL::ShaderType::TESSELATION_EVALUATION;
  31. }
  32. return GL::ShaderType::INVALID;
  33. }
  34. Error Shader::readAndCompile(const char* path, GL::Shader& s,
  35. GL::ShaderType st) {
  36. List<char> code;
  37. Error error = readFile(code, path);
  38. if(error.has()) {
  39. return error;
  40. }
  41. return compileType(s, code, st);
  42. }
  43. Error Shader::readFile(List<char>& code, const char* path) const {
  44. FILE* in = fopen(path, "r");
  45. if(in == nullptr) {
  46. Error e = {"cannot read file: "};
  47. e.message.append(path);
  48. return e;
  49. }
  50. while(true) {
  51. int c = fgetc(in);
  52. if(c == EOF) {
  53. break;
  54. }
  55. code.add(static_cast<char>(c));
  56. }
  57. code.add('\0');
  58. if(fclose(in) != 0) {
  59. Error e = {"cannot close file: "};
  60. e.message.append(path);
  61. return e;
  62. }
  63. return {};
  64. }
  65. Error Shader::compileType(GL::Shader& s, const List<char>& code,
  66. GL::ShaderType st) {
  67. s = GL::createShader(st);
  68. GL::compileShader(s, code.begin());
  69. Error error = GL::getError("compile error");
  70. if(error.has()) {
  71. return error;
  72. }
  73. return GL::getCompileError(s);
  74. }
  75. void Shader::use() const {
  76. GL::useProgram(program);
  77. }
  78. void Shader::setMatrix(const char* name, const float* data) {
  79. GL::setMatrix(program, name, data);
  80. }
  81. void Shader::setMatrix(const char* name, const Matrix& m) {
  82. setMatrix(name, m.getValues());
  83. }
  84. void Shader::setInt(const char* name, int data) {
  85. GL::setInt(program, name, data);
  86. }
  87. void Shader::setFloat(const char* name, float data) {
  88. GL::setFloat(program, name, data);
  89. }
  90. void Shader::setVector(const char* name, const Vector2& v) {
  91. GL::set2Float(program, name, &(v[0]));
  92. }
  93. void Shader::setVector(const char* name, const Vector3& v) {
  94. GL::set3Float(program, name, &(v[0]));
  95. }
  96. void Shader::setVector(const char* name, const Vector4& v) {
  97. GL::set4Float(program, name, &(v[0]));
  98. }