aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/Graphics/Shader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/Graphics/Shader.cpp')
-rw-r--r--src/libjin/Graphics/Shader.cpp484
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