diff options
Diffstat (limited to 'src/libjin/graphics/shaders/jsl_compiler.cpp')
-rw-r--r-- | src/libjin/graphics/shaders/jsl_compiler.cpp | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/libjin/graphics/shaders/jsl_compiler.cpp b/src/libjin/graphics/shaders/jsl_compiler.cpp new file mode 100644 index 0000000..44908e8 --- /dev/null +++ b/src/libjin/graphics/shaders/jsl_compiler.cpp @@ -0,0 +1,156 @@ +#include "../../core/configuration.h" +#if defined(jin_graphics) && (jin_graphics & jin_graphics_shader) + +#include "../../common/string.h" +#include "../../Filesystem/buffer.h" + +#include "jsl_compiler.h" + +using namespace std; +using namespace JinEngine::Filesystem; + +namespace JinEngine +{ + namespace Graphics + { + namespace Shaders + { + + /// + /// Uniforms: + /// jin_ProjectionMatrix --+ + /// jin_ModelViewMatrix |- Uniforms + /// jin_MainTexture | + /// jin_RenderTargetSize | + /// jin_Time --+ + /// + /// Built-in variables in vertex shader: + /// jin_VertexCoords --+ + /// jin_TextureCoords |- Attributes + /// jin_VertexColor --+ + /// jin_Color ---- GLSL built in + /// + /// Built-in variables in fragment shader: + /// jin_Color --+ + /// jin_XY |- Inputs + /// jin_UV | + /// jin_COLOR --+ + /// + + JinEngine::String SHADER_PROJECTION_MATRIX = "jin_ProjectionMatrix"; + JinEngine::String SHADER_MODELVIEW_MATRIX = "jin_ModelViewMatrix"; + JinEngine::String SHADER_MAIN_TEXTURE = "jin_MainTexture"; + JinEngine::String SHADER_VERTEX_COORDS = "jin_VertexCoords"; + JinEngine::String SHADER_TEXTURE_COORDS = "jin_TextureCoords"; + JinEngine::String SHADER_VERTEX_COLOR = "jin_VertexColor"; + JinEngine::String SHADER_TIME = "jin_Time"; + JinEngine::String SHADER_RENDERTARGET_SIZE = "jin_RenderTargetSize"; + JinEngine::String SHADER_VERSION = "#version 130 core \n"; + JinEngine::String SHADER_DEFINITIONS = + // Types + "#define Number float \n" + "#define Texture sampler2D \n" + "#define Canvas sampler2D \n" + "#define Color vec4 \n" + "#define Vec2 vec2 \n" + "#define Vec3 vec3 \n" + "#define Vec4 vec4 \n" + // Functions + "#define texel texture2D \n" + // Structs + "struct Vertex \n" + "{ \n" + " vec2 xy; \n" + " vec2 uv; \n" + " vec4 color; \n" + "}; \n" + "\n"; + JinEngine::String SHADER_UNIFORMS = + "uniform Texture " + SHADER_MAIN_TEXTURE + "; \n" // Main texture goes first. + "uniform mat4 " + SHADER_PROJECTION_MATRIX + "; \n" + "uniform mat4 " + SHADER_MODELVIEW_MATRIX + "; \n" + "uniform vec2 " + SHADER_TIME + "; \n" + "uniform vec2 " + SHADER_RENDERTARGET_SIZE + "; \n"; + + JinEngine::String JSLCompiler::formatVertexShader(const JinEngine::String& vert) + { + static JinEngine::String vert_part1 = + SHADER_VERSION + + SHADER_DEFINITIONS + + SHADER_UNIFORMS + + "in vec2 " + SHADER_VERTEX_COORDS + "; \n" + "in vec2 " + SHADER_TEXTURE_COORDS + "; \n" + "in vec4 " + SHADER_VERTEX_COLOR + "; \n"; // Color data in unsigned byte. + static JinEngine::String vert_part2 = + "\n" + "out vec4 jin_Color; \n" + "out vec2 jin_XY; \n" + "out vec2 jin_UV; \n" + "out vec4 jin_COLOR; \n" + "void main()\n" + "{\n" + " vec4 v = " + SHADER_MODELVIEW_MATRIX + " * vec4(" + SHADER_VERTEX_COORDS + ", 0, 1.0); \n" + " Vertex _v = vert(Vertex(v.xy, " + SHADER_TEXTURE_COORDS + ", " + SHADER_VERTEX_COLOR + ")); \n" + " gl_Position = " + SHADER_PROJECTION_MATRIX + " * vec4(_v.xy, 0, 1.0f); \n" + " jin_Color = gl_Color; \n" + " jin_XY = _v.xy; \n" + " jin_UV = _v.uv; \n" + " jin_COLOR = _v.color; \n" + "}"; + return vert_part1 + vert + vert_part2; + } + + JinEngine::String JSLCompiler::formatFragmentShader(const JinEngine::String& frag) + { + static JinEngine::String frag_part1 = + SHADER_VERSION + + SHADER_DEFINITIONS + + SHADER_UNIFORMS + + "in vec4 jin_Color; \n" + "in vec2 jin_XY; \n" + "in vec2 jin_UV; \n" + "in vec4 jin_COLOR; \n"; + static JinEngine::String frag_part2 = + "\n" + "out vec4 jin_OutColor; \n" + "void main() \n" + "{ \n" + " jin_OutColor = frag(jin_Color, " + SHADER_MAIN_TEXTURE + ", Vertex(jin_XY, jin_UV, jin_COLOR)); \n" + "} \n"; + return frag_part1 + frag + frag_part2; + } + + bool JSLCompiler::compile(const string& jsl, string* vertex_shader, string* fragment_shader) + { + // parse shader source, need some optimizations + int loc_VERTEX_SHADER = jsl.find("#VERTEX_SHADER"); + int loc_END_VERTEX_SHADER = jsl.find("#END_VERTEX_SHADER"); + int loc_FRAGMENT_SHADER = jsl.find("#FRAGMENT_SHADER"); + int loc_END_FRAGMENT_SHADER = jsl.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. + { + // Compile JSL vertex program. + int start = loc_VERTEX_SHADER + strlen("#VERTEX_SHADER"); + *vertex_shader = jsl.substr(start, loc_END_VERTEX_SHADER - start); + vertex_shader->assign(formatVertexShader(*vertex_shader)); + } + { + // Compile JSL fragment program. + int start = loc_FRAGMENT_SHADER + strlen("#FRAGMENT_SHADER"); + *fragment_shader = jsl.substr(start, loc_END_FRAGMENT_SHADER - start); + fragment_shader->assign(formatFragmentShader(*fragment_shader)); + } + return true; + } + + } // namespace Shaders + } // namespace Graphics +} // namespace JinEngine + +#endif // (jin_graphics) && (jin_graphics & jin_graphics_shader)
\ No newline at end of file |