Stefan Dösinger : wined3d: A point size fix.

Alexandre Julliard julliard at winehq.org
Fri Oct 26 08:34:52 CDT 2007


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Mon Oct 22 12:15:03 2007 +0200

wined3d: A point size fix.

---

 dlls/wined3d/state.c |   78 +++++++++++++++++++++++++++-----------------------
 1 files changed, 42 insertions(+), 36 deletions(-)

diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 5fe1cec..7e847c9 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -1248,19 +1248,6 @@ static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     }
 }
 
-static void state_psize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    union {
-        DWORD d;
-        float f;
-    } tmpvalue;
-
-    /* FIXME: check that pointSize isn't outside glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize ); or -ve */
-    tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE];
-    TRACE("Set point size to %f\n", tmpvalue.f);
-    glPointSize(tmpvalue.f);
-    checkGLcall("glPointSize(...);");
-}
-
 static void state_psizemin(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     union {
         DWORD d;
@@ -1311,31 +1298,45 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3
 
     /* Default values */
     GLfloat att[3] = {1.0f, 0.0f, 0.0f};
+    union {
+        DWORD d;
+        float f;
+    } pointSize, A, B, C;
 
-    /*
-     * Minimum valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f.
-     * This means that OpenGL will clamp really small point sizes to 1.0f.
-     * To correct for this we need to multiply by the scale factor when sizes
-     * are less than 1.0f. scale_factor =  1.0f / point_size.
-     */
-    GLfloat pointSize = *((float*)&stateblock->renderState[WINED3DRS_POINTSIZE]);
-    if(pointSize > 0.0f) {
-        GLfloat scaleFactor;
+    pointSize.d = stateblock->renderState[WINED3DRS_POINTSIZE];
+    A.d = stateblock->renderState[WINED3DRS_POINTSCALE_A];
+    B.d = stateblock->renderState[WINED3DRS_POINTSCALE_B];
+    C.d = stateblock->renderState[WINED3DRS_POINTSCALE_C];
 
-        if(pointSize < 1.0f) {
-            scaleFactor = pointSize * pointSize;
+    if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
+        GLfloat scaleFactor;
+        float h = stateblock->viewport.Height;
+
+        if(pointSize.f < 1.0f) {
+            /*
+             * Minimum valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f.
+             * This means that OpenGL will clamp really small point sizes to 1.0f.
+             * To correct for this we need to multiply by the scale factor when sizes
+             * are less than 1.0f. scale_factor =  1.0f / point_size.
+             */
+            scaleFactor = pointSize.f;
+        } else if(pointSize.f > GL_LIMITS(pointsize)) {
+            /* gl already scales the input to glPointSize,
+             * d3d scales the result after the point size scale.
+             * If the point size is bigger than the max size, use the
+             * scaling to scale it bigger, and set the gl point size to max
+             */
+            scaleFactor = pointSize.f / GL_LIMITS(pointsize);
+            TRACE("scale: %f\n", scaleFactor);
+            pointSize.f = GL_LIMITS(pointsize);
         } else {
             scaleFactor = 1.0f;
         }
+        scaleFactor = pow(h * scaleFactor, 2);
 
-        if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
-            att[0] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_A]) /
-                    (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
-            att[1] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_B]) /
-                    (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
-            att[2] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_C]) /
-                    (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
-        }
+        att[0] = A.f / scaleFactor;
+        att[1] = B.f / scaleFactor;
+        att[2] = C.f / scaleFactor;
     }
 
     if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
@@ -1345,9 +1346,12 @@ static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3
     else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
         GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
         checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...");
-    } else {
-        TRACE("POINT_PARAMETERS not supported in this version of opengl\n");
+    } else if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
+        WARN("POINT_PARAMETERS not supported in this version of opengl\n");
     }
+
+    glPointSize(pointSize.f);
+    checkGLcall("glPointSize(...);");
 }
 
 static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
@@ -3468,7 +3472,9 @@ static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCon
     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
         transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
     }
-
+    if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) {
+        state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context);
+    }
 }
 
 static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
@@ -3787,7 +3793,7 @@ const struct StateEntry StateTable[] =
     { /*151, WINED3DRS_VERTEXBLEND                  */      STATE_RENDER(WINED3DRS_VERTEXBLEND),                state_vertexblend   },
     { /*152, WINED3DRS_CLIPPLANEENABLE              */      STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      },
     { /*153, WINED3DRS_SOFTWAREVERTEXPROCESSING     */      0,                                                  state_nogl          },
-    { /*154, WINED3DRS_POINTSIZE                    */      STATE_RENDER(WINED3DRS_POINTSIZE),                  state_psize         },
+    { /*154, WINED3DRS_POINTSIZE                    */      STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        },
     { /*155, WINED3DRS_POINTSIZE_MIN                */      STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin      },
     { /*156, WINED3DRS_POINTSPRITEENABLE            */      STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          state_pointsprite   },
     { /*157, WINED3DRS_POINTSCALEENABLE             */      STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        },




More information about the wine-cvs mailing list