Overriding with a plain redefinition is now deprecated.
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;
}
-vec3 get_vertex_normal()
+virtual vec3 get_vertex_normal()
{
return normal;
}
-vec4 transform_position(vec4 pos)
+virtual vec4 transform_position(vec4 pos)
{
return eye_obj_matrix*pos;
}
-vec3 transform_normal(vec3 nor)
+virtual vec3 transform_normal(vec3 nor)
{
return eye_obj_normal_matrix*nor;
}
shadow_transform(eye_vertex);
}
-void custom_transform()
+virtual void custom_transform()
{
}
}
#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);
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);
}
-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)
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);
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;
return pbr_material.metalness;
}
-float get_roughness_value()
+virtual float get_roughness_value()
{
if(use_roughness_map)
return texture(roughness_map, texcoord.xy).r;
return pbr_material.roughness;
}
-float get_occlusion_value()
+virtual float get_occlusion_value()
{
if(use_occlusion_map)
return texture(occlusion_map, texcoord.xy).r;
return 1.0;
}
-vec3 get_emission_color()
+virtual vec3 get_emission_color()
{
if(use_emission_map)
return texture(emission_map, texcoord.xy).rgb;
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);
return basic_material.diffuse;
}
-vec3 get_specular_color()
+virtual vec3 get_specular_color()
{
if(use_specular_map)
return texture(specular_map, texcoord.xy).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;
return basic_material.shininess;
}
-vec3 get_emission_color()
+virtual vec3 get_emission_color()
{
if(use_emission_map)
return texture(emission_map, texcoord.xy).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;
}
#pragma MSP stage(fragment)
-float get_shadow_factor(int index)
+virtual float get_shadow_factor(int index)
{
if(use_shadow_map)
{
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.
}
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)=="(")
{
RefPtr<FunctionDeclaration> func = create_node<FunctionDeclaration>();
+ func->virtua = check("virtual");
func->return_type = expect_type();
func->name = expect_identifier();
tokenizer.expect("(");
}
tokenizer.expect(")");
+ func->overrd = check("override");
+
string token = tokenizer.peek_token();
if(token=="{")
{
FunctionDeclaration::FunctionDeclaration():
+ virtua(false),
+ overrd(false),
definition(0),
return_type_declaration(0)
{ }
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),
std::string return_type;
std::string name;
NodeArray<VariableDeclaration> parameters;
+ bool virtua;
+ bool overrd;
Block body;
std::string signature;
--- /dev/null
+#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;
+}
+*/