[10/11] ddraw/tests: Add assorted D3D3 DrawPrimitive/visual tests.
Octavian Voicu
octavian.voicu at gmail.com
Mon Nov 7 16:27:13 CST 2011
Similar to the D3D2 tests, except for D3D3 specific features:
- Switch to IDirectDrawSurface4, IDirect3DDevice3, IDirect3DMaterial3,
IDirect3DViewport3 interfaces.
- Use D3DLIGHT2 when setting light properties.
- Switch to D3DFVF_ vertex types, but also test D3DVT_ ones.
- Add an extra FVF vertex type with coords, normals, and colors.
- Also test D3DDP_DONOTLIGHT flag (introduced in D3D3).
---
dlls/ddraw/tests/visual.c | 249 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 248 insertions(+), 1 deletions(-)
diff --git a/dlls/ddraw/tests/visual.c b/dlls/ddraw/tests/visual.c
index 8c919b2..49cd23d 100644
--- a/dlls/ddraw/tests/visual.c
+++ b/dlls/ddraw/tests/visual.c
@@ -2724,6 +2724,253 @@ out:
return ret;
}
+static void D3D3_DrawPrimitiveTests(void)
+{
+ 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[] and is_todo[] arrays bellow.
+ -----------
+ | \ 5| \ 7|
+ |4 \ |6 \ |
+ -----------
+ | \ 1| \ 3|
+ |0 \ |2 \ |
+ ----------- */
+ DWORD expected[] = { GRAY, WHITE, YELLOW2, YELLOW, GREEN, GREEN, BLUE, BLUE };
+ BOOL is_todo[] = { TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE };
+ UINT i, x, y, xgrid[] = {1,2,4,5,1,2,4,5}, ygrid[] = {5,4,5,4,2,1,2,1};
+ IDirect3DLight *Direct3DLight;
+ IDirect3DMaterial3 *Direct3DMaterial3;
+ D3DLIGHT2 light;
+ D3DMATERIAL mat;
+ D3DMATERIALHANDLE hMat;
+ DDBLTFX ddbltfx;
+ RECT rc = { 0, 0 };
+ HRESULT hr;
+ DWORD oldcull, oldlighting, val, color;
+
+ /* Fill entire surface with red. */
+ memset(&ddbltfx, 0, sizeof(ddbltfx));
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ U5(ddbltfx).dwFillColor = RED;
+ hr = IDirectDrawSurface4_Blt(Surface4, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
+ ok(hr == DD_OK, "Blt returned: %08x\n", hr);
+
+ /* Make sure getPixelColor works correctly. */
+ color = D3D3_getPixelColor(DirectDraw4, Surface4, 320, 240);
+ ok(color == RED, "getPixelColor returned: %08x\n", color);
+
+ /* Setup a diffuse directional gray light, perpendicular on the triangles. */
+ hr = IDirect3D3_CreateLight(Direct3D3, &Direct3DLight, NULL);
+ ok(hr == D3D_OK, "CreateLight returned: %08x\n", hr);
+ memset(&light, 0, sizeof(light));
+ light.dwSize = sizeof(light);
+ light.dltType = D3DLIGHT_DIRECTIONAL;
+ light.dcvColor.r = .5f;
+ light.dcvColor.g = .5f;
+ light.dcvColor.b = .5f;
+ light.dcvColor.a = 1.f;
+ light.dvDirection.x = 0.f;
+ light.dvDirection.y = 0.f;
+ light.dvDirection.z = -1.f;
+ light.dwFlags = D3DLIGHT_ACTIVE;
+ hr = IDirect3DLight_SetLight(Direct3DLight, (D3DLIGHT *)&light);
+ ok(hr == D3D_OK, "SetLight returned: %08x\n", hr);
+ hr = IDirect3DViewport3_AddLight(Viewport3, Direct3DLight);
+ ok(hr == D3D_OK, "AddLight returned: %08x\n", hr);
+
+ /* Use a material that reflects only diffuse light. */
+ hr = IDirect3D3_CreateMaterial(Direct3D3, &Direct3DMaterial3, NULL);
+ ok(hr == D3D_OK, "CreateMaterial returned: %08x\n", hr);
+ memset(&mat, 0, sizeof(mat));
+ mat.dwSize = sizeof(mat);
+ mat.dcvDiffuse.r = 1.f;
+ mat.dcvDiffuse.g = 1.f;
+ mat.dcvDiffuse.b = 1.f;
+ mat.dcvDiffuse.a = 1.f;
+ hr = IDirect3DMaterial3_SetMaterial(Direct3DMaterial3, &mat);
+ ok(hr == D3D_OK, "SetMaterial returned: %08x\n", hr);
+ hr = IDirect3DMaterial3_GetHandle(Direct3DMaterial3, Direct3DDevice3, &hMat);
+ ok(hr == D3D_OK, "GetHandle returned: %08x\n", hr);
+ hr = IDirect3DDevice3_SetLightState(Direct3DDevice3, D3DLIGHTSTATE_MATERIAL, hMat);
+ ok(hr == D3D_OK, "SetLightState returned: %08x\n", hr);
+ hr = IDirect3DDevice3_SetLightState(Direct3DDevice3, D3DLIGHTSTATE_COLORVERTEX, TRUE);
+ ok(hr == D3D_OK, "SetLightState returned: %08x\n", hr);
+
+ hr = IDirect3DDevice3_BeginScene(Direct3DDevice3);
+ 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 = IDirect3DDevice3_GetRenderState(Direct3DDevice3, D3DRENDERSTATE_CULLMODE, &oldcull);
+ ok(hr == D3D_OK, "GetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+
+ /* IDirect3DDevice3 doesn't have D3DRENDERSTATE_LIGHTING, but get/set seem to work w/o any side effects. */
+ hr = IDirect3DDevice3_GetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, &oldlighting);
+ ok(hr == D3D_OK, "GetRenderState returned: %08x\n", hr);
+ todo_wine ok(oldlighting == 0xffffffff, "D3DRENDERSTATE_LIGHTING is: %08x\n", oldlighting);
+
+ /* Try to disable lighting -- shouldn't have any effect. */
+ hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, FALSE);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice3_GetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, &val);
+ ok(hr == D3D_OK, "GetRenderState returned: %08x\n", hr);
+ ok(val == FALSE, "D3DRENDERSTATE_LIGHTING is: %08x\n", val);
+
+ /* Note: IDirect3DDevice3::DrawPrimitive calls with D3DVT_ vertex types should fail. */
+
+ /* Triangle 0 -- D3DFVF_VERTEX (vertices with normals, but without colors). */
+ hr = IDirect3DDevice3_DrawPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, D3DVT_VERTEX,
+ vertices, 3, D3DDP_WAIT);
+ ok(hr != DDERR_INVALIDPARAMS, "DrawPrimitive returned: %08x\n", hr);
+ hr = IDirect3DDevice3_DrawPrimitive(Direct3DDevice3, 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 = IDirect3DDevice3_DrawPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, fvf,
+ fvfvertices, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 4 -- D3DFVF_LVERTEX. */
+ hr = IDirect3DDevice3_DrawPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, D3DVT_LVERTEX,
+ lvertices, 3, D3DDP_WAIT);
+ ok(hr != DDERR_INVALIDPARAMS, "DrawPrimitive returned: %08x\n", hr);
+ hr = IDirect3DDevice3_DrawPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, D3DFVF_LVERTEX,
+ lvertices, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 6 -- D3DFVF_TLVERTEX. */
+ hr = IDirect3DDevice3_DrawPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, D3DVT_TLVERTEX,
+ tlvertices, 3, D3DDP_WAIT);
+ ok(hr != DDERR_INVALIDPARAMS, "DrawPrimitive returned: %08x\n", hr);
+ hr = IDirect3DDevice3_DrawPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX,
+ tlvertices, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Try to enable lighting -- shouldn't have any effect. */
+ hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, TRUE);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice3_GetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, &val);
+ ok(hr == D3D_OK, "GetRenderState returned: %08x\n", hr);
+ ok(val == TRUE, "D3DRENDERSTATE_LIGHTING is: %08x\n", val);
+
+ /* Triangle 1 -- D3DFVF_VERTEX with D3DDP_DONOTLIGHT.
+ From DirectX SDK docs: if flag D3DDP_DONOTLIGHT is set and a diffuse or specular
+ component is not specified, the system uses the default color for the missing
+ component (0xFFFFFFFF for diffuse and 0x00000000 for specular). */
+ hr = IDirect3DDevice3_DrawPrimitive(Direct3DDevice3, 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) with D3DDP_DONOTLIGHT. */
+ hr = IDirect3DDevice3_DrawPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, fvf,
+ fvfvertices + 1, 3, D3DDP_DONOTLIGHT | D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 5 -- D3DFVF_LVERTEX. */
+ hr = IDirect3DDevice3_DrawPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, D3DFVF_LVERTEX,
+ lvertices + 1, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 7 -- D3DFVF_TLVERTEX. */
+ hr = IDirect3DDevice3_DrawPrimitive(Direct3DDevice3, D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX,
+ tlvertices + 1, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Restore state. */
+ hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_CULLMODE, oldcull);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice3_SetRenderState(Direct3DDevice3, D3DRENDERSTATE_LIGHTING, oldlighting);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+
+ hr = IDirect3DDevice3_EndScene(Direct3DDevice3);
+ ok(hr == D3D_OK, "EndScene returned: %08x\n", hr);
+ }
+
+ /* Blit to window (for debugging, tests read directly from surface). */
+ MapWindowPoints(window, NULL, (POINT *)&rc, 1);
+ rc.right = rc.left + 640;
+ rc.bottom = rc.top + 480;
+
+ memset(&ddbltfx, 0, sizeof(ddbltfx));
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ hr = IDirectDrawSurface4_Blt(Primary4, &rc, Surface4, NULL, DDBLT_WAIT, &ddbltfx);
+ ok(hr == DD_OK, "Blt 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 = D3D3_getPixelColor(DirectDraw4, Surface4, x, y);
+ if (is_todo[i])
+ todo_wine
+ ok(color_match(color, expected[i], 1), "%d: getPixelColor(%d,%d) returned %08x, expected %08x.\n",
+ i, x, y, color, expected[i]);
+ else
+ ok(color_match(color, expected[i], 1), "%d: getPixelColor(%d,%d) returned %08x, expected %08x.\n",
+ i, x, y, color, expected[i]);
+ }
+
+ /* Cleanup lights and material. */
+ hr = IDirect3DViewport3_DeleteLight(Viewport3, Direct3DLight);
+ ok(hr == D3D_OK, "DeleteLight returned: %08x\n", hr);
+ IDirect3DLight_Release(Direct3DLight);
+ hr = IDirect3DDevice3_SetLightState(Direct3DDevice3, D3DLIGHTSTATE_MATERIAL, 0);
+ todo_wine
+ ok(hr == D3D_OK, "SetLightState returned: %08x\n", hr);
+ IDirect3DMaterial3_Release(Direct3DMaterial3);
+}
+
static void D3D3_ViewportClearTest(void)
{
HRESULT hr;
@@ -3808,7 +4055,7 @@ cleanup:
skip("Cannot initialize D3D3, skipping\n");
}
else {
- /* todo */
+ D3D3_DrawPrimitiveTests();
}
D3D3_releaseObjects();
--
1.7.4.1
More information about the wine-patches
mailing list