ddraw: Implement IDirect3DViewport3::TransformVertices.
This commit is contained in:
parent
125b9b7dcf
commit
e4bf7ab578
|
@ -818,7 +818,14 @@ static void CapsTest(void)
|
|||
IDirectDraw_Release(dd1);
|
||||
}
|
||||
|
||||
static void ExecutebufferTest(void)
|
||||
struct v_in {
|
||||
float x, y, z;
|
||||
};
|
||||
struct v_out {
|
||||
float x, y, z, rhw;
|
||||
};
|
||||
|
||||
static void Direct3D1Test(void)
|
||||
{
|
||||
IDirect3DDevice *dev1 = NULL;
|
||||
IDirectDraw *dd;
|
||||
|
@ -833,6 +840,21 @@ static void ExecutebufferTest(void)
|
|||
D3DINSTRUCTION *instr;
|
||||
D3DBRANCH *branch;
|
||||
unsigned int idx = 0;
|
||||
static struct v_in testverts[] = {
|
||||
{0.0, 0.0, 0.0}, { 1.0, 1.0, 1.0}, {-1.0, -1.0, -1.0},
|
||||
{0.5, 0.5, 0.5}, {-0.5, -0.5, -0.5}, {-0.5, -0.5, 0.0},
|
||||
};
|
||||
static struct v_in cliptest[] = {
|
||||
{25.59, 25.59, 1.0}, {-25.59, -25.59, 0.0},
|
||||
{25.61, 25.61, 1.01}, {-25.60, -25.60, -0.01},
|
||||
};
|
||||
static struct v_in offscreentest[] = {
|
||||
{128.1, 0.0, 0.0},
|
||||
};
|
||||
struct v_out out[sizeof(testverts) / sizeof(testverts[0])];
|
||||
D3DHVERTEX outH[sizeof(testverts) / sizeof(testverts[0])];
|
||||
D3DTRANSFORMDATA transformdata;
|
||||
DWORD i = FALSE;
|
||||
|
||||
/* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */
|
||||
hr = DirectDrawCreate(NULL, &dd, NULL);
|
||||
|
@ -897,6 +919,7 @@ static void ExecutebufferTest(void)
|
|||
ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr);
|
||||
hr = IDirect3DViewport_Initialize(vp, d3d);
|
||||
ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr);
|
||||
|
||||
hr = IDirect3DDevice_AddViewport(dev1, vp);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
|
||||
vp_data.dwSize = sizeof(vp_data);
|
||||
|
@ -916,8 +939,262 @@ static void ExecutebufferTest(void)
|
|||
hr = IDirect3DDevice_Execute(dev1, exebuf, vp, D3DEXECUTE_CLIPPED);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr);
|
||||
|
||||
memset(&transformdata, 0, sizeof(transformdata));
|
||||
transformdata.dwSize = sizeof(transformdata);
|
||||
transformdata.lpIn = (void *) testverts;
|
||||
transformdata.dwInSize = sizeof(testverts[0]);
|
||||
transformdata.lpOut = out;
|
||||
transformdata.dwOutSize = sizeof(out[0]);
|
||||
|
||||
transformdata.lpHOut = NULL;
|
||||
hr = IDirect3DViewport_TransformVertices(vp, sizeof(testverts) / sizeof(testverts[0]),
|
||||
&transformdata, D3DTRANSFORM_UNCLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
|
||||
transformdata.lpHOut = outH;
|
||||
memset(outH, 0xaa, sizeof(outH));
|
||||
hr = IDirect3DViewport_TransformVertices(vp, sizeof(testverts) / sizeof(testverts[0]),
|
||||
&transformdata, D3DTRANSFORM_UNCLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == 0, "Offscreen is %d\n", i);
|
||||
|
||||
for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
|
||||
static const struct v_out cmp[] = {
|
||||
{128.0, 128.0, 0.0, 1}, {129.0, 127.0, 1.0, 1}, {127.0, 129.0, -1, 1},
|
||||
{128.5, 127.5, 0.5, 1}, {127.5, 128.5, -0.5, 1}, {127.5, 128.5, 0, 1}
|
||||
};
|
||||
|
||||
ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
|
||||
cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
|
||||
"Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
|
||||
out[i].x, out[i].y, out[i].z, out[i].rhw,
|
||||
cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
|
||||
}
|
||||
for(i = 0; i < sizeof(outH); i++) {
|
||||
if(((unsigned char *) outH)[i] != 0xaa) {
|
||||
ok(FALSE, "Homogenous output was generated despite UNCLIPPED flag\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vp_data.dvScaleX = 5;
|
||||
vp_data.dvScaleY = 5;
|
||||
vp_data.dvMinZ = -25;
|
||||
vp_data.dvMaxZ = 60;
|
||||
hr = IDirect3DViewport_SetViewport(vp, &vp_data);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
|
||||
hr = IDirect3DViewport_TransformVertices(vp, sizeof(testverts) / sizeof(testverts[0]),
|
||||
&transformdata, D3DTRANSFORM_UNCLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == 0, "Offscreen is %d\n", i);
|
||||
for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
|
||||
static const struct v_out cmp[] = {
|
||||
{128.0, 128.0, 0.0, 1}, {133.0, 123.0, 1.0, 1}, {123.0, 133.0, -1, 1},
|
||||
{130.5, 125.5, 0.5, 1}, {125.5, 130.5, -0.5, 1}, {125.5, 130.5, 0, 1}
|
||||
};
|
||||
ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
|
||||
cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
|
||||
"Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
|
||||
out[i].x, out[i].y, out[i].z, out[i].rhw,
|
||||
cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
|
||||
}
|
||||
|
||||
vp_data.dwX = 10;
|
||||
vp_data.dwY = 20;
|
||||
hr = IDirect3DViewport_SetViewport(vp, &vp_data);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
|
||||
hr = IDirect3DViewport_TransformVertices(vp, sizeof(testverts) / sizeof(testverts[0]),
|
||||
&transformdata, D3DTRANSFORM_UNCLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == 0, "Offscreen is %d\n", i);
|
||||
for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
|
||||
static const struct v_out cmp[] = {
|
||||
{138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, {133.0, 153.0, -1, 1},
|
||||
{140.5, 145.5, 0.5, 1}, {135.5, 150.5, -0.5, 1}, {135.5, 150.5, 0, 1}
|
||||
};
|
||||
ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
|
||||
cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
|
||||
"Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
|
||||
out[i].x, out[i].y, out[i].z, out[i].rhw,
|
||||
cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
|
||||
}
|
||||
|
||||
memset(out, 0xbb, sizeof(out));
|
||||
hr = IDirect3DViewport_TransformVertices(vp, sizeof(testverts) / sizeof(testverts[0]),
|
||||
&transformdata, D3DTRANSFORM_CLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == 0, "Offscreen is %d\n", i);
|
||||
for(i = 0; i < sizeof(testverts) / sizeof(testverts[0]); i++) {
|
||||
static const D3DHVERTEX cmpH[] = {
|
||||
{0, { 0.0}, { 0.0}, { 0.0}}, {0, { 1.0}, { 1.0}, {1.0}},
|
||||
{D3DCLIP_FRONT, {-1.0}, {-1.0}, {-1.0}}, {0, { 0.5}, { 0.5}, {0.5}},
|
||||
{D3DCLIP_FRONT, {-0.5}, {-0.5}, {-0.5}}, {0, {-0.5}, {-0.5}, {0.0}}
|
||||
};
|
||||
ok(cmpH[i].hx == outH[i].hx && cmpH[i].hy == outH[i].hy &&
|
||||
cmpH[i].hz == outH[i].hz && cmpH[i].dwFlags == outH[i].dwFlags,
|
||||
"HVertex %d differs. Got %08x %f %f %f, expexted %08x %f %f %f\n", i + 1,
|
||||
outH[i].dwFlags, outH[i].hx, outH[i].hy, outH[i].hz,
|
||||
cmpH[i].dwFlags, cmpH[i].hx, cmpH[i].hy, cmpH[i].hz);
|
||||
|
||||
/* No scheme has been found behind those return values. It seems to be
|
||||
* whatever data windows has when throwing the vertex away. Modify the
|
||||
* input test vertices to test this more. Depending on the input data
|
||||
* it can happen that the z coord gets written into y, or simmilar things
|
||||
*/
|
||||
if(0)
|
||||
{
|
||||
static const struct v_out cmp[] = {
|
||||
{138.0, 148.0, 0.0, 1}, {143.0, 143.0, 1.0, 1}, { -1.0, -1.0, 0.5, 1},
|
||||
{140.5, 145.5, 0.5, 1}, { -0.5, -0.5, -0.5, 1}, {135.5, 150.5, 0.0, 1}
|
||||
};
|
||||
ok(cmp[i].x == out[i].x && cmp[i].y == out[i].y &&
|
||||
cmp[i].z == out[i].z && cmp[i].rhw == out[i].rhw,
|
||||
"Vertex %d differs. Got %f %f %f %f, expexted %f %f %f %f\n", i + 1,
|
||||
out[i].x, out[i].y, out[i].z, out[i].rhw,
|
||||
cmp[i].x, cmp[i].y, cmp[i].z, cmp[i].rhw);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < sizeof(out) / sizeof(DWORD); i++) {
|
||||
ok(((DWORD *) out)[i] != 0xbbbbbbbb,
|
||||
"Regular output DWORD %d remained untouched\n", i);
|
||||
}
|
||||
|
||||
transformdata.lpIn = (void *) cliptest;
|
||||
transformdata.dwInSize = sizeof(cliptest[0]);
|
||||
hr = IDirect3DViewport_TransformVertices(vp, sizeof(cliptest) / sizeof(cliptest[0]),
|
||||
&transformdata, D3DTRANSFORM_CLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == 0, "Offscreen is %d\n", i);
|
||||
for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
|
||||
DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
|
||||
{
|
||||
0,
|
||||
0,
|
||||
D3DCLIP_RIGHT | D3DCLIP_BACK | D3DCLIP_TOP,
|
||||
D3DCLIP_LEFT | D3DCLIP_BOTTOM | D3DCLIP_FRONT,
|
||||
};
|
||||
ok(Flags[i] == outH[i].dwFlags,
|
||||
"Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
|
||||
outH[i].dwFlags, Flags[i]);
|
||||
}
|
||||
|
||||
vp_data.dwWidth = 10;
|
||||
vp_data.dwHeight = 1000;
|
||||
hr = IDirect3DViewport_SetViewport(vp, &vp_data);
|
||||
i = 10;
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
|
||||
hr = IDirect3DViewport_TransformVertices(vp, sizeof(cliptest) / sizeof(cliptest[0]),
|
||||
&transformdata, D3DTRANSFORM_CLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == 0, "Offscreen is %d\n", i);
|
||||
for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
|
||||
DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
|
||||
{
|
||||
D3DCLIP_RIGHT,
|
||||
D3DCLIP_LEFT,
|
||||
D3DCLIP_RIGHT | D3DCLIP_BACK,
|
||||
D3DCLIP_LEFT | D3DCLIP_FRONT,
|
||||
};
|
||||
ok(Flags[i] == outH[i].dwFlags,
|
||||
"Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
|
||||
outH[i].dwFlags, Flags[i]);
|
||||
}
|
||||
vp_data.dwWidth = 256;
|
||||
vp_data.dwHeight = 256;
|
||||
vp_data.dvScaleX = 1;
|
||||
vp_data.dvScaleY = 1;
|
||||
hr = IDirect3DViewport_SetViewport(vp, &vp_data);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
|
||||
hr = IDirect3DViewport_TransformVertices(vp, sizeof(cliptest) / sizeof(cliptest[0]),
|
||||
&transformdata, D3DTRANSFORM_CLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == 0, "Offscreen is %s\n", i ? "TRUE" : "FALSE");
|
||||
for(i = 0; i < sizeof(cliptest) / sizeof(cliptest[0]); i++) {
|
||||
DWORD Flags[sizeof(cliptest) / sizeof(cliptest[0])] =
|
||||
{
|
||||
0,
|
||||
0,
|
||||
D3DCLIP_BACK,
|
||||
D3DCLIP_FRONT,
|
||||
};
|
||||
ok(Flags[i] == outH[i].dwFlags,
|
||||
"Cliptest %d differs. Got %08x expexted %08x\n", i + 1,
|
||||
outH[i].dwFlags, Flags[i]);
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
vp_data.dwWidth = 5;
|
||||
vp_data.dwHeight = 5;
|
||||
vp_data.dvScaleX = 10000;
|
||||
vp_data.dvScaleY = 10000;
|
||||
hr = IDirect3DViewport_SetViewport(vp, &vp_data);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr);
|
||||
transformdata.lpIn = cliptest;
|
||||
hr = IDirect3DViewport_TransformVertices(vp, 1,
|
||||
&transformdata, D3DTRANSFORM_UNCLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == 0, "Offscreen is %d\n", i);
|
||||
hr = IDirect3DViewport_TransformVertices(vp, 1,
|
||||
&transformdata, D3DTRANSFORM_CLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %d\n", i);
|
||||
hr = IDirect3DViewport_TransformVertices(vp, 2,
|
||||
&transformdata, D3DTRANSFORM_CLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == 0, "Offscreen is %d\n", i);
|
||||
transformdata.lpIn = cliptest + 1;
|
||||
hr = IDirect3DViewport_TransformVertices(vp, 1,
|
||||
&transformdata, D3DTRANSFORM_CLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %d\n", i);
|
||||
|
||||
transformdata.lpIn = (void *) offscreentest;
|
||||
transformdata.dwInSize = sizeof(offscreentest[0]);
|
||||
vp_data.dwWidth = 257;
|
||||
vp_data.dwHeight = 257;
|
||||
vp_data.dvScaleX = 1;
|
||||
vp_data.dvScaleY = 1;
|
||||
hr = IDirect3DViewport_SetViewport(vp, &vp_data);
|
||||
i = 12345;
|
||||
hr = IDirect3DViewport_TransformVertices(vp, sizeof(offscreentest) / sizeof(offscreentest[0]),
|
||||
&transformdata, D3DTRANSFORM_CLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == 0, "Offscreen is %d\n", i);
|
||||
vp_data.dwWidth = 256;
|
||||
vp_data.dwHeight = 256;
|
||||
hr = IDirect3DViewport_SetViewport(vp, &vp_data);
|
||||
i = 12345;
|
||||
hr = IDirect3DViewport_TransformVertices(vp, sizeof(offscreentest) / sizeof(offscreentest[0]),
|
||||
&transformdata, D3DTRANSFORM_CLIPPED,
|
||||
&i);
|
||||
ok(hr == D3D_OK, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
ok(i == D3DCLIP_RIGHT, "Offscreen is %d\n", i);
|
||||
|
||||
hr = IDirect3DViewport_TransformVertices(vp, sizeof(testverts) / sizeof(testverts[0]),
|
||||
&transformdata, 0,
|
||||
&i);
|
||||
ok(hr == DDERR_INVALIDPARAMS, "IDirect3DViewport_TransformVertices returned %08x\n", hr);
|
||||
|
||||
hr = IDirect3DDevice_DeleteViewport(dev1, vp);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr);
|
||||
ok(hr == D3D_OK, "IDirect3DDevice_DeleteViewport returned %08x\n", hr);
|
||||
|
||||
IDirect3DViewport_Release(vp);
|
||||
IDirect3DExecuteBuffer_Release(exebuf);
|
||||
IDirect3DDevice_Release(dev1);
|
||||
|
@ -946,5 +1223,5 @@ START_TEST(d3d)
|
|||
LimitTest();
|
||||
CapsTest();
|
||||
ReleaseDirect3D();
|
||||
ExecutebufferTest();
|
||||
Direct3D1Test();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Direct3D Viewport
|
||||
* Copyright (c) 1998 Lionel ULMER
|
||||
* Copyright (c) 2006 Stefan DÖSINGER
|
||||
* Copyright (c) 2006-2007 Stefan DÖSINGER
|
||||
*
|
||||
* This file contains the implementation of Direct3DViewport2.
|
||||
*
|
||||
|
@ -325,14 +325,26 @@ IDirect3DViewportImpl_SetViewport(IDirect3DViewport3 *iface,
|
|||
*
|
||||
* Transforms vertices by the transformation matrix.
|
||||
*
|
||||
* This function is pretty simmilar to IDirect3DVertexBuffer7::ProcessVertices,
|
||||
* so its tempting to forward it to ProcessVertices. However, there are some
|
||||
* tiny differences. First, the lpOffscreen flag that is reported back,
|
||||
* then there is the homogenous vertex that is generated. Also there's a lack
|
||||
* of FVFs, but still a custom stride. Last, the d3d1 - d3d3 viewport has some
|
||||
* settings(scale) that d3d7 and wined3d do not have. All in all wrapping to
|
||||
* ProcessVertices doesn't pay of in terms of wrapper code needed and code
|
||||
* reused.
|
||||
*
|
||||
* Params:
|
||||
* dwVertexCount: The number of vertices to be transformed
|
||||
* lpData: Pointer to the vertex data
|
||||
* dwFlags: D3DTRANSFORM_CLIPPED or D3DTRANSFORM_UNCLIPPED
|
||||
* lpOffScreen: Is set to nonzero if all vertices are off-screen
|
||||
* lpOffScreen: Set to the clipping plane clipping the vertex, if only one
|
||||
* vertex is transformed and clipping is on. 0 otherwise
|
||||
*
|
||||
* Returns:
|
||||
* D3D_OK because it's a stub
|
||||
* D3D_OK on success
|
||||
* D3DERR_VIEWPORTHASNODEVICE if the viewport is not assigned to a device
|
||||
* DDERR_INVALIDPARAMS if no clipping flag is specified
|
||||
*
|
||||
*****************************************************************************/
|
||||
static HRESULT WINAPI
|
||||
|
@ -343,9 +355,124 @@ IDirect3DViewportImpl_TransformVertices(IDirect3DViewport3 *iface,
|
|||
DWORD *lpOffScreen)
|
||||
{
|
||||
ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
|
||||
FIXME("(%p)->(%08x,%p,%08x,%p): stub!\n", This, dwVertexCount, lpData, dwFlags, lpOffScreen);
|
||||
if (lpOffScreen)
|
||||
*lpOffScreen = 0;
|
||||
D3DMATRIX view_mat, world_mat, proj_mat, mat;
|
||||
float *in;
|
||||
float *out;
|
||||
float x, y, z, w;
|
||||
unsigned int i;
|
||||
D3DVIEWPORT vp = This->viewports.vp1;
|
||||
D3DHVERTEX *outH;
|
||||
TRACE("(%p)->(%08x,%p,%08x,%p)\n", This, dwVertexCount, lpData, dwFlags, lpOffScreen);
|
||||
|
||||
/* Tests on windows show that Windows crashes when this occurs,
|
||||
* so don't return the (intuitive) return value
|
||||
if(!This->active_device)
|
||||
{
|
||||
WARN("No device active, returning D3DERR_VIEWPORTHASNODEVICE\n");
|
||||
return D3DERR_VIEWPORTHASNODEVICE;
|
||||
}
|
||||
*/
|
||||
|
||||
if(!(dwFlags & (D3DTRANSFORM_UNCLIPPED | D3DTRANSFORM_CLIPPED)))
|
||||
{
|
||||
WARN("No clipping flag passed, returning DDERR_INVALIDPARAMS\n");
|
||||
return DDERR_INVALIDPARAMS;
|
||||
}
|
||||
|
||||
|
||||
EnterCriticalSection(&ddraw_cs);
|
||||
IWineD3DDevice_GetTransform(This->active_device->wineD3DDevice,
|
||||
D3DTRANSFORMSTATE_VIEW,
|
||||
(WINED3DMATRIX*) &view_mat);
|
||||
|
||||
IWineD3DDevice_GetTransform(This->active_device->wineD3DDevice,
|
||||
D3DTRANSFORMSTATE_PROJECTION,
|
||||
(WINED3DMATRIX*) &proj_mat);
|
||||
|
||||
IWineD3DDevice_GetTransform(This->active_device->wineD3DDevice,
|
||||
WINED3DTS_WORLDMATRIX(0),
|
||||
(WINED3DMATRIX*) &world_mat);
|
||||
multiply_matrix(&mat,&view_mat,&world_mat);
|
||||
multiply_matrix(&mat,&proj_mat,&mat);
|
||||
|
||||
in = (float *) lpData->lpIn;
|
||||
out = (float *) lpData->lpOut;
|
||||
outH = lpData->lpHOut;
|
||||
for(i = 0; i < dwVertexCount; i++)
|
||||
{
|
||||
x = (in[0] * mat._11) + (in[1] * mat._21) + (in[2] * mat._31) + (1.0 * mat._41);
|
||||
y = (in[0] * mat._12) + (in[1] * mat._22) + (in[2] * mat._32) + (1.0 * mat._42);
|
||||
z = (in[0] * mat._13) + (in[1] * mat._23) + (in[2] * mat._33) + (1.0 * mat._43);
|
||||
w = (in[0] * mat._14) + (in[1] * mat._24) + (in[2] * mat._34) + (1.0 * mat._44);
|
||||
|
||||
if(dwFlags & D3DTRANSFORM_CLIPPED)
|
||||
{
|
||||
/* If clipping is enabled, Windows assumes that outH is
|
||||
* a valid pointer
|
||||
*/
|
||||
outH[i].u1.hx = x; outH[i].u2.hy = y; outH[i].u3.hz = z;
|
||||
|
||||
outH[i].dwFlags = 0;
|
||||
if(x * vp.dvScaleX > ((float) vp.dwWidth * 0.5))
|
||||
outH[i].dwFlags |= D3DCLIP_RIGHT;
|
||||
if(x * vp.dvScaleX <= -((float) vp.dwWidth) * 0.5)
|
||||
outH[i].dwFlags |= D3DCLIP_LEFT;
|
||||
if(y * vp.dvScaleY > ((float) vp.dwHeight * 0.5))
|
||||
outH[i].dwFlags |= D3DCLIP_TOP;
|
||||
if(y * vp.dvScaleY <= -((float) vp.dwHeight) * 0.5)
|
||||
outH[i].dwFlags |= D3DCLIP_BOTTOM;
|
||||
if(z < 0.0)
|
||||
outH[i].dwFlags |= D3DCLIP_FRONT;
|
||||
if(z > 1.0)
|
||||
outH[i].dwFlags |= D3DCLIP_BACK;
|
||||
|
||||
if(outH[i].dwFlags)
|
||||
{
|
||||
/* Looks like native just drops the vertex, leaves whatever data
|
||||
* it has in the output buffer and goes on with the next vertex.
|
||||
* The exact scheme hasn't been figured out yet, but windows
|
||||
* definitly writes something there.
|
||||
*/
|
||||
out[0] = x;
|
||||
out[1] = y;
|
||||
out[2] = z;
|
||||
out[3] = w;
|
||||
in = (float *) ((char *) in + lpData->dwInSize);
|
||||
out = (float *) ((char *) out + lpData->dwOutSize);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
w = 1 / w;
|
||||
x *= w; y *= w; z *= w;
|
||||
|
||||
out[0] = vp.dwWidth / 2 + vp.dwX + x * vp.dvScaleX;
|
||||
out[1] = vp.dwHeight / 2 + vp.dwY - y * vp.dvScaleY;
|
||||
out[2] = z;
|
||||
out[3] = w;
|
||||
in = (float *) ((char *) in + lpData->dwInSize);
|
||||
out = (float *) ((char *) out + lpData->dwOutSize);
|
||||
}
|
||||
|
||||
/* According to the d3d test, the offscreen flag is set only
|
||||
* if exactly one vertex is transformed. Its 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;
|
||||
}
|
||||
LeaveCriticalSection(&ddraw_cs);
|
||||
|
||||
TRACE("All done\n");
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue