diff options
Diffstat (limited to 'src/libjin/Graphics/Shader.cpp')
-rw-r--r-- | src/libjin/Graphics/Shader.cpp | 161 |
1 files changed, 117 insertions, 44 deletions
diff --git a/src/libjin/Graphics/Shader.cpp b/src/libjin/Graphics/Shader.cpp index e882d35..6c8e3b5 100644 --- a/src/libjin/Graphics/Shader.cpp +++ b/src/libjin/Graphics/Shader.cpp @@ -1,6 +1,9 @@ -#include "../modules.h" +#include <regex> +#include "../jin_configuration.h" #if LIBJIN_MODULES_RENDER +#include <iostream> + #include "../utils/macros.h" #include "Shader.h" #include "../Filesystem/Buffer.h" @@ -10,6 +13,7 @@ namespace graphics { using namespace jin::filesystem; + using namespace std; /** * default_texture @@ -17,7 +21,14 @@ namespace graphics * SHADER_FORMAT_SIZE * formatShader */ - #include "base.shader.h" + #include "Shaders/base.shader.h" + #include "Shaders/default.shader.h" + + const char* Shader::PROJECTION_MATRIX = "_projectionMatrix_"; + const char* Shader::MODEL_MATRIX = "_modelMatrix_"; + const char* Shader::MAIN_TEXTURE = "_main_texture_"; + const char* Shader::VERTEX_COORDS = "_vert_coord_"; + const char* Shader::TEXTURE_COORDS = "_tex_coord_"; /** * https://stackoverflow.com/questions/27941496/use-sampler-without-passing-through-value @@ -44,46 +55,84 @@ namespace graphics */ const int DEFAULT_TEXTURE_UNIT = 0; - /*static*/ JSLProgram* JSLProgram::currentJSLProgram = nullptr; + /*static*/ Shader* Shader::currentShader = nullptr; - JSLProgram* JSLProgram::createJSLProgram(const char* program) + Shader* Shader::createShader(const string& program) { - JSLProgram* jsl = nullptr; + Shader* shader = nullptr; try { - jsl = new JSLProgram(program); + shader = new Shader(program); } catch(...) { return nullptr; } - return jsl; + return shader; } - JSLProgram::JSLProgram(const char* program) + Shader::Shader(const string& program) : currentTextureUnit(DEFAULT_TEXTURE_UNIT) { - Buffer b = Buffer(strlen(program) + SHADER_FORMAT_SIZE); - formatShader((char*)b.data, program); - GLuint shader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(shader, 1, (const GLchar**)&b.data, NULL); - glCompileShader(shader); + if (!compile(program)) + throw 0; + } + + Shader::~Shader() + { + if (currentShader == this) + unuse(); + } + + bool Shader::compile(const string& program) + { + int loc_VERTEX_SHADER = program.find("#VERTEX_SHADER"); + int loc_END_VERTEX_SHADER = program.find("#END_VERTEX_SHADER"); + int loc_FRAGMENT_SHADER = program.find("#FRAGMENT_SHADER"); + int loc_END_FRAGMENT_SHADER = program.find("#END_FRAGMENT_SHADER"); + if (loc_VERTEX_SHADER == string::npos + || loc_END_VERTEX_SHADER == string::npos + || loc_FRAGMENT_SHADER == string::npos + || loc_END_FRAGMENT_SHADER == string::npos + ) + return false; + int p = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER"); + string vertex_shader = program.substr(p, loc_END_VERTEX_SHADER - p); + Buffer vbuffer = Buffer(vertex_shader.length() + BASE_VERTEX_SHADER_SIZE); + formatVertexShader((char*)vbuffer.data, vertex_shader.c_str()); + p = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER"); + string fragment_shader = program.substr(p, loc_END_FRAGMENT_SHADER - p); + Buffer fbuffer = Buffer(fragment_shader.length() + BASE_FRAGMENT_SHADER_SIZE); + formatFragmentShader((char*)fbuffer.data, fragment_shader.c_str()); + /* compile */ GLint success; - glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + GLuint vshader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vshader, 1, (const GLchar**)&vbuffer.data, NULL); + glCompileShader(vshader); + glGetShaderiv(vshader, GL_COMPILE_STATUS, &success); + //std::cout << (char*)vbuffer.data << std::endl; + //Buffer log = Buffer(1024); + //int len; + //glGetShaderInfoLog(vshader, sizeof(log), &len, (GLchar*)log.data); + //std::cout << (char*)log.data << std::endl; if (success == GL_FALSE) - throw 0; + return false; + GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fshader, 1, (const GLchar**)&fbuffer.data, NULL); + glCompileShader(fshader); + glGetShaderiv(fshader, GL_COMPILE_STATUS, &success); + //std::cout << (char*)fbuffer.data << std::endl; + if (success == GL_FALSE) + return false; pid = glCreateProgram(); - glAttachShader(pid, shader); + glAttachShader(pid, vshader); + glAttachShader(pid, fshader); glLinkProgram(pid); glGetProgramiv(pid, GL_LINK_STATUS, &success); + //glGetProgramInfoLog(pid, 1024, &len, (GLchar*)log.data); + //std::cout << (char*)log.data << std::endl; if (success == GL_FALSE) - throw 0; - } - - JSLProgram::~JSLProgram() - { - if (currentJSLProgram == this) - unuse(); + throw false; } static inline GLint getMaxTextureUnits() @@ -93,22 +142,20 @@ namespace graphics return maxTextureUnits; } - void JSLProgram::use() + void Shader::use() { glUseProgram(pid); - currentJSLProgram = this; - /* bind default texture */ - int loc = glGetUniformLocation(pid, default_texture); - glUniform1i(loc, DEFAULT_TEXTURE_UNIT); + currentShader = this; + sendInt(Shader::MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT); } - /*static*/ void JSLProgram::unuse() + /*static*/ void Shader::unuse() { glUseProgram(0); - currentJSLProgram = nullptr; + currentShader = nullptr; } - GLint JSLProgram::claimTextureUnit(const std::string& name) + GLint Shader::claimTextureUnit(const std::string& name) { std::map<std::string, GLint>::iterator unit = textureUnits.find(name); if (unit != textureUnits.end()) @@ -121,10 +168,17 @@ namespace graphics } #define checkJSL() \ - if (currentJSLProgram != this) \ + if (currentShader != this) \ return - void JSLProgram::sendFloat(const char* variable, float number) + void Shader::sendInt(const char* name, int value) + { + checkJSL(); + int loc = glGetUniformLocation(pid, name); + glUniform1i(loc, value); + } + + void Shader::sendFloat(const char* variable, float number) { checkJSL(); int loc = glGetUniformLocation(pid, variable); @@ -145,7 +199,7 @@ namespace graphics * TextureUnit textureUnits[GL_MAX_TEXTURE_IMAGE_UNITS] * GLuint currentTextureUnit = 0; */ - void JSLProgram::sendTexture(const char* variable, const Texture* tex) + void Shader::sendTexture(const char* variable, const Texture* tex) { checkJSL(); GLint location = glGetUniformLocation(pid, variable); @@ -157,14 +211,13 @@ namespace graphics // TODO: 쳣 return; } + gl.activeTexUnit(unit); glUniform1i(location, unit); - glActiveTexture(GL_TEXTURE0 + unit); - glBindTexture(GL_TEXTURE_2D, tex->getTexture()); - - glActiveTexture(GL_TEXTURE0); + gl.bindTexture(tex->getTexture()); + gl.activeTexUnit(0); } - void JSLProgram::sendCanvas(const char* variable, const Canvas* canvas) + void Shader::sendCanvas(const char* variable, const Canvas* canvas) { checkJSL(); GLint location = glGetUniformLocation(pid, variable); @@ -178,33 +231,33 @@ namespace graphics } glUniform1i(location, unit); glActiveTexture(GL_TEXTURE0 + unit); - glBindTexture(GL_TEXTURE_2D, canvas->getTexture()); + gl.bindTexture(canvas->getTexture()); glActiveTexture(GL_TEXTURE0); } - void JSLProgram::sendVec2(const char* name, float x, float y) + void Shader::sendVec2(const char* name, float x, float y) { checkJSL(); int loc = glGetUniformLocation(pid, name); glUniform2f(loc, x, y); } - void JSLProgram::sendVec3(const char* name, float x, float y, float z) + void Shader::sendVec3(const char* name, float x, float y, float z) { checkJSL(); int loc = glGetUniformLocation(pid, name); glUniform3f(loc, x, y, z); } - void JSLProgram::sendVec4(const char* name, float x, float y, float z, float w) + void Shader::sendVec4(const char* name, float x, float y, float z, float w) { checkJSL(); int loc = glGetUniformLocation(pid, name); glUniform4f(loc, x, y, z, w); } - void JSLProgram::sendColor(const char* name, const Color* col) + void Shader::sendColor(const char* name, const Color* col) { checkJSL(); int loc = glGetUniformLocation(pid, name); @@ -216,6 +269,26 @@ namespace graphics ); } + void Shader::sendMatrix4(const char* name, const math::Matrix* mat4) + { + int loc = glGetUniformLocation(pid, name); + glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements()); + } + + void Shader::bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) + { + GLint loc = glGetAttribLocation(pid, VERTEX_COORDS); + glEnableVertexAttribArray(0); + glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); + } + + void Shader::bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) + { + GLint loc = glGetAttribLocation(pid, TEXTURE_COORDS); + glEnableVertexAttribArray(1); + glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); + } + } // graphics } // jin |