Commit 2003c7ab authored by Jason Edmeades's avatar Jason Edmeades Committed by Alexandre Julliard

Add {G,S}etRenderState and {G,S}etTextureStageState support, and

ensure the stateblock is fully populated at device startup.
parent 20f83973
......@@ -374,15 +374,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetClipPlane(LPDIRECT3DDEVICE9 iface, DWOR
HRESULT WINAPI IDirect3DDevice9Impl_SetRenderState(LPDIRECT3DDEVICE9 iface, D3DRENDERSTATETYPE State, DWORD Value) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
FIXME("(%p) : stub\n", This);
return D3D_OK;
return IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
}
HRESULT WINAPI IDirect3DDevice9Impl_GetRenderState(LPDIRECT3DDEVICE9 iface, D3DRENDERSTATETYPE State, DWORD* pValue) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
TRACE("(%p) for State %d = %ld\n", This, State, This->UpdateStateBlock->renderstate[State]);
*pValue = This->StateBlock->renderstate[State];
return D3D_OK;
return IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
}
HRESULT WINAPI IDirect3DDevice9Impl_SetClipStatus(LPDIRECT3DDEVICE9 iface, CONST D3DCLIPSTATUS9* pClipStatus) {
......@@ -411,15 +408,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetTexture(LPDIRECT3DDEVICE9 iface, DWORD
HRESULT WINAPI IDirect3DDevice9Impl_GetTextureStageState(LPDIRECT3DDEVICE9 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->UpdateStateBlock->texture_state[Stage][Type]);
*pValue = This->UpdateStateBlock->texture_state[Stage][Type];
return D3D_OK;
return IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, Type, pValue);
}
HRESULT WINAPI IDirect3DDevice9Impl_SetTextureStageState(LPDIRECT3DDEVICE9 iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
FIXME("(%p) : stub\n", This);
return D3D_OK;
return IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, Type, Value);
}
HRESULT WINAPI IDirect3DDevice9Impl_GetSamplerState(LPDIRECT3DDEVICE9 iface, DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* pValue) {
......
......@@ -124,6 +124,79 @@ void setup_light(IWineD3DDevice *iface, LONG Index, PLIGHTINFOEL *lightInfo) {
glPopMatrix();
}
/* Apply the current values to the specified texture stage */
void WINAPI IWineD3DDeviceImpl_SetupTextureStates(IWineD3DDevice *iface, DWORD Stage, DWORD Flags) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
int i = 0;
float col[4];
BOOL changeTexture = TRUE;
TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
for (i = 1; i < HIGHEST_TEXTURE_STATE; i++) {
BOOL skip = FALSE;
switch (i) {
/* Performance: For texture states where multiples effect the outcome, only bother
applying the last one as it will pick up all the other values */
case D3DTSS_COLORARG0: /* Will be picked up when setting color op */
case D3DTSS_COLORARG1: /* Will be picked up when setting color op */
case D3DTSS_COLORARG2: /* Will be picked up when setting color op */
case D3DTSS_ALPHAARG0: /* Will be picked up when setting alpha op */
case D3DTSS_ALPHAARG1: /* Will be picked up when setting alpha op */
case D3DTSS_ALPHAARG2: /* Will be picked up when setting alpha op */
skip = TRUE;
break;
/* Performance: If the texture states only impact settings for the texture unit
(compared to the texture object) then there is no need to reapply them. The
only time they need applying is the first time, since we cheat and put the
values into the stateblock without applying.
Per-texture unit: texture function (eg. combine), ops and args
texture env color
texture generation settings
Note: Due to some special conditions there may be a need to do particular ones
of these, which is what the Flags allows */
case D3DTSS_COLOROP:
case D3DTSS_TEXCOORDINDEX:
if (!(Flags == REAPPLY_ALL)) skip=TRUE;
break;
case D3DTSS_ALPHAOP:
if (!(Flags & REAPPLY_ALPHAOP)) skip=TRUE;
break;
default:
skip = FALSE;
}
if (skip == FALSE) {
/* Performance: Only change to this texture if we have to */
if (changeTexture) {
/* Make appropriate texture active */
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_ACTIVETEXTURE(Stage);
} else if (Stage > 0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
}
changeTexture = FALSE;
}
/* Now apply the change */
IWineD3DDevice_SetTextureStageState(iface, Stage, i, This->stateBlock->textureState[Stage][i]);
}
}
/* Note the D3DRS value applies to all textures, but GL has one
* per texture, so apply it now ready to be used!
*/
D3DCOLORTOGLFLOAT4(This->stateBlock->renderState[D3DRS_TEXTUREFACTOR], col);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
TRACE("-----------------------> Updated the texture at stage %ld to have new texture state information\n", Stage);
}
/**********************************************************
* IWineD3DDevice implementation follows
**********************************************************/
......@@ -347,7 +420,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_SetTransform(IWineD3DDevice *iface, D3DTRANS
GL_ACTIVETEXTURE(tex);
#if 0 /* TODO: */
set_texture_matrix((float *)lpmatrix,
This->updateStateBlock->texture_state[tex][D3DTSS_TEXTURETRANSFORMFLAGS]);
This->updateStateBlock->textureState[tex][D3DTSS_TEXTURETRANSFORMFLAGS]);
#endif
}
......@@ -992,13 +1065,10 @@ HRESULT WINAPI IWineD3DDeviceImpl_SetMaterial(IWineD3DDevice *iface, CONST WINED
checkGLcall("glMaterialfv");
/* Only change material color if specular is enabled, otherwise it is set to black */
#if 0 /* TODO */
if (This->stateBlock->renderstate[D3DRS_SPECULARENABLE]) {
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->UpdateStateBlock->material.Specular);
if (This->stateBlock->renderState[D3DRS_SPECULARENABLE]) {
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->updateStateBlock->material.Specular);
checkGLcall("glMaterialfv");
} else {
#endif
{
float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
checkGLcall("glMaterialfv");
......@@ -1108,6 +1178,1418 @@ HRESULT WINAPI IWineD3DDeviceImpl_GetViewport(IWineD3DDevice *iface, WINED3DVIEW
}
/*****
* Get / Set Render States
* TODO: Verify against dx9 definitions
*****/
HRESULT WINAPI IWineD3DDeviceImpl_SetRenderState(IWineD3DDevice *iface, D3DRENDERSTATETYPE State, DWORD Value) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
DWORD OldValue = This->stateBlock->renderState[State];
/* Simple way of refering to either a DWORD or a 4 byte float */
union {
DWORD d;
float f;
} tmpvalue;
TRACE("(%p)->state = %s(%d), value = %ld\n", This, debug_d3drenderstate(State), State, Value);
This->updateStateBlock->changed.renderState[State] = TRUE;
This->updateStateBlock->set.renderState[State] = TRUE;
This->updateStateBlock->renderState[State] = Value;
/* Handle recording of state blocks */
if (This->isRecordingState) {
TRACE("Recording... not performing anything\n");
return D3D_OK;
}
ENTER_GL();
switch (State) {
case D3DRS_FILLMODE :
switch ((D3DFILLMODE) Value) {
case D3DFILL_POINT : glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); break;
case D3DFILL_WIREFRAME : glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;
case D3DFILL_SOLID : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;
default:
FIXME("Unrecognized D3DRS_FILLMODE value %ld\n", Value);
}
checkGLcall("glPolygonMode (fillmode)");
break;
case D3DRS_LIGHTING :
if (Value) {
glEnable(GL_LIGHTING);
checkGLcall("glEnable GL_LIGHTING");
} else {
glDisable(GL_LIGHTING);
checkGLcall("glDisable GL_LIGHTING");
}
break;
case D3DRS_ZENABLE :
switch ((D3DZBUFFERTYPE) Value) {
case D3DZB_FALSE:
glDisable(GL_DEPTH_TEST);
checkGLcall("glDisable GL_DEPTH_TEST");
break;
case D3DZB_TRUE:
glEnable(GL_DEPTH_TEST);
checkGLcall("glEnable GL_DEPTH_TEST");
break;
case D3DZB_USEW:
glEnable(GL_DEPTH_TEST);
checkGLcall("glEnable GL_DEPTH_TEST");
FIXME("W buffer is not well handled\n");
break;
default:
FIXME("Unrecognized D3DZBUFFERTYPE value %ld\n", Value);
}
break;
case D3DRS_CULLMODE :
/* If we are culling "back faces with clockwise vertices" then
set front faces to be counter clockwise and enable culling
of back faces */
switch ((D3DCULL) Value) {
case D3DCULL_NONE:
glDisable(GL_CULL_FACE);
checkGLcall("glDisable GL_CULL_FACE");
break;
case D3DCULL_CW:
glEnable(GL_CULL_FACE);
checkGLcall("glEnable GL_CULL_FACE");
if (This->renderUpsideDown) {
glFrontFace(GL_CW);
checkGLcall("glFrontFace GL_CW");
} else {
glFrontFace(GL_CCW);
checkGLcall("glFrontFace GL_CCW");
}
glCullFace(GL_BACK);
break;
case D3DCULL_CCW:
glEnable(GL_CULL_FACE);
checkGLcall("glEnable GL_CULL_FACE");
if (This->renderUpsideDown) {
glFrontFace(GL_CCW);
checkGLcall("glFrontFace GL_CCW");
} else {
glFrontFace(GL_CW);
checkGLcall("glFrontFace GL_CW");
}
glCullFace(GL_BACK);
break;
default:
FIXME("Unrecognized/Unhandled D3DCULL value %ld\n", Value);
}
break;
case D3DRS_SHADEMODE :
switch ((D3DSHADEMODE) Value) {
case D3DSHADE_FLAT:
glShadeModel(GL_FLAT);
checkGLcall("glShadeModel");
break;
case D3DSHADE_GOURAUD:
glShadeModel(GL_SMOOTH);
checkGLcall("glShadeModel");
break;
case D3DSHADE_PHONG:
FIXME("D3DSHADE_PHONG isn't supported?\n");
LEAVE_GL();
return D3DERR_INVALIDCALL;
default:
FIXME("Unrecognized/Unhandled D3DSHADEMODE value %ld\n", Value);
}
break;
case D3DRS_DITHERENABLE :
if (Value) {
glEnable(GL_DITHER);
checkGLcall("glEnable GL_DITHER");
} else {
glDisable(GL_DITHER);
checkGLcall("glDisable GL_DITHER");
}
break;
case D3DRS_ZWRITEENABLE :
if (Value) {
glDepthMask(1);
checkGLcall("glDepthMask");
} else {
glDepthMask(0);
checkGLcall("glDepthMask");
}
break;
case D3DRS_ZFUNC :
{
int glParm = GL_LESS;
switch ((D3DCMPFUNC) Value) {
case D3DCMP_NEVER: glParm=GL_NEVER; break;
case D3DCMP_LESS: glParm=GL_LESS; break;
case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
case D3DCMP_GREATER: glParm=GL_GREATER; break;
case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
default:
FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
}
glDepthFunc(glParm);
checkGLcall("glDepthFunc");
}
break;
case D3DRS_AMBIENT :
{
float col[4];
D3DCOLORTOGLFLOAT4(Value, col);
TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
checkGLcall("glLightModel for MODEL_AMBIENT");
}
break;
case D3DRS_ALPHABLENDENABLE :
if (Value) {
glEnable(GL_BLEND);
checkGLcall("glEnable GL_BLEND");
} else {
glDisable(GL_BLEND);
checkGLcall("glDisable GL_BLEND");
};
break;
case D3DRS_SRCBLEND :
case D3DRS_DESTBLEND :
{
int newVal = GL_ZERO;
switch (Value) {
case D3DBLEND_ZERO : newVal = GL_ZERO; break;
case D3DBLEND_ONE : newVal = GL_ONE; break;
case D3DBLEND_SRCCOLOR : newVal = GL_SRC_COLOR; break;
case D3DBLEND_INVSRCCOLOR : newVal = GL_ONE_MINUS_SRC_COLOR; break;
case D3DBLEND_SRCALPHA : newVal = GL_SRC_ALPHA; break;
case D3DBLEND_INVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA; break;
case D3DBLEND_DESTALPHA : newVal = GL_DST_ALPHA; break;
case D3DBLEND_INVDESTALPHA : newVal = GL_ONE_MINUS_DST_ALPHA; break;
case D3DBLEND_DESTCOLOR : newVal = GL_DST_COLOR; break;
case D3DBLEND_INVDESTCOLOR : newVal = GL_ONE_MINUS_DST_COLOR; break;
case D3DBLEND_SRCALPHASAT : newVal = GL_SRC_ALPHA_SATURATE; break;
case D3DBLEND_BOTHSRCALPHA : newVal = GL_SRC_ALPHA;
This->srcBlend = newVal;
This->dstBlend = newVal;
break;
case D3DBLEND_BOTHINVSRCALPHA : newVal = GL_ONE_MINUS_SRC_ALPHA;
This->srcBlend = newVal;
This->dstBlend = newVal;
break;
default:
FIXME("Unrecognized src/dest blend value %ld (%d)\n", Value, State);
}
if (State == D3DRS_SRCBLEND) This->srcBlend = newVal;
if (State == D3DRS_DESTBLEND) This->dstBlend = newVal;
TRACE("glBlendFunc src=%x, dst=%x\n", This->srcBlend, This->dstBlend);
glBlendFunc(This->srcBlend, This->dstBlend);
checkGLcall("glBlendFunc");
}
break;
case D3DRS_ALPHATESTENABLE :
if (Value) {
glEnable(GL_ALPHA_TEST);
checkGLcall("glEnable GL_ALPHA_TEST");
} else {
glDisable(GL_ALPHA_TEST);
checkGLcall("glDisable GL_ALPHA_TEST");
}
break;
case D3DRS_ALPHAFUNC :
{
int glParm = GL_LESS;
float ref = ((float) This->stateBlock->renderState[D3DRS_ALPHAREF]) / 255.0f;
switch ((D3DCMPFUNC) Value) {
case D3DCMP_NEVER: glParm = GL_NEVER; break;
case D3DCMP_LESS: glParm = GL_LESS; break;
case D3DCMP_EQUAL: glParm = GL_EQUAL; break;
case D3DCMP_LESSEQUAL: glParm = GL_LEQUAL; break;
case D3DCMP_GREATER: glParm = GL_GREATER; break;
case D3DCMP_NOTEQUAL: glParm = GL_NOTEQUAL; break;
case D3DCMP_GREATEREQUAL: glParm = GL_GEQUAL; break;
case D3DCMP_ALWAYS: glParm = GL_ALWAYS; break;
default:
FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
}
TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
glAlphaFunc(glParm, ref);
This->alphafunc = glParm;
checkGLcall("glAlphaFunc");
}
break;
case D3DRS_ALPHAREF :
{
int glParm = This->alphafunc;
float ref = 1.0f;
ref = ((float) Value) / 255.0f;
TRACE("glAlphaFunc with Parm=%x, ref=%f\n", glParm, ref);
glAlphaFunc(glParm, ref);
checkGLcall("glAlphaFunc");
}
break;
case D3DRS_CLIPPLANEENABLE :
case D3DRS_CLIPPING :
{
/* Ensure we only do the changed clip planes */
DWORD enable = 0xFFFFFFFF;
DWORD disable = 0x00000000;
/* If enabling / disabling all */
if (State == D3DRS_CLIPPING) {
if (Value) {
enable = This->stateBlock->renderState[D3DRS_CLIPPLANEENABLE];
disable = 0x00;
} else {
disable = This->stateBlock->renderState[D3DRS_CLIPPLANEENABLE];
enable = 0x00;
}
} else {
enable = Value & ~OldValue;
disable = ~Value & OldValue;
}
if (enable & D3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
if (enable & D3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
if (enable & D3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
if (enable & D3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
if (enable & D3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
if (enable & D3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
if (disable & D3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
if (disable & D3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
if (disable & D3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
if (disable & D3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
if (disable & D3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
if (disable & D3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
/** update clipping status */
if (enable) {
This->stateBlock->clip_status.ClipUnion = 0;
This->stateBlock->clip_status.ClipIntersection = 0xFFFFFFFF;
} else {
This->stateBlock->clip_status.ClipUnion = 0;
This->stateBlock->clip_status.ClipIntersection = 0;
}
}
break;
case D3DRS_BLENDOP :
{
int glParm = GL_FUNC_ADD;
switch ((D3DBLENDOP) Value) {
case D3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
case D3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
case D3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
case D3DBLENDOP_MIN : glParm = GL_MIN; break;
case D3DBLENDOP_MAX : glParm = GL_MAX; break;
default:
FIXME("Unrecognized/Unhandled D3DBLENDOP value %ld\n", Value);
}
TRACE("glBlendEquation(%x)\n", glParm);
glBlendEquation(glParm);
checkGLcall("glBlendEquation");
}
break;
case D3DRS_TEXTUREFACTOR :
{
unsigned int i;
/* Note the texture color applies to all textures whereas
GL_TEXTURE_ENV_COLOR applies to active only */
float col[4];
D3DCOLORTOGLFLOAT4(Value, col);
/* Set the default alpha blend color */
glBlendColor(col[0], col[1], col[2], col[3]);
checkGLcall("glBlendColor");
/* And now the default texture color as well */
for (i = 0; i < GL_LIMITS(textures); i++) {
/* Note the D3DRS value applies to all textures, but GL has one
per texture, so apply it now ready to be used! */
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_ACTIVETEXTURE(i);
} else if (i>0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
}
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
}
}
break;
case D3DRS_SPECULARENABLE :
{
/* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
specular color. This is wrong:
Separate specular color means the specular colour is maintained separately, whereas
single color means it is merged in. However in both cases they are being used to
some extent.
To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
running 1.4 yet!
*/
if (Value) {
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->updateStateBlock->material.Specular);
checkGLcall("glMaterialfv");
if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
glEnable(GL_COLOR_SUM_EXT);
} else {
TRACE("Specular colors cannot be enabled in this version of opengl\n");
}
checkGLcall("glEnable(GL_COLOR_SUM)");
} else {
float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* for the case of enabled lighting: */
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
checkGLcall("glMaterialfv");
/* for the case of disabled lighting: */
if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
glDisable(GL_COLOR_SUM_EXT);
} else {
TRACE("Specular colors cannot be disabled in this version of opengl\n");
}
checkGLcall("glDisable(GL_COLOR_SUM)");
}
}
break;
case D3DRS_STENCILENABLE :
if (Value) {
glEnable(GL_STENCIL_TEST);
checkGLcall("glEnable GL_STENCIL_TEST");
} else {
glDisable(GL_STENCIL_TEST);
checkGLcall("glDisable GL_STENCIL_TEST");
}
break;
case D3DRS_STENCILFUNC :
{
int glParm = GL_ALWAYS;
int ref = This->stateBlock->renderState[D3DRS_STENCILREF];
GLuint mask = This->stateBlock->renderState[D3DRS_STENCILMASK];
switch ((D3DCMPFUNC) Value) {
case D3DCMP_NEVER: glParm=GL_NEVER; break;
case D3DCMP_LESS: glParm=GL_LESS; break;
case D3DCMP_EQUAL: glParm=GL_EQUAL; break;
case D3DCMP_LESSEQUAL: glParm=GL_LEQUAL; break;
case D3DCMP_GREATER: glParm=GL_GREATER; break;
case D3DCMP_NOTEQUAL: glParm=GL_NOTEQUAL; break;
case D3DCMP_GREATEREQUAL: glParm=GL_GEQUAL; break;
case D3DCMP_ALWAYS: glParm=GL_ALWAYS; break;
default:
FIXME("Unrecognized/Unhandled D3DCMPFUNC value %ld\n", Value);
}
TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
This->stencilfunc = glParm;
glStencilFunc(glParm, ref, mask);
checkGLcall("glStencilFunc");
}
break;
case D3DRS_STENCILREF :
{
int glParm = This->stencilfunc;
int ref = 0;
GLuint mask = This->stateBlock->renderState[D3DRS_STENCILMASK];
ref = Value;
TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
glStencilFunc(glParm, ref, mask);
checkGLcall("glStencilFunc");
}
break;
case D3DRS_STENCILMASK :
{
int glParm = This->stencilfunc;
int ref = This->stateBlock->renderState[D3DRS_STENCILREF];
GLuint mask = Value;
TRACE("glStencilFunc with Parm=%x, ref=%d, mask=%x\n", glParm, ref, mask);
glStencilFunc(glParm, ref, mask);
checkGLcall("glStencilFunc");
}
break;
case D3DRS_STENCILFAIL :
{
GLenum fail ;
GLenum zpass ;
GLenum zfail ;
fail = StencilOp(Value);
glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
glStencilOp(fail, zfail, zpass);
checkGLcall("glStencilOp(fail, zfail, zpass);");
}
break;
case D3DRS_STENCILZFAIL :
{
GLenum fail ;
GLenum zpass ;
GLenum zfail ;
glGetIntegerv(GL_STENCIL_FAIL, &fail);
checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);
checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &zpass);");
zfail = StencilOp(Value);
TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
glStencilOp(fail, zfail, zpass);
checkGLcall("glStencilOp(fail, zfail, zpass);");
}
break;
case D3DRS_STENCILPASS :
{
GLenum fail ;
GLenum zpass ;
GLenum zfail ;
glGetIntegerv(GL_STENCIL_FAIL, &fail);
checkGLcall("glGetIntegerv(GL_STENCIL_FAIL, &fail);");
zpass = StencilOp(Value);
glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);
checkGLcall("glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &zfail);");
TRACE("StencilOp fail=%x, zfail=%x, zpass=%x\n", fail, zfail, zpass);
glStencilOp(fail, zfail, zpass);
checkGLcall("glStencilOp(fail, zfail, zpass);");
}
break;
case D3DRS_STENCILWRITEMASK :
{
glStencilMask(Value);
TRACE("glStencilMask(%lu)\n", Value);
checkGLcall("glStencilMask");
}
break;
case D3DRS_FOGENABLE :
{
if (Value/* && This->stateBlock->renderState[D3DRS_FOGTABLEMODE] != D3DFOG_NONE*/) {
glEnable(GL_FOG);
checkGLcall("glEnable GL_FOG");
} else {
glDisable(GL_FOG);
checkGLcall("glDisable GL_FOG");
}
}
break;
case D3DRS_RANGEFOGENABLE :
{
if (Value) {
TRACE("Enabled RANGEFOG");
} else {
TRACE("Disabled RANGEFOG");
}
}
break;
case D3DRS_FOGCOLOR :
{
float col[4];
D3DCOLORTOGLFLOAT4(Value, col);
/* Set the default alpha blend color */
glFogfv(GL_FOG_COLOR, &col[0]);
checkGLcall("glFog GL_FOG_COLOR");
}
break;
case D3DRS_FOGTABLEMODE :
{
glHint(GL_FOG_HINT, GL_NICEST);
switch (Value) {
case D3DFOG_NONE: /* I don't know what to do here */ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
case D3DFOG_EXP: glFogi(GL_FOG_MODE, GL_EXP); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
case D3DFOG_EXP2: glFogi(GL_FOG_MODE, GL_EXP2); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break;
case D3DFOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break;
default:
FIXME("Unsupported Value(%lu) for D3DRS_FOGTABLEMODE!\n", Value);
}
if (GL_SUPPORT(NV_FOG_DISTANCE)) {
glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
}
}
break;
case D3DRS_FOGVERTEXMODE :
{
glHint(GL_FOG_HINT, GL_FASTEST);
switch (Value) {
case D3DFOG_NONE: /* I don't know what to do here */ checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
case D3DFOG_EXP: glFogi(GL_FOG_MODE, GL_EXP); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP"); break;
case D3DFOG_EXP2: glFogi(GL_FOG_MODE, GL_EXP2); checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2"); break;
case D3DFOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR); checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR"); break;
default:
FIXME("Unsupported Value(%lu) for D3DRS_FOGTABLEMODE!\n", Value);
}
if (GL_SUPPORT(NV_FOG_DISTANCE)) {
glFogi(GL_FOG_DISTANCE_MODE_NV, This->stateBlock->renderState[D3DRS_RANGEFOGENABLE] ? GL_EYE_RADIAL_NV : GL_EYE_PLANE_ABSOLUTE_NV);
}
}
break;
case D3DRS_FOGSTART :
{
tmpvalue.d = Value;
glFogfv(GL_FOG_START, &tmpvalue.f);
checkGLcall("glFogf(GL_FOG_START, (float) Value)");
TRACE("Fog Start == %f\n", tmpvalue.f);
}
break;
case D3DRS_FOGEND :
{
tmpvalue.d = Value;
glFogfv(GL_FOG_END, &tmpvalue.f);
checkGLcall("glFogf(GL_FOG_END, (float) Value)");
TRACE("Fog End == %f\n", tmpvalue.f);
}
break;
case D3DRS_FOGDENSITY :
{
tmpvalue.d = Value;
glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
}
break;
case D3DRS_VERTEXBLEND :
{
This->updateStateBlock->vertex_blend = (D3DVERTEXBLENDFLAGS) Value;
TRACE("Vertex Blending state to %ld\n", Value);
}
break;
case D3DRS_TWEENFACTOR :
{
tmpvalue.d = Value;
This->updateStateBlock->tween_factor = tmpvalue.f;
TRACE("Vertex Blending Tween Factor to %f\n", This->updateStateBlock->tween_factor);
}
break;
case D3DRS_INDEXEDVERTEXBLENDENABLE :
{
TRACE("Indexed Vertex Blend Enable to %ul\n", (BOOL) Value);
}
break;
case D3DRS_COLORVERTEX :
case D3DRS_DIFFUSEMATERIALSOURCE :
case D3DRS_SPECULARMATERIALSOURCE :
case D3DRS_AMBIENTMATERIALSOURCE :
case D3DRS_EMISSIVEMATERIALSOURCE :
{
GLenum Parm = GL_AMBIENT_AND_DIFFUSE;
if (This->stateBlock->renderState[D3DRS_COLORVERTEX]) {
TRACE("diff %ld, amb %ld, emis %ld, spec %ld\n",
This->stateBlock->renderState[D3DRS_DIFFUSEMATERIALSOURCE],
This->stateBlock->renderState[D3DRS_AMBIENTMATERIALSOURCE],
This->stateBlock->renderState[D3DRS_EMISSIVEMATERIALSOURCE],
This->stateBlock->renderState[D3DRS_SPECULARMATERIALSOURCE]);
if (This->stateBlock->renderState[D3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) {
if (This->stateBlock->renderState[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
Parm = GL_AMBIENT_AND_DIFFUSE;
} else {
Parm = GL_DIFFUSE;
}
} else if (This->stateBlock->renderState[D3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
Parm = GL_AMBIENT;
} else if (This->stateBlock->renderState[D3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) {
Parm = GL_EMISSION;
} else if (This->stateBlock->renderState[D3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) {
Parm = GL_SPECULAR;
} else {
Parm = -1;
}
if (Parm == -1) {
if (This->tracking_color != DISABLED_TRACKING) This->tracking_color = NEEDS_DISABLE;
} else {
This->tracking_color = NEEDS_TRACKING;
This->tracking_parm = Parm;
}
} else {
if (This->tracking_color != DISABLED_TRACKING) This->tracking_color = NEEDS_DISABLE;
}
}
break;
case D3DRS_LINEPATTERN :
{
union {
DWORD d;
D3DLINEPATTERN lp;
} tmppattern;
tmppattern.d = Value;
TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
if (tmppattern.lp.wRepeatFactor) {
glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
checkGLcall("glLineStipple(repeat, linepattern)");
glEnable(GL_LINE_STIPPLE);
checkGLcall("glEnable(GL_LINE_STIPPLE);");
} else {
glDisable(GL_LINE_STIPPLE);
checkGLcall("glDisable(GL_LINE_STIPPLE);");
}
}
break;
case D3DRS_ZBIAS :
{
if (Value) {
tmpvalue.d = Value;
TRACE("ZBias value %f\n", tmpvalue.f);
glPolygonOffset(0, -tmpvalue.f);
checkGLcall("glPolygonOffset(0, -Value)");
glEnable(GL_POLYGON_OFFSET_FILL);
checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
glEnable(GL_POLYGON_OFFSET_LINE);
checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
glEnable(GL_POLYGON_OFFSET_POINT);
checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
} else {
glDisable(GL_POLYGON_OFFSET_FILL);
checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
glDisable(GL_POLYGON_OFFSET_LINE);
checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
glDisable(GL_POLYGON_OFFSET_POINT);
checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
}
}
break;
case D3DRS_NORMALIZENORMALS :
if (Value) {
glEnable(GL_NORMALIZE);
checkGLcall("glEnable(GL_NORMALIZE);");
} else {
glDisable(GL_NORMALIZE);
checkGLcall("glDisable(GL_NORMALIZE);");
}
break;
case D3DRS_POINTSIZE :
tmpvalue.d = Value;
TRACE("Set point size to %f\n", tmpvalue.f);
glPointSize(tmpvalue.f);
checkGLcall("glPointSize(...);");
break;
case D3DRS_POINTSIZE_MIN :
if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
tmpvalue.d = Value;
GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, tmpvalue.f);
checkGLcall("glPointParameterfEXT(...);");
} else {
FIXME("D3DRS_POINTSIZE_MIN not supported on this opengl\n");
}
break;
case D3DRS_POINTSIZE_MAX :
if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
tmpvalue.d = Value;
GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, tmpvalue.f);
checkGLcall("glPointParameterfEXT(...);");
} else {
FIXME("D3DRS_POINTSIZE_MAX not supported on this opengl\n");
}
break;
case D3DRS_POINTSCALE_A :
case D3DRS_POINTSCALE_B :
case D3DRS_POINTSCALE_C :
case D3DRS_POINTSCALEENABLE :
{
/* If enabled, supply the parameters, otherwise fall back to defaults */
if (This->stateBlock->renderState[D3DRS_POINTSCALEENABLE]) {
GLfloat att[3] = {1.0f, 0.0f, 0.0f};
att[0] = *((float*)&This->stateBlock->renderState[D3DRS_POINTSCALE_A]);
att[1] = *((float*)&This->stateBlock->renderState[D3DRS_POINTSCALE_B]);
att[2] = *((float*)&This->stateBlock->renderState[D3DRS_POINTSCALE_C]);
if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);");
} else {
TRACE("D3DRS_POINTSCALEENABLE not supported on this opengl\n");
}
} else {
GLfloat att[3] = {1.0f, 0.0f, 0.0f};
if (GL_SUPPORT(EXT_POINT_PARAMETERS)) {
GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...);");
} else {
TRACE("D3DRS_POINTSCALEENABLE not supported, but not on either\n");
}
}
break;
}
case D3DRS_COLORWRITEENABLE :
{
TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
Value & D3DCOLORWRITEENABLE_RED ? 1 : 0,
Value & D3DCOLORWRITEENABLE_GREEN ? 1 : 0,
Value & D3DCOLORWRITEENABLE_BLUE ? 1 : 0,
Value & D3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
glColorMask(Value & D3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
Value & D3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
Value & D3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
Value & D3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
checkGLcall("glColorMask(...)");
}
break;
case D3DRS_LOCALVIEWER :
{
GLint state = (Value) ? 1 : 0;
TRACE("Local Viewer Enable to %ul\n", (BOOL) Value);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, state);
}
break;
case D3DRS_LASTPIXEL :
{
if (Value) {
TRACE("Last Pixel Drawing Enabled\n");
} else {
FIXME("Last Pixel Drawing Disabled, not handled yet\n");
}
}
break;
case D3DRS_SOFTWAREVERTEXPROCESSING :
{
if (Value) {
TRACE("Software Processing Enabled\n");
} else {
TRACE("Software Processing Disabled\n");
}
}
break;
/** not supported */
case D3DRS_ZVISIBLE :
{
LEAVE_GL();
return D3DERR_INVALIDCALL;
}
/* Unhandled yet...! */
case D3DRS_EDGEANTIALIAS :
case D3DRS_WRAP0 :
case D3DRS_WRAP1 :
case D3DRS_WRAP2 :
case D3DRS_WRAP3 :
case D3DRS_WRAP4 :
case D3DRS_WRAP5 :
case D3DRS_WRAP6 :
case D3DRS_WRAP7 :
case D3DRS_POINTSPRITEENABLE :
case D3DRS_MULTISAMPLEANTIALIAS :
case D3DRS_MULTISAMPLEMASK :
case D3DRS_PATCHEDGESTYLE :
case D3DRS_PATCHSEGMENTS :
case D3DRS_DEBUGMONITORTOKEN :
case D3DRS_POSITIONORDER :
case D3DRS_NORMALORDER :
/*Put back later: FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value); */
FIXME("(%p)->(%d,%ld) not handled yet\n", This, State, Value);
break;
default:
FIXME("(%p)->(%d,%ld) unrecognized\n", This, State, Value);
}
LEAVE_GL();
return D3D_OK;
}
HRESULT WINAPI IWineD3DDeviceImpl_GetRenderState(IWineD3DDevice *iface, D3DRENDERSTATETYPE State, DWORD *pValue) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
TRACE("(%p) for State %d = %ld\n", This, State, This->stateBlock->renderState[State]);
*pValue = This->stateBlock->renderState[State];
return D3D_OK;
}
/*****
* Get / Set Texture Stage States
* TODO: Verify against dx9 definitions
*****/
HRESULT WINAPI IWineD3DDeviceImpl_SetTextureStageState(IWineD3DDevice *iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
union {
float f;
DWORD d;
} tmpvalue;
/* FIXME: Handle 3d textures? What if TSS value set before set texture? Need to reapply all values? */
TRACE("(%p) : Stage=%ld, Type=%s(%d), Value=%ld\n", This, Stage, debug_d3dtexturestate(Type), Type, Value);
/* Reject invalid texture units */
if (Stage >= GL_LIMITS(textures)) {
TRACE("Attempt to access invalid texture rejected\n");
return D3DERR_INVALIDCALL;
}
This->updateStateBlock->changed.textureState[Stage][Type] = TRUE;
This->updateStateBlock->set.textureState[Stage][Type] = TRUE;
This->updateStateBlock->textureState[Stage][Type] = Value;
/* Handle recording of state blocks */
if (This->isRecordingState) {
TRACE("Recording... not performing anything\n");
return D3D_OK;
}
ENTER_GL();
/* Make appropriate texture active */
VTRACE(("Activating appropriate texture state %ld\n", Stage));
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_ACTIVETEXTURE(Stage);
} else if (Stage > 0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
}
switch (Type) {
case D3DTSS_MINFILTER :
case D3DTSS_MIPFILTER :
{
DWORD ValueMIN = This->stateBlock->textureState[Stage][D3DTSS_MINFILTER];
DWORD ValueMIP = This->stateBlock->textureState[Stage][D3DTSS_MIPFILTER];
GLint realVal = GL_LINEAR;
if (ValueMIN == D3DTEXF_NONE) {
/* Doesn't really make sense - Windows just seems to disable
mipmapping when this occurs */
FIXME("Odd - minfilter of none, just disabling mipmaps\n");
realVal = GL_LINEAR;
} else if (ValueMIN == D3DTEXF_POINT) {
/* GL_NEAREST_* */
if (ValueMIP == D3DTEXF_NONE) {
realVal = GL_NEAREST;
} else if (ValueMIP == D3DTEXF_POINT) {
realVal = GL_NEAREST_MIPMAP_NEAREST;
} else if (ValueMIP == D3DTEXF_LINEAR) {
realVal = GL_NEAREST_MIPMAP_LINEAR;
} else {
FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
realVal = GL_NEAREST;
}
} else if (ValueMIN == D3DTEXF_LINEAR) {
/* GL_LINEAR_* */
if (ValueMIP == D3DTEXF_NONE) {
realVal = GL_LINEAR;
} else if (ValueMIP == D3DTEXF_POINT) {
realVal = GL_LINEAR_MIPMAP_NEAREST;
} else if (ValueMIP == D3DTEXF_LINEAR) {
realVal = GL_LINEAR_MIPMAP_LINEAR;
} else {
FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
realVal = GL_LINEAR;
}
} else if (ValueMIN == D3DTEXF_ANISOTROPIC) {
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
if (ValueMIP == D3DTEXF_NONE) {
realVal = GL_LINEAR_MIPMAP_LINEAR;
} else if (ValueMIP == D3DTEXF_POINT) {
realVal = GL_LINEAR_MIPMAP_NEAREST;
} else if (ValueMIP == D3DTEXF_LINEAR) {
realVal = GL_LINEAR_MIPMAP_LINEAR;
} else {
FIXME("Unhandled D3DTSS_MIPFILTER value of %ld\n", ValueMIP);
realVal = GL_LINEAR;
}
} else {
WARN("Trying to use ANISOTROPIC_FILTERING for D3DTSS_MINFILTER. But not supported by OpenGL driver\n");
realVal = GL_LINEAR;
}
} else {
FIXME("Unhandled D3DTSS_MINFILTER value of %ld\n", ValueMIN);
realVal = GL_LINEAR_MIPMAP_LINEAR;
}
TRACE("ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x\n", ValueMIN, ValueMIP, realVal);
glTexParameteri(This->stateBlock->textureDimensions[Stage], GL_TEXTURE_MIN_FILTER, realVal);
checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
/**
* if we juste choose to use ANISOTROPIC filtering, refresh openGL state
*/
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && D3DTEXF_ANISOTROPIC == ValueMIN) {
glTexParameteri(This->stateBlock->textureDimensions[Stage],
GL_TEXTURE_MAX_ANISOTROPY_EXT,
This->stateBlock->textureState[Stage][D3DTSS_MAXANISOTROPY]);
checkGLcall("glTexParameter GL_TEXTURE_MAX_ANISOTROPY_EXT, ...");
}
}
break;
case D3DTSS_MAGFILTER :
{
DWORD ValueMAG = This->stateBlock->textureState[Stage][D3DTSS_MAGFILTER];
GLint realVal = GL_NEAREST;
if (ValueMAG == D3DTEXF_POINT) {
realVal = GL_NEAREST;
} else if (ValueMAG == D3DTEXF_LINEAR) {
realVal = GL_LINEAR;
} else if (ValueMAG == D3DTEXF_ANISOTROPIC) {
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
realVal = GL_LINEAR;
} else {
FIXME("Trying to use ANISOTROPIC_FILTERING for D3DTSS_MAGFILTER. But not supported by current OpenGL driver\n");
realVal = GL_NEAREST;
}
} else {
FIXME("Unhandled D3DTSS_MAGFILTER value of %ld\n", ValueMAG);
realVal = GL_NEAREST;
}
TRACE("ValueMAG=%ld setting MAGFILTER to %x\n", ValueMAG, realVal);
glTexParameteri(This->stateBlock->textureDimensions[Stage], GL_TEXTURE_MAG_FILTER, realVal);
checkGLcall("glTexParameter GL_TEXTURE_MAG_FILTER, ...");
/**
* if we juste choose to use ANISOTROPIC filtering, refresh openGL state
*/
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && D3DTEXF_ANISOTROPIC == ValueMAG) {
glTexParameteri(This->stateBlock->textureDimensions[Stage],
GL_TEXTURE_MAX_ANISOTROPY_EXT,
This->stateBlock->textureState[Stage][D3DTSS_MAXANISOTROPY]);
checkGLcall("glTexParameter GL_TEXTURE_MAX_ANISOTROPY_EXT, ...");
}
}
break;
case D3DTSS_MAXMIPLEVEL :
{
/**
* Not really the same, but the more apprioprate than nothing
*/
glTexParameteri(This->stateBlock->textureDimensions[Stage],
GL_TEXTURE_BASE_LEVEL,
This->stateBlock->textureState[Stage][D3DTSS_MAXMIPLEVEL]);
checkGLcall("glTexParameteri GL_TEXTURE_BASE_LEVEL ...");
}
break;
case D3DTSS_MAXANISOTROPY :
{
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC)) {
glTexParameteri(This->stateBlock->textureDimensions[Stage],
GL_TEXTURE_MAX_ANISOTROPY_EXT,
This->stateBlock->textureState[Stage][D3DTSS_MAXANISOTROPY]);
checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
}
}
break;
case D3DTSS_MIPMAPLODBIAS :
{
if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
tmpvalue.d = Value;
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
GL_TEXTURE_LOD_BIAS_EXT,
tmpvalue.f);
checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
}
}
break;
case D3DTSS_ALPHAOP :
case D3DTSS_COLOROP :
{
if ((Value == D3DTOP_DISABLE) && (Type == D3DTSS_COLOROP)) {
/* TODO: Disable by making this and all later levels disabled */
glDisable(GL_TEXTURE_1D);
checkGLcall("Disable GL_TEXTURE_1D");
glDisable(GL_TEXTURE_2D);
checkGLcall("Disable GL_TEXTURE_2D");
glDisable(GL_TEXTURE_3D);
checkGLcall("Disable GL_TEXTURE_3D");
break; /* Don't bother setting the texture operations */
} else {
/* Enable only the appropriate texture dimension */
if (Type == D3DTSS_COLOROP) {
if (This->stateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
glEnable(GL_TEXTURE_1D);
checkGLcall("Enable GL_TEXTURE_1D");
} else {
glDisable(GL_TEXTURE_1D);
checkGLcall("Disable GL_TEXTURE_1D");
}
if (This->stateBlock->textureDimensions[Stage] == GL_TEXTURE_2D) {
if (GL_SUPPORT(NV_TEXTURE_SHADER) && This->texture_shader_active) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
checkGLcall("Enable GL_TEXTURE_2D");
} else {
glEnable(GL_TEXTURE_2D);
checkGLcall("Enable GL_TEXTURE_2D");
}
} else {
glDisable(GL_TEXTURE_2D);
checkGLcall("Disable GL_TEXTURE_2D");
}
if (This->stateBlock->textureDimensions[Stage] == GL_TEXTURE_3D) {
glEnable(GL_TEXTURE_3D);
checkGLcall("Enable GL_TEXTURE_3D");
} else {
glDisable(GL_TEXTURE_3D);
checkGLcall("Disable GL_TEXTURE_3D");
}
if (This->stateBlock->textureDimensions[Stage] == GL_TEXTURE_CUBE_MAP_ARB) {
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("Enable GL_TEXTURE_CUBE_MAP");
} else {
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("Disable GL_TEXTURE_CUBE_MAP");
}
}
}
/* Drop through... (Except disable case) */
case D3DTSS_COLORARG0 :
case D3DTSS_COLORARG1 :
case D3DTSS_COLORARG2 :
case D3DTSS_ALPHAARG0 :
case D3DTSS_ALPHAARG1 :
case D3DTSS_ALPHAARG2 :
{
BOOL isAlphaArg = (Type == D3DTSS_ALPHAOP || Type == D3DTSS_ALPHAARG1 ||
Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
if (isAlphaArg) {
set_tex_op(iface, TRUE, Stage, This->stateBlock->textureState[Stage][D3DTSS_ALPHAOP],
This->stateBlock->textureState[Stage][D3DTSS_ALPHAARG1],
This->stateBlock->textureState[Stage][D3DTSS_ALPHAARG2],
This->stateBlock->textureState[Stage][D3DTSS_ALPHAARG0]);
} else {
set_tex_op(iface, FALSE, Stage, This->stateBlock->textureState[Stage][D3DTSS_COLOROP],
This->stateBlock->textureState[Stage][D3DTSS_COLORARG1],
This->stateBlock->textureState[Stage][D3DTSS_COLORARG2],
This->stateBlock->textureState[Stage][D3DTSS_COLORARG0]);
}
}
break;
}
case D3DTSS_ADDRESSU :
case D3DTSS_ADDRESSV :
case D3DTSS_ADDRESSW :
{
GLint wrapParm = GL_REPEAT;
switch (Value) {
case D3DTADDRESS_WRAP: wrapParm = GL_REPEAT; break;
case D3DTADDRESS_CLAMP: wrapParm = GL_CLAMP_TO_EDGE; break;
case D3DTADDRESS_BORDER:
{
if (GL_SUPPORT(ARB_TEXTURE_BORDER_CLAMP)) {
wrapParm = GL_CLAMP_TO_BORDER_ARB;
} else {
/* FIXME: Not right, but better */
FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
wrapParm = GL_REPEAT;
}
}
break;
case D3DTADDRESS_MIRROR:
{
if (GL_SUPPORT(ARB_TEXTURE_MIRRORED_REPEAT)) {
wrapParm = GL_MIRRORED_REPEAT_ARB;
} else {
/* Unsupported in OpenGL pre-1.4 */
FIXME("Unsupported D3DTADDRESS_MIRROR (needs GL_ARB_texture_mirrored_repeat) state %d\n", Type);
wrapParm = GL_REPEAT;
}
}
break;
case D3DTADDRESS_MIRRORONCE:
{
if (GL_SUPPORT(ATI_TEXTURE_MIRROR_ONCE)) {
wrapParm = GL_MIRROR_CLAMP_TO_EDGE_ATI;
} else {
FIXME("Unsupported D3DTADDRESS_MIRRORONCE (needs GL_ATI_texture_mirror_once) state %d\n", Type);
wrapParm = GL_REPEAT;
}
}
break;
default:
FIXME("Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d\n", Value, Type);
wrapParm = GL_REPEAT;
}
switch (Type) {
case D3DTSS_ADDRESSU:
TRACE("Setting WRAP_S to %d for %x\n", wrapParm, This->stateBlock->textureDimensions[Stage]);
glTexParameteri(This->stateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_S, wrapParm);
checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_S, wrapParm)");
break;
case D3DTSS_ADDRESSV:
TRACE("Setting WRAP_T to %d for %x\n", wrapParm, This->stateBlock->textureDimensions[Stage]);
glTexParameteri(This->stateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_T, wrapParm);
checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_T, wrapParm)");
break;
case D3DTSS_ADDRESSW:
TRACE("Setting WRAP_R to %d for %x\n", wrapParm, This->stateBlock->textureDimensions[Stage]);
glTexParameteri(This->stateBlock->textureDimensions[Stage], GL_TEXTURE_WRAP_R, wrapParm);
checkGLcall("glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm)");
break;
default: /* nop */
break; /** stupic compilator */
}
}
break;
case D3DTSS_BORDERCOLOR :
{
float col[4];
D3DCOLORTOGLFLOAT4(Value, col);
TRACE("Setting border color for %x to %lx\n", This->stateBlock->textureDimensions[Stage], Value);
glTexParameterfv(This->stateBlock->textureDimensions[Stage], GL_TEXTURE_BORDER_COLOR, &col[0]);
checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
}
break;
case D3DTSS_TEXCOORDINDEX :
{
/* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive */
/* FIXME: From MSDN: The D3DTSS_TCI_* flags are mutually exclusive. If you include
one flag, you can still specify an index value, which the system uses to
determine the texture wrapping mode.
eg. SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | 1 );
means use the vertex position (camera-space) as the input texture coordinates
for this texture stage, and the wrap mode set in the D3DRS_WRAP1 render
state. We do not (yet) support the D3DRENDERSTATE_WRAPx values, nor tie them up
to the TEXCOORDINDEX value */
/**
* Be careful the value of the mask 0xF0000 come from d3d8types.h infos
*/
switch (Value & 0xFFFF0000) {
case D3DTSS_TCI_PASSTHRU:
/*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R)");
break;
case D3DTSS_TCI_CAMERASPACEPOSITION:
/* CameraSpacePosition means use the vertex position, transformed to camera space,
as the input texture coordinates for this stage's texture transformation. This
equates roughly to EYE_LINEAR */
{
float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
glPopMatrix();
TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
glEnable(GL_TEXTURE_GEN_S);
checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
glEnable(GL_TEXTURE_GEN_T);
checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
glEnable(GL_TEXTURE_GEN_R);
checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
}
break;
case D3DTSS_TCI_CAMERASPACENORMAL:
{
if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
glPopMatrix();
glEnable(GL_TEXTURE_GEN_S);
checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
glEnable(GL_TEXTURE_GEN_T);
checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
glEnable(GL_TEXTURE_GEN_R);
checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
}
}
break;
case D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
{
if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
TRACE("D3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
glPopMatrix();
glEnable(GL_TEXTURE_GEN_S);
checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
glEnable(GL_TEXTURE_GEN_T);
checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
glEnable(GL_TEXTURE_GEN_R);
checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
}
}
break;
/* Unhandled types: */
default:
/* Todo: */
/* ? disable GL_TEXTURE_GEN_n ? */
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
FIXME("Unhandled D3DTSS_TEXCOORDINDEX %lx\n", Value);
break;
}
}
break;
/* Unhandled */
case D3DTSS_TEXTURETRANSFORMFLAGS :
set_texture_matrix((float *)&This->stateBlock->transforms[D3DTS_TEXTURE0 + Stage].u.m[0][0], Value);
break;
case D3DTSS_BUMPENVMAT00 :
case D3DTSS_BUMPENVMAT01 :
TRACE("BUMPENVMAT0%u Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT00, Stage, Type, Value);
break;
case D3DTSS_BUMPENVMAT10 :
case D3DTSS_BUMPENVMAT11 :
TRACE("BUMPENVMAT1%u Stage=%ld, Type=%d, Value =%ld\n", Type - D3DTSS_BUMPENVMAT10, Stage, Type, Value);
break;
case D3DTSS_BUMPENVLSCALE :
TRACE("BUMPENVLSCALE Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
break;
case D3DTSS_BUMPENVLOFFSET :
TRACE("BUMPENVLOFFSET Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
break;
case D3DTSS_RESULTARG :
TRACE("RESULTARG Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
break;
default:
/* Put back later: FIXME("(%p) : stub, Stage=%ld, Type=%d, Value =%ld\n", This, Stage, Type, Value); */
TRACE("Still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);
}
LEAVE_GL();
return D3D_OK;
}
HRESULT WINAPI IWineD3DDeviceImpl_GetTextureStageState(IWineD3DDevice *iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
TRACE("(%p) : requesting Stage %ld, Type %d getting %ld\n", This, Stage, Type, This->updateStateBlock->textureState[Stage][Type]);
*pValue = This->updateStateBlock->textureState[Stage][Type];
return D3D_OK;
}
/*****
* Scene related functions
*****/
HRESULT WINAPI IWineD3DDeviceImpl_BeginScene(IWineD3DDevice *iface) {
......@@ -1290,11 +2772,17 @@ IWineD3DDeviceVtbl IWineD3DDevice_Vtbl =
IWineD3DDeviceImpl_GetIndices,
IWineD3DDeviceImpl_SetViewport,
IWineD3DDeviceImpl_GetViewport,
IWineD3DDeviceImpl_SetRenderState,
IWineD3DDeviceImpl_GetRenderState,
IWineD3DDeviceImpl_SetTextureStageState,
IWineD3DDeviceImpl_GetTextureStageState,
IWineD3DDeviceImpl_BeginScene,
IWineD3DDeviceImpl_DrawPrimitive,
IWineD3DDeviceImpl_DrawIndexedPrimitive,
IWineD3DDeviceImpl_DrawPrimitiveUP,
IWineD3DDeviceImpl_DrawIndexedPrimitiveUP
IWineD3DDeviceImpl_DrawIndexedPrimitiveUP,
IWineD3DDeviceImpl_SetupTextureStates
};
......@@ -1565,7 +1565,7 @@ HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, D3DDEV
vp.Height = *(pPresentationParameters->BackBufferHeight);
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
/* TODO: IWineD3DDevice_SetViewport((LPDIRECT3DDEVICE9) object, &vp); */
IWineD3DDevice_SetViewport((IWineD3DDevice *)object, &vp);
}
/* Initialize the current view state */
......
......@@ -202,14 +202,10 @@ void init_materials(IWineD3DDevice *iface, BOOL isDiffuseSupplied) {
checkGLcall("glMaterialfv");
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &This->stateBlock->material.Diffuse);
checkGLcall("glMaterialfv");
#if 0 /* TODO */
if (This->stateBlock->renderstate[D3DRS_SPECULARENABLE]) {
if (This->stateBlock->renderState[D3DRS_SPECULARENABLE]) {
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &This->stateBlock->material.Specular);
checkGLcall("glMaterialfv");
} else {
#else
{
#endif
float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
checkGLcall("glMaterialfv");
......@@ -429,7 +425,7 @@ void primitiveConvertToStridedData(IWineD3DDevice *iface, Direct3DVertexStridedD
}
/* Blending is numBlends * FLOATs followed by a DWORD for UBYTE4 */
/** do we have to Check This->updateStateBlock->renderstate[D3DRS_INDEXEDVERTEXBLENDENABLE] ? */
/** do we have to Check This->updateStateBlock->renderState[D3DRS_INDEXEDVERTEXBLENDENABLE] ? */
numBlends = ((thisFVF & D3DFVF_POSITION_MASK) >> 1) - 2 +
((FALSE == (thisFVF & D3DFVF_LASTBETA_UBYTE4)) ? 0 : -1); /* WARNING can be < 0 because -2 */
if (numBlends > 0) {
......@@ -1502,7 +1498,7 @@ void drawPrimitive(IWineD3DDevice *iface,
useHW = (((vs_mode == VS_HW) && GL_SUPPORT(ARB_VERTEX_PROGRAM)) &&
This->devType != D3DDEVTYPE_REF &&
!This->stateBlock->renderstate[D3DRS_SOFTWAREVERTEXPROCESSING] &&
!This->stateBlock->renderState[D3DRS_SOFTWAREVERTEXPROCESSING] &&
vertex_shader->usage != D3DUSAGE_SOFTWAREPROCESSING);
/** init Constants */
......
......@@ -34,6 +34,16 @@ HRESULT WINAPI IWineD3DStateBlockImpl_GetParent(IWineD3DStateBlock *iface, IUnkn
HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock* iface) {
IWineD3DStateBlockImpl *This = (IWineD3DStateBlockImpl *)iface;
IWineD3DDeviceImpl *ThisDevice = (IWineD3DDeviceImpl *)(This->wineD3DDevice);
union {
D3DLINEPATTERN lp;
DWORD d;
} lp;
union {
float f;
DWORD d;
} tmpfloat;
unsigned int i;
/* Note this may have a large overhead but it should only be executed
once, in order to initialize the complete state of the device and
......@@ -41,6 +51,205 @@ HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStateBlock*
TRACE("-----------------------> Setting up device defaults...\n");
This->blockType = D3DSBT_ALL;
/* FIXME: Set some of the defaults for lights, transforms etc */
memcpy(&This->transforms[D3DTS_PROJECTION], &identity, sizeof(identity));
memcpy(&This->transforms[D3DTS_VIEW], &identity, sizeof(identity));
for (i = 0; i < 256; ++i) {
memcpy(&This->transforms[D3DTS_WORLDMATRIX(i)], &identity, sizeof(identity));
}
/* Render states: */
if (ThisDevice->presentParms.EnableAutoDepthStencil) {
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_ZENABLE, D3DZB_TRUE);
} else {
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_ZENABLE, D3DZB_FALSE);
}
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_FILLMODE, D3DFILL_SOLID);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
lp.lp.wRepeatFactor = 0; lp.lp.wLinePattern = 0;
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_LINEPATTERN, lp.d);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_ZWRITEENABLE, TRUE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_ALPHATESTENABLE, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_LASTPIXEL, TRUE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_SRCBLEND, D3DBLEND_ONE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_DESTBLEND, D3DBLEND_ZERO);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_CULLMODE, D3DCULL_CCW);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_ALPHAREF, 0xff); /*??*/
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_DITHERENABLE, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_ALPHABLENDENABLE, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_FOGENABLE, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_SPECULARENABLE, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_ZVISIBLE, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_FOGCOLOR, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
tmpfloat.f = 0.0f;
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_FOGSTART, tmpfloat.d);
tmpfloat.f = 1.0f;
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_FOGEND, tmpfloat.d);
tmpfloat.f = 1.0f;
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_FOGDENSITY, tmpfloat.d);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_EDGEANTIALIAS, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_ZBIAS, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_RANGEFOGENABLE, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_STENCILENABLE, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
/* Setting stencil func also uses values for stencil ref/mask, so manually set defaults
* so only a single call performed (and ensure defaults initialized before making that call)
*
* IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_STENCILREF, 0);
* IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_STENCILMASK, 0xFFFFFFFF);
*/
This->renderState[D3DRS_STENCILREF] = 0;
This->renderState[D3DRS_STENCILMASK] = 0xFFFFFFFF;
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_TEXTUREFACTOR, 0xFFFFFFFF);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_WRAP0, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_WRAP1, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_WRAP2, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_WRAP3, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_WRAP4, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_WRAP5, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_WRAP6, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_WRAP7, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_CLIPPING, TRUE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_LIGHTING, TRUE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_AMBIENT, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_COLORVERTEX, TRUE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_LOCALVIEWER, TRUE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_NORMALIZENORMALS, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_VERTEXBLEND, D3DVBF_DISABLE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_CLIPPLANEENABLE, 0);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
tmpfloat.f = 1.0f;
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_POINTSIZE, tmpfloat.d);
tmpfloat.f = 0.0f;
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_POINTSIZE_MIN, tmpfloat.d);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_POINTSPRITEENABLE, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_POINTSCALEENABLE, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_POINTSCALE_A, TRUE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_POINTSCALE_B, TRUE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_POINTSCALE_C, TRUE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_MULTISAMPLEANTIALIAS, TRUE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_PATCHEDGESTYLE, D3DPATCHEDGE_DISCRETE);
tmpfloat.f = 1.0f;
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_PATCHSEGMENTS, tmpfloat.d);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_DEBUGMONITORTOKEN, D3DDMT_DISABLE);
tmpfloat.f = 64.0f;
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_POINTSIZE_MAX, tmpfloat.d);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_COLORWRITEENABLE, 0x0000000F);
tmpfloat.f = 0.0f;
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_TWEENFACTOR, tmpfloat.d);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_BLENDOP, D3DBLENDOP_ADD);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_POSITIONORDER, D3DORDER_CUBIC);
IWineD3DDevice_SetRenderState(This->wineD3DDevice, D3DRS_NORMALORDER, D3DORDER_LINEAR);
/** clipping status */
This->clip_status.ClipUnion = 0;
This->clip_status.ClipIntersection = 0xFFFFFFFF;
/* Texture Stage States - Put directly into state block, we will call function below */
for (i = 0; i < GL_LIMITS(textures); i++) {
TRACE("Setting up default texture states for texture Stage %d\n", i);
memcpy(&This->transforms[D3DTS_TEXTURE0 + i], &identity, sizeof(identity));
This->textureState[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE;
This->textureState[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE;
This->textureState[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT;
This->textureState[i][D3DTSS_ALPHAOP ] = (i==0)? D3DTOP_SELECTARG1 : D3DTOP_DISABLE;
This->textureState[i][D3DTSS_ALPHAARG1 ] = D3DTA_TEXTURE;
This->textureState[i][D3DTSS_ALPHAARG2 ] = D3DTA_CURRENT;
This->textureState[i][D3DTSS_BUMPENVMAT00 ] = (DWORD) 0.0;
This->textureState[i][D3DTSS_BUMPENVMAT01 ] = (DWORD) 0.0;
This->textureState[i][D3DTSS_BUMPENVMAT10 ] = (DWORD) 0.0;
This->textureState[i][D3DTSS_BUMPENVMAT11 ] = (DWORD) 0.0;
This->textureState[i][D3DTSS_TEXCOORDINDEX ] = i;
This->textureState[i][D3DTSS_ADDRESSU ] = D3DTADDRESS_WRAP;
This->textureState[i][D3DTSS_ADDRESSV ] = D3DTADDRESS_WRAP;
This->textureState[i][D3DTSS_BORDERCOLOR ] = 0x00;
This->textureState[i][D3DTSS_MAGFILTER ] = D3DTEXF_POINT;
This->textureState[i][D3DTSS_MINFILTER ] = D3DTEXF_POINT;
This->textureState[i][D3DTSS_MIPFILTER ] = D3DTEXF_NONE;
This->textureState[i][D3DTSS_MIPMAPLODBIAS ] = 0;
This->textureState[i][D3DTSS_MAXMIPLEVEL ] = 0;
This->textureState[i][D3DTSS_MAXANISOTROPY ] = 1;
This->textureState[i][D3DTSS_BUMPENVLSCALE ] = (DWORD) 0.0;
This->textureState[i][D3DTSS_BUMPENVLOFFSET ] = (DWORD) 0.0;
This->textureState[i][D3DTSS_TEXTURETRANSFORMFLAGS ] = D3DTTFF_DISABLE;
This->textureState[i][D3DTSS_ADDRESSW ] = D3DTADDRESS_WRAP;
This->textureState[i][D3DTSS_COLORARG0 ] = D3DTA_CURRENT;
This->textureState[i][D3DTSS_ALPHAARG0 ] = D3DTA_CURRENT;
This->textureState[i][D3DTSS_RESULTARG ] = D3DTA_CURRENT;
}
/* Under DirectX you can have texture stage operations even if no texture is
bound, whereas opengl will only do texture operations when a valid texture is
bound. We emulate this by creating dummy textures and binding them to each
texture stage, but disable all stages by default. Hence if a stage is enabled
then the default texture will kick in until replaced by a SetTexture call */
ENTER_GL();
for (i = 0; i < GL_LIMITS(textures); i++) {
GLubyte white = 255;
/* Note this avoids calling settexture, so pretend it has been called */
This->set.textures[i] = TRUE;
This->changed.textures[i] = TRUE;
This->textures[i] = NULL;
/* Make appropriate texture active */
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_ACTIVETEXTURE(i);
} else if (i > 0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
}
/* Generate an opengl texture name */
glGenTextures(1, &ThisDevice->dummyTextureName[i]);
checkGLcall("glGenTextures");
TRACE("Dummy Texture %d given name %d\n", i, ThisDevice->dummyTextureName[i]);
/* Generate a dummy 1d texture */
This->textureDimensions[i] = GL_TEXTURE_1D;
glBindTexture(GL_TEXTURE_1D, ThisDevice->dummyTextureName[i]);
checkGLcall("glBindTexture");
glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &white);
checkGLcall("glTexImage1D");
/* Reapply all the texture state information to this texture */
IWineD3DDevice_SetupTextureStates(This->wineD3DDevice, i, REAPPLY_ALL);
}
LEAVE_GL();
#if 0 /* TODO: Palette support */
/* defaulting palettes */
for (i = 0; i < MAX_PALETTES; ++i) {
int j;
for (j = 0; j < 256; ++j) {
This->palettes[i][j].peRed = 0xFF;
This->palettes[i][j].peGreen = 0xFF;
This->palettes[i][j].peBlue = 0xFF;
This->palettes[i][j].peFlags = 0xFF;
}
}
This->currentPalette = 0;
#endif /* TODO: Palette support */
TRACE("-----------------------> Device defaults now set up...\n");
return D3D_OK;
}
......
......@@ -25,6 +25,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
/*****************************************************************************
* Trace formatting of useful values
*/
const char* debug_d3dformat(D3DFORMAT fmt) {
switch (fmt) {
#define FMT_TO_STR(fmt) case fmt: return #fmt
......@@ -140,3 +143,1379 @@ const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType) {
return "unrecognized";
}
}
const char* debug_d3drenderstate(DWORD state) {
switch (state) {
#define D3DSTATE_TO_STR(u) case u: return #u
D3DSTATE_TO_STR(D3DRS_ZENABLE );
D3DSTATE_TO_STR(D3DRS_FILLMODE );
D3DSTATE_TO_STR(D3DRS_SHADEMODE );
D3DSTATE_TO_STR(D3DRS_LINEPATTERN );
D3DSTATE_TO_STR(D3DRS_ZWRITEENABLE );
D3DSTATE_TO_STR(D3DRS_ALPHATESTENABLE );
D3DSTATE_TO_STR(D3DRS_LASTPIXEL );
D3DSTATE_TO_STR(D3DRS_SRCBLEND );
D3DSTATE_TO_STR(D3DRS_DESTBLEND );
D3DSTATE_TO_STR(D3DRS_CULLMODE );
D3DSTATE_TO_STR(D3DRS_ZFUNC );
D3DSTATE_TO_STR(D3DRS_ALPHAREF );
D3DSTATE_TO_STR(D3DRS_ALPHAFUNC );
D3DSTATE_TO_STR(D3DRS_DITHERENABLE );
D3DSTATE_TO_STR(D3DRS_ALPHABLENDENABLE );
D3DSTATE_TO_STR(D3DRS_FOGENABLE );
D3DSTATE_TO_STR(D3DRS_SPECULARENABLE );
D3DSTATE_TO_STR(D3DRS_ZVISIBLE );
D3DSTATE_TO_STR(D3DRS_FOGCOLOR );
D3DSTATE_TO_STR(D3DRS_FOGTABLEMODE );
D3DSTATE_TO_STR(D3DRS_FOGSTART );
D3DSTATE_TO_STR(D3DRS_FOGEND );
D3DSTATE_TO_STR(D3DRS_FOGDENSITY );
D3DSTATE_TO_STR(D3DRS_EDGEANTIALIAS );
D3DSTATE_TO_STR(D3DRS_ZBIAS );
D3DSTATE_TO_STR(D3DRS_RANGEFOGENABLE );
D3DSTATE_TO_STR(D3DRS_STENCILENABLE );
D3DSTATE_TO_STR(D3DRS_STENCILFAIL );
D3DSTATE_TO_STR(D3DRS_STENCILZFAIL );
D3DSTATE_TO_STR(D3DRS_STENCILPASS );
D3DSTATE_TO_STR(D3DRS_STENCILFUNC );
D3DSTATE_TO_STR(D3DRS_STENCILREF );
D3DSTATE_TO_STR(D3DRS_STENCILMASK );
D3DSTATE_TO_STR(D3DRS_STENCILWRITEMASK );
D3DSTATE_TO_STR(D3DRS_TEXTUREFACTOR );
D3DSTATE_TO_STR(D3DRS_WRAP0 );
D3DSTATE_TO_STR(D3DRS_WRAP1 );
D3DSTATE_TO_STR(D3DRS_WRAP2 );
D3DSTATE_TO_STR(D3DRS_WRAP3 );
D3DSTATE_TO_STR(D3DRS_WRAP4 );
D3DSTATE_TO_STR(D3DRS_WRAP5 );
D3DSTATE_TO_STR(D3DRS_WRAP6 );
D3DSTATE_TO_STR(D3DRS_WRAP7 );
D3DSTATE_TO_STR(D3DRS_CLIPPING );
D3DSTATE_TO_STR(D3DRS_LIGHTING );
D3DSTATE_TO_STR(D3DRS_AMBIENT );
D3DSTATE_TO_STR(D3DRS_FOGVERTEXMODE );
D3DSTATE_TO_STR(D3DRS_COLORVERTEX );
D3DSTATE_TO_STR(D3DRS_LOCALVIEWER );
D3DSTATE_TO_STR(D3DRS_NORMALIZENORMALS );
D3DSTATE_TO_STR(D3DRS_DIFFUSEMATERIALSOURCE );
D3DSTATE_TO_STR(D3DRS_SPECULARMATERIALSOURCE );
D3DSTATE_TO_STR(D3DRS_AMBIENTMATERIALSOURCE );
D3DSTATE_TO_STR(D3DRS_EMISSIVEMATERIALSOURCE );
D3DSTATE_TO_STR(D3DRS_VERTEXBLEND );
D3DSTATE_TO_STR(D3DRS_CLIPPLANEENABLE );
D3DSTATE_TO_STR(D3DRS_SOFTWAREVERTEXPROCESSING );
D3DSTATE_TO_STR(D3DRS_POINTSIZE );
D3DSTATE_TO_STR(D3DRS_POINTSIZE_MIN );
D3DSTATE_TO_STR(D3DRS_POINTSPRITEENABLE );
D3DSTATE_TO_STR(D3DRS_POINTSCALEENABLE );
D3DSTATE_TO_STR(D3DRS_POINTSCALE_A );
D3DSTATE_TO_STR(D3DRS_POINTSCALE_B );
D3DSTATE_TO_STR(D3DRS_POINTSCALE_C );
D3DSTATE_TO_STR(D3DRS_MULTISAMPLEANTIALIAS );
D3DSTATE_TO_STR(D3DRS_MULTISAMPLEMASK );
D3DSTATE_TO_STR(D3DRS_PATCHEDGESTYLE );
D3DSTATE_TO_STR(D3DRS_PATCHSEGMENTS );
D3DSTATE_TO_STR(D3DRS_DEBUGMONITORTOKEN );
D3DSTATE_TO_STR(D3DRS_POINTSIZE_MAX );
D3DSTATE_TO_STR(D3DRS_INDEXEDVERTEXBLENDENABLE );
D3DSTATE_TO_STR(D3DRS_COLORWRITEENABLE );
D3DSTATE_TO_STR(D3DRS_TWEENFACTOR );
D3DSTATE_TO_STR(D3DRS_BLENDOP );
D3DSTATE_TO_STR(D3DRS_POSITIONORDER );
D3DSTATE_TO_STR(D3DRS_NORMALORDER );
#undef D3DSTATE_TO_STR
default:
FIXME("Unrecognized %lu render state!\n", state);
return "unrecognized";
}
}
const char* debug_d3dtexturestate(DWORD state) {
switch (state) {
#define D3DSTATE_TO_STR(u) case u: return #u
D3DSTATE_TO_STR(D3DTSS_COLOROP );
D3DSTATE_TO_STR(D3DTSS_COLORARG1 );
D3DSTATE_TO_STR(D3DTSS_COLORARG2 );
D3DSTATE_TO_STR(D3DTSS_ALPHAOP );
D3DSTATE_TO_STR(D3DTSS_ALPHAARG1 );
D3DSTATE_TO_STR(D3DTSS_ALPHAARG2 );
D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT00 );
D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT01 );
D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT10 );
D3DSTATE_TO_STR(D3DTSS_BUMPENVMAT11 );
D3DSTATE_TO_STR(D3DTSS_TEXCOORDINDEX );
D3DSTATE_TO_STR(D3DTSS_ADDRESSU );
D3DSTATE_TO_STR(D3DTSS_ADDRESSV );
D3DSTATE_TO_STR(D3DTSS_BORDERCOLOR );
D3DSTATE_TO_STR(D3DTSS_MAGFILTER );
D3DSTATE_TO_STR(D3DTSS_MINFILTER );
D3DSTATE_TO_STR(D3DTSS_MIPFILTER );
D3DSTATE_TO_STR(D3DTSS_MIPMAPLODBIAS );
D3DSTATE_TO_STR(D3DTSS_MAXMIPLEVEL );
D3DSTATE_TO_STR(D3DTSS_MAXANISOTROPY );
D3DSTATE_TO_STR(D3DTSS_BUMPENVLSCALE );
D3DSTATE_TO_STR(D3DTSS_BUMPENVLOFFSET );
D3DSTATE_TO_STR(D3DTSS_TEXTURETRANSFORMFLAGS );
D3DSTATE_TO_STR(D3DTSS_ADDRESSW );
D3DSTATE_TO_STR(D3DTSS_COLORARG0 );
D3DSTATE_TO_STR(D3DTSS_ALPHAARG0 );
D3DSTATE_TO_STR(D3DTSS_RESULTARG );
#undef D3DSTATE_TO_STR
case 12:
/* Note D3DTSS are not consecutive, so skip these */
return "unused";
break;
default:
FIXME("Unrecognized %lu texture state!\n", state);
return "unrecognized";
}
}
/*****************************************************************************
* Useful functions mapping GL <-> D3D values
*/
GLenum StencilOp(DWORD op) {
switch(op) {
case D3DSTENCILOP_KEEP : return GL_KEEP;
case D3DSTENCILOP_ZERO : return GL_ZERO;
case D3DSTENCILOP_REPLACE : return GL_REPLACE;
case D3DSTENCILOP_INCRSAT : return GL_INCR;
case D3DSTENCILOP_DECRSAT : return GL_DECR;
case D3DSTENCILOP_INVERT : return GL_INVERT;
case D3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
case D3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
default:
FIXME("Invalid stencil op %ld\n", op);
return GL_ALWAYS;
}
}
/* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
#if defined (GL_VERSION_1_3)
# define useext(A) A
# define combine_ext 1
#elif defined (GL_EXT_texture_env_combine)
# define useext(A) A##_EXT
# define combine_ext 1
#elif defined (GL_ARB_texture_env_combine)
# define useext(A) A##_ARB
# define combine_ext 1
#else
# undef combine_ext
#endif
#if !defined(combine_ext)
void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
{
FIXME("Requires opengl combine extensions to work\n");
return;
}
#else
/* Setup the texture operations texture stage states */
void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
{
#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
GLenum src1, src2, src3;
GLenum opr1, opr2, opr3;
GLenum comb_target;
GLenum src0_target, src1_target, src2_target;
GLenum opr0_target, opr1_target, opr2_target;
GLenum scal_target;
GLenum opr=0, invopr, src3_target, opr3_target;
BOOL Handled = FALSE;
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
TRACE("Alpha?(%d), Stage:%d Op(%d), a1(%ld), a2(%ld), a3(%ld)\n", isAlpha, Stage, op, arg1, arg2, arg3);
ENTER_GL();
/* Note: Operations usually involve two ars, src0 and src1 and are operations of
the form (a1 <operation> a2). However, some of the more complex operations
take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
in a third parameter called a0. Therefore these are operations of the form
a0 <operation> a1 <operation> a2, ie the new parameter goes to the front.
However, below we treat the new (a0) parameter as src2/opr2, so in the actual
functions below, expect their syntax to differ slightly to those listed in the
manuals, ie replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
This affects D3DTOP_MULTIPLYADD and D3DTOP_LERP */
if (isAlpha) {
comb_target = useext(GL_COMBINE_ALPHA);
src0_target = useext(GL_SOURCE0_ALPHA);
src1_target = useext(GL_SOURCE1_ALPHA);
src2_target = useext(GL_SOURCE2_ALPHA);
opr0_target = useext(GL_OPERAND0_ALPHA);
opr1_target = useext(GL_OPERAND1_ALPHA);
opr2_target = useext(GL_OPERAND2_ALPHA);
scal_target = GL_ALPHA_SCALE;
}
else {
comb_target = useext(GL_COMBINE_RGB);
src0_target = useext(GL_SOURCE0_RGB);
src1_target = useext(GL_SOURCE1_RGB);
src2_target = useext(GL_SOURCE2_RGB);
opr0_target = useext(GL_OPERAND0_RGB);
opr1_target = useext(GL_OPERAND1_RGB);
opr2_target = useext(GL_OPERAND2_RGB);
scal_target = useext(GL_RGB_SCALE);
}
/* From MSDN (D3DTSS_ALPHAARG1) :
The default argument is D3DTA_TEXTURE. If no texture is set for this stage,
then the default argument is D3DTA_DIFFUSE.
FIXME? If texture added/removed, may need to reset back as well? */
if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == D3DTA_TEXTURE) {
GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlpha, &src1, &opr1);
} else {
GetSrcAndOpFromValue(arg1, isAlpha, &src1, &opr1);
}
GetSrcAndOpFromValue(arg2, isAlpha, &src2, &opr2);
GetSrcAndOpFromValue(arg3, isAlpha, &src3, &opr3);
TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
Handled = TRUE; /* Assume will be handled */
/* Other texture operations require special extensions: */
if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
if (isAlpha) {
opr = GL_SRC_ALPHA;
invopr = GL_ONE_MINUS_SRC_ALPHA;
src3_target = GL_SOURCE3_ALPHA_NV;
opr3_target = GL_OPERAND3_ALPHA_NV;
} else {
opr = GL_SRC_COLOR;
invopr = GL_ONE_MINUS_SRC_COLOR;
src3_target = GL_SOURCE3_RGB_NV;
opr3_target = GL_OPERAND3_RGB_NV;
}
switch (op) {
case D3DTOP_DISABLE: /* Only for alpha */
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
break;
case D3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
case D3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
if (op == D3DTOP_SELECTARG1) {
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
} else {
glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
}
glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
break;
case D3DTOP_MODULATE:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_MODULATE2X:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
break;
case D3DTOP_MODULATE4X:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
break;
case D3DTOP_ADD:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_ADDSIGNED:
glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_ADDSIGNED2X:
glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
break;
case D3DTOP_ADDSMOOTH:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
switch (opr1) {
case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_BLENDDIFFUSEALPHA:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_BLENDTEXTUREALPHA:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_BLENDFACTORALPHA:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_BLENDTEXTUREALPHAPM:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_MODULATEALPHA_ADDCOLOR:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
switch (opr) {
case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_MODULATECOLOR_ADDALPHA:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
switch (opr1) {
case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
switch (opr1) {
case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
switch (opr1) {
case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
switch (opr1) {
case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_MULTIPLYADD:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_BUMPENVMAP:
{
if (GL_SUPPORT(NV_TEXTURE_SHADER)) {
/*
texture unit 0: GL_TEXTURE_2D
texture unit 1: GL_DOT_PRODUCT_NV
texture unit 2: GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV
texture unit 3: GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV
*/
float m[2][2];
union {
float f;
DWORD d;
} tmpvalue;
tmpvalue.d = This->stateBlock->textureState[Stage][D3DTSS_BUMPENVMAT00];
m[0][0] = tmpvalue.f;
tmpvalue.d = This->stateBlock->textureState[Stage][D3DTSS_BUMPENVMAT01];
m[0][1] = tmpvalue.f;
tmpvalue.d = This->stateBlock->textureState[Stage][D3DTSS_BUMPENVMAT10];
m[1][0] = tmpvalue.f;
tmpvalue.d = This->stateBlock->textureState[Stage][D3DTSS_BUMPENVMAT11];
m[1][1] = tmpvalue.f;
/*FIXME("Stage %d matrix is (%.2f,%.2f),(%.2f,%.2f)\n", Stage, m[0][0], m[0][1], m[1][0], m[1][0]);*/
if (FALSE == This->texture_shader_active) {
This->texture_shader_active = TRUE;
glEnable(GL_TEXTURE_SHADER_NV);
}
/*
glEnable(GL_REGISTER_COMBINERS_NV);
glCombinerParameteriNV (GL_NUM_GENERAL_COMBINERS_NV, 1);
glCombinerInputNV (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_SIGNED_IDENTITY_NV, GL_RGB);
glCombinerInputNV (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_NONE, GL_UNSIGNED_INVERT_NV, GL_RGB);
glCombinerInputNV (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE2_ARB, GL_SIGNED_IDENTITY_NV, GL_RGB);
glCombinerInputNV (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_NONE, GL_UNSIGNED_INVERT_NV, GL_RGB);
glCombinerOutputNV (GL_COMBINER0_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_PRIMARY_COLOR_NV, 0, 0, 0, 0, 0);
glCombinerInputNV (GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_SIGNED_IDENTITY_NV, GL_ALPHA);
glCombinerInputNV (GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_B_NV, GL_NONE, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
glCombinerInputNV (GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_C_NV, GL_TEXTURE2_ARB, GL_SIGNED_IDENTITY_NV, GL_ALPHA);
glCombinerInputNV (GL_COMBINER0_NV, GL_ALPHA, GL_VARIABLE_D_NV, GL_NONE, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
glCombinerOutputNV (GL_COMBINER0_NV, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_PRIMARY_COLOR_NV, 0, 0, 0, 0, 0);
glDisable (GL_PER_STAGE_CONSTANTS_NV);
glCombinerParameteriNV (GL_COLOR_SUM_CLAMP_NV, 0);
glFinalCombinerInputNV (GL_VARIABLE_A_NV, 0, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV (GL_VARIABLE_B_NV, 0, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV (GL_VARIABLE_C_NV, 0, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV (GL_VARIABLE_D_NV, GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV (GL_VARIABLE_E_NV, 0, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV (GL_VARIABLE_F_NV, 0, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
glFinalCombinerInputNV (GL_VARIABLE_G_NV, GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
*/
/*
int i;
for (i = 0; i < Stage; i++) {
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_ACTIVETEXTURE(i);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
checkGLcall("Activate texture..");
} else if (i>0) {
FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
}
}
*/
/*
GL_ACTIVETEXTURE(Stage - 1);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
*/
/*
GL_ACTIVETEXTURE(Stage);
checkGLcall("Activate texture.. to update const color");
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV);
checkGLcall("glTexEnv");
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + Stage - 1);
checkGLcall("glTexEnv");
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, (float*)&m[0]);
checkGLcall("glTexEnv");
*/
LEAVE_GL();
return;
break;
}
}
case D3DTOP_BUMPENVMAPLUMINANCE:
default:
Handled = FALSE;
}
if (Handled) {
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
LEAVE_GL();
return;
}
} /* GL_NV_texture_env_combine4 */
Handled = TRUE; /* Again, assume handled */
switch (op) {
case D3DTOP_DISABLE: /* Only for alpha */
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_SELECTARG1:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_SELECTARG2:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_MODULATE:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_MODULATE2X:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
break;
case D3DTOP_MODULATE4X:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
break;
case D3DTOP_ADD:
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_ADDSIGNED:
glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_ADDSIGNED2X:
glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
break;
case D3DTOP_SUBTRACT:
if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
} else {
FIXME("This version of opengl does not support GL_SUBTRACT\n");
}
break;
case D3DTOP_BLENDDIFFUSEALPHA:
glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_BLENDTEXTUREALPHA:
glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_BLENDFACTORALPHA:
glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_BLENDCURRENTALPHA:
glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_DOTPRODUCT3:
if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
} else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
} else {
FIXME("This version of opengl does not support GL_DOT3\n");
}
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_LERP:
glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
case D3DTOP_ADDSMOOTH:
if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
switch (opr1) {
case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
} else
Handled = FALSE;
break;
case D3DTOP_BLENDTEXTUREALPHAPM:
if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
} else
Handled = FALSE;
break;
case D3DTOP_MODULATEALPHA_ADDCOLOR:
if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
switch (opr1) {
case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
} else
Handled = FALSE;
break;
case D3DTOP_MODULATECOLOR_ADDALPHA:
if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
switch (opr1) {
case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
} else
Handled = FALSE;
break;
case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
switch (opr1) {
case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
} else
Handled = FALSE;
break;
case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
switch (opr1) {
case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
switch (opr1) {
case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
} else
Handled = FALSE;
break;
case D3DTOP_MULTIPLYADD:
if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
} else
Handled = FALSE;
break;
default:
Handled = FALSE;
}
if (Handled) {
BOOL combineOK = TRUE;
if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
DWORD op2;
if (isAlpha) {
op2 = This->stateBlock->textureState[Stage][D3DTSS_COLOROP];
} else {
op2 = This->stateBlock->textureState[Stage][D3DTSS_ALPHAOP];
}
/* Note: If COMBINE4 in effect can't go back to combine! */
switch (op2) {
case D3DTOP_ADDSMOOTH:
case D3DTOP_BLENDTEXTUREALPHAPM:
case D3DTOP_MODULATEALPHA_ADDCOLOR:
case D3DTOP_MODULATECOLOR_ADDALPHA:
case D3DTOP_MODULATEINVALPHA_ADDCOLOR:
case D3DTOP_MODULATEINVCOLOR_ADDALPHA:
case D3DTOP_MULTIPLYADD:
/* Ignore those implemented in both cases */
switch (op) {
case D3DTOP_SELECTARG1:
case D3DTOP_SELECTARG2:
combineOK = FALSE;
Handled = FALSE;
break;
default:
FIXME("Can't use COMBINE4 and COMBINE together, thisop=%d, otherop=%ld, isAlpha(%d)\n", op, op2, isAlpha);
LEAVE_GL();
return;
}
}
}
if (combineOK) {
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
LEAVE_GL();
return;
}
}
LEAVE_GL();
/* After all the extensions, if still unhandled, report fixme */
FIXME("Unhandled texture operation %d\n", op);
#undef GLINFO_LOCATION
}
#endif
/* Setup this textures matrix according to the texture flags*/
void set_texture_matrix(const float *smat, DWORD flags)
{
float mat[16];
glMatrixMode(GL_TEXTURE);
if (flags == D3DTTFF_DISABLE) {
glLoadIdentity();
checkGLcall("glLoadIdentity()");
return;
}
if (flags == (D3DTTFF_COUNT1|D3DTTFF_PROJECTED)) {
ERR("Invalid texture transform flags: D3DTTFF_COUNT1|D3DTTFF_PROJECTED\n");
checkGLcall("glLoadIdentity()");
return;
}
memcpy(mat, smat, 16*sizeof(float));
switch (flags & ~D3DTTFF_PROJECTED) {
case D3DTTFF_COUNT1: mat[1] = mat[5] = mat[9] = mat[13] = 0;
case D3DTTFF_COUNT2: mat[2] = mat[6] = mat[10] = mat[14] = 0;
default: mat[3] = mat[7] = mat[11] = 0, mat[15] = 1;
}
if (flags & D3DTTFF_PROJECTED) switch (flags & ~D3DTTFF_PROJECTED) {
case D3DTTFF_COUNT2:
mat[3] = mat[1], mat[7] = mat[5], mat[11] = mat[9], mat[15] = mat[13];
mat[1] = mat[5] = mat[9] = mat[13] = 0;
break;
case D3DTTFF_COUNT3:
mat[3] = mat[2], mat[7] = mat[6], mat[11] = mat[10], mat[15] = mat[14];
mat[2] = mat[6] = mat[10] = mat[14] = 0;
break;
}
glLoadMatrixf(mat);
checkGLcall("glLoadMatrixf(mat)");
}
void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand)
{
BOOL isAlphaReplicate = FALSE;
BOOL isComplement = FALSE;
*operand = GL_SRC_COLOR;
*source = GL_TEXTURE;
/* Catch alpha replicate */
if (iValue & D3DTA_ALPHAREPLICATE) {
iValue = iValue & ~D3DTA_ALPHAREPLICATE;
isAlphaReplicate = TRUE;
}
/* Catch Complement */
if (iValue & D3DTA_COMPLEMENT) {
iValue = iValue & ~D3DTA_COMPLEMENT;
isComplement = TRUE;
}
/* Calculate the operand */
if (isAlphaReplicate && !isComplement) {
*operand = GL_SRC_ALPHA;
} else if (isAlphaReplicate && isComplement) {
*operand = GL_ONE_MINUS_SRC_ALPHA;
} else if (isComplement) {
if (isAlphaArg) {
*operand = GL_ONE_MINUS_SRC_ALPHA;
} else {
*operand = GL_ONE_MINUS_SRC_COLOR;
}
} else {
if (isAlphaArg) {
*operand = GL_SRC_ALPHA;
} else {
*operand = GL_SRC_COLOR;
}
}
/* Calculate the source */
switch (iValue & D3DTA_SELECTMASK) {
case D3DTA_CURRENT: *source = GL_PREVIOUS_EXT;
break;
case D3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT;
break;
case D3DTA_TEXTURE: *source = GL_TEXTURE;
break;
case D3DTA_TFACTOR: *source = GL_CONSTANT_EXT;
break;
case D3DTA_SPECULAR:
/*
* According to the GL_ARB_texture_env_combine specs, SPECULAR is
* 'Secondary color' and isn't supported until base GL supports it
* There is no concept of temp registers as far as I can tell
*/
FIXME("Unhandled texture arg D3DTA_SPECULAR\n");
*source = GL_TEXTURE;
break;
default:
FIXME("Unrecognized texture arg %ld\n", iValue);
*source = GL_TEXTURE;
}
}
......@@ -69,18 +69,51 @@ extern int num_lock;
/*****************************************************************************
* Defines
*/
/* GL related defines */
/* ------------------ */
#define GL_SUPPORT(ExtName) (GLINFO_LOCATION.supported[ExtName] != 0)
#define GL_LIMITS(ExtName) (GLINFO_LOCATION.max_##ExtName)
#define GL_EXTCALL(FuncName) (GLINFO_LOCATION.FuncName)
#define D3DCOLOR_R(dw) (((float) (((dw) >> 16) & 0xFF)) / 255.0f)
#define D3DCOLOR_G(dw) (((float) (((dw) >> 8) & 0xFF)) / 255.0f)
#define D3DCOLOR_B(dw) (((float) (((dw) >> 0) & 0xFF)) / 255.0f)
#define D3DCOLOR_A(dw) (((float) (((dw) >> 24) & 0xFF)) / 255.0f)
#define D3DCOLORTOGLFLOAT4(dw, vec) \
(vec)[0] = D3DCOLOR_R(dw); \
(vec)[1] = D3DCOLOR_G(dw); \
(vec)[2] = D3DCOLOR_B(dw); \
(vec)[3] = D3DCOLOR_A(dw);
/* Note: The following is purely to keep the source code as clear from #ifdefs as possible */
#if defined(GL_VERSION_1_3)
#define GL_ACTIVETEXTURE(textureNo) \
glActiveTexture(GL_TEXTURE0 + textureNo); \
checkGLcall("glActiveTexture");
#else
#define GL_ACTIVETEXTURE(textureNo) \
glActiveTextureARB(GL_TEXTURE0_ARB + textureNo); \
checkGLcall("glActiveTextureARB");
#endif
/* DirectX Device Limits */
/* --------------------- */
#define MAX_STREAMS 16 /* Maximum possible streams - used for fixed size arrays
See MaxStreams in MSDN under GetDeviceCaps */
#define HIGHEST_TRANSFORMSTATE 512
/* Highest value in D3DTRANSFORMSTATETYPE */
#define HIGHEST_RENDER_STATE 209
/* Highest D3DRS_ value */
#define HIGHEST_TEXTURE_STATE 32
/* Highest D3DTSS_ value */
#define WINED3D_VSHADER_MAX_CONSTANTS 96
/* Maximum number of constants provided to the shaders */
#define MAX_CLIPPLANES D3DMAXUSERCLIPPLANES
/* Checking of API calls */
/* --------------------- */
#define checkGLcall(A) \
{ \
GLint err = glGetError(); \
......@@ -91,6 +124,10 @@ extern int num_lock;
} \
}
/* Trace routines / diagnostics */
/* ---------------------------- */
/* Dump out a matrix and copy it */
#define conv_mat(mat,gl_mat) \
do { \
TRACE("%f %f %f %f\n", (mat)->u.s._11, (mat)->u.s._12, (mat)->u.s._13, (mat)->u.s._14); \
......@@ -100,17 +137,6 @@ do {
memcpy(gl_mat, (mat), 16 * sizeof(float)); \
} while (0)
/* The following is purely to keep the source code as clear from #ifdefs as possible */
#if defined(GL_VERSION_1_3)
#define GL_ACTIVETEXTURE(textureNo) \
glActiveTexture(GL_TEXTURE0 + textureNo); \
checkGLcall("glActiveTexture");
#else
#define GL_ACTIVETEXTURE(textureNo) \
glActiveTextureARB(GL_TEXTURE0_ARB + textureNo); \
checkGLcall("glActiveTextureARB");
#endif
/* Macro to dump out the current state of the light chain */
#define DUMP_LIGHT_CHAIN() \
{ \
......@@ -121,11 +147,20 @@ do {
} \
}
/* Trace vector and strided data information */
#define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w);
#define TRACE_STRIDED(sd,name) TRACE( #name "=(data:%p, stride:%ld, type:%ld)\n", sd->u.s.name.lpData, sd->u.s.name.dwStride, sd->u.s.name.dwType);
/* Defines used for optimizations */
/* Only reapply what is necessary */
#define REAPPLY_ALPHAOP 0x0001
#define REAPPLY_ALL 0xFFFF
/* Advance declaration of structures to satisfy compiler */
typedef struct IWineD3DStateBlockImpl IWineD3DStateBlockImpl;
/* Global variables */
extern const float identity[16];
/*****************************************************************************
......@@ -268,6 +303,11 @@ typedef struct IWineD3DDeviceImpl
#define IS_TRACKING 1 /* tracking_parm is tracking diffuse color */
#define NEEDS_TRACKING 2 /* Tracking needs to be enabled when needed */
#define NEEDS_DISABLE 3 /* Tracking needs to be disabled when needed*/
UINT srcBlend;
UINT dstBlend;
UINT alphafunc;
UINT stencilfunc;
BOOL texture_shader_active; /* TODO: Confirm use is correct */
/* State block related */
BOOL isRecordingState;
......@@ -283,6 +323,9 @@ typedef struct IWineD3DDeviceImpl
/* For rendering to a texture using glCopyTexImage */
BOOL renderUpsideDown;
/* Textures for when no other textures are mapped */
UINT dummyTextureName[8];
} IWineD3DDeviceImpl;
extern IWineD3DDeviceVtbl IWineD3DDevice_Vtbl;
......@@ -380,6 +423,8 @@ typedef struct SAVEDSTATES {
BOOL textures[8];
BOOL transform[HIGHEST_TRANSFORMSTATE];
BOOL viewport;
BOOL renderState[HIGHEST_RENDER_STATE];
BOOL textureState[8][HIGHEST_TEXTURE_STATE];
BOOL clipplane[MAX_CLIPPLANES];
} SAVEDSTATES;
......@@ -428,9 +473,20 @@ struct IWineD3DStateBlockImpl
/* Material */
WINED3DMATERIAL material;
/* Indexed Vertex Blending */
D3DVERTEXBLENDFLAGS vertex_blend;
FLOAT tween_factor;
/* RenderState */
DWORD renderState[HIGHEST_RENDER_STATE];
/* Texture */
IWineD3DBaseTexture *textures[8];
int textureDimensions[8];
/* Texture State Stage */
DWORD textureState[8][HIGHEST_TEXTURE_STATE];
};
extern IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl;
......@@ -438,11 +494,21 @@ extern IWineD3DStateBlockVtbl IWineD3DStateBlock_Vtbl;
/*****************************************************************************
* Utility function prototypes
*/
/* Trace routines */
const char* debug_d3dformat(D3DFORMAT fmt);
const char* debug_d3ddevicetype(D3DDEVTYPE devtype);
const char* debug_d3dresourcetype(D3DRESOURCETYPE res);
const char* debug_d3dusage(DWORD usage);
const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType);
const char* debug_d3drenderstate(DWORD state);
const char* debug_d3dtexturestate(DWORD state);
/* Routines for GL <-> D3D values */
GLenum StencilOp(DWORD op);
void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
void set_texture_matrix(const float *smat, DWORD flags);
void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand);
#if 0 /* Needs fixing during rework */
/*****************************************************************************
......
......@@ -182,11 +182,19 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown)
STDMETHOD(GetIndices)(THIS_ IWineD3DIndexBuffer ** ppIndexData,UINT * pBaseVertexIndex) PURE;
STDMETHOD(SetViewport)(THIS_ CONST WINED3DVIEWPORT * pViewport) PURE;
STDMETHOD(GetViewport)(THIS_ WINED3DVIEWPORT * pViewport) PURE;
STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD Value) PURE;
STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD * pValue) PURE;
STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) PURE;
STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD * pValue) PURE;
STDMETHOD(BeginScene)(THIS) PURE;
STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) PURE;
STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType,INT baseVIdx, UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) PURE;
STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void * pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE;
STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertexIndices,UINT PrimitiveCount,CONST void * pIndexData,D3DFORMAT IndexDataFormat,CONST void * pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE;
/*** Internal use IWineD3D methods ***/
STDMETHOD_(void, SetupTextureStates)(THIS_ DWORD Stage, DWORD Flags);
};
#undef INTERFACE
......@@ -221,11 +229,16 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown)
#define IWineD3DDevice_GetIndices(p,a,b) (p)->lpVtbl->GetIndices(p,a,b)
#define IWineD3DDevice_SetViewport(p,a) (p)->lpVtbl->SetViewport(p,a)
#define IWineD3DDevice_GetViewport(p,a) (p)->lpVtbl->GetViewport(p,a)
#define IWineD3DDevice_SetRenderState(p,a,b) (p)->lpVtbl->SetRenderState(p,a,b)
#define IWineD3DDevice_GetRenderState(p,a,b) (p)->lpVtbl->GetRenderState(p,a,b)
#define IWineD3DDevice_SetTextureStageState(p,a,b,c) (p)->lpVtbl->SetTextureStageState(p,a,b,c)
#define IWineD3DDevice_GetTextureStageState(p,a,b,c) (p)->lpVtbl->GetTextureStageState(p,a,b,c)
#define IWineD3DDevice_BeginScene(p) (p)->lpVtbl->BeginScene(p)
#define IWineD3DDevice_DrawPrimitive(p,a,b,c) (p)->lpVtbl->DrawPrimitive(p,a,b,c)
#define IWineD3DDevice_DrawIndexedPrimitive(p,a,b,c,d,e,f) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e,f)
#define IWineD3DDevice_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d)
#define IWineD3DDevice_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h)
#define IWineD3DDevice_SetupTextureStates(p,a,b) (p)->lpVtbl->SetupTextureStates(p,a,b)
#endif
/*****************************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment