ddraw: Fix offscreen flag handling in TransformVertices.
Signed-off-by: Stefan Dösinger <stefandoesinger@gmx.at> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
606441e57e
commit
56e9a6e792
|
@ -9362,12 +9362,7 @@ static void test_transform_vertices(void)
|
|||
}
|
||||
|
||||
/* Finally try to figure out how the DWORD dwOffscreen works.
|
||||
* Apparently no vertex is offscreen with clipping off,
|
||||
* 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. */
|
||||
* It is a logical AND of the vertices' dwFlags members. */
|
||||
vp_data = vp_template;
|
||||
vp_data.dwWidth = 5;
|
||||
vp_data.dwHeight = 5;
|
||||
|
@ -9387,17 +9382,38 @@ static void test_transform_vertices(void)
|
|||
&transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
|
||||
ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
|
||||
ok(offscreen == (D3DCLIP_RIGHT | D3DCLIP_TOP), "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);
|
||||
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;
|
||||
hr = IDirect3DViewport_TransformVertices(viewport, 1,
|
||||
&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);
|
||||
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.dwInSize = sizeof(offscreentest[0]);
|
||||
|
|
|
@ -372,8 +372,8 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE
|
|||
* dwVertexCount: The number of vertices to be transformed
|
||||
* lpData: Pointer to the vertex data
|
||||
* dwFlags: D3DTRANSFORM_CLIPPED or D3DTRANSFORM_UNCLIPPED
|
||||
* lpOffScreen: Set to the clipping plane clipping the vertex, if only one
|
||||
* vertex is transformed and clipping is on. 0 otherwise
|
||||
* offscreen: Logical AND of the planes that clipped the vertices if clipping
|
||||
* is on. 0 if clipping is off.
|
||||
*
|
||||
* Returns:
|
||||
* D3D_OK on success
|
||||
|
@ -391,7 +391,7 @@ struct transform_vertices_vertex
|
|||
};
|
||||
|
||||
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);
|
||||
D3DVIEWPORT vp = viewport->viewports.vp1;
|
||||
|
@ -401,8 +401,8 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
|
|||
unsigned int i;
|
||||
D3DHVERTEX *outH;
|
||||
|
||||
TRACE("iface %p, vertex_count %u, vertex_data %p, flags %#x, clip_plane %p.\n",
|
||||
iface, dwVertexCount, lpData, dwFlags, lpOffScreen);
|
||||
TRACE("iface %p, vertex_count %u, vertex_data %p, flags %#x, offscreen %p.\n",
|
||||
iface, dwVertexCount, lpData, dwFlags, offscreen);
|
||||
|
||||
/* Tests on windows show that Windows crashes when this occurs,
|
||||
* so don't return the (intuitive) return value
|
||||
|
@ -428,6 +428,12 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
|
|||
multiply_matrix(&mat, &view_mat, &world_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;
|
||||
for(i = 0; i < dwVertexCount; i++)
|
||||
{
|
||||
|
@ -460,6 +466,8 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
|
|||
if(z > 1.0)
|
||||
outH[i].dwFlags |= D3DCLIP_BACK;
|
||||
|
||||
*offscreen &= outH[i].dwFlags;
|
||||
|
||||
if(outH[i].dwFlags)
|
||||
{
|
||||
/* Looks like native just drops the vertex, leaves whatever data
|
||||
|
@ -485,22 +493,6 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
|
|||
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();
|
||||
|
||||
TRACE("All done\n");
|
||||
|
|
Loading…
Reference in New Issue