[PATCH 7/7] ddraw/tests: Port the lighting test to the previous d3d versions.
Matteo Bruni
mbruni at codeweavers.com
Mon Mar 30 13:18:06 CDT 2015
---
dlls/ddraw/tests/ddraw1.c | 384 ++++++++++++++++++++++++++++++++++++++++++++++
dlls/ddraw/tests/ddraw2.c | 276 +++++++++++++++++++++++++++++++++
dlls/ddraw/tests/ddraw4.c | 283 ++++++++++++++++++++++++++++++++++
3 files changed, 943 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index efb00b2..9857943 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -146,6 +146,21 @@ static void emit_process_vertices(void **ptr, DWORD flags, WORD base_idx, DWORD
*ptr = pv + 1;
}
+static void emit_set_ts(void **ptr, D3DTRANSFORMSTATETYPE state, DWORD value)
+{
+ D3DINSTRUCTION *inst = *ptr;
+ D3DSTATE *ts = (D3DSTATE *)(inst + 1);
+
+ inst->bOpcode = D3DOP_STATETRANSFORM;
+ inst->bSize = sizeof(*ts);
+ inst->wCount = 1;
+
+ U1(*ts).dtstTransformStateType = state;
+ U2(*ts).dwArg[0] = value;
+
+ *ptr = ts + 1;
+}
+
static void emit_set_ls(void **ptr, D3DLIGHTSTATETYPE state, DWORD value)
{
D3DINSTRUCTION *inst = *ptr;
@@ -200,6 +215,30 @@ static void emit_tquad(void **ptr, WORD base_idx)
*ptr = tri;
}
+static void emit_tquad_tlist(void **ptr, WORD base_idx)
+{
+ D3DINSTRUCTION *inst = *ptr;
+ D3DTRIANGLE *tri = (D3DTRIANGLE *)(inst + 1);
+
+ inst->bOpcode = D3DOP_TRIANGLE;
+ inst->bSize = sizeof(*tri);
+ inst->wCount = 2;
+
+ U1(*tri).v1 = base_idx;
+ U2(*tri).v2 = base_idx + 1;
+ U3(*tri).v3 = base_idx + 2;
+ tri->wFlags = D3DTRIFLAG_START;
+ ++tri;
+
+ U1(*tri).v1 = base_idx + 2;
+ U2(*tri).v2 = base_idx + 3;
+ U3(*tri).v3 = base_idx;
+ tri->wFlags = D3DTRIFLAG_START;
+ ++tri;
+
+ *ptr = tri;
+}
+
static void emit_end(void **ptr)
{
D3DINSTRUCTION *inst = *ptr;
@@ -5320,6 +5359,350 @@ static void test_material(void)
DestroyWindow(window);
}
+static void test_lighting(void)
+{
+ static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
+ static D3DMATRIX mat =
+ {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ },
+ mat_singular =
+ {
+ 1.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ },
+ mat_transf =
+ {
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f, 0.0f,
+ 10.f, 10.0f, 10.0f, 1.0f,
+ };
+ static D3DLVERTEX unlitquad[] =
+ {
+ {{-1.0f}, {-1.0f}, {0.1f}, 0, {0xffff0000}, {0}, {0.0f}, {0.0f}},
+ {{-1.0f}, { 0.0f}, {0.1f}, 0, {0xffff0000}, {0}, {0.0f}, {0.0f}},
+ {{ 0.0f}, { 0.0f}, {0.1f}, 0, {0xffff0000}, {0}, {0.0f}, {0.0f}},
+ {{ 0.0f}, {-1.0f}, {0.1f}, 0, {0xffff0000}, {0}, {0.0f}, {0.0f}},
+ },
+ litquad[] =
+ {
+ {{-1.0f}, { 0.0f}, {0.1f}, 0, {0xff00ff00}, {0}, {0.0f}, {0.0f}},
+ {{-1.0f}, { 1.0f}, {0.1f}, 0, {0xff00ff00}, {0}, {0.0f}, {0.0f}},
+ {{ 0.0f}, { 1.0f}, {0.1f}, 0, {0xff00ff00}, {0}, {0.0f}, {0.0f}},
+ {{ 0.0f}, { 0.0f}, {0.1f}, 0, {0xff00ff00}, {0}, {0.0f}, {0.0f}},
+ };
+ static D3DVERTEX unlitnquad[] =
+ {
+ {{0.0f}, {-1.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{0.0f}, { 0.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{1.0f}, { 0.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{1.0f}, {-1.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ },
+ litnquad[] =
+ {
+ {{0.0f}, { 0.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{0.0f}, { 1.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{1.0f}, { 1.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{1.0f}, { 0.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ },
+ nquad[] =
+ {
+ {{-1.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {-1.0f}, {0.0f}, {0.0f}},
+ {{-1.0f}, { 1.0f}, {0.0f}, {0.0f}, {0.0f}, {-1.0f}, {0.0f}, {0.0f}},
+ {{ 1.0f}, { 1.0f}, {0.0f}, {0.0f}, {0.0f}, {-1.0f}, {0.0f}, {0.0f}},
+ {{ 1.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {-1.0f}, {0.0f}, {0.0f}},
+ },
+ rotatedquad[] =
+ {
+ {{-10.0f}, {-11.0f}, {11.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {0.0f}},
+ {{-10.0f}, { -9.0f}, {11.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {0.0f}},
+ {{-10.0f}, { -9.0f}, { 9.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {0.0f}},
+ {{-10.0f}, {-11.0f}, { 9.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {0.0f}},
+ };
+
+ HWND window;
+ IDirect3D *d3d;
+ IDirect3DDevice *device;
+ IDirectDraw *ddraw;
+ IDirectDrawSurface *rt;
+ IDirect3DViewport *viewport;
+ IDirect3DMaterial *material;
+ IDirect3DLight *light;
+ IDirect3DExecuteBuffer *execute_buffer;
+ D3DEXECUTEBUFFERDESC exec_desc;
+ D3DMATERIALHANDLE mat_handle;
+ D3DMATRIXHANDLE world_handle, view_handle, proj_handle;
+ D3DLIGHT light_desc;
+ HRESULT hr;
+ D3DCOLOR color;
+ void *ptr;
+ UINT inst_length;
+ ULONG refcount;
+
+ window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 640, 480, 0, 0, 0, 0);
+ ddraw = create_ddraw();
+ ok(!!ddraw, "Failed to create a ddraw object.\n");
+ if (!(device = create_device(ddraw, window, DDSCL_NORMAL)))
+ {
+ skip("Failed to create a 3D device, skipping test.\n");
+ DestroyWindow(window);
+ return;
+ }
+
+ hr = IDirect3DDevice_GetDirect3D(device, &d3d);
+ ok(SUCCEEDED(hr), "Failed to get D3D interface, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&rt);
+ ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
+
+ viewport = create_viewport(device, 0, 0, 640, 480);
+ material = create_diffuse_material(device, 1.0f, 1.0f, 1.0f, 1.0f);
+ viewport_set_background(device, viewport, material);
+
+ hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice_CreateMatrix(device, &world_handle);
+ ok(hr == D3D_OK, "Creating a matrix object failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice_SetMatrix(device, world_handle, &mat);
+ ok(hr == D3D_OK, "Setting a matrix object failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice_CreateMatrix(device, &view_handle);
+ ok(hr == D3D_OK, "Creating a matrix object failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice_SetMatrix(device, view_handle, &mat);
+ ok(hr == D3D_OK, "Setting a matrix object failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice_CreateMatrix(device, &proj_handle);
+ ok(hr == D3D_OK, "Creating a matrix object failed, hr %#x.\n", hr);
+ hr = IDirect3DDevice_SetMatrix(device, proj_handle, &mat);
+ ok(hr == D3D_OK, "Setting a matrix object failed, hr %#x.\n", hr);
+
+ memset(&exec_desc, 0, sizeof(exec_desc));
+ exec_desc.dwSize = sizeof(exec_desc);
+ exec_desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
+ exec_desc.dwBufferSize = 1024;
+ exec_desc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
+
+ hr = IDirect3DDevice_CreateExecuteBuffer(device, &exec_desc, &execute_buffer, NULL);
+ ok(SUCCEEDED(hr), "Failed to create execute buffer, hr %#x.\n", hr);
+
+ hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc);
+ ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
+
+ memcpy(exec_desc.lpData, unlitquad, sizeof(unlitquad));
+ ptr = ((BYTE *)exec_desc.lpData) + sizeof(unlitquad);
+ emit_set_ts(&ptr, D3DTRANSFORMSTATE_WORLD, world_handle);
+ emit_set_ts(&ptr, D3DTRANSFORMSTATE_VIEW, view_handle);
+ emit_set_ts(&ptr, D3DTRANSFORMSTATE_PROJECTION, proj_handle);
+ emit_set_rs(&ptr, D3DRENDERSTATE_CLIPPING, FALSE);
+ emit_set_rs(&ptr, D3DRENDERSTATE_ZENABLE, FALSE);
+ emit_set_rs(&ptr, D3DRENDERSTATE_FOGENABLE, FALSE);
+ emit_set_rs(&ptr, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
+ emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORM, 0, 4);
+ emit_tquad_tlist(&ptr, 0);
+ emit_end(&ptr);
+ inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData;
+ inst_length -= sizeof(unlitquad);
+
+ hr = IDirect3DExecuteBuffer_Unlock(execute_buffer);
+ ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ set_execute_data(execute_buffer, 4, sizeof(unlitquad), inst_length);
+ hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED);
+ ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr);
+
+ hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc);
+ ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
+
+ memcpy(exec_desc.lpData, litquad, sizeof(litquad));
+ ptr = ((BYTE *)exec_desc.lpData) + sizeof(litquad);
+ emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORM, 0, 4);
+ emit_tquad_tlist(&ptr, 0);
+ emit_end(&ptr);
+ inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData;
+ inst_length -= sizeof(litquad);
+
+ hr = IDirect3DExecuteBuffer_Unlock(execute_buffer);
+ ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr);
+
+ set_execute_data(execute_buffer, 4, sizeof(litquad), inst_length);
+ hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED);
+ ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr);
+
+ hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc);
+ ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
+
+ memcpy(exec_desc.lpData, unlitnquad, sizeof(unlitnquad));
+ ptr = ((BYTE *)exec_desc.lpData) + sizeof(unlitnquad);
+ emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORMLIGHT, 0, 4);
+ emit_tquad_tlist(&ptr, 0);
+ emit_end(&ptr);
+ inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData;
+ inst_length -= sizeof(unlitnquad);
+
+ hr = IDirect3DExecuteBuffer_Unlock(execute_buffer);
+ ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr);
+
+ set_execute_data(execute_buffer, 4, sizeof(unlitnquad), inst_length);
+ hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED);
+ ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr);
+
+ hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc);
+ ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
+
+ memcpy(exec_desc.lpData, litnquad, sizeof(litnquad));
+ ptr = ((BYTE *)exec_desc.lpData) + sizeof(litnquad);
+ emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORMLIGHT, 0, 4);
+ emit_tquad_tlist(&ptr, 0);
+ emit_end(&ptr);
+ inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData;
+ inst_length -= sizeof(litnquad);
+
+ hr = IDirect3DExecuteBuffer_Unlock(execute_buffer);
+ ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr);
+
+ set_execute_data(execute_buffer, 4, sizeof(litnquad), inst_length);
+ hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED);
+ ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 160, 360);
+ ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 160, 120);
+ ok(color == 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 480, 360);
+ ok(color == 0x00ffffff, "Unlit quad with normals has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 480, 120);
+ ok(color == 0x00ffffff, "Lit quad with normals has color 0x%08x.\n", color);
+
+ hr = IDirect3DMaterial_GetHandle(material, device, &mat_handle);
+ ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
+
+ hr = IDirect3D_CreateLight(d3d, &light, NULL);
+ ok(SUCCEEDED(hr), "Failed to create a light object, hr %#x.\n", hr);
+ memset(&light_desc, 0, sizeof(light_desc));
+ light_desc.dwSize = sizeof(light_desc);
+ light_desc.dltType = D3DLIGHT_DIRECTIONAL;
+ U1(U(light_desc).dcvColor).r = 0.0f;
+ U2(U(light_desc).dcvColor).g = 0.0f;
+ U3(U(light_desc).dcvColor).b = 1.0f;
+ U4(U(light_desc).dcvColor).a = 1.0f;
+ light_desc.dvDirection.z = 1.0f;
+ hr = IDirect3DLight_SetLight(light, &light_desc);
+ ok(SUCCEEDED(hr), "Failed to set light, hr %#x.\n", hr);
+ hr = IDirect3DViewport_AddLight(viewport, light);
+ ok(SUCCEEDED(hr), "Failed to add a light to the viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc);
+ ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
+
+ memcpy(exec_desc.lpData, nquad, sizeof(nquad));
+ ptr = ((BYTE *)exec_desc.lpData) + sizeof(nquad);
+ emit_set_ls(&ptr, D3DLIGHTSTATE_MATERIAL, mat_handle);
+ emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORMLIGHT, 0, 4);
+ emit_tquad_tlist(&ptr, 0);
+ emit_end(&ptr);
+ inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData;
+ inst_length -= sizeof(nquad);
+
+ hr = IDirect3DExecuteBuffer_Unlock(execute_buffer);
+ ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr);
+
+ set_execute_data(execute_buffer, 4, sizeof(nquad), inst_length);
+ hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED);
+ ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 320, 240);
+ todo_wine ok(color == 0x000000ff, "Lit quad with light has color 0x%08x.\n", color);
+
+ hr = IDirect3DDevice_SetMatrix(device, world_handle, &mat_singular);
+ ok(hr == D3D_OK, "Setting a matrix object failed, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED);
+ ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 160, 240);
+ ok(color == 0x00ffffff, "Cleared area has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 480, 240);
+ todo_wine ok(color == 0x000000b4, "Lit quad with singular world matrix has color 0x%08x.\n", color);
+
+ hr = IDirect3DDevice_SetMatrix(device, world_handle, &mat_transf);
+ ok(hr == D3D_OK, "Setting a matrix object failed, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc);
+ ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
+
+ memcpy(exec_desc.lpData, rotatedquad, sizeof(rotatedquad));
+ ptr = ((BYTE *)exec_desc.lpData) + sizeof(rotatedquad);
+ emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORMLIGHT, 0, 4);
+ emit_tquad_tlist(&ptr, 0);
+ emit_end(&ptr);
+ inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData;
+ inst_length -= sizeof(rotatedquad);
+
+ hr = IDirect3DExecuteBuffer_Unlock(execute_buffer);
+ ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr);
+
+ set_execute_data(execute_buffer, 4, sizeof(rotatedquad), inst_length);
+ hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED);
+ ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 320, 240);
+ todo_wine ok(color == 0x000000ff, "Lit quad with transformation matrix has color 0x%08x.\n", color);
+
+ IDirect3DExecuteBuffer_Release(execute_buffer);
+ IDirect3DDevice_DeleteMatrix(device, world_handle);
+ IDirect3DDevice_DeleteMatrix(device, view_handle);
+ IDirect3DDevice_DeleteMatrix(device, proj_handle);
+ IDirect3DLight_Release(light);
+ destroy_material(material);
+ destroy_viewport(device, viewport);
+ IDirectDrawSurface_Release(rt);
+ refcount = IDirect3DDevice_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ IDirect3D_Release(d3d);
+ refcount = IDirectDraw_Release(ddraw);
+ ok(!refcount, "Ddraw object has %u references left.\n", refcount);
+ DestroyWindow(window);
+}
+
static void test_palette_gdi(void)
{
IDirectDrawSurface *surface, *primary;
@@ -6939,6 +7322,7 @@ START_TEST(ddraw1)
test_palette_complex();
test_p8_rgb_blit();
test_material();
+ test_lighting();
test_palette_gdi();
test_palette_alpha();
test_lost_device();
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 5f59f06..5febc17 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -6394,6 +6394,281 @@ static void test_material(void)
DestroyWindow(window);
}
+static void test_lighting(void)
+{
+ static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
+ static D3DMATRIX mat =
+ {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ },
+ mat_singular =
+ {
+ 1.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ },
+ mat_transf =
+ {
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f, 0.0f,
+ 10.f, 10.0f, 10.0f, 1.0f,
+ };
+ static D3DLVERTEX unlitquad[] =
+ {
+ {{-1.0f}, {-1.0f}, {0.1f}, 0, {0xffff0000}, {0}, {0.0f}, {0.0f}},
+ {{-1.0f}, { 0.0f}, {0.1f}, 0, {0xffff0000}, {0}, {0.0f}, {0.0f}},
+ {{ 0.0f}, { 0.0f}, {0.1f}, 0, {0xffff0000}, {0}, {0.0f}, {0.0f}},
+ {{ 0.0f}, {-1.0f}, {0.1f}, 0, {0xffff0000}, {0}, {0.0f}, {0.0f}},
+ },
+ litquad[] =
+ {
+ {{-1.0f}, { 0.0f}, {0.1f}, 0, {0xff00ff00}, {0}, {0.0f}, {0.0f}},
+ {{-1.0f}, { 1.0f}, {0.1f}, 0, {0xff00ff00}, {0}, {0.0f}, {0.0f}},
+ {{ 0.0f}, { 1.0f}, {0.1f}, 0, {0xff00ff00}, {0}, {0.0f}, {0.0f}},
+ {{ 0.0f}, { 0.0f}, {0.1f}, 0, {0xff00ff00}, {0}, {0.0f}, {0.0f}},
+ };
+ static D3DVERTEX unlitnquad[] =
+ {
+ {{0.0f}, {-1.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{0.0f}, { 0.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{1.0f}, { 0.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{1.0f}, {-1.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ },
+ litnquad[] =
+ {
+ {{0.0f}, { 0.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{0.0f}, { 1.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{1.0f}, { 1.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ {{1.0f}, { 0.0f}, {0.1f}, {1.0f}, {1.0f}, {1.0f}, {0.0f}, {0.0f}},
+ },
+ nquad[] =
+ {
+ {{-1.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {-1.0f}, {0.0f}, {0.0f}},
+ {{-1.0f}, { 1.0f}, {0.0f}, {0.0f}, {0.0f}, {-1.0f}, {0.0f}, {0.0f}},
+ {{ 1.0f}, { 1.0f}, {0.0f}, {0.0f}, {0.0f}, {-1.0f}, {0.0f}, {0.0f}},
+ {{ 1.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {-1.0f}, {0.0f}, {0.0f}},
+ },
+ rotatedquad[] =
+ {
+ {{-10.0f}, {-11.0f}, {11.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {0.0f}},
+ {{-10.0f}, { -9.0f}, {11.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {0.0f}},
+ {{-10.0f}, { -9.0f}, { 9.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {0.0f}},
+ {{-10.0f}, {-11.0f}, { 9.0f}, {-1.0f}, {0.0f}, {0.0f}, {0.0f}, {0.0f}},
+ };
+ static WORD indices[] = {0, 1, 2, 2, 3, 0};
+
+ HWND window;
+ IDirect3D2 *d3d;
+ IDirect3DDevice2 *device;
+ IDirectDraw2 *ddraw;
+ IDirectDrawSurface *rt;
+ IDirect3DViewport2 *viewport;
+ IDirect3DMaterial2 *material;
+ IDirect3DLight *light;
+ D3DMATERIALHANDLE mat_handle;
+ D3DLIGHT2 light_desc;
+ HRESULT hr;
+ D3DCOLOR color;
+ ULONG refcount;
+
+ window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 640, 480, 0, 0, 0, 0);
+ ddraw = create_ddraw();
+ ok(!!ddraw, "Failed to create a ddraw object.\n");
+ if (!(device = create_device(ddraw, window, DDSCL_NORMAL)))
+ {
+ skip("Failed to create a 3D device, skipping test.\n");
+ DestroyWindow(window);
+ return;
+ }
+
+ hr = IDirect3DDevice2_GetDirect3D(device, &d3d);
+ ok(SUCCEEDED(hr), "Failed to get D3D interface, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_GetRenderTarget(device, &rt);
+ ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
+
+ viewport = create_viewport(device, 0, 0, 640, 480);
+ hr = IDirect3DDevice2_SetCurrentViewport(device, viewport);
+ ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
+
+ material = create_diffuse_material(device, 1.0f, 1.0f, 1.0f, 1.0f);
+ viewport_set_background(device, viewport, material);
+
+ hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &mat);
+ ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &mat);
+ ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &mat);
+ ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ZENABLE, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable zbuffer, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
+ ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ /* There is no D3DRENDERSTATE_LIGHTING on ddraw < 7. */
+ hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DVT_LVERTEX, unlitquad,
+ 4, indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
+ ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DVT_LVERTEX, litquad,
+ 4, indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DVT_VERTEX, unlitnquad,
+ 4, indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
+ ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DVT_VERTEX, litnquad,
+ 4, indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 160, 360);
+ ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 160, 120);
+ ok(color == 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 480, 360);
+ ok(color == 0x00ffffff, "Unlit quad with normals has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 480, 120);
+ ok(color == 0x00ffffff, "Lit quad with normals has color 0x%08x.\n", color);
+
+ hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
+ ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
+
+ hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle);
+ ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
+ hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
+ ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
+
+ hr = IDirect3D2_CreateLight(d3d, &light, NULL);
+ ok(SUCCEEDED(hr), "Failed to create a light object, hr %#x.\n", hr);
+ memset(&light_desc, 0, sizeof(light_desc));
+ light_desc.dwSize = sizeof(light_desc);
+ light_desc.dltType = D3DLIGHT_DIRECTIONAL;
+ U1(U(light_desc).dcvColor).r = 0.0f;
+ U2(U(light_desc).dcvColor).g = 0.0f;
+ U3(U(light_desc).dcvColor).b = 1.0f;
+ U4(U(light_desc).dcvColor).a = 1.0f;
+ light_desc.dvDirection.z = 1.0f;
+ hr = IDirect3DLight_SetLight(light, (D3DLIGHT *)&light_desc);
+ ok(SUCCEEDED(hr), "Failed to set light, hr %#x.\n", hr);
+ hr = IDirect3DViewport2_AddLight(viewport, light);
+ ok(SUCCEEDED(hr), "Failed to add a light to the viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DVT_VERTEX, nquad,
+ 4, indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 320, 240);
+ ok(color == 0x00000000, "Lit quad with no light has color 0x%08x.\n", color);
+
+ light_desc.dwFlags = D3DLIGHT_ACTIVE;
+ hr = IDirect3DLight_SetLight(light, (D3DLIGHT *)&light_desc);
+ ok(SUCCEEDED(hr), "Failed to set light, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DVT_VERTEX, nquad,
+ 4, indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 320, 240);
+ ok(color == 0x000000ff, "Lit quad with light has color 0x%08x.\n", color);
+
+ hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &mat_singular);
+ ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DVT_VERTEX, nquad,
+ 4, indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 160, 240);
+ ok(color == 0x00ffffff, "Cleared area has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 480, 240);
+ ok(color == 0x000000b4, "Lit quad with singular world matrix has color 0x%08x.\n", color);
+
+ hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &mat_transf);
+ ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, D3DVT_VERTEX, rotatedquad,
+ 4, indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice2_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 320, 240);
+ ok(color == 0x000000ff, "Lit quad with transformation matrix has color 0x%08x.\n", color);
+
+ IDirect3DLight_Release(light);
+ destroy_material(material);
+ destroy_viewport(device, viewport);
+ IDirectDrawSurface2_Release(rt);
+ refcount = IDirect3DDevice2_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ IDirect3D2_Release(d3d);
+ IDirectDraw2_Release(ddraw);
+ ok(!refcount, "Ddraw object has %u references left.\n", refcount);
+ DestroyWindow(window);
+}
+
static void test_palette_gdi(void)
{
IDirectDrawSurface *surface, *primary;
@@ -7958,6 +8233,7 @@ START_TEST(ddraw2)
test_palette_complex();
test_p8_rgb_blit();
test_material();
+ test_lighting();
test_palette_gdi();
test_palette_alpha();
test_lost_device();
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 70ca117..2c8240d 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -3735,6 +3735,288 @@ static void test_draw_strided(void)
DestroyWindow(window);
}
+static void test_lighting(void)
+{
+ static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
+ static D3DMATRIX mat =
+ {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ },
+ mat_singular =
+ {
+ 1.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ },
+ mat_transf =
+ {
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f, 0.0f,
+ 10.f, 10.0f, 10.0f, 1.0f,
+ };
+ static struct
+ {
+ struct vec3 position;
+ DWORD diffuse;
+ }
+ unlitquad[] =
+ {
+ {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
+ {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
+ {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
+ {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
+ },
+ litquad[] =
+ {
+ {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
+ {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
+ {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
+ {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
+ };
+ static struct
+ {
+ struct vec3 position;
+ struct vec3 normal;
+ DWORD diffuse;
+ }
+ unlitnquad[] =
+ {
+ {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
+ {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
+ {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
+ {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
+ },
+ litnquad[] =
+ {
+ {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
+ {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
+ {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
+ {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
+ },
+ nquad[] =
+ {
+ {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
+ {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
+ {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
+ {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
+ },
+ rotatedquad[] =
+ {
+ {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
+ {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
+ {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
+ {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
+ };
+ static WORD indices[] = {0, 1, 2, 2, 3, 0};
+
+ HWND window;
+ IDirect3D3 *d3d;
+ IDirect3DDevice3 *device;
+ IDirectDrawSurface4 *rt;
+ IDirect3DViewport3 *viewport;
+ IDirect3DMaterial3 *material;
+ IDirect3DLight *light;
+ D3DMATERIALHANDLE mat_handle;
+ D3DLIGHT2 light_desc;
+ HRESULT hr;
+ DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
+ DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
+ D3DCOLOR color;
+ ULONG refcount;
+
+ window = CreateWindowA("static", "ddraw_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 = IDirect3DDevice3_GetDirect3D(device, &d3d);
+ ok(SUCCEEDED(hr), "Failed to get D3D interface, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
+ ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
+
+ viewport = create_viewport(device, 0, 0, 640, 480);
+ hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
+ ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &mat);
+ ok(SUCCEEDED(hr), "Failed to set world transformation, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &mat);
+ ok(SUCCEEDED(hr), "Failed to set view transformation, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &mat);
+ ok(SUCCEEDED(hr), "Failed to set projection transformation, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_CLIPPING, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_ZENABLE, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable zbuffer, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_FOGENABLE, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_STENCILENABLE, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable stencil buffer, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
+ ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ /* There is no D3DRENDERSTATE_LIGHTING on ddraw < 7. */
+ hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, unlitquad, 4,
+ indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
+ ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, fvf, litquad, 4,
+ indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
+ ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, unlitnquad, 4,
+ indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
+ ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, litnquad, 4,
+ indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 160, 360);
+ ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 160, 120);
+ ok(color == 0x0000ff00, "Lit quad without normals has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 480, 360);
+ ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 480, 120);
+ ok(color == 0x00ffff00, "Lit quad with normals has color 0x%08x.\n", color);
+
+ hr = IDirect3DDevice3_SetRenderState(device, D3DRENDERSTATE_LIGHTING, TRUE);
+ ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
+
+ material = create_diffuse_material(device, 0.0f, 1.0f, 0.0f, 0.0f);
+ hr = IDirect3DMaterial3_GetHandle(material, device, &mat_handle);
+ ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
+ hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
+ ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
+
+ hr = IDirect3D3_CreateLight(d3d, &light, NULL);
+ ok(SUCCEEDED(hr), "Failed to create a light object, hr %#x.\n", hr);
+ memset(&light_desc, 0, sizeof(light_desc));
+ light_desc.dwSize = sizeof(light_desc);
+ light_desc.dltType = D3DLIGHT_DIRECTIONAL;
+ U1(U(light_desc).dcvColor).r = 1.0f;
+ U2(U(light_desc).dcvColor).g = 1.0f;
+ U3(U(light_desc).dcvColor).b = 1.0f;
+ U4(U(light_desc).dcvColor).a = 1.0f;
+ light_desc.dvDirection.z = 1.0f;
+ hr = IDirect3DLight_SetLight(light, (D3DLIGHT *)&light_desc);
+ ok(SUCCEEDED(hr), "Failed to set light, hr %#x.\n", hr);
+ hr = IDirect3DViewport3_AddLight(viewport, light);
+ ok(SUCCEEDED(hr), "Failed to add a light to the viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, nquad, 4,
+ indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 320, 240);
+ ok(color == 0x00000000, "Lit quad with no light has color 0x%08x.\n", color);
+
+ light_desc.dwFlags = D3DLIGHT_ACTIVE;
+ hr = IDirect3DLight_SetLight(light, (D3DLIGHT *)&light_desc);
+ ok(SUCCEEDED(hr), "Failed to set light, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, nquad, 4,
+ indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 320, 240);
+ ok(color == 0x000000ff, "Lit quad with light has color 0x%08x.\n", color);
+
+ hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &mat_singular);
+ ok(SUCCEEDED(hr), "Failed to set world transformation, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, nquad, 4,
+ indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 160, 240);
+ ok(color == 0x00ffffff, "Cleared area has color 0x%08x.\n", color);
+ color = get_surface_color(rt, 480, 240);
+ ok(color == 0x000000b4, "Lit quad with singular world matrix has color 0x%08x.\n", color);
+
+ hr = IDirect3DDevice3_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &mat_transf);
+ ok(SUCCEEDED(hr), "Failed to set world transformation, hr %#x.\n", hr);
+
+ hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
+ ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, nfvf, rotatedquad, 4,
+ indices, 6, 0);
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice3_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ color = get_surface_color(rt, 320, 240);
+ ok(color == 0x000000ff, "Lit quad with transformation matrix has color 0x%08x.\n", color);
+
+ IDirect3DLight_Release(light);
+ destroy_material(material);
+ IDirectDrawSurface4_Release(rt);
+ refcount = IDirect3DDevice3_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ IDirect3D3_Release(d3d);
+ DestroyWindow(window);
+}
+
static void test_clear_rect_count(void)
{
IDirectDrawSurface4 *rt;
@@ -8870,6 +9152,7 @@ START_TEST(ddraw4)
test_vb_discard();
test_coop_level_multi_window();
test_draw_strided();
+ test_lighting();
test_clear_rect_count();
test_coop_level_versions();
test_lighting_interface_versions();
--
2.0.5
More information about the wine-patches
mailing list