[PATCH v2 5/7] wined3d: Implement point lights in process_vertices_strided().
Paul Gofman
gofmanp at gmail.com
Fri May 17 03:51:52 CDT 2019
Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
dlls/ddraw/tests/ddraw1.c | 62 +++++++++++++++++++++++++++++++++++++++
dlls/wined3d/device.c | 61 +++++++++++++++++++++++++++++++++++++-
2 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index 7c9721e78a..965b1794b0 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -6355,6 +6355,39 @@ static void test_specular_lighting(void)
{{1.0f}, {1.0f}, {1.0f}, {0.0f}},
{{0.0f}, {0.0f}, {0.0f}},
{{0.0f}, {0.0f}, {1.0f}},
+ },
+ point =
+ {
+ sizeof(D3DLIGHT2),
+ D3DLIGHT_POINT,
+ {{1.0f}, {1.0f}, {1.0f}, {0.0f}},
+ {{0.0f}, {0.0f}, {0.0f}},
+ {{0.0f}, {0.0f}, {0.0f}},
+ 100.0f,
+ 0.0f,
+ 0.0f, 0.0f, 1.0f,
+ },
+ point_side =
+ {
+ sizeof(D3DLIGHT2),
+ D3DLIGHT_POINT,
+ {{1.0f}, {1.0f}, {1.0f}, {0.0f}},
+ {{-1.1f}, {0.0f}, {1.1f}},
+ {{0.0f}, {0.0f}, {0.0f}},
+ 100.0f,
+ 0.0f,
+ 1.0f, 0.0f, 0.0f,
+ },
+ point_far =
+ {
+ sizeof(D3DLIGHT2),
+ D3DLIGHT_POINT,
+ {{1.0f}, {1.0f}, {1.0f}, {0.0f}},
+ {{0.0f}, {0.0f}, {0.1f}},
+ {{0.0f}, {0.0f}, {0.0f}},
+ 1.0f,
+ 0.0f,
+ 1.0f, 0.0f, 0.0f,
};
static const struct expected_color
{
@@ -6373,6 +6406,30 @@ static void test_specular_lighting(void)
{320, 360, 0x00717171},
{480, 360, 0x003c3c3c},
},
+ expected_point_local[] =
+ {
+ {160, 120, 0x00000000},
+ {320, 120, 0x00090909},
+ {480, 120, 0x00000000},
+ {160, 240, 0x00090909},
+ {320, 240, 0x00fafafa},
+ {480, 240, 0x00090909},
+ {160, 360, 0x00000000},
+ {320, 360, 0x00090909},
+ {480, 360, 0x00000000},
+ },
+ expected_point_far[] =
+ {
+ {160, 120, 0x00000000},
+ {320, 120, 0x00000000},
+ {480, 120, 0x00000000},
+ {160, 240, 0x00000000},
+ {320, 240, 0x00ffffff},
+ {480, 240, 0x00000000},
+ {160, 360, 0x00000000},
+ {320, 360, 0x00000000},
+ {480, 360, 0x00000000},
+ },
expected_zero[] =
{
{160, 120, 0x00000000},
@@ -6395,7 +6452,12 @@ static void test_specular_lighting(void)
tests[] =
{
{&directional, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)},
+ {&point, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)},
+ {&point_side, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)},
+ {&point_far, 1.0f, expected_point_far, ARRAY_SIZE(expected_point_far)},
{&directional, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)},
+ {&point, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)},
+ {&point_far, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)},
};
D3DMATRIXHANDLE world_handle, view_handle, proj_handle;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 8576012f21..76dcd3b1c6 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3299,6 +3299,9 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win
case WINED3D_LIGHT_DIRECTIONAL:
++ls->directional_light_count;
break;
+ case WINED3D_LIGHT_POINT:
+ ++ls->point_light_count;
+ break;
default:
FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type);
continue;
@@ -3326,6 +3329,26 @@ static void init_transformed_lights(struct lights_settings *ls, const struct win
light->specular = light_info->OriginalParms.specular;
++index;
}
+
+ for (i = 0; i < lights_count; ++i)
+ {
+ light_info = lights[i];
+ if (light_info->OriginalParms.type != WINED3D_LIGHT_POINT)
+ continue;
+
+ light = &ls->lights[index];
+
+ multiply_vector_matrix(&light->position, &light_info->position, &state->transforms[WINED3D_TS_VIEW]);
+ light->range = light_info->OriginalParms.range;
+ light->c_att = light_info->OriginalParms.attenuation0;
+ light->l_att = light_info->OriginalParms.attenuation1;
+ light->q_att = light_info->OriginalParms.attenuation2;
+
+ light->diffuse = light_info->OriginalParms.diffuse;
+ light->ambient = light_info->OriginalParms.ambient;
+ light->specular = light_info->OriginalParms.specular;
+ ++index;
+ }
}
static void update_light_diffuse_specular(struct wined3d_color *diffuse, struct wined3d_color *specular,
@@ -3367,8 +3390,9 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d
struct wined3d_vec3 normal_transformed = {0.0f};
struct wined3d_vec4 position_transformed;
const struct light_transformed *light;
+ struct wined3d_vec3 dir, dst;
unsigned int i, index;
- float rcp_w;
+ float rcp_w, att;
multiply_vector_matrix(&position_transformed, position, &ls->modelview_matrix);
rcp_w = 1.0f / position_transformed.w;
@@ -3399,6 +3423,41 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d
update_light_diffuse_specular(diffuse, specular, &light->direction, 1.0f, material_shininess,
&normal_transformed, &position_transformed_normalized, light, ls);
}
+
+ for (i = 0; i < ls->point_light_count; ++i, ++index)
+ {
+ light = &ls->lights[index];
+ dir.x = light->position.x - position_transformed.x;
+ dir.y = light->position.y - position_transformed.y;
+ dir.z = light->position.z - position_transformed.z;
+
+ dst.z = wined3d_vec3_dot(&dir, &dir);
+ dst.y = sqrtf(dst.z);
+ dst.x = 1.0f;
+ if (ls->legacy_lighting)
+ {
+ dst.y = (light->range - dst.y) / light->range;
+ if (!(dst.y > 0.0f))
+ continue;
+ dst.z = dst.y * dst.y;
+ }
+ else
+ {
+ if (!(dst.y <= light->range))
+ continue;
+ }
+ att = dst.x * light->c_att + dst.y * light->l_att + dst.z * light->q_att;
+ if (!ls->legacy_lighting)
+ att = 1.0f / att;
+
+ madd_color_rgb(ambient, &light->ambient, att);
+ if (normal)
+ {
+ normalize_vec3(&dir, &dir);
+ update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess,
+ &normal_transformed, &position_transformed_normalized, light, ls);
+ }
+ }
}
/* Context activation is done by the caller. */
--
2.21.0
More information about the wine-devel
mailing list