From 8a6553da149694f9a188d2b28b46318d37add3ef Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Fri, 10 Jul 2009 11:28:49 +0200 Subject: [PATCH] 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 1f5a75060e..1ba7ca5354 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 2158d0b58e..9f77b5bb15 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 b80c35c77a..60c363cba5 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 */ -- 2.32.0.93.g670b81a890