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