From 06817138c8f234e299a137fab94fb956169d21c5 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 12 Aug 2016 23:39:06 +0300 Subject: [PATCH] Support user clip planes in generated shaders --- source/programbuilder.cpp | 21 ++++++++++++++++++--- source/programbuilder.h | 6 ++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/source/programbuilder.cpp b/source/programbuilder.cpp index e1b34d09..f8c3973f 100644 --- a/source/programbuilder.cpp +++ b/source/programbuilder.cpp @@ -110,6 +110,7 @@ const ProgramBuilder::VariableDefinition ProgramBuilder::standard_variables[] = { FRAGMENT, "diffuse_sample", "vec4", "texture2D(diffusemap, texture_coord)", 0 }, { VERTEX, "gl_Position", "vec4", "projection_matrix*eye_vertex", 0 }, + { VERTEX, "gl_ClipDistance[i]", "float", "dot(eye_vertex, clip_planes[i].equation)", "c" }, { VERTEX, "fog_coord", "float", "-eye_vertex.z", 0 }, { VERTEX, "shd_vertex", "vec3", "(shd_eye_matrix*eye_vertex).xyz", 0 }, { VERTEX, "tbn_sky_dir", "vec3", "eye_sky_dir*eye_tbn_matrix", "n" }, @@ -151,9 +152,11 @@ const ProgramBuilder::VariableDefinition ProgramBuilder::standard_variables[] = { UNIFORM, "Lighting::fog_color", "vec4", "gl_Fog.color", 0 }, { UNIFORM, "Lighting::fog_density", "float", "gl_Fog.density", 0 }, { UNIFORM, "Material::material", "MaterialParameters", "gl_FrontMaterial", 0 }, + { UNIFORM, "Clipping::clip_planes", "ClipPlane[MAX_CLIP_PLANES]", 0, 0 }, { TYPE, "LightSourceParameters", "struct { vec4 position; vec4 diffuse; vec4 specular; }", "gl_LightSourceParameters", 0 }, { TYPE, "MaterialParameters", "struct { vec4 ambient; vec4 diffuse; vec4 specular; float shininess; }", "gl_MaterialParameters", 0 }, + { TYPE, "ClipPlane", "struct { vec4 equation; }", 0, 0 }, // Terminator entry { NO_SCOPE, 0, 0, 0, 0 } @@ -272,6 +275,8 @@ void ProgramBuilder::add_shaders(Program &prog) const list variables; list resolved_vars; + if(features.clipping) + variables.push_back(ShaderVariable("gl_ClipDistance[i]")); variables.push_front(ShaderVariable("gl_Position")); variables.push_front(ShaderVariable(features.legacy ? "gl_FragColor" : "frag_color")); @@ -454,6 +459,10 @@ string ProgramBuilder::create_source(const list &variables, Va } } + // The clip distance array must be declared manually to give it a size + if(scope==VERTEX && features.clipping) + source += format("out float gl_ClipDistance[%d];\n", features.max_clip_planes); + source += "void main()\n{\n"; list loop_vars; @@ -490,7 +499,7 @@ string ProgramBuilder::create_source(const list &variables, Va } InterfaceFlags iface = (*j)->get_interface_flags(scope); - if(iface&OUTPUT) + if((iface&(OUTPUT|GOAL))==OUTPUT) { string expr = ((*j)->inlined ? create_expression(**j, "i") : (*j)->resolved_name+"[i]"); source += format("\t\t%c_%s[i] = %s;\n", interfaces[scope], (*j)->resolved_name, expr); @@ -503,7 +512,7 @@ string ProgramBuilder::create_source(const list &variables, Va InterfaceFlags iface = (*i)->get_interface_flags(scope); - if((*i)->array_size>1) + if((*i)->array_size>1 || ((*i)->array_size==1 && (iface&GOAL))) { if((*i)->variable->scope==scope || (iface&OUTPUT)) { @@ -731,7 +740,9 @@ ProgramBuilder::StandardFeatures::StandardFeatures(): specular(false), normalmap(false), shadow(false), - reflection(false) + reflection(false), + clipping(false), + max_clip_planes(1) { if(get_gl_api()==OPENGL_ES2) legacy = !(get_glsl_version()>=Version(3, 0)); @@ -762,6 +773,8 @@ string ProgramBuilder::StandardFeatures::create_flags() const flags += 's'; if(reflection) flags += 'e'; + if(clipping) + flags += 'c'; if(legacy && get_gl_api()==OPENGL) flags += 'g'; @@ -861,6 +874,8 @@ void ProgramBuilder::ShaderVariable::resolve_array(const StandardFeatures &featu { if(array_subscript=="MAX_LIGHTS") array_size = features.max_lights; + else if(array_subscript=="MAX_CLIP_PLANES") + array_size = features.max_clip_planes; else if(isnumrc(array_subscript)) array_size = lexical_cast(array_subscript); else diff --git a/source/programbuilder.h b/source/programbuilder.h index ecd006d5..97a706e0 100644 --- a/source/programbuilder.h +++ b/source/programbuilder.h @@ -98,6 +98,12 @@ public: equivalend in the pipeline. */ bool reflection; + /** Clip primitives against user defined clip planes. */ + bool clipping; + + /** Number of clipping planes to process. */ + unsigned max_clip_planes; + /** Force the use of legacy shaders conforming to GLSL 1.10. Defaults to true if the version of GLSL is less than 1.30, false otherwise. */ bool legacy; -- 2.43.0