From 1381ca7c5a447d122570d80e145f3518e04f64a7 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Tue, 21 May 2019 01:27:36 +0430 Subject: [PATCH] wined3d: Implement point lights in process_vertices_strided(). Signed-off-by: Paul Gofman Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/ddraw/tests/ddraw1.c | 62 +++++++++++++++++++++++++++++++++++++++ dlls/wined3d/device.c | 61 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 22b43c42295..5c9ccba63bf 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -6356,6 +6356,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 { @@ -6374,6 +6407,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}, @@ -6396,7 +6453,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 23aca23d24d..f5b9caadd28 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3292,6 +3292,10 @@ static void init_transformed_lights(struct lights_settings *ls, ++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; @@ -3319,6 +3323,26 @@ static void init_transformed_lights(struct lights_settings *ls, light->specular = light_info->OriginalParms.specular; ++index; } + + for (i = 0; i < light_count; ++i) + { + light_info = lights[i]; + if (light_info->OriginalParms.type != WINED3D_LIGHT_POINT) + continue; + + light = &ls->lights[index]; + + wined3d_vec4_transform(&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, @@ -3353,7 +3377,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 att; wined3d_vec4_transform(&position_transformed, position, &ls->modelview_matrix); position_transformed_normalised = *(const struct wined3d_vec3 *)&position_transformed; @@ -3381,6 +3407,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_normalised, 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; + + wined3d_color_rgb_mul_add(ambient, &light->ambient, att); + if (normal) + { + wined3d_vec3_normalise(&dir); + update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess, + &normal_transformed, &position_transformed_normalised, light, ls); + } + } } /* Context activation is done by the caller. */