diff options
Diffstat (limited to 'src/libjin/Graphics/Shader.cpp')
-rw-r--r-- | src/libjin/Graphics/Shader.cpp | 484 |
1 files changed, 242 insertions, 242 deletions
diff --git a/src/libjin/Graphics/Shader.cpp b/src/libjin/Graphics/Shader.cpp index 688fa51..8788900 100644 --- a/src/libjin/Graphics/Shader.cpp +++ b/src/libjin/Graphics/Shader.cpp @@ -9,274 +9,274 @@ #include "../Filesystem/Buffer.h" namespace jin { -namespace graphics -{ + namespace graphics + { - using namespace jin::filesystem; - using namespace std; + using namespace jin::filesystem; + using namespace std; - /** - * default_texture - * base_shader - * SHADER_FORMAT_SIZE - * formatShader - */ - #include "Shaders/default.shader.h" + /** + * default_texture + * base_shader + * SHADER_FORMAT_SIZE + * formatShader + */ + #include "Shaders/default.shader.h" - /** - * https://stackoverflow.com/questions/27941496/use-sampler-without-passing-through-value - * The default value of a sampler variable is 0. From the GLSL 3.30 spec, - * section "4.3.5 Uniforms": - * - * The link time initial value is either the value of the variable's - * initializer, if present, or 0 if no initializer is present.Sampler - * types cannot have initializers. - * - * Since a value of 0 means that it's sampling from texture unit 0, it will - * work without ever setting the value as long as you bind your textures to - * unit 0. This is well defined behavior. - * - * Since texture unit 0 is also the default until you call glActiveTexture() - * with a value other than GL_TEXTURE0, it's very common to always use unit - * 0 as long as shaders do not need more than one texture.Which means that - * often times, setting the sampler uniforms is redundant for simple - * applications. - * - * I would still prefer to always set the values.If nothing else, it makes - * it clear to anybody reading your code that you really mean to sample from - * texture unit 0, and did not just forget to set the value. - */ - const int DEFAULT_TEXTURE_UNIT = 0; + /** + * https://stackoverflow.com/questions/27941496/use-sampler-without-passing-through-value + * The default value of a sampler variable is 0. From the GLSL 3.30 spec, + * section "4.3.5 Uniforms": + * + * The link time initial value is either the value of the variable's + * initializer, if present, or 0 if no initializer is present.Sampler + * types cannot have initializers. + * + * Since a value of 0 means that it's sampling from texture unit 0, it will + * work without ever setting the value as long as you bind your textures to + * unit 0. This is well defined behavior. + * + * Since texture unit 0 is also the default until you call glActiveTexture() + * with a value other than GL_TEXTURE0, it's very common to always use unit + * 0 as long as shaders do not need more than one texture.Which means that + * often times, setting the sampler uniforms is redundant for simple + * applications. + * + * I would still prefer to always set the values.If nothing else, it makes + * it clear to anybody reading your code that you really mean to sample from + * texture unit 0, and did not just forget to set the value. + */ + const int DEFAULT_TEXTURE_UNIT = 0; - /*static*/ Shader* Shader::currentShader = nullptr; + /*static*/ Shader* Shader::currentShader = nullptr; - Shader* Shader::createShader(const string& program) - { - Shader* shader = nullptr; - try - { - shader = new Shader(program); - } - catch(...) - { - return nullptr; - } - return shader; - } + Shader* Shader::createShader(const string& program) + { + Shader* shader = nullptr; + try + { + shader = new Shader(program); + } + catch(...) + { + return nullptr; + } + return shader; + } - Shader::Shader(const string& program) - : currentTextureUnit(DEFAULT_TEXTURE_UNIT) - { - if (!compile(program)) - throw 0; - } + Shader::Shader(const string& program) + : currentTextureUnit(DEFAULT_TEXTURE_UNIT) + { + if (!compile(program)) + throw 0; + } - Shader::~Shader() - { - if (currentShader == this) - unuse(); - } + Shader::~Shader() + { + if (currentShader == this) + unuse(); + } - bool Shader::compile(const string& program) - { - /* parse shader source, need some optimizations */ - 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; - /* load vertex and fragment shader source into buffers */ - int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER"); - string vertex_shader = program.substr(start, loc_END_VERTEX_SHADER - start); - Buffer vbuffer = Buffer(vertex_shader.length() + BASE_VERTEX_SHADER_SIZE); - formatVertexShader((char*)vbuffer.data, vertex_shader.c_str()); - start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER"); - string fragment_shader = program.substr(start, loc_END_FRAGMENT_SHADER - start); - Buffer fbuffer = Buffer(fragment_shader.length() + BASE_FRAGMENT_SHADER_SIZE); - formatFragmentShader((char*)fbuffer.data, fragment_shader.c_str()); - /* compile */ - GLint success; - GLuint vshader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vshader, 1, (const GLchar**)&vbuffer.data, NULL); - glCompileShader(vshader); - glGetShaderiv(vshader, GL_COMPILE_STATUS, &success); - if (success == GL_FALSE) - return false; - GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fshader, 1, (const GLchar**)&fbuffer.data, NULL); - glCompileShader(fshader); - glGetShaderiv(fshader, GL_COMPILE_STATUS, &success); - if (success == GL_FALSE) - return false; - pid = glCreateProgram(); - glAttachShader(pid, vshader); - glAttachShader(pid, fshader); - glLinkProgram(pid); - glGetProgramiv(pid, GL_LINK_STATUS, &success); - if (success == GL_FALSE) - throw false; - } + bool Shader::compile(const string& program) + { + /* parse shader source, need some optimizations */ + 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; + /* load vertex and fragment shader source into buffers */ + int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER"); + string vertex_shader = program.substr(start, loc_END_VERTEX_SHADER - start); + Buffer vbuffer = Buffer(vertex_shader.length() + BASE_VERTEX_SHADER_SIZE); + formatVertexShader((char*)vbuffer.data, vertex_shader.c_str()); + start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER"); + string fragment_shader = program.substr(start, loc_END_FRAGMENT_SHADER - start); + Buffer fbuffer = Buffer(fragment_shader.length() + BASE_FRAGMENT_SHADER_SIZE); + formatFragmentShader((char*)fbuffer.data, fragment_shader.c_str()); + /* compile */ + GLint success; + GLuint vshader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vshader, 1, (const GLchar**)&vbuffer.data, NULL); + glCompileShader(vshader); + glGetShaderiv(vshader, GL_COMPILE_STATUS, &success); + if (success == GL_FALSE) + return false; + GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fshader, 1, (const GLchar**)&fbuffer.data, NULL); + glCompileShader(fshader); + glGetShaderiv(fshader, GL_COMPILE_STATUS, &success); + if (success == GL_FALSE) + return false; + pid = glCreateProgram(); + glAttachShader(pid, vshader); + glAttachShader(pid, fshader); + glLinkProgram(pid); + glGetProgramiv(pid, GL_LINK_STATUS, &success); + if (success == GL_FALSE) + throw false; + } - static inline GLint getMaxTextureUnits() - { - GLint maxTextureUnits = 0; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); - return maxTextureUnits; - } + static inline GLint getMaxTextureUnits() + { + GLint maxTextureUnits = 0; + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); + return maxTextureUnits; + } - void Shader::use() - { - glUseProgram(pid); - currentShader = this; - sendInt(SHADER_MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT); - } + void Shader::use() + { + glUseProgram(pid); + currentShader = this; + sendInt(SHADER_MAIN_TEXTURE, DEFAULT_TEXTURE_UNIT); + } - /*static*/ void Shader::unuse() - { - glUseProgram(0); - currentShader = nullptr; - } + /*static*/ void Shader::unuse() + { + glUseProgram(0); + currentShader = nullptr; + } - GLint Shader::claimTextureUnit(const std::string& name) - { - std::map<std::string, GLint>::iterator unit = textureUnits.find(name); - if (unit != textureUnits.end()) - return unit->second; - static GLint MAX_TEXTURE_UNITS = getMaxTextureUnits(); - if (++currentTextureUnit >= MAX_TEXTURE_UNITS) - return 0; - textureUnits[name] = currentTextureUnit; - return currentTextureUnit; - } + GLint Shader::claimTextureUnit(const std::string& name) + { + std::map<std::string, GLint>::iterator unit = textureUnits.find(name); + if (unit != textureUnits.end()) + return unit->second; + static GLint MAX_TEXTURE_UNITS = getMaxTextureUnits(); + if (++currentTextureUnit >= MAX_TEXTURE_UNITS) + return 0; + textureUnits[name] = currentTextureUnit; + return currentTextureUnit; + } -#define checkJSL() \ - if (currentShader != this) \ - return + #define checkJSL() \ + if (currentShader != this) \ + return - void Shader::sendInt(const char* name, int value) - { - checkJSL(); - int loc = glGetUniformLocation(pid, name); - glUniform1i(loc, value); - } + 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); - glUniform1f(loc, number); - } + void Shader::sendFloat(const char* variable, float number) + { + checkJSL(); + int loc = glGetUniformLocation(pid, variable); + glUniform1f(loc, number); + } - /** - * https://www.douban.com/note/627332677/ - * struct TextureUnit - * { - * GLuint targetTexture1D; - * GLuint targetTexture2D; - * GLuint targetTexture3D; - * GLuint targetTextureCube; - * ... - * }; - * - * TextureUnit textureUnits[GL_MAX_TEXTURE_IMAGE_UNITS] - * GLuint currentTextureUnit = 0; - */ - void Shader::sendTexture(const char* variable, const Texture* tex) - { - checkJSL(); - GLint location = glGetUniformLocation(pid, variable); - if (location == -1) - return; - GLint unit = claimTextureUnit(variable); - if (unit == 0) - { - // TODO: 쳣 - return; - } - gl.activeTexUnit(unit); - glUniform1i(location, unit); - gl.bindTexture(tex->getTexture()); - gl.activeTexUnit(0); - } + /** + * https://www.douban.com/note/627332677/ + * struct TextureUnit + * { + * GLuint targetTexture1D; + * GLuint targetTexture2D; + * GLuint targetTexture3D; + * GLuint targetTextureCube; + * ... + * }; + * + * TextureUnit textureUnits[GL_MAX_TEXTURE_IMAGE_UNITS] + * GLuint currentTextureUnit = 0; + */ + void Shader::sendTexture(const char* variable, const Texture* tex) + { + checkJSL(); + GLint location = glGetUniformLocation(pid, variable); + if (location == -1) + return; + GLint unit = claimTextureUnit(variable); + if (unit == 0) + { + // TODO: 쳣 + return; + } + gl.activeTexUnit(unit); + glUniform1i(location, unit); + gl.bindTexture(tex->getTexture()); + gl.activeTexUnit(0); + } - void Shader::sendCanvas(const char* variable, const Canvas* canvas) - { - checkJSL(); - GLint location = glGetUniformLocation(pid, variable); - if (location == -1) - return; - GLint unit = claimTextureUnit(variable); - if (unit == 0) - { - // TODO: 쳣 - return; - } - glUniform1i(location, unit); - glActiveTexture(GL_TEXTURE0 + unit); - gl.bindTexture(canvas->getTexture()); + void Shader::sendCanvas(const char* variable, const Canvas* canvas) + { + checkJSL(); + GLint location = glGetUniformLocation(pid, variable); + if (location == -1) + return; + GLint unit = claimTextureUnit(variable); + if (unit == 0) + { + // TODO: 쳣 + return; + } + glUniform1i(location, unit); + glActiveTexture(GL_TEXTURE0 + unit); + gl.bindTexture(canvas->getTexture()); - glActiveTexture(GL_TEXTURE0); - } + glActiveTexture(GL_TEXTURE0); + } - void Shader::sendVec2(const char* name, float x, float y) - { - checkJSL(); - int loc = glGetUniformLocation(pid, name); - glUniform2f(loc, x, y); - } + void Shader::sendVec2(const char* name, float x, float y) + { + checkJSL(); + int loc = glGetUniformLocation(pid, name); + glUniform2f(loc, x, y); + } - void Shader::sendVec3(const char* name, float x, float y, float z) - { - checkJSL(); - int loc = glGetUniformLocation(pid, name); - glUniform3f(loc, x, y, 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 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 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 Shader::sendColor(const char* name, const Color* col) - { - checkJSL(); - int loc = glGetUniformLocation(pid, name); - glUniform4f(loc, - col->r / 255.f, - col->g / 255.f, - col->b / 255.f, - col->a / 255.f - ); - } + void Shader::sendColor(const char* name, const Color* col) + { + checkJSL(); + int loc = glGetUniformLocation(pid, name); + glUniform4f(loc, + col->r / 255.f, + col->g / 255.f, + col->b / 255.f, + col->a / 255.f + ); + } - void Shader::sendMatrix4(const char* name, const math::Matrix* mat4) - { - int loc = glGetUniformLocation(pid, name); - glUniformMatrix4fv(loc, 1, GL_FALSE, mat4->getElements()); - } + 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, SHADER_VERTEX_COORDS); - glEnableVertexAttribArray(0); - glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); - } + void Shader::bindVertexPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) + { + GLint loc = glGetAttribLocation(pid, SHADER_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, SHADER_TEXTURE_COORDS); - glEnableVertexAttribArray(1); - glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); - } + void Shader::bindUVPointer(int n, GLenum type, GLsizei stride, const GLvoid * pointers) + { + GLint loc = glGetAttribLocation(pid, SHADER_TEXTURE_COORDS); + glEnableVertexAttribArray(1); + glVertexAttribPointer(loc, n, type, GL_FALSE, stride, pointers); + } -} // graphics + } // graphics } // jin #endif // LIBJIN_MODULES_RENDER
\ No newline at end of file |