Stefan Dösinger wrote:
Am Mittwoch, 2. Januar 2008 12:44:24 schrieb Stefan Dösinger:
Am Mittwoch, 2. Januar 2008 13:38:57 schrieb Alexander Dorofeyev:
In case of colorkey emulation for a texture, if the application wants to select alpha from diffuse color at stage 0, a fixup to modulate with texture alpha more closely matches what the application wants than fixup to just select alpha from texture.
I tested pop3d and Moto Racer 2. Pop3d still works as expected, but moto racer 2 has some missing geometry. It draws some opaque parts of the scene with color keying on, and a diffuse alpha of 0.0, so the alpha test kicks in and the geometry is missing.
Oh now I see this case I haven't thought about. For some reason, or maybe no reason at all, Moto racer sets alphaop to selectarg1 and alphaarg1 to current (diffuse)! That looks kind of strange (if it then gives vertices with diffuse alpha = 0), but maybe it's just "optimizing" by setting states it will need later. And it expects it to work despite diffuse alpha is 0 because it disables alpha blending and alpha test. In wine though the latter state is overriden by colorkey emulation so the result is bad. But I think this can be sorted out by checking ALPHABLENDENABLE, because it's probably a reasonable indicator for telling whether the app is going to give something meaningful in diffuse alpha or not. Do you think something along the lines of attached patch can be an acceptable solution? With it, AVP1 game works properly and it also seems to bring back geometry in moto racer, at least as far as I can tell.
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index c09a0e3..54a156c 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -36,6 +36,8 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
#define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
+static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context); + static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { /* Used for states which are not mapped to a gl state as-is, but used somehow different, * e.g as a parameter for drawing, or which are unimplemented in windows d3d @@ -351,6 +353,8 @@ static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend); glBlendFunc(srcBlend, dstBlend); checkGLcall("glBlendFunc"); + + tex_alphaop(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context); }
static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { @@ -1954,12 +1958,18 @@ static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D op = WINED3DTOP_SELECTARG1; } else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE) { - arg2 = WINED3DTA_TEXTURE; - op = WINED3DTOP_MODULATE; + if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) { + arg2 = WINED3DTA_TEXTURE; + op = WINED3DTOP_MODULATE; + } + else arg1 = WINED3DTA_TEXTURE; } else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE) { - arg1 = WINED3DTA_TEXTURE; - op = WINED3DTOP_MODULATE; + if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) { + arg1 = WINED3DTA_TEXTURE; + op = WINED3DTOP_MODULATE; + } + else arg2 = WINED3DTA_TEXTURE; } } }