[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