From: Józef Kucia Subject: [PATCH 3/4] wined3d: Implement normals transformation for vertex blending. Message-Id: <1435818408-9494-3-git-send-email-joseph.kucia@gmail.com> Date: Thu, 2 Jul 2015 08:26:47 +0200 --- dlls/wined3d/glsl_shader.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index c3ecb77..335ad23 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -121,7 +121,7 @@ struct glsl_vs_program GLint modelview_matrix_location[MAX_VERTEX_BLENDS]; GLint projection_matrix_location; - GLint normal_matrix_location; + GLint normal_matrix_location[MAX_VERTEX_BLENDS]; GLint texture_matrix_location[MAX_TEXTURES]; GLint material_ambient_location; GLint material_diffuse_location; @@ -1065,14 +1065,17 @@ static BOOL invert_matrix(struct wined3d_matrix *out, struct wined3d_matrix *m) } static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_context *context, - const struct wined3d_state *state, struct glsl_shader_prog_link *prog) + const struct wined3d_state *state, struct glsl_shader_prog_link *prog, int index) { const struct wined3d_gl_info *gl_info = context->gl_info; float mat[3 * 3]; struct wined3d_matrix mv; unsigned int i, j; - get_modelview_matrix(context, state, 0, &mv); + if (prog->vs.normal_matrix_location[index] == -1) + return; + + get_modelview_matrix(context, state, index, &mv); if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_FFP_LIGHTING) invert_matrix_3d(&mv, &mv); else @@ -1084,7 +1087,7 @@ static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_con for (j = 0; j < 3; ++j) mat[i * 3 + j] = (&mv._11)[j * 4 + i]; - GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location, 1, FALSE, mat)); + GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location[index], 1, FALSE, mat)); checkGLcall("glUniformMatrix3fv"); } @@ -1322,7 +1325,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE, &mat._11)); checkGLcall("glUniformMatrix4fv"); - shader_glsl_ffp_vertex_normalmatrix_uniform(context, state, prog); + shader_glsl_ffp_vertex_normalmatrix_uniform(context, state, prog, 0); } if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND) @@ -1337,6 +1340,8 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context get_modelview_matrix(context, state, i, &mat); GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); checkGLcall("glUniformMatrix4fv"); + + shader_glsl_ffp_vertex_normalmatrix_uniform(context, state, prog, i); } } @@ -5600,7 +5605,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct wined3d_string_buffe shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_BLENDS); shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n"); - shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n"); + shader_addline(buffer, "uniform mat3 ffp_normal_matrix[%u];\n", MAX_VERTEX_BLENDS); shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", MAX_TEXTURES); shader_addline(buffer, "uniform struct\n{\n"); @@ -5658,6 +5663,8 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct wined3d_string_buffe } } + shader_addline(buffer, "ffp_attrib_blendweight[%u] = 1.0;\n", settings->vertexblends); + if (settings->transformed) { shader_addline(buffer, "vec4 ec_pos = vec4(ffp_attrib_position.xyz, 1.0);\n"); @@ -5666,7 +5673,6 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct wined3d_string_buffe } else { - shader_addline(buffer, "ffp_attrib_blendweight[%u] = 1.0;\n", settings->vertexblends); for (i = 0; i < settings->vertexblends; ++i) shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i); @@ -5680,12 +5686,15 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct wined3d_string_buffe shader_addline(buffer, "ec_pos /= ec_pos.w;\n"); } - if (!settings->normal) - shader_addline(buffer, "vec3 normal = vec3(0.0);\n"); - else if (settings->normalize) - shader_addline(buffer, "vec3 normal = normalize(ffp_normal_matrix * ffp_attrib_normal);\n"); - else - shader_addline(buffer, "vec3 normal = ffp_normal_matrix * ffp_attrib_normal;\n"); + shader_addline(buffer, "vec3 normal = vec3(0.0);\n"); + if (settings->normal) + { + for (i = 0; i < settings->vertexblends + 1; ++i) + shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (ffp_normal_matrix[%u] * ffp_attrib_normal);\n", i, i); + + if (settings->normalize) + shader_addline(buffer, "normal = normalize(normal);\n"); + } shader_glsl_ffp_vertex_lighting(buffer, settings, legacy_lighting); @@ -6464,7 +6473,11 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); } vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix")); - vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix")); + for (i = 0; i < MAX_VERTEX_BLENDS; i++) + { + string_buffer_sprintf(name, "ffp_normal_matrix[%u]", i); + vs->normal_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer)); + } for (i = 0; i < MAX_TEXTURES; ++i) { string_buffer_sprintf(name, "ffp_texture_matrix[%u]", i); -- 2.3.6