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

This commit is contained in:
Stefan Dösinger 2009-07-10 11:28:49 +02:00 committed by Alexandre Julliard
parent cce1c44afa
commit 8a6553da14
3 changed files with 81 additions and 3 deletions

View File

@ -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"
}
};

View File

@ -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 {

View File

@ -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 */