diff options
Diffstat (limited to 'src/libjin/Render/JSL.cpp')
-rw-r--r-- | src/libjin/Render/JSL.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/src/libjin/Render/JSL.cpp b/src/libjin/Render/JSL.cpp new file mode 100644 index 0000000..4ce660b --- /dev/null +++ b/src/libjin/Render/JSL.cpp @@ -0,0 +1,158 @@ +#include "../modules.h" +#if JIN_MODULES_RENDER + +#include "../utils/macros.h" +#include "jsl.h" +namespace jin +{ +namespace render +{ + //vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords) + static const char* base_f = " " + //"#version 120 \n" + "#define number float \n" + "#define Image sampler2D \n" + "#define Canvas sampler2D \n" + "#define Color vec4 \n" + "#define Texel texture2D \n" + "#define extern uniform \n" + "uniform Image _tex0_; \n" + "%s \n" + "void main(){ \n" + " gl_FragColor = effect(gl_Color, _tex0_, gl_TexCoord[0].xy, gl_FragCoord.xy);\n" + "}\0"; + + shared JSLProgram* JSLProgram::currentJSLProgram = nullptr; + + JSLProgram* JSLProgram::createJSLProgram(const char* program) + { + return new JSLProgram(program); + } + + JSLProgram::JSLProgram(const char* program) + : currentTextureUnit(0) + { + initialize(program); + } + + JSLProgram::~JSLProgram() + { + destroy(); + } + + inline void JSLProgram::destroy() + { + if (currentJSLProgram == this) + unuse(); + } + + inline void JSLProgram::initialize(const char* program) + { + char* fs = (char*)alloca(strlen(program) + strlen(base_f)); + sprintf(fs, base_f, program); + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, (const GLchar**)&fs, NULL); + glCompileShader(fragmentShader); + + pid = glCreateProgram(); + glAttachShader(pid, fragmentShader); + glLinkProgram(pid); + } + + static inline GLint getMaxTextureUnits() + { + GLint maxTextureUnits = 0; + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); + return maxTextureUnits; + } + + GLint JSLProgram::getTextureUnit(const std::string& name) + { + std::map<std::string, GLint>::iterator texture_unit = texturePool.find(name); + if (texture_unit != texturePool.end()) + return texture_unit->second; + static GLint maxTextureUnits = getMaxTextureUnits(); + if (++currentTextureUnit >= maxTextureUnits) + return 0; + texturePool[name] = currentTextureUnit; + return currentTextureUnit; + } + +#define checkJSL() if (currentJSLProgram != this) return + + void JSLProgram::sendFloat(const char* variable, float number) + { + checkJSL(); + + int loc = glGetUniformLocation(pid, variable); + glUniform1f(loc, number); + } + + void JSLProgram::sendTexture(const char* variable, const Texture* tex) + { + checkJSL(); + + GLint location = glGetUniformLocation(pid, variable); + if (location == -1) + return; + GLint texture_unit = getTextureUnit(variable); + glUniform1i(location, texture_unit); + glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, tex->getTexture()); + glActiveTexture(GL_TEXTURE0); + } + + void JSLProgram::sendCanvas(const char* variable, const Canvas* canvas) + { + checkJSL(); + + GLint location = glGetUniformLocation(pid, variable); + if (location == -1) + return; + GLint texture_unit = getTextureUnit(variable); + glUniform1i(location, texture_unit); + glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, canvas->getTexture()); + glActiveTexture(GL_TEXTURE0); + } + + void JSLProgram::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) + { + 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) + { + checkJSL(); + + int loc = glGetUniformLocation(pid, name); + glUniform4f(loc, x, y, z, w); + } + + void JSLProgram::sendColor(const char* name, const color* col) + { + checkJSL(); + + int loc = glGetUniformLocation(pid, name); + glUniform4f(loc, + col->rgba.r / 255.f, + col->rgba.g / 255.f, + col->rgba.b / 255.f, + col->rgba.a / 255.f + ); + } + +} +} +#endif // JIN_MODULES_RENDER |