Stefan Dösinger : wined3d: Only use 4 component specular colors if GL allows it.

Alexandre Julliard julliard at winehq.org
Fri Jul 10 08:52:06 CDT 2009


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Fri Jul 10 11:28:49 2009 +0200

wined3d: Only use 4 component specular colors if GL allows it.

---

 dlls/wined3d/directx.c         |   47 ++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/state.c           |   36 ++++++++++++++++++++++++++++--
 dlls/wined3d/wined3d_private.h |    1 +
 3 files changed, 81 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 1f5a750..1ba7ca5 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -612,6 +612,33 @@ static BOOL match_dx10_capable(const WineD3D_GL_Info *gl_info, const char *gl_re
     return gl_info->max_glsl_varyings > 44;
 }
 
+/* A GL context is provided by the caller */
+static BOOL match_allows_spec_alpha(const WineD3D_GL_Info *gl_info, const char *gl_renderer)
+{
+    GLenum error;
+    DWORD data[16];
+
+    if(!GL_SUPPORT(EXT_SECONDARY_COLOR)) return FALSE;
+
+    ENTER_GL();
+    while(glGetError());
+    GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data);
+    error = glGetError();
+    LEAVE_GL();
+
+    if(error == GL_NO_ERROR)
+    {
+        TRACE("GL Implementation accepts 4 component specular color pointers\n");
+        return TRUE;
+    }
+    else
+    {
+        TRACE("GL implementation does not accept 4 component specular colors, error %s\n",
+              debug_glerror(error));
+        return FALSE;
+    }
+}
+
 static void quirk_arb_constants(WineD3D_GL_Info *gl_info)
 {
     TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL.\n", gl_info->vs_arb_constantsF);
@@ -721,6 +748,11 @@ static void quirk_clip_varying(WineD3D_GL_Info *gl_info)
     gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING;
 }
 
+static void quirk_allows_specular_alpha(WineD3D_GL_Info *gl_info)
+{
+    gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA;
+}
+
 struct driver_quirk
 {
     BOOL (*match)(const WineD3D_GL_Info *gl_info, const char *gl_renderer);
@@ -770,6 +802,21 @@ struct driver_quirk quirk_table[] =
         match_dx10_capable,
         quirk_clip_varying,
         "Reserved varying for gl_ClipPos"
+    },
+    {
+        /* GL_EXT_secondary_color does not allow 4 component secondary colors, but most
+         * GL implementations accept it. The Mac GL is the only implementation known to
+         * reject it.
+         *
+         * If we can pass 4 component specular colors, do it, because (a) we don't have
+         * to screw around with the data, and (b) the D3D fixed function vertex pipeline
+         * passes specular alpha to the pixel shader if any is used. Otherwise the
+         * specular alpha is used to pass the fog coordinate, which we pass to opengl
+         * via GL_EXT_fog_coord.
+         */
+        match_allows_spec_alpha,
+        quirk_allows_specular_alpha,
+        "Allow specular alpha quirk"
     }
 };
 
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 2158d0b..9f77b5b 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -4199,15 +4199,45 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const struct wine
         VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data));
 
         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
+            GLenum type = e->format_desc->gl_vtx_type;
+            GLint format = e->format_desc->gl_vtx_format;
+
             if (curVBO != e->buffer_object)
             {
                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
                 checkGLcall("glBindBufferARB");
                 curVBO = e->buffer_object;
             }
-            GL_EXTCALL(glSecondaryColorPointerEXT)(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type,
-                    e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
-            checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
+
+            if(format != 4 || (GLINFO_LOCATION.quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
+            {
+                /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
+                 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
+                 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
+                 * 4 component secondary colors use it
+                 */
+                GL_EXTCALL(glSecondaryColorPointerEXT)(format, type,
+                        e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+                checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
+            }
+            else
+            {
+                switch(type)
+                {
+                    case GL_UNSIGNED_BYTE:
+                        GL_EXTCALL(glSecondaryColorPointerEXT)(3, GL_UNSIGNED_BYTE,
+                                e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+                        checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
+                        break;
+
+                    default:
+                        FIXME("Add 4 component specular color pointers for type %x\n", type);
+                        /* Make sure that the right color component is dropped */
+                        GL_EXTCALL(glSecondaryColorPointerEXT)(3, type,
+                                e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
+                        checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
+                }
+            }
             glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
             checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
         } else {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b80c35c..60c363c 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -47,6 +47,7 @@
 #define WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT       0x00000001
 #define WINED3D_QUIRK_SET_TEXCOORD_W            0x00000002
 #define WINED3D_QUIRK_GLSL_CLIP_VARYING         0x00000004
+#define WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA     0x00000008
 
 /* Texture format fixups */
 




More information about the wine-cvs mailing list