From: Mikko Rasa Date: Sun, 7 Nov 2021 14:12:11 +0000 (+0200) Subject: Fix GLSL matrix construction from individual elements X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=e1dacd64ec555d7344d32a9c11e785f1dc3d0929 Fix GLSL matrix construction from individual elements --- diff --git a/source/glsl/resolve.cpp b/source/glsl/resolve.cpp index eb99bec2..406d7780 100644 --- a/source/glsl/resolve.cpp +++ b/source/glsl/resolve.cpp @@ -972,6 +972,11 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) { unsigned column_count = basic->size&0xFFFF; unsigned row_count = basic->size>>16; + + vector > columns; + columns.reserve(column_count); + bool changed_columns = false; + if(call.arguments.size()==1) { /* A matrix can be constructed from a single element or another @@ -994,8 +999,6 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) current_block->body.insert(insert_point, temporary); // Create expressions to build each column. - vector > columns; - columns.reserve(column_count); for(unsigned j=0; j ref = new VariableReference; @@ -1016,13 +1019,7 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) truncate_vector(columns.back(), row_count); } - call.arguments.resize(column_count); - copy(columns.begin(), columns.end(), call.arguments.begin()); - - /* Let VariableResolver process the new nodes and finish - resolving the constructor on the next pass. */ - r_any_resolved = true; - return; + changed_columns = true; } else return; @@ -1031,9 +1028,6 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) { /* Construct a matrix from individual components in column-major order. Arguments must align at column boundaries. */ - vector > columns; - columns.reserve(column_count); - vector > column_args; column_args.reserve(row_count); unsigned column_component_count = 0; @@ -1067,11 +1061,24 @@ void ExpressionResolver::visit_constructor(FunctionCall &call) else if(column_component_count>row_count) // Argument alignment mismatch. return; + + changed_columns = true; } } } else return; + + if(changed_columns) + { + call.arguments.resize(column_count); + copy(columns.begin(), columns.end(), call.arguments.begin()); + + /* Let VariableResolver process the new nodes and finish + resolving the constructor on the next pass. */ + r_any_resolved = true; + return; + } } else return; diff --git a/tests/glsl/matrix_from_elements.glsl b/tests/glsl/matrix_from_elements.glsl new file mode 100644 index 00000000..42b16556 --- /dev/null +++ b/tests/glsl/matrix_from_elements.glsl @@ -0,0 +1,31 @@ +uniform Transform +{ + vec3 translation; + float rotation; +}; + +#pragma MSP stage(vertex) +layout(location=0) in vec2 position; +void main() +{ + float c = cos(rotation); + float s = sin(rotation); + mat3 m = mat3(c, s, 0.0, -s, c, 0.0, translation); + gl_Position = vec4((m*vec3(position, 1.0)).xy, 0.0, 1.0); +} + +/* Expected output: vertex +layout(binding=48) uniform Transform +{ + vec3 translation; + float rotation; +}; +layout(location=0) in vec2 position; +void main() +{ + float c = cos(rotation); + float s = sin(rotation); + + gl_Position = vec4((mat3(vec3(c, s, 0.0), vec3(-s, c, 0.0), translation)*vec3(position, 1.0)).xy, 0.0, 1.0); +} +*/