[PATCH 3/4] wined3d: Implement normals transformation for vertex blending.

Józef Kucia joseph.kucia at gmail.com
Thu Jul 2 01:26:47 CDT 2015


---
 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




More information about the wine-patches mailing list