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