From 859015dce969a0d9ba2bc603d6dbb2685159e393 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 15 Nov 2016 19:09:50 +0200 Subject: [PATCH] Add a builtin module for standard shaders It doesn't support multiple lights as generating the necessary array interfaces through a geometry shader turned out to be rather non-trivial. I plan to add deferred rendering modules with multi-light support later. --- Build | 9 ++ scripts/resgen.py | 41 +++++++ shaderlib/singlepass.glsl | 247 ++++++++++++++++++++++++++++++++++++++ source/resources.cpp | 20 ++- source/resources.h | 5 + 5 files changed, 321 insertions(+), 1 deletion(-) create mode 100755 scripts/resgen.py create mode 100644 shaderlib/singlepass.glsl diff --git a/Build b/Build index ca380f31..fcdb6328 100644 --- a/Build +++ b/Build @@ -29,15 +29,24 @@ package "mspgl" }; }; + generate "RES" + { + in_suffix ".glsl"; + out_suffix ".cpp"; + command "scripts/resgen.py"; + }; + library "mspgl" { source "source"; source "extensions"; + source "shaderlib"; install true; install_map { map "source" "include/msp/gl"; map "extensions" "include/msp/gl/extensions"; + map "shaderlib" "include/msp/gl/resources"; }; }; diff --git a/scripts/resgen.py b/scripts/resgen.py new file mode 100755 index 00000000..16cfbfb9 --- /dev/null +++ b/scripts/resgen.py @@ -0,0 +1,41 @@ +#!/usr/bin/python + +import sys +import os + +def makename(text): + result = "" + for c in text: + if c.isalnum(): + result += c + else: + result += '_' + return result + +def escape(text): + result = "" + for c in text: + if c=='\t': + result += "\\t" + elif c=='\n': + result += "\\n" + elif c=='"': + result += "\\\"" + else: + result += c + return result + +name = makename(os.path.split(sys.argv[1])[1]) +lines = open(sys.argv[1]).readlines() +out = open(sys.argv[2], "w") +out.write("""namespace Msp { +namespace GL { +""") +out.write("extern const char {}_data[] =\n".format(name)) +for l in lines: + out.write("\t\"{}\"\n".format(escape(l))) +out.write("""; + +} // namespace GL +} // namespace Msp +""") diff --git a/shaderlib/singlepass.glsl b/shaderlib/singlepass.glsl new file mode 100644 index 00000000..f8940f7d --- /dev/null +++ b/shaderlib/singlepass.glsl @@ -0,0 +1,247 @@ +struct LightSourceParameters +{ + vec4 position; + vec4 diffuse; + vec4 specular; +}; + +struct MaterialParameters +{ + vec4 ambient; + vec4 diffuse; + vec4 specular; + float shininess; +}; + +struct ClipPlane +{ + vec4 equation; +}; + +uniform mat4 eye_obj_matrix; +uniform mat3 eye_obj_normal_matrix; +uniform Transform +{ + mat4 projection_matrix; +}; + +uniform Material +{ + MaterialParameters material; + float reflectivity; +}; + +const bool use_vertex_color = false; + +const bool use_lighting = false; +const bool use_specular = false; +const bool use_sky = false; +const bool use_fog = false; +uniform Lighting +{ + // Declared as an array for compatibility reasons + LightSourceParameters light_sources[1]; + vec4 ambient_color; + vec4 sky_color; + vec3 eye_sky_dir; + float horizon_limit; + vec4 fog_color; + float fog_density; +}; + +const bool use_diffuse_map = false; +uniform sampler2D diffuse_map; + +const bool use_normal_map = false; +uniform sampler2D normal_map; + +const bool use_shadow_map = false; +uniform sampler2DShadow shadow; +uniform ShadowMap +{ + float shadow_darkness; + mat4 shd_eye_matrix; +}; + +const bool use_reflection = false; +const bool use_environment_map = false; +uniform samplerCube environment; +uniform EnvMap +{ + mat3 env_eye_matrix; +}; + +const int max_clip_planes = 0; +uniform Clipping +{ + ClipPlane clip_planes[max_clip_planes]; +}; + +////// vertex +in vec4 vertex; +in vec4 texcoord; +in vec4 color; +in vec3 normal; +in vec3 tangent; +in vec3 binormal; + +vec4 get_vertex_position() +{ + return vertex; +} + +vec3 get_vertex_normal() +{ + return normal; +} + +void singlepass_transform_and_lighting() +{ + out vec4 eye_vertex = eye_obj_matrix*get_vertex_position(); + gl_Position = projection_matrix*eye_vertex; + + out vec3 eye_normal = eye_obj_normal_matrix*get_vertex_normal(); + vec3 eye_tangent = eye_obj_normal_matrix*tangent; + vec3 eye_binormal = eye_obj_normal_matrix*binormal; + out mat3 eye_tbn_matrix = mat3(eye_tangent, eye_binormal, eye_normal); + + out vec3 incident_dir = normalize(eye_vertex.xyz); + if(use_normal_map) + incident_dir = incident_dir*eye_tbn_matrix; + + vec3 ldir = normalize(light_sources[0].position.xyz-eye_vertex.xyz*light_sources[0].position.w); + if(use_normal_map) + ldir = ldir*eye_tbn_matrix; + out vec3 light_dir = ldir; + + out vec3 tbn_sky_dir = eye_sky_dir*eye_tbn_matrix; + out vec3 shadow_coord = (shd_eye_matrix*eye_vertex).xyz; + out float fog_coord = eye_vertex.z; + + for(int i=0; i().base().suffix(".tex3d").keyword("texture3d"); add_type().base().suffix(".texcb").keyword("texture_cube"); add_type().base().suffix(".tex2da").keyword("texture2d_array"); + + add_source(get_builtins()); +} + +DataFile::BuiltinSource &Resources::get_builtins() +{ + static DataFile::BuiltinSource builtins; + bool init_done = false; + + if(!init_done) + { + builtins.add_object("singlepass.glsl", singlepass_glsl_data); + init_done = true; + } + + return builtins; } void Resources::set_default_texture_filter(TextureFilter tf) @@ -117,7 +135,7 @@ Program *Resources::create_program(const string &name) if(RefPtr io = open_from_sources(name)) { ProgramCompiler compiler; - compiler.compile(*io); + compiler.compile(*io, this); RefPtr program = new Program; compiler.add_shaders(*program); program->link(); diff --git a/source/resources.h b/source/resources.h index 1f3880aa..838b0229 100644 --- a/source/resources.h +++ b/source/resources.h @@ -1,6 +1,7 @@ #ifndef MSP_GL_RESOURCES_H_ #define MSP_GL_RESOURCES_H_ +#include #include #include "texture.h" @@ -26,6 +27,10 @@ private: public: Resources(); +private: + static DataFile::BuiltinSource &get_builtins(); + +public: void set_default_texture_filter(TextureFilter); /** Enables or disables sRGB conversion. If enabled, textures and material -- 2.43.0