Commit 56e9a6e7 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

ddraw: Fix offscreen flag handling in TransformVertices.

parent 606441e5
...@@ -9362,12 +9362,7 @@ static void test_transform_vertices(void) ...@@ -9362,12 +9362,7 @@ static void test_transform_vertices(void)
} }
/* Finally try to figure out how the DWORD dwOffscreen works. /* Finally try to figure out how the DWORD dwOffscreen works.
* Apparently no vertex is offscreen with clipping off, * It is a logical AND of the vertices' dwFlags members. */
* and with clipping on the offscreen flag is set if only one vertex
* is transformed, and this vertex is offscreen.
*
* FIXME: This is wrong. It might be the logical AND of all
* output clip flags. */
vp_data = vp_template; vp_data = vp_template;
vp_data.dwWidth = 5; vp_data.dwWidth = 5;
vp_data.dwHeight = 5; vp_data.dwHeight = 5;
...@@ -9387,17 +9382,38 @@ static void test_transform_vertices(void) ...@@ -9387,17 +9382,38 @@ static void test_transform_vertices(void)
&transformdata, D3DTRANSFORM_CLIPPED, &offscreen); &transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
ok(offscreen == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %x.\n", offscreen); ok(offscreen == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %x.\n", offscreen);
offscreen = 0xdeadbeef;
hr = IDirect3DViewport_TransformVertices(viewport, 2, hr = IDirect3DViewport_TransformVertices(viewport, 2,
&transformdata, D3DTRANSFORM_CLIPPED, &offscreen); &transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
todo_wine ok(offscreen == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %x.\n", offscreen); ok(offscreen == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %x.\n", offscreen);
hr = IDirect3DViewport_TransformVertices(viewport, 3,
&transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
ok(!offscreen, "Offscreen is %x.\n", offscreen);
transformdata.lpIn = cliptest + 1;
hr = IDirect3DViewport_TransformVertices(viewport, 1,
&transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
ok(offscreen == (D3DCLIP_BACK | D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %x.\n", offscreen);
transformdata.lpIn = cliptest + 2; transformdata.lpIn = cliptest + 2;
hr = IDirect3DViewport_TransformVertices(viewport, 1, hr = IDirect3DViewport_TransformVertices(viewport, 1,
&transformdata, D3DTRANSFORM_CLIPPED, &offscreen); &transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
ok(offscreen == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %x.\n", offscreen); ok(offscreen == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %x.\n", offscreen);
offscreen = 0xdeadbeef;
hr = IDirect3DViewport_TransformVertices(viewport, 2,
&transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
ok(offscreen == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %x.\n", offscreen);
transformdata.lpIn = cliptest + 3;
hr = IDirect3DViewport_TransformVertices(viewport, 1,
&transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
ok(offscreen == (D3DCLIP_FRONT | D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %x.\n", offscreen);
transformdata.lpIn = offscreentest; transformdata.lpIn = offscreentest;
transformdata.dwInSize = sizeof(offscreentest[0]); transformdata.dwInSize = sizeof(offscreentest[0]);
......
...@@ -372,8 +372,8 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE ...@@ -372,8 +372,8 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE
* dwVertexCount: The number of vertices to be transformed * dwVertexCount: The number of vertices to be transformed
* lpData: Pointer to the vertex data * lpData: Pointer to the vertex data
* dwFlags: D3DTRANSFORM_CLIPPED or D3DTRANSFORM_UNCLIPPED * dwFlags: D3DTRANSFORM_CLIPPED or D3DTRANSFORM_UNCLIPPED
* lpOffScreen: Set to the clipping plane clipping the vertex, if only one * offscreen: Logical AND of the planes that clipped the vertices if clipping
* vertex is transformed and clipping is on. 0 otherwise * is on. 0 if clipping is off.
* *
* Returns: * Returns:
* D3D_OK on success * D3D_OK on success
...@@ -391,7 +391,7 @@ struct transform_vertices_vertex ...@@ -391,7 +391,7 @@ struct transform_vertices_vertex
}; };
static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
DWORD dwVertexCount, D3DTRANSFORMDATA *lpData, DWORD dwFlags, DWORD *lpOffScreen) DWORD dwVertexCount, D3DTRANSFORMDATA *lpData, DWORD dwFlags, DWORD *offscreen)
{ {
struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
D3DVIEWPORT vp = viewport->viewports.vp1; D3DVIEWPORT vp = viewport->viewports.vp1;
...@@ -401,8 +401,8 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, ...@@ -401,8 +401,8 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
unsigned int i; unsigned int i;
D3DHVERTEX *outH; D3DHVERTEX *outH;
TRACE("iface %p, vertex_count %u, vertex_data %p, flags %#x, clip_plane %p.\n", TRACE("iface %p, vertex_count %u, vertex_data %p, flags %#x, offscreen %p.\n",
iface, dwVertexCount, lpData, dwFlags, lpOffScreen); iface, dwVertexCount, lpData, dwFlags, offscreen);
/* Tests on windows show that Windows crashes when this occurs, /* Tests on windows show that Windows crashes when this occurs,
* so don't return the (intuitive) return value * so don't return the (intuitive) return value
...@@ -428,6 +428,12 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, ...@@ -428,6 +428,12 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
multiply_matrix(&mat, &view_mat, &world_mat); multiply_matrix(&mat, &view_mat, &world_mat);
multiply_matrix(&mat, &viewport->active_device->legacy_projection, &mat); multiply_matrix(&mat, &viewport->active_device->legacy_projection, &mat);
/* The pointer is not tested against NULL on Windows. */
if (dwFlags & D3DTRANSFORM_CLIPPED)
*offscreen = ~0U;
else
*offscreen = 0;
outH = lpData->lpHOut; outH = lpData->lpHOut;
for(i = 0; i < dwVertexCount; i++) for(i = 0; i < dwVertexCount; i++)
{ {
...@@ -460,6 +466,8 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, ...@@ -460,6 +466,8 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
if(z > 1.0) if(z > 1.0)
outH[i].dwFlags |= D3DCLIP_BACK; outH[i].dwFlags |= D3DCLIP_BACK;
*offscreen &= outH[i].dwFlags;
if(outH[i].dwFlags) if(outH[i].dwFlags)
{ {
/* Looks like native just drops the vertex, leaves whatever data /* Looks like native just drops the vertex, leaves whatever data
...@@ -485,22 +493,6 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface, ...@@ -485,22 +493,6 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
out->payload = in->payload; out->payload = in->payload;
} }
/* According to the d3d test, the offscreen flag is set only
* if exactly one vertex is transformed. It's not documented,
* but the test shows that the lpOffscreen flag is set to the
* flag combination of clipping planes that clips the vertex.
*
* If clipping is requested, Windows assumes that the offscreen
* param is a valid pointer.
*/
if(dwVertexCount == 1 && dwFlags & D3DTRANSFORM_CLIPPED)
{
*lpOffScreen = outH[0].dwFlags;
}
else if(*lpOffScreen)
{
*lpOffScreen = 0;
}
wined3d_mutex_unlock(); wined3d_mutex_unlock();
TRACE("All done\n"); TRACE("All done\n");
......
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