wined3d: Implement spot lights in process_vertices_strided().
Signed-off-by: Paul Gofman <gofmanp@gmail.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1381ca7c5a
commit
8c47f565cf
|
@ -6368,6 +6368,18 @@ static void test_specular_lighting(void)
|
|||
0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
},
|
||||
spot =
|
||||
{
|
||||
sizeof(D3DLIGHT2),
|
||||
D3DLIGHT_SPOT,
|
||||
{{1.0f}, {1.0f}, {1.0f}, {0.0f}},
|
||||
{{0.0f}, {0.0f}, {0.0f}},
|
||||
{{0.0f}, {0.0f}, {1.0f}},
|
||||
100.0f,
|
||||
1.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
M_PI / 12.0f, M_PI / 3.0f
|
||||
},
|
||||
point_side =
|
||||
{
|
||||
sizeof(D3DLIGHT2),
|
||||
|
@ -6419,6 +6431,18 @@ static void test_specular_lighting(void)
|
|||
{320, 360, 0x00090909},
|
||||
{480, 360, 0x00000000},
|
||||
},
|
||||
expected_spot_local[] =
|
||||
{
|
||||
{160, 120, 0x00000000},
|
||||
{320, 120, 0x00020202},
|
||||
{480, 120, 0x00000000},
|
||||
{160, 240, 0x00020202},
|
||||
{320, 240, 0x00fafafa},
|
||||
{480, 240, 0x00020202},
|
||||
{160, 360, 0x00000000},
|
||||
{320, 360, 0x00020202},
|
||||
{480, 360, 0x00000000},
|
||||
},
|
||||
expected_point_far[] =
|
||||
{
|
||||
{160, 120, 0x00000000},
|
||||
|
@ -6454,10 +6478,12 @@ static void test_specular_lighting(void)
|
|||
{
|
||||
{&directional, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)},
|
||||
{&point, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)},
|
||||
{&spot, 30.0f, expected_spot_local, ARRAY_SIZE(expected_spot_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)},
|
||||
{&spot, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)},
|
||||
{&point_far, 0.0f, expected_zero, ARRAY_SIZE(expected_zero)},
|
||||
};
|
||||
|
||||
|
|
|
@ -3296,6 +3296,10 @@ static void init_transformed_lights(struct lights_settings *ls,
|
|||
++ls->point_light_count;
|
||||
break;
|
||||
|
||||
case WINED3D_LIGHT_SPOT:
|
||||
++ls->spot_light_count;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type);
|
||||
continue;
|
||||
|
@ -3343,6 +3347,32 @@ 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_SPOT)
|
||||
continue;
|
||||
|
||||
light = &ls->lights[index];
|
||||
|
||||
wined3d_vec4_transform(&light->position, &light_info->position, &state->transforms[WINED3D_TS_VIEW]);
|
||||
wined3d_vec4_transform(&vec4, &light_info->direction, &state->transforms[WINED3D_TS_VIEW]);
|
||||
light->direction = *(struct wined3d_vec3 *)&vec4;
|
||||
wined3d_vec3_normalise(&light->direction);
|
||||
light->range = light_info->OriginalParms.range;
|
||||
light->falloff = light_info->OriginalParms.falloff;
|
||||
light->c_att = light_info->OriginalParms.attenuation0;
|
||||
light->l_att = light_info->OriginalParms.attenuation1;
|
||||
light->q_att = light_info->OriginalParms.attenuation2;
|
||||
light->cos_htheta = cosf(light_info->OriginalParms.theta / 2.0f);
|
||||
light->cos_hphi = cosf(light_info->OriginalParms.phi / 2.0f);
|
||||
|
||||
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,
|
||||
|
@ -3442,6 +3472,54 @@ static void compute_light(struct wined3d_color *ambient, struct wined3d_color *d
|
|||
&normal_transformed, &position_transformed_normalised, light, ls);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ls->spot_light_count; ++i, ++index)
|
||||
{
|
||||
float t;
|
||||
|
||||
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;
|
||||
}
|
||||
wined3d_vec3_normalise(&dir);
|
||||
t = -wined3d_vec3_dot(&dir, &light->direction);
|
||||
if (t > light->cos_htheta)
|
||||
att = 1.0f;
|
||||
else if (t <= light->cos_hphi)
|
||||
att = 0.0f;
|
||||
else
|
||||
att = powf((t - light->cos_hphi) / (light->cos_htheta - light->cos_hphi), light->falloff);
|
||||
|
||||
t = dst.x * light->c_att + dst.y * light->l_att + dst.z * light->q_att;
|
||||
if (ls->legacy_lighting)
|
||||
att *= t;
|
||||
else
|
||||
att /= t;
|
||||
|
||||
wined3d_color_rgb_mul_add(ambient, &light->ambient, att);
|
||||
|
||||
if (normal)
|
||||
update_light_diffuse_specular(diffuse, specular, &dir, att, material_shininess,
|
||||
&normal_transformed, &position_transformed_normalised, light, ls);
|
||||
}
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
|
|
Loading…
Reference in New Issue