Matteo Bruni : ddraw: Take user clip planes into account in d3d7 ComputeSphereVisibility().

Alexandre Julliard julliard at winehq.org
Tue Mar 14 16:14:37 CDT 2017


Module: wine
Branch: master
Commit: 5f5e83977b8a184b28ced55210978d22ac56a607
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5f5e83977b8a184b28ced55210978d22ac56a607

Author: Matteo Bruni <mbruni at codeweavers.com>
Date:   Tue Mar 14 00:09:55 2017 +0100

ddraw: Take user clip planes into account in d3d7 ComputeSphereVisibility().

Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ddraw/device.c | 105 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 59 insertions(+), 46 deletions(-)

diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 56a4a6b..6e212c9 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -4494,24 +4494,26 @@ static HRESULT WINAPI d3d_device3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface
  *
  *****************************************************************************/
 
-static DWORD in_plane(UINT plane, D3DVECTOR normal, D3DVALUE origin_plane, D3DVECTOR center, D3DVALUE radius)
+static DWORD in_plane(UINT idx, struct wined3d_vec4 p, D3DVECTOR center, D3DVALUE radius)
 {
     float distance, norm;
 
-    norm = sqrtf(normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z);
-    distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm;
+    norm = sqrtf(p.x * p.x + p.y * p.y + p.z * p.z);
+    distance = (p.x * center.u1.x + p.y * center.u2.y + p.z * center.u3.z + p.w) / norm;
 
-    if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane;
-    if ( distance < -radius ) return (D3DSTATUS_CLIPUNIONLEFT  | D3DSTATUS_CLIPINTERSECTIONLEFT) << plane;
+    if (fabs(distance) < radius)
+        return D3DSTATUS_CLIPUNIONLEFT << idx;
+    if (distance < -radius)
+        return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << idx;
     return 0;
 }
 
 static HRESULT WINAPI d3d_device7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
         D3DVECTOR *centers, D3DVALUE *radii, DWORD sphere_count, DWORD flags, DWORD *return_values)
 {
+    struct wined3d_vec4 plane[12];
+    DWORD enabled_planes;
     D3DMATRIX m, temp;
-    D3DVALUE origin_plane[6];
-    D3DVECTOR vec[6];
     HRESULT hr;
     UINT i, j;
 
@@ -4519,56 +4521,67 @@ static HRESULT WINAPI d3d_device7_ComputeSphereVisibility(IDirect3DDevice7 *ifac
             iface, centers, radii, sphere_count, flags, return_values);
 
     hr = d3d_device7_GetTransform(iface, D3DTRANSFORMSTATE_WORLD, &m);
-    if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
+    if (hr != DD_OK)
+        return DDERR_INVALIDPARAMS;
     hr = d3d_device7_GetTransform(iface, D3DTRANSFORMSTATE_VIEW, &temp);
-    if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
+    if (hr != DD_OK)
+        return DDERR_INVALIDPARAMS;
     multiply_matrix(&m, &temp, &m);
 
     hr = d3d_device7_GetTransform(iface, D3DTRANSFORMSTATE_PROJECTION, &temp);
-    if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
+    if (hr != DD_OK)
+        return DDERR_INVALIDPARAMS;
     multiply_matrix(&m, &temp, &m);
 
-/* Left plane */
-    vec[0].u1.x = m._14 + m._11;
-    vec[0].u2.y = m._24 + m._21;
-    vec[0].u3.z = m._34 + m._31;
-    origin_plane[0] = m._44 + m._41;
-
-/* Right plane */
-    vec[1].u1.x = m._14 - m._11;
-    vec[1].u2.y = m._24 - m._21;
-    vec[1].u3.z = m._34 - m._31;
-    origin_plane[1] = m._44 - m._41;
-
-/* Top plane */
-    vec[2].u1.x = m._14 - m._12;
-    vec[2].u2.y = m._24 - m._22;
-    vec[2].u3.z = m._34 - m._32;
-    origin_plane[2] = m._44 - m._42;
-
-/* Bottom plane */
-    vec[3].u1.x = m._14 + m._12;
-    vec[3].u2.y = m._24 + m._22;
-    vec[3].u3.z = m._34 + m._32;
-    origin_plane[3] = m._44 + m._42;
-
-/* Front plane */
-    vec[4].u1.x = m._13;
-    vec[4].u2.y = m._23;
-    vec[4].u3.z = m._33;
-    origin_plane[4] = m._43;
-
-/* Back plane*/
-    vec[5].u1.x = m._14 - m._13;
-    vec[5].u2.y = m._24 - m._23;
-    vec[5].u3.z = m._34 - m._33;
-    origin_plane[5] = m._44 - m._43;
+    IDirect3DDevice7_GetRenderState(iface, D3DRENDERSTATE_CLIPPLANEENABLE, &enabled_planes);
+
+    /* Left plane. */
+    plane[0].x = m._14 + m._11;
+    plane[0].y = m._24 + m._21;
+    plane[0].z = m._34 + m._31;
+    plane[0].w = m._44 + m._41;
+
+    /* Right plane. */
+    plane[1].x = m._14 - m._11;
+    plane[1].y = m._24 - m._21;
+    plane[1].z = m._34 - m._31;
+    plane[1].w = m._44 - m._41;
+
+    /* Top plane. */
+    plane[2].x = m._14 - m._12;
+    plane[2].y = m._24 - m._22;
+    plane[2].z = m._34 - m._32;
+    plane[2].w = m._44 - m._42;
+
+    /* Bottom plane. */
+    plane[3].x = m._14 + m._12;
+    plane[3].y = m._24 + m._22;
+    plane[3].z = m._34 + m._32;
+    plane[3].w = m._44 + m._42;
+
+    /* Front plane. */
+    plane[4].x = m._13;
+    plane[4].y = m._23;
+    plane[4].z = m._33;
+    plane[4].w = m._43;
+
+    /* Back plane. */
+    plane[5].x = m._14 - m._13;
+    plane[5].y = m._24 - m._23;
+    plane[5].z = m._34 - m._33;
+    plane[5].w = m._44 - m._43;
+
+    for (j = 6; j < 12; ++j)
+        IDirect3DDevice7_GetClipPlane(iface, j - 6, (D3DVALUE *)&plane[j]);
 
     for (i = 0; i < sphere_count; ++i)
     {
         return_values[i] = 0;
         for (j = 0; j < 6; ++j)
-            return_values[i] |= in_plane(j, vec[j], origin_plane[j], centers[i], radii[i]);
+            return_values[i] |= in_plane(j, plane[j], centers[i], radii[i]);
+        for (; j < 12; ++j)
+            if (enabled_planes & 1u << (j - 6))
+                return_values[i] |= in_plane(j, plane[j], centers[i], radii[i]);
     }
 
     return D3D_OK;




More information about the wine-cvs mailing list