Home | Info | Community | Development | myReactOS | Contact Us
[static]
Definition at line 399 of file viewport.c.
{ IDirect3DViewportImpl *This = impl_from_IDirect3DViewport3(iface); D3DMATRIX view_mat, world_mat, mat; float *in; float *out; float x, y, z, w; unsigned int i; D3DVIEWPORT vp = This->viewports.vp1; D3DHVERTEX *outH; TRACE("iface %p, vertex_count %u, vertex_data %p, flags %#x, clip_plane %p.\n", iface, 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; } wined3d_mutex_lock(); wined3d_device_get_transform(This->active_device->wined3d_device, D3DTRANSFORMSTATE_VIEW, (struct wined3d_matrix *)&view_mat); wined3d_device_get_transform(This->active_device->wined3d_device, WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix *)&world_mat); multiply_matrix(&mat, &view_mat, &world_mat); multiply_matrix(&mat, &This->active_device->legacy_projection, &mat); in = lpData->lpIn; out = 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 * definitely 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; } wined3d_mutex_unlock(); TRACE("All done\n"); return DD_OK; }