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