Don't use it unless we have a specular color in the vertex attributes, but allow it if there's no diffuse color.
Signed-off-by: Stefan Dösinger stefan@codeweavers.com --- dlls/wined3d/utils.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 937c1bc0df6..ccf5b846efc 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5854,6 +5854,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_d3d_info *d3d_info = context->d3d_info; unsigned int coord_idx, i; + BOOL has_diffuse, has_specular;
memset(settings, 0, sizeof(*settings));
@@ -5911,12 +5912,38 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, settings->point_size = state->gl_primitive_type == GL_POINTS; settings->per_vertex_point_size = !!(si->use_map & 1u << WINED3D_FFP_PSIZE);
- if (state->render_states[WINED3D_RS_COLORVERTEX] && (si->use_map & (1u << WINED3D_FFP_DIFFUSE))) + has_diffuse = si->use_map & (1u << WINED3D_FFP_DIFFUSE); + has_specular = si->use_map & (1u << WINED3D_FFP_SPECULAR); + + if (state->render_states[WINED3D_RS_COLORVERTEX] && (has_diffuse || has_specular)) { - settings->diffuse_source = state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE]; - settings->emissive_source = state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE]; - settings->ambient_source = state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE]; - settings->specular_source = state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]; + if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1 && has_diffuse) + settings->diffuse_source = WINED3D_MCS_COLOR1; + else if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR2 && has_specular) + settings->diffuse_source = WINED3D_MCS_COLOR2; + else + settings->diffuse_source = WINED3D_MCS_MATERIAL; + + if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1 && has_diffuse) + settings->emissive_source = WINED3D_MCS_COLOR1; + else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR2 && has_specular) + settings->emissive_source = WINED3D_MCS_COLOR2; + else + settings->emissive_source = WINED3D_MCS_MATERIAL; + + if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1 && has_diffuse) + settings->ambient_source = WINED3D_MCS_COLOR1; + else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR2 && has_specular) + settings->ambient_source = WINED3D_MCS_COLOR2; + else + settings->ambient_source = WINED3D_MCS_MATERIAL; + + if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1 && has_diffuse) + settings->specular_source = WINED3D_MCS_COLOR1; + else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR2 && has_specular) + settings->specular_source = WINED3D_MCS_COLOR2; + else + settings->specular_source = WINED3D_MCS_MATERIAL; } else {
Signed-off-by: Stefan Dösinger stefan@codeweavers.com --- dlls/d3d9/tests/visual.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index b36c1890392..4be84a92f02 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -24027,6 +24027,118 @@ done: DestroyWindow(window); }
+static void test_color_vertex(void) +{ + IDirect3D9 *d3d; + IDirect3DDevice9 *device; + D3DCOLOR color; + ULONG refcount; + HWND window; + HRESULT hr; + D3DMATERIAL9 material; + unsigned int i; + + /* The idea here is to set up ambient light parameters in a way that the ambient color from the + * material is just passed through. The emissive color is just passed through anyway. The sum of + * ambient + emissive should allow deduction of where the material color came from. + * + * Note that in cases without a D3DFVF_DIFFUSE flag the first color value in the struct will be + * fed into the specular vertex color slot. */ + static const struct + { + DWORD fvf, color_vertex, ambient, emissive, result; + } + tests[] = + { + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, FALSE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0}, + + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ffff00}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x0000ff80}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR1, 0x00ff0000}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR2, D3DMCS_COLOR2, 0x0000ff00}, + + {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0080}, + {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x000000c0}, + {D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x00ff0080}, + {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0040}, + {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040}, + {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR2, D3DMCS_MATERIAL, 0x000000c0}, + + {0, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0}, + }; + + static const struct + { + struct vec3 position; + DWORD diffuse; + DWORD specular; + } + quad[] = + { + {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + {{ 1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + {{ 1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + }; + + window = create_window(); + ok(!!window, "Failed to create a window.\n"); + + d3d = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + if (!(device = create_device(d3d, window, window, TRUE))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + IDirect3D9_Release(d3d); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_AMBIENT, 0xffffffff); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + + memset(&material, 0, sizeof(material)); + material.Ambient.b = 0.5; + material.Emissive.b = 0.25; + hr = IDirect3DDevice9_SetMaterial(device, &material); + ok(SUCCEEDED(hr), "Failed to set material, hr %#x\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORVERTEX, tests[i].color_vertex); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_AMBIENTMATERIALSOURCE, tests[i].ambient); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_EMISSIVEMATERIALSOURCE, tests[i].emissive); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | tests[i].fvf); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + + hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0); + ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr); + + hr = IDirect3DDevice9_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0])); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + color = getPixelColor(device, 320, 240); + ok(color_match(color, tests[i].result, 1), + "Expected color 0x%08x for test %u, got 0x%08x.\n", + tests[i].result, i, color); + } + + refcount = IDirect3DDevice9_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + IDirect3D9_Release(d3d); + DestroyWindow(window); +} + START_TEST(visual) { D3DADAPTER_IDENTIFIER9 identifier; @@ -24164,4 +24276,5 @@ START_TEST(visual) test_mvp_software_vertex_shaders(); test_null_format(); test_map_synchronisation(); + test_color_vertex(); }
Signed-off-by: Stefan Dösinger stefan@codeweavers.com --- dlls/d3d8/tests/visual.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+)
diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c index bed70d8a17c..c60af691011 100644 --- a/dlls/d3d8/tests/visual.c +++ b/dlls/d3d8/tests/visual.c @@ -10279,6 +10279,117 @@ done: DestroyWindow(window); }
+static void test_color_vertex(void) +{ + IDirect3D8 *d3d; + IDirect3DDevice8 *device; + D3DCOLOR color; + ULONG refcount; + HWND window; + HRESULT hr; + D3DMATERIAL8 material; + unsigned int i; + + /* The idea here is to set up ambient light parameters in a way that the ambient color from the + * material is just passed through. The emissive color is just passed through anyway. The sum of + * ambient + emissive should allow deduction of where the material color came from. + * + * Note that in cases without a D3DFVF_DIFFUSE flag the first color value in the struct will be + * fed into the specular vertex color slot. */ + static const struct + { + DWORD fvf, color_vertex, ambient, emissive, result; + } + tests[] = + { + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, FALSE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0}, + + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ffff00}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x0000ff80}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR1, 0x00ff0000}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR2, D3DMCS_COLOR2, 0x0000ff00}, + + {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0080}, + {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x000000c0}, + {D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x00ff0080}, + {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0040}, + {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040}, + {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR2, D3DMCS_MATERIAL, 0x000000c0}, + + {0, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0}, + }; + static const struct + { + struct vec3 position; + DWORD diffuse; + DWORD specular; + } + quad[] = + { + {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + {{ 1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + {{ 1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + }; + + window = create_window(); + ok(!!window, "Failed to create a window.\n"); + + d3d = Direct3DCreate8(D3D_SDK_VERSION); + ok(!!d3d, "Failed to create a D3D object.\n"); + if (!(device = create_device(d3d, window, window, TRUE))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + IDirect3D8_Release(d3d); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_AMBIENT, 0xffffffff); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + + memset(&material, 0, sizeof(material)); + material.Ambient.b = 0.5; + material.Emissive.b = 0.25; + hr = IDirect3DDevice8_SetMaterial(device, &material); + ok(SUCCEEDED(hr), "Failed to set material, hr %#x\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORVERTEX, tests[i].color_vertex); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_AMBIENTMATERIALSOURCE, tests[i].ambient); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice8_SetRenderState(device, D3DRS_EMISSIVEMATERIALSOURCE, tests[i].emissive); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | tests[i].fvf); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + + hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0); + ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr); + + hr = IDirect3DDevice8_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0])); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice8_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + color = getPixelColor(device, 320, 240); + ok(color_match(color, tests[i].result, 1), + "Expected color 0x%08x for test %u, got 0x%08x.\n", + tests[i].result, i, color); + } + + refcount = IDirect3DDevice8_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + IDirect3D8_Release(d3d); + DestroyWindow(window); +} + START_TEST(visual) { D3DADAPTER_IDENTIFIER8 identifier; @@ -10352,4 +10463,5 @@ START_TEST(visual) test_drawindexedprimitiveup(); test_map_synchronisation(); test_viewport(); + test_color_vertex(); }
A ddraw4 version is on my TODO list. ddraw1 and ddraw2 cannot use lighting and per-vertex color at the same time due to the predefined D3D*VERTEX structs. ddraw4 can, and it has D3DLIGHTSTATE_COLORVERTEX, but the material source states are missing. I assume that one or more of the material properties then track the vertex color, but I have to find out which.
Signed-off-by: Stefan Dösinger stefan@codeweavers.com --- dlls/ddraw/tests/ddraw7.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 35a45c03456..bf34962f853 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -14267,6 +14267,138 @@ static void test_viewport(void) DestroyWindow(window); }
+static void test_color_vertex(void) +{ + IDirectDrawSurface7 *rt; + IDirect3DDevice7 *device; + unsigned int i; + ULONG refcount; + HWND window; + HRESULT hr; + D3DMATERIAL7 material; + D3DCOLOR color; + + static struct + { + struct vec3 position; + DWORD diffuse; + DWORD specular; + } + quad_2c[] = + { + {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + {{ 1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + {{ 1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00}, + }; + static struct + { + struct vec3 position; + DWORD color; + } + quad_1c[] = + { + {{-1.0f, -1.0f, 0.0f}, 0xffff0000}, + {{-1.0f, 1.0f, 0.0f}, 0xffff0000}, + {{ 1.0f, -1.0f, 0.0f}, 0xffff0000}, + {{ 1.0f, 1.0f, 0.0f}, 0xffff0000}, + }; + static struct + { + struct vec3 position; + } + quad_0c[] = + { + {{-1.0f, -1.0f, 0.0f}}, + {{-1.0f, 1.0f, 0.0f}}, + {{ 1.0f, -1.0f, 0.0f}}, + {{ 1.0f, 1.0f, 0.0f}}, + }; + + /* The idea here is to set up ambient light parameters in a way that the ambient color from the + * material is just passed through. The emissive color is just passed through anyway. The sum of + * ambient + emissive should allow deduction of where the material color came from. */ + static const struct + { + DWORD fvf, color_vertex, ambient, emissive, result; + void *vtx; + } + tests[] = + { + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, FALSE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0, quad_2c}, + + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ffff00, quad_2c}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x0000ff80, quad_2c}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040, quad_2c}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR1, 0x00ff0000, quad_2c}, + {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR2, D3DMCS_COLOR2, 0x0000ff00, quad_2c}, + + {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0080, quad_1c}, + {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x000000c0, quad_1c}, + {D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x00ff0080, quad_1c}, + {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0040, quad_1c}, + {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040, quad_1c}, + {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR2, D3DMCS_MATERIAL, 0x000000c0, quad_1c}, + + {0, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0, quad_0c}, + }; + + window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + if (!(device = create_device(window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + DestroyWindow(window); + return; + } + hr = IDirect3DDevice7_GetRenderTarget(device, &rt); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_AMBIENT, 0xffffffff); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + + memset(&material, 0, sizeof(material)); + U3(U1(material).ambient).b = 0.5; + U3(U3(material).emissive).b = 0.25f; + hr = IDirect3DDevice7_SetMaterial(device, &material); + ok(SUCCEEDED(hr), "Failed to set material, hr %#x\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_COLORVERTEX, tests[i].color_vertex); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_AMBIENTMATERIALSOURCE, tests[i].ambient); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_EMISSIVEMATERIALSOURCE, tests[i].emissive); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); + ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr); + + hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0); + ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr); + + hr = IDirect3DDevice7_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr); + hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | tests[i].fvf, + tests[i].vtx, 4, 0); + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDirect3DDevice7_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr); + + color = get_surface_color(rt, 320, 240); + ok(compare_color(color, tests[i].result, 1), + "Expected color 0x%08x for test %u, got 0x%08x.\n", + tests[i].result, i, color); + } + + IDirectDrawSurface7_Release(rt); + refcount = IDirect3DDevice7_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw7) { DDDEVICEIDENTIFIER2 identifier; @@ -14402,4 +14534,5 @@ START_TEST(ddraw7) test_clear(); test_enum_surfaces(); test_viewport(); + test_color_vertex(); }