]> git.tdb.fi Git - libs/gl.git/commitdiff
Add GLSL keywords for overriding functions
authorMikko Rasa <tdb@tdb.fi>
Sat, 13 Mar 2021 14:02:41 +0000 (16:02 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sat, 13 Mar 2021 14:14:51 +0000 (16:14 +0200)
Overriding with a plain redefinition is now deprecated.

shaderlib/common.glsl
shaderlib/cooktorrance.glsl
shaderlib/phong.glsl
shaderlib/shadow.glsl
source/glsl/generate.cpp
source/glsl/parser.cpp
source/glsl/syntax.cpp
source/glsl/syntax.h
tests/glsl/function_override.glsl [new file with mode: 0644]

index eb191e45dc7f6e03ce31473b81eba73449241c40..9e794f1d2c17eca99c48f847bf0d91ba96235ac1 100644 (file)
@@ -4,22 +4,22 @@ import shadow;
 layout(constant_id=auto) const bool use_normal_map = false;
 
 #pragma MSP stage(vertex)
 layout(constant_id=auto) const bool use_normal_map = false;
 
 #pragma MSP stage(vertex)
-vec4 get_vertex_position()
+virtual vec4 get_vertex_position()
 {
        return vertex;
 }
 
 {
        return vertex;
 }
 
-vec3 get_vertex_normal()
+virtual vec3 get_vertex_normal()
 {
        return normal;
 }
 
 {
        return normal;
 }
 
-vec4 transform_position(vec4 pos)
+virtual vec4 transform_position(vec4 pos)
 {
        return eye_obj_matrix*pos;
 }
 
 {
        return eye_obj_matrix*pos;
 }
 
-vec3 transform_normal(vec3 nor)
+virtual vec3 transform_normal(vec3 nor)
 {
        return eye_obj_normal_matrix*nor;
 }
 {
        return eye_obj_normal_matrix*nor;
 }
@@ -52,7 +52,7 @@ void standard_transform()
        shadow_transform(eye_vertex);
 }
 
        shadow_transform(eye_vertex);
 }
 
-void custom_transform()
+virtual void custom_transform()
 {
 }
 
 {
 }
 
@@ -64,7 +64,7 @@ void main()
 }
 
 #pragma MSP stage(fragment)
 }
 
 #pragma MSP stage(fragment)
-vec3 get_fragment_normal()
+virtual vec3 get_fragment_normal()
 {
        if(use_normal_map)
                return normalize(texture(normal_map, texcoord.xy).xyz*2.0-1.0);
 {
        if(use_normal_map)
                return normalize(texture(normal_map, texcoord.xy).xyz*2.0-1.0);
@@ -72,12 +72,12 @@ vec3 get_fragment_normal()
                return vec3(0.0, 0.0, 1.0);
 }
 
                return vec3(0.0, 0.0, 1.0);
 }
 
-vec4 get_environment_sample(vec3 direction)
+virtual vec4 get_environment_sample(vec3 direction)
 {
        return texture(environment_map, direction);
 }
 
 {
        return texture(environment_map, direction);
 }
 
