|
@@ -4,61 +4,48 @@
|
|
|
#include "utils/Logger.h"
|
|
|
#include "wrapper/GL.h"
|
|
|
|
|
|
-Shader::Shader() : vertex(0), geometry(0), fragment(0), program(0) {
|
|
|
+Shader::Shader() : shaders(0), program(0) {
|
|
|
}
|
|
|
|
|
|
Shader::~Shader() {
|
|
|
- GL::deleteShader(vertex);
|
|
|
- GL::deleteShader(geometry);
|
|
|
- GL::deleteShader(fragment);
|
|
|
+ for(GL::Shader shader : shaders) {
|
|
|
+ GL::deleteShader(shader);
|
|
|
+ }
|
|
|
GL::deleteProgram(program);
|
|
|
}
|
|
|
|
|
|
-Error Shader::compile(const char* vertexPath, const char* geometryPath,
|
|
|
- const char* fragmentPath) {
|
|
|
- if(vertexPath != nullptr) {
|
|
|
- Error error = compile(vertexPath, vertex, GL::VERTEX_SHADER);
|
|
|
- if(error.has()) {
|
|
|
- return error;
|
|
|
- }
|
|
|
- }
|
|
|
- if(geometryPath != nullptr) {
|
|
|
- Error error = compile(geometryPath, geometry, GL::GEOMETRY_SHADER);
|
|
|
- if(error.has()) {
|
|
|
- return error;
|
|
|
- }
|
|
|
- }
|
|
|
- if(fragmentPath != nullptr) {
|
|
|
- Error error = compile(fragmentPath, fragment, GL::FRAGMENT_SHADER);
|
|
|
- if(error.has()) {
|
|
|
- return error;
|
|
|
- }
|
|
|
- }
|
|
|
- program = GL::createProgram();
|
|
|
- if(vertexPath != nullptr) {
|
|
|
- GL::attachShader(program, vertex);
|
|
|
+static bool endsWith(const char* path, int length, const char* ending) {
|
|
|
+ int endingLength = strlen(ending);
|
|
|
+ if(length < endingLength) {
|
|
|
+ return false;
|
|
|
}
|
|
|
- if(geometryPath != nullptr) {
|
|
|
- GL::attachShader(program, geometry);
|
|
|
- }
|
|
|
- if(fragmentPath != nullptr) {
|
|
|
- GL::attachShader(program, fragment);
|
|
|
- }
|
|
|
- GL::linkProgram(program);
|
|
|
- Error error = GL::getError("cannot link");
|
|
|
- if(error.has()) {
|
|
|
- return error;
|
|
|
+ return strcmp(path + (length - endingLength), ending) == 0;
|
|
|
+}
|
|
|
+
|
|
|
+GL::ShaderType Shader::getShaderType(const char* path) const {
|
|
|
+ int length = strlen(path);
|
|
|
+ if(endsWith(path, length, ".vs")) {
|
|
|
+ return GL::VERTEX_SHADER;
|
|
|
+ } else if(endsWith(path, length, ".fs")) {
|
|
|
+ return GL::FRAGMENT_SHADER;
|
|
|
+ } else if(endsWith(path, length, ".gs")) {
|
|
|
+ return GL::GEOMETRY_SHADER;
|
|
|
+ } else if(endsWith(path, length, ".tcs")) {
|
|
|
+ return GL::TESSELATION_CONTROL_SHADER;
|
|
|
+ } else if(endsWith(path, length, ".tes")) {
|
|
|
+ return GL::TESSELATION_EVALUATION_SHADER;
|
|
|
}
|
|
|
- return GL::getLinkerError(program);
|
|
|
+ return GL::NO_SHADER;
|
|
|
}
|
|
|
|
|
|
-Error Shader::compile(const char* path, GL::Shader& s, GL::ShaderType st) {
|
|
|
+Error Shader::readAndCompile(const char* path, GL::Shader& s,
|
|
|
+ GL::ShaderType st) {
|
|
|
List<char> code;
|
|
|
Error error = readFile(code, path);
|
|
|
if(error.has()) {
|
|
|
return error;
|
|
|
}
|
|
|
- return compile(s, code, st);
|
|
|
+ return compileType(s, code, st);
|
|
|
}
|
|
|
|
|
|
Error Shader::readFile(List<char>& code, const char* path) const {
|
|
@@ -78,8 +65,8 @@ Error Shader::readFile(List<char>& code, const char* path) const {
|
|
|
return {};
|
|
|
}
|
|
|
|
|
|
-Error Shader::compile(GL::Shader& s, const List<char>& code,
|
|
|
- GL::ShaderType st) {
|
|
|
+Error Shader::compileType(GL::Shader& s, const List<char>& code,
|
|
|
+ GL::ShaderType st) {
|
|
|
s = GL::createShader(st);
|
|
|
GL::compileShader(s, code.begin());
|
|
|
Error error = GL::getError("compile error");
|