[08/11] ddraw/tests: Add assorted D3D2 DrawPrimitive/visual tests.
Octavian Voicu
octavian.voicu at gmail.com
Mon Nov 7 16:27:11 CST 2011
Among others, test that D3DRENDERSTATE_LIGHTING is ignored, as it should be
(it wasn't introduced until D3D7).
---
dlls/ddraw/tests/visual.c | 227 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 226 insertions(+), 1 deletions(-)
diff --git a/dlls/ddraw/tests/visual.c b/dlls/ddraw/tests/visual.c
index 832a9de..32d7de3 100644
--- a/dlls/ddraw/tests/visual.c
+++ b/dlls/ddraw/tests/visual.c
@@ -2292,6 +2292,231 @@ static void D3D2_releaseObjects(void)
window = NULL;
}
+static void D3D2_DrawPrimitiveTests(void)
+{
+ enum {
+ BLACK = 0x000000,
+ BLUE = 0x0000ff,
+ GREEN = 0x00ff00,
+ GRAY = 0x808080,
+ RED = 0xff0000,
+ WHITE = 0xffffff
+ };
+ D3DVERTEX vertices1[] = { /* 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} }
+ };
+ D3DVERTEX vertices2[] = { /* bottom-right corner of screen */
+ /* x y z nx ny nz tu tv */
+ { { 0.f}, {-1.f}, {0.f}, {0.f}, {0.f}, {1.f}, {0.f}, {0.f} },
+ { { 1.f}, {-1.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} },
+ { { 1.f}, { 0.f}, {0.f}, {0.f}, {0.f}, {1.f}, {0.f}, {0.f} }
+ };
+ 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[] = { WHITE, WHITE, GRAY, GRAY, GREEN, GREEN, BLUE, BLUE };
+ BOOL is_todo[] = { FALSE, 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;
+ IDirect3DMaterial2 *Direct3DMaterial2;
+ 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 = IDirectDrawSurface_Blt(Surface1, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
+ ok(hr == DD_OK, "Blt returned: %08x\n", hr);
+
+ /* Make sure getPixelColor works correctly. */
+ color = D3D1_getPixelColor(DirectDraw1, Surface1, 320, 240);
+ ok(color == RED, "getPixelColor returned: %08x\n", color);
+
+ /* Setup a diffuse directional gray light, perpendicular on the triangles. */
+ hr = IDirect3D2_CreateLight(Direct3D2, &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 = IDirect3DViewport2_AddLight(Viewport2, Direct3DLight);
+ ok(hr == D3D_OK, "AddLight returned: %08x\n", hr);
+
+ /* Use a material that reflects only diffuse light. */
+ hr = IDirect3D2_CreateMaterial(Direct3D2, &Direct3DMaterial2, 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 = IDirect3DMaterial2_SetMaterial(Direct3DMaterial2, &mat);
+ ok(hr == D3D_OK, "SetMaterial returned: %08x\n", hr);
+ hr = IDirect3DMaterial2_GetHandle(Direct3DMaterial2, Direct3DDevice2, &hMat);
+ ok(hr == D3D_OK, "GetHandle returned: %08x\n", hr);
+ hr = IDirect3DDevice2_SetLightState(Direct3DDevice2, D3DLIGHTSTATE_MATERIAL, hMat);
+ ok(hr == D3D_OK, "SetLightState returned: %08x\n", hr);
+ hr = IDirect3DDevice2_SetLightState(Direct3DDevice2, D3DLIGHTSTATE_COLORVERTEX, TRUE);
+ ok(hr == D3D_OK, "SetLightState returned: %08x\n", hr);
+
+ hr = IDirect3DDevice2_BeginScene(Direct3DDevice2);
+ 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 = IDirect3DDevice2_GetRenderState(Direct3DDevice2, D3DRENDERSTATE_CULLMODE, &oldcull);
+ ok(hr == D3D_OK, "GetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice2_SetRenderState(Direct3DDevice2, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+
+ /* IDirect3DDevice2 doesn't have D3DRENDERSTATE_LIGHTING, but get/set seem to work w/o any side effects. */
+ hr = IDirect3DDevice2_GetRenderState(Direct3DDevice2, 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 = IDirect3DDevice2_SetRenderState(Direct3DDevice2, D3DRENDERSTATE_LIGHTING, FALSE);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice2_GetRenderState(Direct3DDevice2, D3DRENDERSTATE_LIGHTING, &val);
+ ok(hr == D3D_OK, "GetRenderState returned: %08x\n", hr);
+ ok(val == FALSE, "D3DRENDERSTATE_LIGHTING is: %08x\n", val);
+
+ /* Triangle 0 -- D3DVT_VERTEX with D3DDP_DONOTLIGHT.
+ IDirect3DDevice2::DrawPrimitive doesn't have the D3DDP_DONOTLIGHT flag,
+ it should be ignored. */
+ hr = IDirect3DDevice2_DrawPrimitive(Direct3DDevice2, D3DPT_TRIANGLELIST, D3DVT_VERTEX,
+ vertices1, 3, D3DDP_DONOTLIGHT | D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 2 -- D3DVT_VERTEX. */
+ hr = IDirect3DDevice2_DrawPrimitive(Direct3DDevice2, D3DPT_TRIANGLELIST, D3DVT_VERTEX,
+ vertices2, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 4 -- D3DVT_LVERTEX. */
+ hr = IDirect3DDevice2_DrawPrimitive(Direct3DDevice2, D3DPT_TRIANGLELIST, D3DVT_LVERTEX,
+ lvertices, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 6 -- D3DVT_TLVERTEX. */
+ hr = IDirect3DDevice2_DrawPrimitive(Direct3DDevice2, D3DPT_TRIANGLELIST, D3DVT_TLVERTEX,
+ tlvertices, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Try to enable lighting -- shouldn't have any effect. */
+ hr = IDirect3DDevice2_SetRenderState(Direct3DDevice2, D3DRENDERSTATE_LIGHTING, TRUE);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice2_GetRenderState(Direct3DDevice2, 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.
+ IDirect3DDevice2::DrawPrimitive doesn't have the D3DDP_DONOTLIGHT flag,
+ it should be ignored. */
+ hr = IDirect3DDevice2_DrawPrimitive(Direct3DDevice2, D3DPT_TRIANGLELIST, D3DVT_VERTEX,
+ vertices1 + 1, 3, D3DDP_DONOTLIGHT | D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 3 -- D3DVT_VERTEX. */
+ hr = IDirect3DDevice2_DrawPrimitive(Direct3DDevice2, D3DPT_TRIANGLELIST, D3DVT_VERTEX,
+ vertices2 + 1, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 5 -- D3DVT_LVERTEX. */
+ hr = IDirect3DDevice2_DrawPrimitive(Direct3DDevice2, D3DPT_TRIANGLELIST, D3DVT_LVERTEX,
+ lvertices + 1, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Triangle 7 -- D3DVT_TLVERTEX. */
+ hr = IDirect3DDevice2_DrawPrimitive(Direct3DDevice2, D3DPT_TRIANGLELIST, D3DVT_TLVERTEX,
+ tlvertices + 1, 3, D3DDP_WAIT);
+ ok(hr == D3D_OK, "DrawPrimitive returned: %08x\n", hr);
+
+ /* Restore state. */
+ hr = IDirect3DDevice2_SetRenderState(Direct3DDevice2, D3DRENDERSTATE_CULLMODE, oldcull);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+ hr = IDirect3DDevice2_SetRenderState(Direct3DDevice2, D3DRENDERSTATE_LIGHTING, oldlighting);
+ ok(hr == D3D_OK, "SetRenderState returned: %08x\n", hr);
+
+ hr = IDirect3DDevice2_EndScene(Direct3DDevice2);
+ 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 = IDirectDrawSurface_Blt(Primary1, &rc, Surface1, 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 = D3D1_getPixelColor(DirectDraw1, Surface1, 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 = IDirect3DViewport2_DeleteLight(Viewport2, Direct3DLight);
+ ok(hr == D3D_OK, "DeleteLight returned: %08x\n", hr);
+ IDirect3DLight_Release(Direct3DLight);
+ hr = IDirect3DDevice2_SetLightState(Direct3DDevice2, D3DLIGHTSTATE_MATERIAL, 0);
+ todo_wine
+ ok(hr == D3D_OK, "SetLightState returned: %08x\n", hr);
+ IDirect3DMaterial2_Release(Direct3DMaterial2);
+}
+
static DWORD D3D3_getPixelColor(IDirectDraw4 *DirectDraw, IDirectDrawSurface4 *Surface, UINT x, UINT y)
{
DWORD ret;
@@ -3430,7 +3655,7 @@ cleanup:
skip("Cannot initialize D3D2, skipping\n");
}
else {
- /* todo */
+ D3D2_DrawPrimitiveTests();
}
D3D2_releaseObjects();
--
1.7.4.1
More information about the wine-patches
mailing list