Commit 7bdbb8c8 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

ddraw/tests: Add some basic material tests.

parent 27a0b8a5
......@@ -126,7 +126,7 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface *surface, UINT x, UINT y)
return color;
}
static void emit_process_vertices(void **ptr, WORD base_idx, DWORD vertex_count)
static void emit_process_vertices(void **ptr, DWORD flags, WORD base_idx, DWORD vertex_count)
{
D3DINSTRUCTION *inst = *ptr;
D3DPROCESSVERTICES *pv = (D3DPROCESSVERTICES *)(inst + 1);
......@@ -135,7 +135,7 @@ static void emit_process_vertices(void **ptr, WORD base_idx, DWORD vertex_count)
inst->bSize = sizeof(*pv);
inst->wCount = 1;
pv->dwFlags = D3DPROCESSVERTICES_COPY;
pv->dwFlags = flags;
pv->wStart = base_idx;
pv->wDest = 0;
pv->dwCount = vertex_count;
......@@ -144,6 +144,21 @@ static void emit_process_vertices(void **ptr, WORD base_idx, DWORD vertex_count)
*ptr = pv + 1;
}
static void emit_set_ls(void **ptr, D3DLIGHTSTATETYPE state, DWORD value)
{
D3DINSTRUCTION *inst = *ptr;
D3DSTATE *ls = (D3DSTATE *)(inst + 1);
inst->bOpcode = D3DOP_STATELIGHT;
inst->bSize = sizeof(*ls);
inst->wCount = 1;
U1(*ls).dlstLightStateType = state;
U2(*ls).dwArg[0] = value;
*ptr = ls + 1;
}
static void emit_set_rs(void **ptr, D3DRENDERSTATETYPE state, DWORD value)
{
D3DINSTRUCTION *inst = *ptr;
......@@ -361,10 +376,9 @@ static void destroy_viewport(IDirect3DDevice *device, IDirect3DViewport *viewpor
IDirect3DViewport_Release(viewport);
}
static IDirect3DMaterial *create_diffuse_material(IDirect3DDevice *device, float r, float g, float b, float a)
static IDirect3DMaterial *create_material(IDirect3DDevice *device, D3DMATERIAL *mat)
{
IDirect3DMaterial *material;
D3DMATERIAL mat;
IDirect3D *d3d;
HRESULT hr;
......@@ -372,17 +386,39 @@ static IDirect3DMaterial *create_diffuse_material(IDirect3DDevice *device, float
ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
hr = IDirect3D_CreateMaterial(d3d, &material, NULL);
ok(SUCCEEDED(hr), "Failed to create material, hr %#x.\n", hr);
hr = IDirect3DMaterial_SetMaterial(material, mat);
ok(SUCCEEDED(hr), "Failed to set material data, hr %#x.\n", hr);
IDirect3D_Release(d3d);
return material;
}
static IDirect3DMaterial *create_diffuse_material(IDirect3DDevice *device, float r, float g, float b, float a)
{
D3DMATERIAL mat;
memset(&mat, 0, sizeof(mat));
mat.dwSize = sizeof(mat);
U1(U(mat).diffuse).r = r;
U2(U(mat).diffuse).g = g;
U3(U(mat).diffuse).b = b;
U4(U(mat).diffuse).a = a;
hr = IDirect3DMaterial_SetMaterial(material, &mat);
ok(SUCCEEDED(hr), "Failed to set material data, hr %#x.\n", hr);
IDirect3D_Release(d3d);
return material;
return create_material(device, &mat);
}
static IDirect3DMaterial *create_emissive_material(IDirect3DDevice *device, float r, float g, float b, float a)
{
D3DMATERIAL mat;
memset(&mat, 0, sizeof(mat));
mat.dwSize = sizeof(mat);
U1(U3(mat).emissive).r = r;
U2(U3(mat).emissive).g = g;
U3(U3(mat).emissive).b = b;
U4(U3(mat).emissive).a = a;
return create_material(device, &mat);
}
static void destroy_material(IDirect3DMaterial *material)
......@@ -1089,7 +1125,7 @@ static void test_zenable(void)
ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
memcpy(exec_desc.lpData, tquad, sizeof(tquad));
ptr = ((BYTE *)exec_desc.lpData) + sizeof(tquad);
emit_process_vertices(&ptr, 0, 4);
emit_process_vertices(&ptr, D3DPROCESSVERTICES_COPY, 0, 4);
emit_set_rs(&ptr, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE);
emit_tquad(&ptr, 0);
emit_end(&ptr);
......@@ -1241,7 +1277,7 @@ static void test_ck_rgba(void)
ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
memcpy(exec_desc.lpData, tquad, sizeof(tquad));
ptr = ((BYTE *)exec_desc.lpData) + sizeof(tquad);
emit_process_vertices(&ptr, 0, 4);
emit_process_vertices(&ptr, D3DPROCESSVERTICES_COPY, 0, 4);
emit_set_rs(&ptr, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle);
emit_set_rs(&ptr, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
emit_set_rs(&ptr, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
......@@ -1250,7 +1286,7 @@ static void test_ck_rgba(void)
emit_tquad(&ptr, 0);
emit_end(&ptr);
draw1_len = (BYTE *)ptr - (BYTE *)exec_desc.lpData - sizeof(tquad);
emit_process_vertices(&ptr, 4, 4);
emit_process_vertices(&ptr, D3DPROCESSVERTICES_COPY, 4, 4);
emit_tquad(&ptr, 0);
emit_set_rs(&ptr, D3DRENDERSTATE_TEXTUREHANDLE, 0);
emit_end(&ptr);
......@@ -1404,24 +1440,24 @@ static void test_ck_default(void)
ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
memcpy(exec_desc.lpData, tquad, sizeof(tquad));
ptr = (BYTE *)exec_desc.lpData + sizeof(tquad);
emit_process_vertices(&ptr, 0, 4);
emit_process_vertices(&ptr, D3DPROCESSVERTICES_COPY, 0, 4);
emit_set_rs(&ptr, D3DRENDERSTATE_TEXTUREHANDLE, texture_handle);
emit_tquad(&ptr, 0);
emit_end(&ptr);
draw1_offset = sizeof(tquad);
draw1_len = (BYTE *)ptr - (BYTE *)exec_desc.lpData - draw1_offset;
emit_process_vertices(&ptr, 0, 4);
emit_process_vertices(&ptr, D3DPROCESSVERTICES_COPY, 0, 4);
emit_set_rs(&ptr, D3DRENDERSTATE_COLORKEYENABLE, FALSE);
emit_tquad(&ptr, 0);
emit_end(&ptr);
draw2_offset = draw1_offset + draw1_len;
draw2_len = (BYTE *)ptr - (BYTE *)exec_desc.lpData - draw2_offset;
emit_process_vertices(&ptr, 0, 4);
emit_process_vertices(&ptr, D3DPROCESSVERTICES_COPY, 0, 4);
emit_tquad(&ptr, 0);
emit_end(&ptr);
draw3_offset = draw2_offset + draw2_len;
draw3_len = (BYTE *)ptr - (BYTE *)exec_desc.lpData - draw3_offset;
emit_process_vertices(&ptr, 0, 4);
emit_process_vertices(&ptr, D3DPROCESSVERTICES_COPY, 0, 4);
emit_set_rs(&ptr, D3DRENDERSTATE_COLORKEYENABLE, TRUE);
emit_tquad(&ptr, 0);
emit_set_rs(&ptr, D3DRENDERSTATE_TEXTUREHANDLE, 0);
......@@ -4800,6 +4836,164 @@ static void test_p8_rgb_blit(void)
DestroyWindow(window);
}
static void test_material(void)
{
IDirect3DExecuteBuffer *execute_buffer;
D3DMATERIALHANDLE mat_handle, tmp;
D3DEXECUTEBUFFERDESC exec_desc;
IDirect3DMaterial *material;
IDirect3DViewport *viewport;
IDirect3DDevice *device;
IDirectDrawSurface *rt;
IDirectDraw *ddraw;
UINT inst_length;
D3DCOLOR color;
ULONG refcount;
unsigned int i;
HWND window;
HRESULT hr;
BOOL valid;
void *ptr;
static D3DVERTEX quad[] =
{
{{-1.0f}, {-1.0f}, {0.0f}, {1.0f}, {0.0f}, {0.0f}},
{{-1.0f}, { 1.0f}, {0.0f}, {1.0f}, {0.0f}, {0.0f}},
{{ 1.0f}, {-1.0f}, {0.0f}, {1.0f}, {0.0f}, {0.0f}},
{{ 1.0f}, { 1.0f}, {0.0f}, {1.0f}, {0.0f}, {0.0f}},
};
static const struct
{
BOOL material;
D3DCOLOR expected_color;
}
test_data[] =
{
{TRUE, 0x0000ff00},
{FALSE, 0x00ffffff},
};
static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
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_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
material = create_diffuse_material(device, 0.0f, 0.0f, 1.0f, 1.0f);
viewport = create_viewport(device, 0, 0, 640, 480);
viewport_set_background(device, viewport, material);
destroy_material(material);
material = create_emissive_material(device, 0.0f, 1.0f, 0.0f, 0.0f);
hr = IDirect3DMaterial_GetHandle(material, device, &mat_handle);
ok(SUCCEEDED(hr), "Failed to get material handle, 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);
for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
{
hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc);
ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr);
memcpy(exec_desc.lpData, quad, sizeof(quad));
ptr = ((BYTE *)exec_desc.lpData) + sizeof(quad);
emit_set_ls(&ptr, D3DLIGHTSTATE_MATERIAL, test_data[i].material ? mat_handle : 0);
emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORMLIGHT, 0, 4);
emit_tquad(&ptr, 0);
emit_end(&ptr);
inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData;
inst_length -= sizeof(quad);
hr = IDirect3DExecuteBuffer_Unlock(execute_buffer);
ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr);
hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER);
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);
set_execute_data(execute_buffer, 4, sizeof(quad), 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);
if (test_data[i].material)
todo_wine ok(compare_color(color, test_data[i].expected_color, 1)
/* The Windows 8 testbot appears to return undefined results. */
|| broken(TRUE),
"Got unexpected color 0x%08x, test %u.\n", color, i);
else
ok(compare_color(color, test_data[i].expected_color, 1),
"Got unexpected color 0x%08x, test %u.\n", color, i);
}
destroy_material(material);
material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f);
hr = IDirect3DMaterial_GetHandle(material, device, &mat_handle);
ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
hr = IDirect3DViewport_SetBackground(viewport, mat_handle);
ok(SUCCEEDED(hr), "Failed to set viewport background, hr %#x.\n", hr);
hr = IDirect3DViewport_GetBackground(viewport, &tmp, &valid);
ok(SUCCEEDED(hr), "Failed to get viewport background, hr %#x.\n", hr);
ok(tmp == mat_handle, "Got unexpected material handle %#x, expected %#x.\n", tmp, mat_handle);
ok(valid, "Got unexpected valid %#x.\n", valid);
hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
hr = IDirect3DViewport_SetBackground(viewport, 0);
ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport_GetBackground(viewport, &tmp, &valid);
ok(SUCCEEDED(hr), "Failed to get viewport background, hr %#x.\n", hr);
ok(tmp == mat_handle, "Got unexpected material handle %#x, expected %#x.\n", tmp, mat_handle);
ok(valid, "Got unexpected valid %#x.\n", valid);
hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
destroy_viewport(device, viewport);
viewport = create_viewport(device, 0, 0, 640, 480);
hr = IDirect3DViewport_GetBackground(viewport, &tmp, &valid);
ok(SUCCEEDED(hr), "Failed to get viewport background, hr %#x.\n", hr);
ok(!tmp, "Got unexpected material handle %#x.\n", tmp);
ok(!valid, "Got unexpected valid %#x.\n", valid);
hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color);
IDirect3DExecuteBuffer_Release(execute_buffer);
destroy_viewport(device, viewport);
destroy_material(material);
IDirectDrawSurface_Release(rt);
refcount = IDirect3DDevice_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
refcount = IDirectDraw_Release(ddraw);
ok(!refcount, "Ddraw object has %u references left.\n", refcount);
DestroyWindow(window);
}
START_TEST(ddraw1)
{
IDirectDraw *ddraw;
......@@ -4847,4 +5041,5 @@ START_TEST(ddraw1)
test_mipmap_lock();
test_palette_complex();
test_p8_rgb_blit();
test_material();
}
......@@ -309,10 +309,9 @@ static void destroy_viewport(IDirect3DDevice2 *device, IDirect3DViewport2 *viewp
IDirect3DViewport2_Release(viewport);
}
static IDirect3DMaterial2 *create_diffuse_material(IDirect3DDevice2 *device, float r, float g, float b, float a)
static IDirect3DMaterial2 *create_material(IDirect3DDevice2 *device, D3DMATERIAL *mat)
{
IDirect3DMaterial2 *material;
D3DMATERIAL mat;
IDirect3D2 *d3d;
HRESULT hr;
......@@ -320,17 +319,39 @@ static IDirect3DMaterial2 *create_diffuse_material(IDirect3DDevice2 *device, flo
ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
hr = IDirect3D2_CreateMaterial(d3d, &material, NULL);
ok(SUCCEEDED(hr), "Failed to create material, hr %#x.\n", hr);
hr = IDirect3DMaterial2_SetMaterial(material, mat);
ok(SUCCEEDED(hr), "Failed to set material data, hr %#x.\n", hr);
IDirect3D2_Release(d3d);
return material;
}
static IDirect3DMaterial2 *create_diffuse_material(IDirect3DDevice2 *device, float r, float g, float b, float a)
{
D3DMATERIAL mat;
memset(&mat, 0, sizeof(mat));
mat.dwSize = sizeof(mat);
U1(U(mat).diffuse).r = r;
U2(U(mat).diffuse).g = g;
U3(U(mat).diffuse).b = b;
U4(U(mat).diffuse).a = a;
hr = IDirect3DMaterial2_SetMaterial(material, &mat);
ok(SUCCEEDED(hr), "Failed to set material data, hr %#x.\n", hr);
IDirect3D2_Release(d3d);
return material;
return create_material(device, &mat);
}
static IDirect3DMaterial2 *create_emissive_material(IDirect3DDevice2 *device, float r, float g, float b, float a)
{
D3DMATERIAL mat;
memset(&mat, 0, sizeof(mat));
mat.dwSize = sizeof(mat);
U1(U3(mat).emissive).r = r;
U2(U3(mat).emissive).g = g;
U3(U3(mat).emissive).b = b;
U4(U3(mat).emissive).a = a;
return create_material(device, &mat);
}
static void destroy_material(IDirect3DMaterial2 *material)
......@@ -3299,12 +3320,10 @@ static void test_lighting_interface_versions(void)
IDirect3DDevice2 *device;
IDirectDrawSurface *rt;
IDirectDraw2 *ddraw;
IDirect3D2 *d3d;
D3DCOLOR color;
HWND window;
HRESULT hr;
D3DMATERIALHANDLE mat_handle;
D3DMATERIAL mat_desc;
DWORD rs;
unsigned int i;
ULONG ref;
......@@ -3381,8 +3400,6 @@ static void test_lighting_interface_versions(void)
DestroyWindow(window);
return;
}
hr = IDirectDraw2_QueryInterface(ddraw, &IID_IDirect3D2, (void **)&d3d);
ok(SUCCEEDED(hr), "Failed to get IDirect3D2 interface, hr %#x.\n", hr);
hr = IDirect3DDevice2_GetRenderTarget(device, &rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
......@@ -3391,13 +3408,7 @@ static void test_lighting_interface_versions(void)
hr = IDirect3DDevice2_SetCurrentViewport(device, viewport);
ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
memset(&mat_desc, 0, sizeof(mat_desc));
mat_desc.dwSize = sizeof(mat_desc);
U2(U3(mat_desc).dcvEmissive).g = 1.0f;
hr = IDirect3D2_CreateMaterial(d3d, &emissive, NULL);
ok(SUCCEEDED(hr), "Failed to create material, hr %#x.\n", hr);
hr = IDirect3DMaterial2_SetMaterial(emissive, &mat_desc);
ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
emissive = create_emissive_material(device, 0.0f, 1.0f, 0.0f, 0.0f);
hr = IDirect3DMaterial2_GetHandle(emissive, device, &mat_handle);
ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
......@@ -3406,10 +3417,7 @@ static void test_lighting_interface_versions(void)
ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
background = create_diffuse_material(device, 0.1f, 0.1f, 0.1f, 0.1f);
hr = IDirect3DMaterial2_GetHandle(background, device, &mat_handle);
ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
hr = IDirect3DViewport2_SetBackground(viewport, mat_handle);
ok(SUCCEEDED(hr), "Failed to set background material, hr %#x.\n", hr);
viewport_set_background(device, viewport, background);
hr = IDirect3DDevice2_GetRenderState(device, D3DRENDERSTATE_SPECULARENABLE, &rs);
ok(SUCCEEDED(hr), "Failed to get specularenable render state, hr %#x.\n", hr);
......@@ -3439,11 +3447,10 @@ static void test_lighting_interface_versions(void)
color, tests[i].color, i);
}
IDirect3DMaterial2_Release(background);
IDirect3DMaterial2_Release(emissive);
destroy_material(background);
destroy_material(emissive);
IDirectDrawSurface_Release(rt);
IDirect3DDevice2_Release(device);
IDirect3D2_Release(d3d);
ref = IDirectDraw2_Release(ddraw);
ok(ref == 0, "Ddraw object not properly released, refcount %u.\n", ref);
DestroyWindow(window);
......@@ -5914,6 +5921,147 @@ static void test_p8_rgb_blit(void)
DestroyWindow(window);
}
static void test_material(void)
{
D3DMATERIALHANDLE mat_handle, tmp;
IDirect3DMaterial2 *material;
IDirect3DViewport2 *viewport;
IDirect3DDevice2 *device;
IDirectDrawSurface *rt;
IDirectDraw2 *ddraw;
D3DCOLOR color;
ULONG refcount;
unsigned int i;
HWND window;
HRESULT hr;
BOOL valid;
static D3DVERTEX quad[] =
{
{{-1.0f}, {-1.0f}, {0.0f}, {1.0f}, {0.0f}, {0.0f}},
{{-1.0f}, { 1.0f}, {0.0f}, {1.0f}, {0.0f}, {0.0f}},
{{ 1.0f}, {-1.0f}, {0.0f}, {1.0f}, {0.0f}, {0.0f}},
{{ 1.0f}, { 1.0f}, {0.0f}, {1.0f}, {0.0f}, {0.0f}},
};
static const struct
{
BOOL material;
D3DCOLOR expected_color;
}
test_data[] =
{
{TRUE, 0x0000ff00},
{FALSE, 0x00ffffff},
};
static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
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_GetRenderTarget(device, &rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
material = create_diffuse_material(device, 0.0f, 0.0f, 1.0f, 1.0f);
viewport = create_viewport(device, 0, 0, 640, 480);
viewport_set_background(device, viewport, material);
hr = IDirect3DDevice2_SetCurrentViewport(device, viewport);
ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
destroy_material(material);
material = create_emissive_material(device, 0.0f, 1.0f, 0.0f, 0.0f);
hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle);
ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
hr = IDirect3DDevice2_GetLightState(device, D3DLIGHTSTATE_MATERIAL, &tmp);
ok(SUCCEEDED(hr), "Failed to get light state, hr %#x.\n", hr);
ok(!tmp, "Got unexpected material handle %#x.\n", tmp);
hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
hr = IDirect3DDevice2_GetLightState(device, D3DLIGHTSTATE_MATERIAL, &tmp);
ok(SUCCEEDED(hr), "Failed to get light state, hr %#x.\n", hr);
ok(tmp == mat_handle, "Got unexpected material handle %#x, expected %#x.\n", tmp, mat_handle);
hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, 0);
ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
hr = IDirect3DDevice2_GetLightState(device, D3DLIGHTSTATE_MATERIAL, &tmp);
ok(SUCCEEDED(hr), "Failed to get light state, hr %#x.\n", hr);
ok(!tmp, "Got unexpected material handle %#x.\n", tmp);
for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
{
hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
hr = IDirect3DDevice2_SetLightState(device, D3DLIGHTSTATE_MATERIAL, test_data[i].material ? mat_handle : 0);
ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
hr = IDirect3DDevice2_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_VERTEX, quad, 4, 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(compare_color(color, test_data[i].expected_color, 1),
"Got unexpected color 0x%08x, test %u.\n", color, i);
}
destroy_material(material);
material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f);
hr = IDirect3DMaterial2_GetHandle(material, device, &mat_handle);
ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
hr = IDirect3DViewport2_SetBackground(viewport, mat_handle);
ok(SUCCEEDED(hr), "Failed to set viewport background, hr %#x.\n", hr);
hr = IDirect3DViewport2_GetBackground(viewport, &tmp, &valid);
ok(SUCCEEDED(hr), "Failed to get viewport background, hr %#x.\n", hr);
ok(tmp == mat_handle, "Got unexpected material handle %#x, expected %#x.\n", tmp, mat_handle);
ok(valid, "Got unexpected valid %#x.\n", valid);
hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
hr = IDirect3DViewport2_SetBackground(viewport, 0);
ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport2_GetBackground(viewport, &tmp, &valid);
ok(SUCCEEDED(hr), "Failed to get viewport background, hr %#x.\n", hr);
ok(tmp == mat_handle, "Got unexpected material handle %#x, expected %#x.\n", tmp, mat_handle);
ok(valid, "Got unexpected valid %#x.\n", valid);
hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
destroy_viewport(device, viewport);
viewport = create_viewport(device, 0, 0, 640, 480);
hr = IDirect3DViewport2_GetBackground(viewport, &tmp, &valid);
ok(SUCCEEDED(hr), "Failed to get viewport background, hr %#x.\n", hr);
ok(!tmp, "Got unexpected material handle %#x.\n", tmp);
ok(!valid, "Got unexpected valid %#x.\n", valid);
hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color);
destroy_viewport(device, viewport);
destroy_material(material);
IDirectDrawSurface_Release(rt);
refcount = IDirect3DDevice2_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
refcount = IDirectDraw2_Release(ddraw);
ok(!refcount, "Ddraw object has %u references left.\n", refcount);
DestroyWindow(window);
}
START_TEST(ddraw2)
{
IDirectDraw2 *ddraw;
......@@ -5967,4 +6115,5 @@ START_TEST(ddraw2)
test_mipmap_lock();
test_palette_complex();
test_p8_rgb_blit();
test_material();
}
......@@ -339,6 +339,56 @@ static void destroy_viewport(IDirect3DDevice3 *device, IDirect3DViewport3 *viewp
IDirect3DViewport3_Release(viewport);
}
static IDirect3DMaterial3 *create_material(IDirect3DDevice3 *device, D3DMATERIAL *mat)
{
IDirect3DMaterial3 *material;
IDirect3D3 *d3d;
HRESULT hr;
hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
hr = IDirect3D3_CreateMaterial(d3d, &material, NULL);
ok(SUCCEEDED(hr), "Failed to create material, hr %#x.\n", hr);
hr = IDirect3DMaterial3_SetMaterial(material, mat);
ok(SUCCEEDED(hr), "Failed to set material data, hr %#x.\n", hr);
IDirect3D3_Release(d3d);
return material;
}
static IDirect3DMaterial3 *create_diffuse_material(IDirect3DDevice3 *device, float r, float g, float b, float a)
{
D3DMATERIAL mat;
memset(&mat, 0, sizeof(mat));
mat.dwSize = sizeof(mat);
U1(U(mat).diffuse).r = r;
U2(U(mat).diffuse).g = g;
U3(U(mat).diffuse).b = b;
U4(U(mat).diffuse).a = a;
return create_material(device, &mat);
}
static IDirect3DMaterial3 *create_emissive_material(IDirect3DDevice3 *device, float r, float g, float b, float a)
{
D3DMATERIAL mat;
memset(&mat, 0, sizeof(mat));
mat.dwSize = sizeof(mat);
U1(U3(mat).emissive).r = r;
U2(U3(mat).emissive).g = g;
U3(U3(mat).emissive).b = b;
U4(U3(mat).emissive).a = a;
return create_material(device, &mat);
}
static void destroy_material(IDirect3DMaterial3 *material)
{
IDirect3DMaterial3_Release(material);
}
static const UINT *expect_messages;
static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
......@@ -3569,12 +3619,10 @@ static void test_lighting_interface_versions(void)
IDirect3DViewport3 *viewport;
IDirect3DDevice3 *device;
IDirectDrawSurface4 *rt;
IDirect3D3 *d3d;
D3DCOLOR color;
HWND window;
HRESULT hr;
D3DMATERIALHANDLE mat_handle;
D3DMATERIAL mat_desc;
DWORD rs;
unsigned int i;
ULONG ref;
......@@ -3712,8 +3760,6 @@ static void test_lighting_interface_versions(void)
DestroyWindow(window);
return;
}
hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
ok(SUCCEEDED(hr), "Failed to get IDirect3D3 interface, hr %#x.\n", hr);
hr = IDirect3DDevice3_GetRenderTarget(device, &rt);
ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
......@@ -3722,13 +3768,7 @@ static void test_lighting_interface_versions(void)
hr = IDirect3DDevice3_SetCurrentViewport(device, viewport);
ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
memset(&mat_desc, 0, sizeof(mat_desc));
mat_desc.dwSize = sizeof(mat_desc);
U2(U3(mat_desc).dcvEmissive).g = 1.0f;
hr = IDirect3D3_CreateMaterial(d3d, &emissive, NULL);
ok(SUCCEEDED(hr), "Failed to create material, hr %#x.\n", hr);
hr = IDirect3DMaterial3_SetMaterial(emissive, &mat_desc);
ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
emissive = create_emissive_material(device, 0.0f, 1.0f, 0.0f, 0.0f);
hr = IDirect3DMaterial3_GetHandle(emissive, device, &mat_handle);
ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
......@@ -3764,12 +3804,10 @@ static void test_lighting_interface_versions(void)
color, tests[i].color, i);
}
IDirect3DMaterial3_Release(emissive);
destroy_material(emissive);
IDirectDrawSurface4_Release(rt);
ref = IDirect3DDevice3_Release(device);
ok(ref == 0, "Device not properly released, refcount %u.\n", ref);
ref = IDirect3D3_Release(d3d);
ok(ref == 0, "D3d not properly released, refcount %u.\n", ref);
DestroyWindow(window);
}
......@@ -6775,6 +6813,157 @@ static void test_p8_rgb_blit(void)
DestroyWindow(window);
}
static void test_material(void)
{
D3DMATERIALHANDLE mat_handle, tmp;
IDirect3DMaterial3 *material;
IDirect3DViewport3 *viewport;
IDirect3DDevice3 *device;
IDirectDrawSurface4 *rt;
D3DCOLOR color;
ULONG refcount;
unsigned int i;
HWND window;
HRESULT hr;
BOOL valid;
static struct
{
struct vec3 position;
struct vec3 normal;
D3DCOLOR diffuse;
}
quad1[] =
{
{{-1.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0xffffffff},
{{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0xffffffff},
{{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0xffffffff},
{{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0xffffffff},
},
quad2[] =
{
{{-1.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0xffff0000},
{{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0xffff0000},
{{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0xffff0000},
{{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0xffff0000},
};
static const struct
{
void *data;
BOOL material;
D3DCOLOR expected_color;
}
test_data[] =
{
{quad1, TRUE, 0x0000ff00},
{quad2, TRUE, 0x0000ff00},
{quad1, FALSE, 0x00ffffff},
{quad2, FALSE, 0x00ff0000},
};
static D3DRECT clear_rect = {{0}, {0}, {640}, {480}};
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_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);
material = create_emissive_material(device, 0.0f, 1.0f, 0.0f, 0.0f);
hr = IDirect3DMaterial3_GetHandle(material, device, &mat_handle);
ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
hr = IDirect3DDevice3_GetLightState(device, D3DLIGHTSTATE_MATERIAL, &tmp);
ok(SUCCEEDED(hr), "Failed to get light state, hr %#x.\n", hr);
ok(!tmp, "Got unexpected material handle %#x.\n", tmp);
hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, mat_handle);
ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
hr = IDirect3DDevice3_GetLightState(device, D3DLIGHTSTATE_MATERIAL, &tmp);
ok(SUCCEEDED(hr), "Failed to get light state, hr %#x.\n", hr);
ok(tmp == mat_handle, "Got unexpected material handle %#x, expected %#x.\n", tmp, mat_handle);
hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, 0);
ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
hr = IDirect3DDevice3_GetLightState(device, D3DLIGHTSTATE_MATERIAL, &tmp);
ok(SUCCEEDED(hr), "Failed to get light state, hr %#x.\n", hr);
ok(!tmp, "Got unexpected material handle %#x.\n", tmp);
for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
{
hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
hr = IDirect3DDevice3_SetLightState(device, D3DLIGHTSTATE_MATERIAL, test_data[i].material ? mat_handle : 0);
ok(SUCCEEDED(hr), "Failed to set material state, hr %#x.\n", hr);
hr = IDirect3DDevice3_BeginScene(device);
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP,
D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE, test_data[i].data, 4, 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(compare_color(color, test_data[i].expected_color, 1),
"Got unexpected color 0x%08x, test %u.\n", color, i);
}
destroy_material(material);
material = create_diffuse_material(device, 1.0f, 0.0f, 0.0f, 1.0f);
hr = IDirect3DMaterial3_GetHandle(material, device, &mat_handle);
ok(SUCCEEDED(hr), "Failed to get material handle, hr %#x.\n", hr);
hr = IDirect3DViewport3_SetBackground(viewport, mat_handle);
ok(SUCCEEDED(hr), "Failed to set viewport background, hr %#x.\n", hr);
hr = IDirect3DViewport3_GetBackground(viewport, &tmp, &valid);
ok(SUCCEEDED(hr), "Failed to get viewport background, hr %#x.\n", hr);
ok(tmp == mat_handle, "Got unexpected material handle %#x, expected %#x.\n", tmp, mat_handle);
ok(valid, "Got unexpected valid %#x.\n", valid);
hr = IDirect3DViewport3_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
hr = IDirect3DViewport3_SetBackground(viewport, 0);
ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
hr = IDirect3DViewport3_GetBackground(viewport, &tmp, &valid);
ok(SUCCEEDED(hr), "Failed to get viewport background, hr %#x.\n", hr);
ok(tmp == mat_handle, "Got unexpected material handle %#x, expected %#x.\n", tmp, mat_handle);
ok(valid, "Got unexpected valid %#x.\n", valid);
hr = IDirect3DViewport3_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
destroy_viewport(device, viewport);
viewport = create_viewport(device, 0, 0, 640, 480);
hr = IDirect3DViewport3_GetBackground(viewport, &tmp, &valid);
ok(SUCCEEDED(hr), "Failed to get viewport background, hr %#x.\n", hr);
ok(!tmp, "Got unexpected material handle %#x.\n", tmp);
ok(!valid, "Got unexpected valid %#x.\n", valid);
hr = IDirect3DViewport3_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
color = get_surface_color(rt, 320, 240);
ok(compare_color(color, 0x00000000, 1), "Got unexpected color 0x%08x.\n", color);
destroy_viewport(device, viewport);
destroy_material(material);
IDirectDrawSurface4_Release(rt);
refcount = IDirect3DDevice3_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
DestroyWindow(window);
}
START_TEST(ddraw4)
{
IDirectDraw4 *ddraw;
......@@ -6834,4 +7023,5 @@ START_TEST(ddraw4)
test_mipmap_lock();
test_palette_complex();
test_p8_rgb_blit();
test_material();
}
......@@ -6660,6 +6660,49 @@ static void test_p8_rgb_blit(void)
DestroyWindow(window);
}
static void test_material(void)
{
static const D3DCOLORVALUE null_color;
IDirect3DDevice7 *device;
D3DMATERIAL7 material;
ULONG refcount;
HWND window;
HRESULT hr;
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 = IDirect3DDevice7_GetMaterial(device, &material);
ok(SUCCEEDED(hr), "Failed to get material, hr %#x.\n", hr);
ok(!memcmp(&U(material).diffuse, &null_color, sizeof(null_color)),
"Got unexpected diffuse color {%.8e, %.8e, %.8e, %.8e}.\n",
U1(U(material).diffuse).r, U2(U(material).diffuse).g,
U3(U(material).diffuse).b, U3(U(material).diffuse).a);
ok(!memcmp(&U1(material).ambient, &null_color, sizeof(null_color)),
"Got unexpected ambient color {%.8e, %.8e, %.8e, %.8e}.\n",
U1(U1(material).ambient).r, U2(U1(material).ambient).g,
U3(U1(material).ambient).b, U3(U1(material).ambient).a);
ok(!memcmp(&U2(material).specular, &null_color, sizeof(null_color)),
"Got unexpected specular color {%.8e, %.8e, %.8e, %.8e}.\n",
U1(U2(material).specular).r, U2(U2(material).specular).g,
U3(U2(material).specular).b, U3(U2(material).specular).a);
ok(!memcmp(&U3(material).emissive, &null_color, sizeof(null_color)),
"Got unexpected emissive color {%.8e, %.8e, %.8e, %.8e}.\n",
U1(U3(material).emissive).r, U2(U3(material).emissive).g,
U3(U3(material).emissive).b, U3(U3(material).emissive).a);
ok(U4(material).power == 0.0f, "Got unexpected power %.8e.\n", U4(material).power);
refcount = IDirect3DDevice7_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
DestroyWindow(window);
}
START_TEST(ddraw7)
{
HMODULE module = GetModuleHandleA("ddraw.dll");
......@@ -6726,4 +6769,5 @@ START_TEST(ddraw7)
test_mipmap_lock();
test_palette_complex();
test_p8_rgb_blit();
test_material();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment