[PATCH 4/5] wined3d: Fix specular lighting calculation.
Matteo Bruni
mbruni at codeweavers.com
Sun Apr 9 14:03:38 CDT 2017
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
For bug 41827.
I don't really like the shader_glsl_ffp_vertex_lighting_footer name but I
couldn't think of anything nicer...
dlls/d3d8/tests/visual.c | 59 +++++++++++++++++++++++++++++++++-------------
dlls/d3d9/tests/visual.c | 59 +++++++++++++++++++++++++++++++++-------------
dlls/ddraw/tests/ddraw2.c | 49 +++++++++++++++++++++++++++++---------
dlls/ddraw/tests/ddraw4.c | 51 +++++++++++++++++++++++++++++----------
dlls/ddraw/tests/ddraw7.c | 59 +++++++++++++++++++++++++++++++++-------------
dlls/wined3d/glsl_shader.c | 50 +++++++++++++++------------------------
6 files changed, 225 insertions(+), 102 deletions(-)
diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c
index d314edb..9a1b28c 100644
--- a/dlls/d3d8/tests/visual.c
+++ b/dlls/d3d8/tests/visual.c
@@ -543,6 +543,18 @@ static void test_specular_lighting(void)
1.2f,
0.0f,
0.0f, 0.0f, 1.0f,
+ },
+ point_side =
+ {
+ D3DLIGHT_POINT,
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {1.0f, 1.0f, 1.0f, 0.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {-1.1f, 0.0f, 1.1f},
+ {0.0f, 0.0f, 0.0f},
+ 100.0f,
+ 0.0f,
+ 0.0f, 0.0f, 0.0f,
};
static const struct expected_color
{
@@ -632,30 +644,45 @@ static void test_specular_lighting(void)
{160, 360, 0x00000000},
{320, 360, 0x005a5a5a},
{480, 360, 0x00000000},
+ },
+ expected_point_side[] =
+ {
+ {160, 120, 0x00000000},
+ {320, 120, 0x00000000},
+ {480, 120, 0x00000000},
+ {160, 240, 0x00000000},
+ {320, 240, 0x00000000},
+ {480, 240, 0x00000000},
+ {160, 360, 0x00000000},
+ {320, 360, 0x00000000},
+ {480, 360, 0x00000000},
};
static const struct
{
const D3DLIGHT8 *light;
BOOL local_viewer;
+ float specular_power;
const struct expected_color *expected;
unsigned int expected_count;
}
tests[] =
{
- {&directional, FALSE, expected_directional,
+ {&directional, FALSE, 30.0f, expected_directional,
sizeof(expected_directional) / sizeof(expected_directional[0])},
- {&directional, TRUE, expected_directional_local,
+ {&directional, TRUE, 30.0f, expected_directional_local,
sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
- {&point, FALSE, expected_point,
+ {&point, FALSE, 30.0f, expected_point,
sizeof(expected_point) / sizeof(expected_point[0])},
- {&point, TRUE, expected_point_local,
+ {&point, TRUE, 30.0f, expected_point_local,
sizeof(expected_point_local) / sizeof(expected_point_local[0])},
- {&spot, FALSE, expected_spot,
+ {&spot, FALSE, 30.0f, expected_spot,
sizeof(expected_spot) / sizeof(expected_spot[0])},
- {&spot, TRUE, expected_spot_local,
+ {&spot, TRUE, 30.0f, expected_spot_local,
sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
- {&point_range, FALSE, expected_point_range,
+ {&point_range, FALSE, 30.0f, expected_point_range,
sizeof(expected_point_range) / sizeof(expected_point_range[0])},
+ {&point_side, TRUE, 0.0f, expected_point_side,
+ sizeof(expected_point_side) / sizeof(expected_point_side[0])},
};
IDirect3DDevice8 *device;
D3DMATERIAL8 material;
@@ -724,15 +751,6 @@ static void test_specular_lighting(void)
hr = IDirect3DDevice8_SetVertexShader(device, fvf);
ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
- memset(&material, 0, sizeof(material));
- material.Specular.r = 1.0f;
- material.Specular.g = 1.0f;
- material.Specular.b = 1.0f;
- material.Specular.a = 1.0f;
- material.Power = 30.0f;
- hr = IDirect3DDevice8_SetMaterial(device, &material);
- ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
-
hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
@@ -746,6 +764,15 @@ static void test_specular_lighting(void)
hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
+ memset(&material, 0, sizeof(material));
+ material.Specular.r = 1.0f;
+ material.Specular.g = 1.0f;
+ material.Specular.b = 1.0f;
+ material.Specular.a = 1.0f;
+ material.Power = tests[i].specular_power;
+ hr = IDirect3DDevice8_SetMaterial(device, &material);
+ ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
+
hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 5f96cc3..700960b 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -634,6 +634,18 @@ static void test_specular_lighting(void)
1.2f,
0.0f,
0.0f, 0.0f, 1.0f,
+ },
+ point_side =
+ {
+ D3DLIGHT_POINT,
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {1.0f, 1.0f, 1.0f, 0.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {-1.1f, 0.0f, 1.1f},
+ {0.0f, 0.0f, 0.0f},
+ 100.0f,
+ 0.0f,
+ 0.0f, 0.0f, 0.0f,
};
static const struct expected_color
{
@@ -723,30 +735,45 @@ static void test_specular_lighting(void)
{160, 360, 0x00000000},
{320, 360, 0x005a5a5a},
{480, 360, 0x00000000},
+ },
+ expected_point_side[] =
+ {
+ {160, 120, 0x00000000},
+ {320, 120, 0x00000000},
+ {480, 120, 0x00000000},
+ {160, 240, 0x00000000},
+ {320, 240, 0x00000000},
+ {480, 240, 0x00000000},
+ {160, 360, 0x00000000},
+ {320, 360, 0x00000000},
+ {480, 360, 0x00000000},
};
static const struct
{
const D3DLIGHT9 *light;
BOOL local_viewer;
+ float specular_power;
const struct expected_color *expected;
unsigned int expected_count;
}
tests[] =
{
- {&directional, FALSE, expected_directional,
+ {&directional, FALSE, 30.0f, expected_directional,
sizeof(expected_directional) / sizeof(expected_directional[0])},
- {&directional, TRUE, expected_directional_local,
+ {&directional, TRUE, 30.0f, expected_directional_local,
sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
- {&point, FALSE, expected_point,
+ {&point, FALSE, 30.0f, expected_point,
sizeof(expected_point) / sizeof(expected_point[0])},
- {&point, TRUE, expected_point_local,
+ {&point, TRUE, 30.0f, expected_point_local,
sizeof(expected_point_local) / sizeof(expected_point_local[0])},
- {&spot, FALSE, expected_spot,
+ {&spot, FALSE, 30.0f, expected_spot,
sizeof(expected_spot) / sizeof(expected_spot[0])},
- {&spot, TRUE, expected_spot_local,
+ {&spot, TRUE, 30.0f, expected_spot_local,
sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
- {&point_range, FALSE, expected_point_range,
+ {&point_range, FALSE, 30.0f, expected_point_range,
sizeof(expected_point_range) / sizeof(expected_point_range[0])},
+ {&point_side, TRUE, 0.0f, expected_point_side,
+ sizeof(expected_point_side) / sizeof(expected_point_side[0])},
};
IDirect3DDevice9 *device;
D3DMATERIAL9 material;
@@ -815,15 +842,6 @@ static void test_specular_lighting(void)
hr = IDirect3DDevice9_SetFVF(device, fvf);
ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
- memset(&material, 0, sizeof(material));
- material.Specular.r = 1.0f;
- material.Specular.g = 1.0f;
- material.Specular.b = 1.0f;
- material.Specular.a = 1.0f;
- material.Power = 30.0f;
- hr = IDirect3DDevice9_SetMaterial(device, &material);
- ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
-
hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
@@ -837,6 +855,15 @@ static void test_specular_lighting(void)
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
+ memset(&material, 0, sizeof(material));
+ material.Specular.r = 1.0f;
+ material.Specular.g = 1.0f;
+ material.Specular.b = 1.0f;
+ material.Specular.a = 1.0f;
+ material.Power = tests[i].specular_power;
+ hr = IDirect3DDevice9_SetMaterial(device, &material);
+ ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
+
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index be950d8..59e073b 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -7104,6 +7104,17 @@ static void test_specular_lighting(void)
{{1.0f}, {1.0f}, {1.0f}, {0.0f}},
{{0.5f}, {0.0f}, {-1.0f}},
{{0.0f}, {0.0f}, {0.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,
};
static const struct expected_color
{
@@ -7157,23 +7168,38 @@ static void test_specular_lighting(void)
{160, 360, 0x00050505},
{320, 360, 0x002c2c2c},
{480, 360, 0x006e6e6e},
+ },
+ expected_point_side[] =
+ {
+ {160, 120, 0x00000000},
+ {320, 120, 0x00000000},
+ {480, 120, 0x00000000},
+ {160, 240, 0x00000000},
+ {320, 240, 0x00000000},
+ {480, 240, 0x00000000},
+ {160, 360, 0x00000000},
+ {320, 360, 0x00000000},
+ {480, 360, 0x00000000},
};
static const struct
{
D3DLIGHT2 *light;
+ float specular_power;
const struct expected_color *expected;
unsigned int expected_count;
}
tests[] =
{
- {&directional, expected_directional_local,
+ {&directional, 30.0f, expected_directional_local,
sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
- {&point, expected_point_local,
+ {&point, 30.0f, expected_point_local,
sizeof(expected_point_local) / sizeof(expected_point_local[0])},
- {&spot, expected_spot_local,
+ {&spot, 30.0f, expected_spot_local,
sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
- {¶llelpoint, expected_parallelpoint,
+ {¶llelpoint, 30.0f, expected_parallelpoint,
sizeof(expected_parallelpoint) / sizeof(expected_parallelpoint[0])},
+ {&point_side, 0.0f, expected_point_side,
+ sizeof(expected_point_side) / sizeof(expected_point_side[0])},
};
IDirect3D2 *d3d;
IDirect3DDevice2 *device;
@@ -7257,12 +7283,6 @@ static void test_specular_lighting(void)
background_material = create_diffuse_material(device, 1.0f, 1.0f, 1.0f, 1.0f);
viewport_set_background(device, viewport, background_material);
- material = create_specular_material(device, 1.0f, 1.0f, 1.0f, 1.0f, 30.0f);
- hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle);
- ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
- hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
- ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
-
hr = IDirect3D2_CreateLight(d3d, &light, NULL);
ok(SUCCEEDED(hr), "Failed to create a light object, hr %#x.\n", hr);
hr = IDirect3DViewport2_AddLight(viewport, light);
@@ -7277,6 +7297,12 @@ static void test_specular_lighting(void)
hr = IDirect3DLight_SetLight(light, (D3DLIGHT *)tests[i].light);
ok(SUCCEEDED(hr), "Failed to set light, hr %#x.\n", hr);
+ material = create_specular_material(device, 1.0f, 1.0f, 1.0f, 1.0f, tests[i].specular_power);
+ hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle);
+ ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
+ ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
+
hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
@@ -7298,12 +7324,13 @@ static void test_specular_lighting(void)
tests[i].expected[j].color, tests[i].expected[j].x,
tests[i].expected[j].y, color, i);
}
+
+ destroy_material(material);
}
hr = IDirect3DViewport2_DeleteLight(viewport, light);
ok(SUCCEEDED(hr), "Failed to remove a light from the viewport, hr %#x.\n", hr);
IDirect3DLight_Release(light);
- destroy_material(material);
destroy_material(background_material);
destroy_viewport(device, viewport);
IDirectDrawSurface2_Release(rt);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 2f92a70..90face2 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -4156,6 +4156,17 @@ static void test_specular_lighting(void)
{{1.0f}, {1.0f}, {1.0f}, {0.0f}},
{{0.5f}, {0.0f}, {-1.0f}},
{{0.0f}, {0.0f}, {0.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,
};
static const struct expected_color
{
@@ -4209,11 +4220,24 @@ static void test_specular_lighting(void)
{160, 360, 0x00050505},
{320, 360, 0x002c2c2c},
{480, 360, 0x006e6e6e},
+ },
+ expected_point_side[] =
+ {
+ {160, 120, 0x00000000},
+ {320, 120, 0x00000000},
+ {480, 120, 0x00000000},
+ {160, 240, 0x00000000},
+ {320, 240, 0x00000000},
+ {480, 240, 0x00000000},
+ {160, 360, 0x00000000},
+ {320, 360, 0x00000000},
+ {480, 360, 0x00000000},
};
static const struct
{
D3DLIGHT2 *light;
BOOL local_viewer;
+ float specular_power;
const struct expected_color *expected;
unsigned int expected_count;
}
@@ -4221,16 +4245,18 @@ static void test_specular_lighting(void)
{
/* D3DRENDERSTATE_LOCALVIEWER does not exist in D3D < 7 (the behavior is
* the one you get on newer D3D versions with it set as TRUE). */
- {&directional, FALSE, expected_directional,
+ {&directional, FALSE, 30.0f, expected_directional,
sizeof(expected_directional) / sizeof(expected_directional[0])},
- {&directional, TRUE, expected_directional,
+ {&directional, TRUE, 30.0f, expected_directional,
sizeof(expected_directional) / sizeof(expected_directional[0])},
- {&point, TRUE, expected_point,
+ {&point, TRUE, 30.0f, expected_point,
sizeof(expected_point) / sizeof(expected_point[0])},
- {&spot, TRUE, expected_spot,
+ {&spot, TRUE, 30.0f, expected_spot,
sizeof(expected_spot) / sizeof(expected_spot[0])},
- {¶llelpoint, TRUE, expected_parallelpoint,
+ {¶llelpoint, TRUE, 30.0f, expected_parallelpoint,
sizeof(expected_parallelpoint) / sizeof(expected_parallelpoint[0])},
+ {&point_side, TRUE, 0.0f, expected_point_side,
+ sizeof(expected_point_side) / sizeof(expected_point_side[0])},
};
IDirect3D3 *d3d;
IDirect3DDevice3 *device;
@@ -4310,12 +4336,6 @@ static void test_specular_lighting(void)
hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
- material = create_specular_material(device, 1.0f, 1.0f, 1.0f, 1.0f, 30.0f);
- hr = IDirect3DMaterial3_GetHandle(material, device, &mat_handle);
- ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
- hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
- ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
-
hr = IDirect3D3_CreateLight(d3d, &light, NULL);
ok(SUCCEEDED(hr), "Failed to create a light object, hr %#x.\n", hr);
hr = IDirect3DViewport3_AddLight(viewport, light);
@@ -4333,6 +4353,12 @@ static void test_specular_lighting(void)
hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_LOCALVIEWER, tests[i].local_viewer);
ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
+ material = create_specular_material(device, 1.0f, 1.0f, 1.0f, 1.0f, tests[i].specular_power);
+ hr = IDirect3DMaterial3_GetHandle(material, device, &mat_handle);
+ ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
+ ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
+
hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
@@ -4354,12 +4380,13 @@ static void test_specular_lighting(void)
tests[i].expected[j].color, tests[i].expected[j].x,
tests[i].expected[j].y, color, i);
}
+
+ destroy_material(material);
}
hr = IDirect3DViewport3_DeleteLight(viewport, light);
ok(SUCCEEDED(hr), "Failed to remove a light from the viewport, hr %#x.\n", hr);
IDirect3DLight_Release(light);
- destroy_material(material);
IDirect3DViewport3_Release(viewport);
IDirectDrawSurface4_Release(rt);
refcount = IDirect3DDevice3_Release(device);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 6a35cb8..c9248cb 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -3829,6 +3829,18 @@ static void test_specular_lighting(void)
1.2f,
0.0f,
0.0f, 0.0f, 1.0f,
+ },
+ point_side =
+ {
+ D3DLIGHT_POINT,
+ {{0.0f}, {0.0f}, {0.0f}, {0.0f}},
+ {{1.0f}, {1.0f}, {1.0f}, {0.0f}},
+ {{0.0f}, {0.0f}, {0.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,
};
static const struct expected_color
{
@@ -3918,30 +3930,45 @@ static void test_specular_lighting(void)
{160, 360, 0x00000000},
{320, 360, 0x005a5a5a},
{480, 360, 0x00000000},
+ },
+ expected_point_side[] =
+ {
+ {160, 120, 0x00000000},
+ {320, 120, 0x00000000},
+ {480, 120, 0x00000000},
+ {160, 240, 0x00000000},
+ {320, 240, 0x00000000},
+ {480, 240, 0x00000000},
+ {160, 360, 0x00000000},
+ {320, 360, 0x00000000},
+ {480, 360, 0x00000000},
};
static const struct
{
D3DLIGHT7 *light;
BOOL local_viewer;
+ float specular_power;
const struct expected_color *expected;
unsigned int expected_count;
}
tests[] =
{
- {&directional, FALSE, expected_directional,
+ {&directional, FALSE, 30.0f, expected_directional,
sizeof(expected_directional) / sizeof(expected_directional[0])},
- {&directional, TRUE, expected_directional_local,
+ {&directional, TRUE, 30.0f, expected_directional_local,
sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
- {&point, FALSE, expected_point,
+ {&point, FALSE, 30.0f, expected_point,
sizeof(expected_point) / sizeof(expected_point[0])},
- {&point, TRUE, expected_point_local,
+ {&point, TRUE, 30.0f, expected_point_local,
sizeof(expected_point_local) / sizeof(expected_point_local[0])},
- {&spot, FALSE, expected_spot,
+ {&spot, FALSE, 30.0f, expected_spot,
sizeof(expected_spot) / sizeof(expected_spot[0])},
- {&spot, TRUE, expected_spot_local,
+ {&spot, TRUE, 30.0f, expected_spot_local,
sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
- {&point_range, FALSE, expected_point_range,
+ {&point_range, FALSE, 30.0f, expected_point_range,
sizeof(expected_point_range) / sizeof(expected_point_range[0])},
+ {&point_side, TRUE, 0.0f, expected_point_side,
+ sizeof(expected_point_side) / sizeof(expected_point_side[0])},
};
IDirect3DDevice7 *device;
IDirectDrawSurface7 *rt;
@@ -4010,15 +4037,6 @@ static void test_specular_lighting(void)
hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
- memset(&material, 0, sizeof(material));
- U1(U2(material).specular).r = 1.0f;
- U2(U2(material).specular).g = 1.0f;
- U3(U2(material).specular).b = 1.0f;
- U4(U2(material).specular).a = 1.0f;
- U4(material).power = 30.0f;
- hr = IDirect3DDevice7_SetMaterial(device, &material);
- ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
-
hr = IDirect3DDevice7_LightEnable(device, 0, TRUE);
ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SPECULARENABLE, TRUE);
@@ -4032,6 +4050,15 @@ static void test_specular_lighting(void)
hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LOCALVIEWER, tests[i].local_viewer);
ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
+ memset(&material, 0, sizeof(material));
+ U1(U2(material).specular).r = 1.0f;
+ U2(U2(material).specular).g = 1.0f;
+ U3(U2(material).specular).b = 1.0f;
+ U4(U2(material).specular).a = 1.0f;
+ U4(material).power = tests[i].specular_power;
+ hr = IDirect3DDevice7_SetMaterial(device, &material);
+ ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
+
hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index c8a970f..7c657bc 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -7624,6 +7624,19 @@ static const char *shader_glsl_ffp_mcs(enum wined3d_material_color_source mcs, c
}
}
+static void shader_glsl_ffp_vertex_lighting_footer(struct wined3d_string_buffer *buffer,
+ const struct wined3d_ffp_vs_settings *settings, unsigned int idx)
+{
+ shader_addline(buffer, "diffuse += clamp(dot(dir, normal), 0.0, 1.0)"
+ " * ffp_light[%u].diffuse.xyz * att;\n", idx);
+ if (settings->localviewer)
+ shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
+ else
+ shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, -1.0)));\n");
+ shader_addline(buffer, "if (dot(dir, normal) > 0.0 && t > 0.0) specular +="
+ " pow(t, ffp_material.shininess) * ffp_light[%u].specular * att;\n", idx);
+}
+
static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer,
const struct wined3d_ffp_vs_settings *settings, BOOL legacy_lighting)
{
@@ -7676,14 +7689,7 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer
continue;
}
shader_addline(buffer, "dir = normalize(dir);\n");
- shader_addline(buffer, "diffuse += (clamp(dot(dir, normal), 0.0, 1.0)"
- " * ffp_light[%u].diffuse.xyz) * att;\n", idx);
- if (settings->localviewer)
- shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
- else
- shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, -1.0)));\n");
- shader_addline(buffer, "if (t > 0.0) specular += (pow(t, ffp_material.shininess)"
- " * ffp_light[%u].specular) * att;\n", idx);
+ shader_glsl_ffp_vertex_lighting_footer(buffer, settings, i);
if (!legacy_lighting)
shader_addline(buffer, "}\n");
}
@@ -7725,14 +7731,7 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer
shader_addline(buffer, "}\n");
continue;
}
- shader_addline(buffer, "diffuse += (clamp(dot(dir, normal), 0.0, 1.0)"
- " * ffp_light[%u].diffuse.xyz) * att;\n", idx);
- if (settings->localviewer)
- shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
- else
- shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, -1.0)));\n");
- shader_addline(buffer, "if (t > 0.0) specular += (pow(t, ffp_material.shininess)"
- " * ffp_light[%u].specular) * att;\n", idx);
+ shader_glsl_ffp_vertex_lighting_footer(buffer, settings, i);
if (!legacy_lighting)
shader_addline(buffer, "}\n");
}
@@ -7742,17 +7741,9 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer
shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz;\n", idx);
if (!settings->normal)
continue;
+ shader_addline(buffer, "att = 1.0;\n");
shader_addline(buffer, "dir = normalize(ffp_light[%u].direction.xyz);\n", idx);
- shader_addline(buffer, "diffuse += clamp(dot(dir, normal), 0.0, 1.0)"
- " * ffp_light[%u].diffuse.xyz;\n", idx);
- /* TODO: In the non-local viewer case the halfvector is constant
- * and could be precomputed and stored in a uniform. */
- if (settings->localviewer)
- shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
- else
- shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, -1.0)));\n");
- shader_addline(buffer, "if (t > 0.0) specular += pow(t, ffp_material.shininess)"
- " * ffp_light[%u].specular;\n", idx);
+ shader_glsl_ffp_vertex_lighting_footer(buffer, settings, i);
}
for (i = 0; i < settings->parallel_point_light_count; ++i, ++idx)
@@ -7760,12 +7751,9 @@ static void shader_glsl_ffp_vertex_lighting(struct wined3d_string_buffer *buffer
shader_addline(buffer, "ambient += ffp_light[%u].ambient.xyz;\n", idx);
if (!settings->normal)
continue;
+ shader_addline(buffer, "att = 1.0;\n");
shader_addline(buffer, "dir = normalize(ffp_light[%u].position.xyz);\n", idx);
- shader_addline(buffer, "diffuse += clamp(dot(dir, normal), 0.0, 1.0)"
- " * ffp_light[%u].diffuse.xyz;\n", idx);
- shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
- shader_addline(buffer, "if (t > 0.0) specular += pow(t, ffp_material.shininess)"
- " * ffp_light[%u].specular;\n", idx);
+ shader_glsl_ffp_vertex_lighting_footer(buffer, settings, i);
}
shader_addline(buffer, "ffp_varying_diffuse.xyz = %s.xyz * ambient + %s.xyz * diffuse + %s.xyz;\n",
--
2.10.2
More information about the wine-patches
mailing list