[11/11] ddraw/tests: Add assorted D3D7 DrawPrimitive/visual tests.
Octavian Voicu
octavian.voicu at gmail.com
Mon Nov 7 16:27:14 CST 2011
Similar to the D3D3 tests, except for D3D7 specific features:
- Switch to IDirect3DDevice7 interface.
- Use IDirect3DDevice7::Clear instead of Blt with DDBLT_COLORFILL.
- Use D3DLIGHT7/D3DMATERIAL7 for setting lights and materials.
- Test that D3DDP_DONOTLIGHT is ignored and D3DRENDERSTATE_LIGHTING works.
--
Note that this test uses fullscreen mode and rendering is done directly
on the primary surface. Wine doesn't fully support that yet, so nothing
is visible on the screen.
---
dlls/ddraw/tests/visual.c | 204 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 204 insertions(+), 0 deletions(-)
diff --git a/dlls/ddraw/tests/visual.c b/dlls/ddraw/tests/visual.c
index 49cd23d..1a4ae78 100644
--- a/dlls/ddraw/tests/visual.c
+++ b/dlls/ddraw/tests/visual.c
@@ -1132,6 +1132,209 @@ static void rhw_zero_test(IDirect3DDevice7 *device)
ok(color == 0, "Got color %08x, expected 00000000\n", color);
}
+static void drawprimitive_test(IDirect3DDevice7 *device)
+{
+ enum {
+ BLACK = 0x000000,
+ BLUE = 0x0000ff,
+ GREEN = 0x00ff00,
+ GRAY = 0x808080,
+ YELLOW2 = 0x808000,
+ RED = 0xff0000,
+ YELLOW = 0xffff00,
+ WHITE = 0xffffff,
+ };
+ D3DVERTEX vertices[] = { /* bottom-left corner of screen */
+ /* x y z nx ny nz tu tv */
+ { {-1.f}, {-1.f}, {0.f}, {0.f}, {0.f}, {1.f}, {0.f}, {0.f} },
+ { { 0.f}, {-1.f}, {0.f}, {0.f}, {0.f}, {1.f}, {0.f}, {0.f} },
+ { {-1.f}, { 0.f}, {0.f}, {0.f}, {0.f}, {1.f}, {0.f}, {0.f} },
+ { { 0.f}, { 0.f}, {0.f}, {0.f}, {0.f}, {1.f}, {0.f}, {0.f} }
+ };
+ DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR;
+ struct {
+ D3DVALUE x;
+ D3DVALUE y;
+ D3DVALUE z;
+ D3DVALUE nx;
+ D3DVALUE ny;
+ D3DVALUE nz;
+ D3DCOLOR diffuse;
+ D3DCOLOR specular;
+ } fvfvertices[] = { /* bottom-right corner of screen */
+ /* x y z nx ny nz diff spec */
+ { 0.f, -1.f, 0.f, 0.f, 0.f, 1.f, YELLOW, YELLOW },
+ { 1.f, -1.f, 0.f, 0.f, 0.f, 1.f, YELLOW, YELLOW },
+ { 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, YELLOW, YELLOW },
+ { 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, YELLOW, YELLOW }
+ };
+ D3DLVERTEX lvertices[] = { /* top-left corner of screen */
+ /* x y z ? diff spec tu tv */
+ { {-1.f}, { 0.f}, {0.f}, 0, {GREEN}, {GREEN}, {0.f}, {0.f} },
+ { { 0.f}, { 0.f}, {0.f}, 0, {GREEN}, {GREEN}, {0.f}, {0.f} },
+ { {-1.f}, { 1.f}, {0.f}, 0, {GREEN}, {GREEN}, {0.f}, {0.f} },
+ { { 0.f}, { 1.f}, {0.f}, 0, {GREEN}, {GREEN}, {0.f}, {0.f} }
+ };
+ D3DTLVERTEX tlvertices[] = { /* top-right corner of screen */
+ /* sx sy sz rhw diff spec tu tv */
+ { {320.f}, { 0.f}, {0.f}, {1.f}, {BLUE}, {BLUE}, {0.f}, {0.f} },
+ { {640.f}, { 0.f}, {0.f}, {1.f}, {BLUE}, {BLUE}, {0.f}, {0.f} },
+ { {320.f}, {240.f}, {0.f}, {1.f}, {BLUE}, {BLUE}, {0.f}, {0.f} },
+ { {640.f}, {240.f}, {0.f}, {1.f}, {BLUE}, {BLUE}, {0.f}, {0.f} }
+ };
+ /* Triangles are drawn on the screen as shown below. Number shown in each
+ triangle is the index for the expected[] array bellow.
+ -----------
+ | \ 5| \ 7|
+ |4 \ |6 \ |
+ -----------
+ | \ 1| \ 3|
+ |0 \ |2 \ |
+ ----------- */
+ DWORD expected[] = { WHITE, GRAY, YELLOW, YELLOW2, GREEN, BLACK, BLUE, BLUE };
+ UINT i, x, y, xgrid[] = {1,2,4,5,1,2,4,5}, ygrid[] = {5,4,5,4,2,1,2,1};
+ D3DLIGHT7 light;
+ D3DMATERIAL7 oldmat, mat;
+ HRESULT hr;
+ DWORD oldcull, oldlighting, val, color;
+
+ /* Setup a diffuse directional gray light, perpendicular on the triangles. */
+ memset(&light, 0, sizeof(D3DLIGHT7));
+ light.dltType = D3DLIGHT_DIRECTIONAL;
+ light.dcvDiffuse.r = .5f;
+ light.dcvDiffuse.g = .5f;
+ light.dcvDiffuse.b = .5f;
+ light.dcvDiffuse.a = 1.f;
+ light.dvDirection.x = 0.f;
+ light.dvDirection.y = 0.f;
+ light.dvDirection.z = -1.f;
+ hr = IDirect3DDevice7_SetLight(device, 0, &light);
+ ok(hr == D3D_OK, "SetLight returned: %08x\n", hr);
+ hr = IDirect3DDevice7_LightEnable(device, 0, TRUE);
+ ok(hr == D3D_OK, "LightEnable returned: %08x\n", hr);
+
+ /* Use a material that reflects only diffuse light. */
+ hr = IDirect3DDevice7_GetMaterial(device, &oldmat);
+ ok(hr == D3D_OK, "GetMaterial returned: %08x\n", hr);
+ memset(&mat, 0, sizeof(mat));
+ mat.dcvDiffuse.r = 1.f;
+ mat.dcvDiffuse.g = 1.f;
+ mat.dcvDiffuse.b = 1.f;
+ mat.dcvDiffuse.a = 1.f;
+ hr = IDirect3DDevice7_SetMaterial(device, &mat);
+ ok(hr == D3D_OK, "SetMaterial returned: %08x\n", hr);
+
+ /* Fill entire surface with red. */
+ hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000 | RED, 0.0, 0);
+ ok(hr == D3D_OK, "Clear returned: %08x\n", hr);
+
+ /* Make sure getPixelColor works correctly. */
+ color = getPixelColor(device, 320, 240);
+ ok(color == RED, "getPixelColor returned: %08x\n", color);
+
+ hr = IDirect3DDevice7_BeginScene(device);
+ ok(hr == D3D_OK, "BeginScene returned: %08x\n", hr);
+
+ if (SUCCEEDED(hr)) {
+ /* Don't cull back faces to reduce number of vertices we need to declare. */
+ hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_CULLMODE, &oldcull);
+ ok(hr == D3D_OK, "GetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+
+ /* Make sure COLORVERTEX is enabled and DIFFUSEMATERIALSOURCE is COLOR1. */
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_COLORVERTEX, TRUE);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+
+ /* Disable lighting initially. */
+ hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_LIGHTING, &oldlighting);
+ ok(hr == D3D_OK, "GetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_LIGHTING, &val);
+ ok(hr == D3D_OK, "GetRenderState returned: %08x\n", hr);
+ ok(val == FALSE, "D3DRENDERSTATE_LIGHTING is: %08x\n", val);
+
+ /* Triangle 0 -- D3DFVF_VERTEX (vertices with normals, but without colors). */
+ hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_VERTEX,
+ vertices, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 2 -- custom fvf (vertices with normals and colors). */
+ hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLELIST, fvf,
+ fvfvertices, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 4 -- D3DFVF_LVERTEX. */
+ hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_LVERTEX,
+ lvertices, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 6 -- D3DFVF_TLVERTEX. */
+ hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX,
+ tlvertices, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Enable lighting. */
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_LIGHTING, &val);
+ ok(hr == D3D_OK, "GetRenderState returned: %08x\n", hr);
+ ok(val == TRUE, "D3DRENDERSTATE_LIGHTING is: %08x\n", val);
+
+ /* Triangle 1 -- D3DVT_VERTEX with D3DDP_DONOTLIGHT.
+ IDirect3DDevice7::DrawPrimitive doesn't have the D3DDP_DONOTLIGHT flag,
+ it should be ignored. */
+ hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_VERTEX,
+ vertices + 1, 3, D3DDP_DONOTLIGHT | D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 3 -- custom fvf (vertices with normals and colors) */
+ hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLELIST, fvf,
+ fvfvertices + 1, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 5 -- D3DFVF_LVERTEX.
+ It seems D3D7 still applies lighting calculations to D3DFVF_LVERTEX vertices,
+ rendering them black since they have no normals. */
+ hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_LVERTEX,
+ lvertices + 1, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 7 -- D3DFVF_TLVERTEX.
+ D3DFVF_TLVERTEX vertices bypass lighting calculations and keep their color values. */
+ hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX,
+ tlvertices + 1, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Restore state. */
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_CULLMODE, oldcull);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, oldlighting);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+
+ hr = IDirect3DDevice7_EndScene(device);
+ ok(hr == D3D_OK, "EndScene returned: %08x\n", hr);
+ }
+
+ for (i = 0; i < 8; i++) {
+ /* Split screen using 5x5 grid points and use those points to sample the triangles. */
+ x = xgrid[i] * 640 / 6;
+ y = ygrid[i] * 480 / 6;
+ color = getPixelColor(device, x, y);
+ ok(color_match(color, expected[i], 1), "%d: getPixelColor(%d,%d) returned %08x, expected %08x.\n",
+ i, x, y, color, expected[i]);
+ }
+
+ /* Disable light and restore material to not interfere with other tests. */
+ hr = IDirect3DDevice7_LightEnable(device, 0, FALSE);
+ ok(hr == D3D_OK, "LightEnable returned: %08x\n", hr);
+ hr = IDirect3DDevice7_SetMaterial(device, &oldmat);
+ ok(hr == D3D_OK, "SetMaterial returned: %08x\n", hr);
+}
+
static BOOL D3D1_createObjects(void)
{
WNDCLASS wc = {0};
@@ -4030,6 +4233,7 @@ START_TEST(visual)
alpha_test(Direct3DDevice);
rhw_zero_test(Direct3DDevice);
cubemap_test(Direct3DDevice);
+ drawprimitive_test(Direct3DDevice);
cleanup:
releaseObjects(); /* release DX7 interfaces for other tests */
--
1.7.4.1
More information about the wine-patches
mailing list