-vec3 get_reflection(vec3 normal, vec3 look)
+virtual vec3 get_reflection(vec3 normal, vec3 look)
 {
        vec3 reflect_dir = reflect(look, normal);
        if(use_normal_map)
 {
        vec3 reflect_dir = reflect(look, normal);
        if(use_normal_map)
index 89b4c99c3156db1f98aa88b37436b915df9cf008..c866058de4dbd0c6dd06fd7b28ad72c25f5b7c44 100644 (file)
@@ -12,7 +12,7 @@ layout(constant_id=auto) const bool use_emission_map = false;
 const float PI = 3.1415926535;
 
 #pragma MSP stage(fragment)
 const float PI = 3.1415926535;
 
 #pragma MSP stage(fragment)
-vec4 get_base_color()
+virtual vec4 get_base_color()
 {
        if(use_base_color_map)
                return texture(base_color_map, texcoord.xy);
 {
        if(use_base_color_map)
                return texture(base_color_map, texcoord.xy);
@@ -20,7 +20,7 @@ vec4 get_base_color()
                return pbr_material.base_color;
 }
 
                return pbr_material.base_color;
 }
 
-float get_metalness_value()
+virtual float get_metalness_value()
 {
        if(use_metalness_map)
                return texture(metalness_map, texcoord.xy).r;
 {
        if(use_metalness_map)
                return texture(metalness_map, texcoord.xy).r;
@@ -28,7 +28,7 @@ float get_metalness_value()
                return pbr_material.metalness;
 }
 
                return pbr_material.metalness;
 }
 
-float get_roughness_value()
+virtual float get_roughness_value()
 {
        if(use_roughness_map)
                return texture(roughness_map, texcoord.xy).r;
 {
        if(use_roughness_map)
                return texture(roughness_map, texcoord.xy).r;
@@ -36,7 +36,7 @@ float get_roughness_value()
                return pbr_material.roughness;
 }
 
                return pbr_material.roughness;
 }
 
-float get_occlusion_value()
+virtual float get_occlusion_value()
 {
        if(use_occlusion_map)
                return texture(occlusion_map, texcoord.xy).r;
 {
        if(use_occlusion_map)
                return texture(occlusion_map, texcoord.xy).r;
@@ -44,7 +44,7 @@ float get_occlusion_value()
                return 1.0;
 }
 
                return 1.0;
 }
 
-vec3 get_emission_color()
+virtual vec3 get_emission_color()
 {
        if(use_emission_map)
                return texture(emission_map, texcoord.xy).rgb;
 {
        if(use_emission_map)
                return texture(emission_map, texcoord.xy).rgb;
index 56fa68c7767e1264d2a170baa4931e69ae8c0482..f9d8d1e72b971827401575a567fc7ba38f3943a9 100644 (file)
@@ -14,7 +14,7 @@ layout(constant_id=auto) const bool use_sky = false;
 layout(constant_id=auto) const bool use_fog = false;
 
 #pragma MSP stage(fragment)
 layout(constant_id=auto) const bool use_fog = false;
 
 #pragma MSP stage(fragment)
-vec4 get_diffuse_color()
+virtual vec4 get_diffuse_color()
 {
        if(use_diffuse_map)
                return texture(diffuse_map, texcoord.xy);
 {
        if(use_diffuse_map)
                return texture(diffuse_map, texcoord.xy);
@@ -22,7 +22,7 @@ vec4 get_diffuse_color()
                return basic_material.diffuse;
 }
 
                return basic_material.diffuse;
 }
 
-vec3 get_specular_color()
+virtual vec3 get_specular_color()
 {
        if(use_specular_map)
                return texture(specular_map, texcoord.xy).rgb;
 {
        if(use_specular_map)
                return texture(specular_map, texcoord.xy).rgb;
@@ -30,7 +30,7 @@ vec3 get_specular_color()
                return basic_material.specular.rgb;
 }
 
                return basic_material.specular.rgb;
 }
 
-float get_shininess_value()
+virtual float get_shininess_value()
 {
        if(use_shininess_map)
                return texture(shininess_map, texcoord.xy).r*255.0;
 {
        if(use_shininess_map)
                return texture(shininess_map, texcoord.xy).r*255.0;
@@ -38,7 +38,7 @@ float get_shininess_value()
                return basic_material.shininess;
 }
 
                return basic_material.shininess;
 }
 
-vec3 get_emission_color()
+virtual vec3 get_emission_color()
 {
        if(use_emission_map)
                return texture(emission_map, texcoord.xy).rgb;
 {
        if(use_emission_map)
                return texture(emission_map, texcoord.xy).rgb;
@@ -46,7 +46,7 @@ vec3 get_emission_color()
                return basic_material.emission.rgb;
 }
 
                return basic_material.emission.rgb;
 }
 
-float get_reflectivity_value()
+virtual float get_reflectivity_value()
 {
        if(use_reflectivity_map)
                return texture(reflectivity_map, texcoord.xy).r;
 {
        if(use_reflectivity_map)
                return texture(reflectivity_map, texcoord.xy).r;
index d751b460778af84155e127b828d21c6f4f614d33..6f4acd2786a6319c242d9ff8300a00ecc535d0a7 100644 (file)
@@ -9,7 +9,7 @@ void shadow_transform(vec4 eye_vertex)
 }
 
 #pragma MSP stage(fragment)
 }
 
 #pragma MSP stage(fragment)
-float get_shadow_factor(int index)
+virtual float get_shadow_factor(int index)
 {
        if(use_shadow_map)
        {
 {
        if(use_shadow_map)
        {
index c670bc1a814ee1002eac71285c9002fe568c1968..2ff751946528f75e2a39f6a512565231ed10ce8c 100644 (file)
@@ -986,6 +986,15 @@ void FunctionResolver::visit(FunctionDeclaration &func)
        vector<FunctionDeclaration *> &decls = declarations[key];
        if(func.definition==&func)
        {
        vector<FunctionDeclaration *> &decls = declarations[key];
        if(func.definition==&func)
        {
+               if(stage_decl && stage_decl->definition)
+               {
+                       if(!func.overrd)
+                               stage->diagnostics.push_back(Diagnostic(Diagnostic::WARN, func.source, func.line,
+                                       format("Overriding function '%s' without the override keyword is deprecated", key)));
+                       if(!stage_decl->definition->virtua)
+                               stage->diagnostics.push_back(Diagnostic(Diagnostic::WARN, func.source, func.line,
+                                       format("Overriding function '%s' not declared as virtual is deprecated", key)));
+               }
                stage_decl = &func;
 
                // Set all previous declarations to use this definition.
                stage_decl = &func;
 
                // Set all previous declarations to use this definition.
index 0c3a5e35a57a35033024989aa96076b06bd141cd..31f9fcb65cc7ffe4da48cacd8cc41e0c7787dba5 100644 (file)
@@ -294,6 +294,8 @@ RefPtr<Statement> Parser::parse_global_declaration()
        }
        else if(is_qualifier(token))
                return parse_variable_declaration();
        }
        else if(is_qualifier(token))
                return parse_variable_declaration();
+       else if(token=="virtual")
+               return parse_function_declaration();
        else if(is_type(token))
        {
                if(tokenizer.peek_token(2)=="(")
        else if(is_type(token))
        {
                if(tokenizer.peek_token(2)=="(")
@@ -750,6 +752,7 @@ RefPtr<FunctionDeclaration> Parser::parse_function_declaration()
 {
        RefPtr<FunctionDeclaration> func = create_node<FunctionDeclaration>();
 
 {
        RefPtr<FunctionDeclaration> func = create_node<FunctionDeclaration>();
 
+       func->virtua = check("virtual");
        func->return_type = expect_type();
        func->name = expect_identifier();
        tokenizer.expect("(");
        func->return_type = expect_type();
        func->name = expect_identifier();
        tokenizer.expect("(");
@@ -768,6 +771,8 @@ RefPtr<FunctionDeclaration> Parser::parse_function_declaration()
        }
        tokenizer.expect(")");
 
        }
        tokenizer.expect(")");
 
+       func->overrd = check("override");
+
        string token = tokenizer.peek_token();
        if(token=="{")
        {
        string token = tokenizer.peek_token();
        if(token=="{")
        {
index 11a099b5ad3175e94b82f8a75b2877ec5e07c5a9..025af2710bb55da807fb686b6876eaef41d4ce22 100644 (file)
@@ -400,6 +400,8 @@ void InterfaceBlock::visit(NodeVisitor &visitor)
 
 
 FunctionDeclaration::FunctionDeclaration():
 
 
 FunctionDeclaration::FunctionDeclaration():
+       virtua(false),
+       overrd(false),
        definition(0),
        return_type_declaration(0)
 { }
        definition(0),
        return_type_declaration(0)
 { }
@@ -409,6 +411,8 @@ FunctionDeclaration::FunctionDeclaration(const FunctionDeclaration &other):
        return_type(other.return_type),
        name(other.name),
        parameters(other.parameters),
        return_type(other.return_type),
        name(other.name),
        parameters(other.parameters),
+       virtua(other.virtua),
+       overrd(other.overrd),
        body(other.body),
        signature(other.signature),
        definition(other.definition==&other ? this : 0),
        body(other.body),
        signature(other.signature),
        definition(other.definition==&other ? this : 0),
index 86972869f2fe03ed2ebdce4bf47efe4e98d1aa5b..81fd6b4f6390050e0312aee3b2d04983e55217e4 100644 (file)
@@ -458,6 +458,8 @@ struct FunctionDeclaration: Statement
        std::string return_type;
        std::string name;
        NodeArray<VariableDeclaration> parameters;
        std::string return_type;
        std::string name;
        NodeArray<VariableDeclaration> parameters;
+       bool virtua;
+       bool overrd;
        Block body;
 
        std::string signature;
        Block body;
 
        std::string signature;
diff --git a/tests/glsl/function_override.glsl b/tests/glsl/function_override.glsl
new file mode 100644 (file)
index 0000000..c7e64d5
--- /dev/null
@@ -0,0 +1,22 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+virtual float get_scale()
+{
+       return 1.0;
+}
+int main()
+{
+       gl_Position = position*get_scale();
+}
+float get_scale() override
+{
+       return 2.0;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+int main()
+{
+       gl_Position = position*2.0;
+}
+*/