Add support for a lot of the remaining texture ops, move code into the

utils module, and clean up the main code path.
This commit is contained in:
Jason Edmeades 2003-06-04 22:20:47 +00:00 committed by Alexandre Julliard
parent 0b5e9d9feb
commit 3d51c865d4
2 changed files with 646 additions and 249 deletions

View File

@ -985,71 +985,6 @@ void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
TRACE("glEnd\n");
}
/**
* @nodoc: todo
*/
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
* isnt supported until base GL supports it
* There is no concept of temp registers as far as I can tell
*/
default:
FIXME("Unrecognized or unhandled texture arg %ld\n", iValue);
*source = GL_TEXTURE;
}
}
/* Apply the current values to the specified texture stage */
void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
@ -3848,63 +3783,22 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 ifa
}
break;
case D3DTSS_COLORARG0 :
case D3DTSS_ALPHAARG0 :
/* FIXME: Mesa seems to struggle setting these at the moment */
/*FIXME("COLORARG0/ALPHAARG0 support still a stub, Stage=%ld, Type=%d, Value =%ld\n", Stage, Type, Value);*/
/*break;*/
case D3DTSS_COLORARG1 :
case D3DTSS_COLORARG2 :
case D3DTSS_ALPHAARG1 :
case D3DTSS_ALPHAARG2 :
{
BOOL isAlphaArg = (Type == D3DTSS_ALPHAARG1 || Type == D3DTSS_ALPHAARG2 || Type == D3DTSS_ALPHAARG0);
int operand = GL_SRC_COLOR;
int source = GL_TEXTURE;
GetSrcAndOpFromValue(Value, isAlphaArg, &source, &operand);
if (isAlphaArg) {
/* 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 (Type == D3DTSS_ALPHAARG1 && This->StateBlock->textures[Stage] == NULL && Value == D3DTA_TEXTURE) {
GetSrcAndOpFromValue(D3DTA_DIFFUSE, isAlphaArg, &source, &operand);
}
TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_ALPHA_EXT(Type), source, OPERANDx_ALPHA_EXT(Type), operand);
glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT(Type), source);
vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_ALPHA_EXT, source);");
glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT(Type), operand);
vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_ALPHA_EXT, operand);");
} else {
TRACE("Source %x = %x, Operand %x = %x\n", SOURCEx_RGB_EXT(Type), source, OPERANDx_RGB_EXT(Type), operand);
glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT(Type), source);
vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, SOURCEx_RGB_EXT, source);");
glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT(Type), operand);
vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, OPERANDx_RGB_EXT, operand);");
}
}
break;
case D3DTSS_ALPHAOP :
case D3DTSS_COLOROP :
{
int Scale = 1;
int Parm = (Type == D3DTSS_ALPHAOP) ? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT;
if (Type == D3DTSS_COLOROP && Value == D3DTOP_DISABLE) {
if (Value == D3DTOP_DISABLE) {
/* 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");
if (Type == D3DTSS_COLOROP) {
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; /* Dont bother setting the texture operations */
} else {
/* Enable only the appropriate texture dimension */
if (Type == D3DTSS_COLOROP) {
if (This->StateBlock->textureDimensions[Stage] == GL_TEXTURE_1D) {
@ -3936,139 +3830,27 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 ifa
checkGLcall("Disable GL_TEXTURE_CUBE_MAP");
}
}
/* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT */
if (Value != D3DTOP_DISABLE) {
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
}
/* Now set up the operand correctly */
switch (Value) {
case D3DTOP_DISABLE :
/* Contrary to the docs, alpha can be disabled when colorop is enabled
and it works, so ignore this op */
TRACE("Disable ALPHAOP but COLOROP enabled!\n");
break;
case D3DTOP_SELECTARG1 :
{
glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
}
break;
case D3DTOP_SELECTARG2 :
{
BOOL isAlphaOp = (Type == D3DTSS_ALPHAOP);
DWORD dwValue = 0;
GLenum source;
GLenum operand;
/*FIXME("see if D3DTOP_SELECTARG2 behavior is correct now!\n");*/
glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_REPLACE)");
/* GL_REPLACE, swap args 0 and 1? */
dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG2 : D3DTSS_COLORARG2];
GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
if (isAlphaOp) {
TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_ALPHA_EXT, source, GL_OPERAND0_ALPHA_EXT, operand);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, source);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, 'source')");
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, operand);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, 'operand')");
} else {
TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE0_RGB_EXT, source, GL_OPERAND0_RGB_EXT, operand);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, source);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 'source')");
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, operand);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, 'operand')");
}
dwValue = This->StateBlock->texture_state[Stage][(isAlphaOp) ? D3DTSS_ALPHAARG1 : D3DTSS_COLORARG1];
GetSrcAndOpFromValue(dwValue, isAlphaOp, &source, &operand);
if (isAlphaOp) {
TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_ALPHA_EXT, source, GL_OPERAND1_ALPHA_EXT, operand);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, source);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, 'source')");
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, operand);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, 'operand')");
} else {
TRACE("Source %x = %x, Operand %x = %x\n", GL_SOURCE1_RGB_EXT, source, GL_OPERAND1_RGB_EXT, operand);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, source);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, 'source')");
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, operand);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, 'operand')");
}
}
break;
case D3DTOP_MODULATE4X : Scale = Scale * 2; /* Drop through */
case D3DTOP_MODULATE2X : Scale = Scale * 2; /* Drop through */
case D3DTOP_MODULATE :
/* Correct scale */
if (Type == D3DTSS_ALPHAOP) {
glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale);
vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, Scale)");
} else {
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale);
vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, Scale)");
}
glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_MODULATE);");
break;
case D3DTOP_ADD :
glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD);
vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD)");
break;
case D3DTOP_ADDSIGNED2X : Scale = Scale * 2; /* Drop through */
case D3DTOP_ADDSIGNED :
glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT);
vcheckGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_ADD_SIGNED_EXT)");
break;
case D3DTOP_DOTPRODUCT3 :
#if defined(GL_VERSION_1_3)
if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
glTexEnvi(GL_TEXTURE_ENV, Parm, GL_DOT3_RGBA);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);");
break;
}
#endif
FIXME("DotProduct3 extension requested but not supported via this version of opengl\n");
break;
case D3DTOP_SUBTRACT :
#if defined(GL_VERSION_1_3)
glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT);
checkGLcall("glTexEnvi(GL_TEXTURE_ENV, Parm, GL_SUBTRACT)");
break;
#else
/**
* @TODO: to check:
* if ARB_texture_env_combine is supported
* we can use GL_SUBTRACT_ARB here
*/
#endif
case D3DTOP_ADDSMOOTH :
case D3DTOP_BLENDDIFFUSEALPHA :
case D3DTOP_BLENDTEXTUREALPHA :
case D3DTOP_BLENDFACTORALPHA :
case D3DTOP_BLENDTEXTUREALPHAPM :
case D3DTOP_BLENDCURRENTALPHA :
case D3DTOP_PREMODULATE :
case D3DTOP_MODULATEALPHA_ADDCOLOR :
case D3DTOP_MODULATECOLOR_ADDALPHA :
case D3DTOP_MODULATEINVALPHA_ADDCOLOR :
case D3DTOP_MODULATEINVCOLOR_ADDALPHA :
case D3DTOP_BUMPENVMAP :
case D3DTOP_BUMPENVMAPLUMINANCE :
case D3DTOP_MULTIPLYADD :
case D3DTOP_LERP :
default:
FIXME("Unhandled texture operation %ld\n", Value);
}
/* 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->texture_state[Stage][D3DTSS_ALPHAOP],
This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG1],
This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG2],
This->StateBlock->texture_state[Stage][D3DTSS_ALPHAARG0]);
} else {
set_tex_op(iface, FALSE, Stage, This->StateBlock->texture_state[Stage][D3DTSS_COLOROP],
This->StateBlock->texture_state[Stage][D3DTSS_COLORARG1],
This->StateBlock->texture_state[Stage][D3DTSS_COLORARG2],
This->StateBlock->texture_state[Stage][D3DTSS_COLORARG0]);
}
}
break;

View File

@ -468,3 +468,618 @@ GLenum StencilOp(DWORD op) {
return GL_ALWAYS;
}
}
/**
* @nodoc: todo
*/
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
* isnt supported until base GL supports it
* There is no concept of temp registers as far as I can tell
*/
default:
FIXME("Unrecognized or unhandled texture arg %ld\n", iValue);
*source = GL_TEXTURE;
}
}
/* 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(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
{
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;
ICOM_THIS(IDirect3DDevice8Impl,iface);
TRACE("Alpha?(%d), Stage:%d Op(%d), a1(%ld), a2(%ld), a3(%ld)\n", isAlpha, Stage, op, arg1, arg2, arg3);
if (op == D3DTOP_DISABLE) return;
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 = useext(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 && Stage==0 && 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 */
switch (op) {
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 defined(GL_VERSION_1_3) || defined (GL_ARB_texture_env_combine)
glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(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");
#endif
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, 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, 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, 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 defined(GL_EXT_texture_env_dot3)
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
#elif defined(GL_ARB_texture_env_dot3)
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
#elif defined (GL_VERSION_1_3)
glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA);
checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA");
#else
FIXME("This version of opengl does not support GL_DOT3\n");
#endif
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, 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, src3);
checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
glTexEnvi(GL_TEXTURE_ENV, opr2_target, src1);
checkGLcall("GL_TEXTURE_ENV, opr2_target, src1");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
default:
Handled = FALSE;
}
if (Handled) {
#if defined(GL_NV_texture_env_combine4)
/* Note: If COMBINE4 in effect cant go back to combine! */
if (isAlpha) {
switch (This->UpdateStateBlock->texture_state[Stage][D3DTSS_COLOROP])
{
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:
FIXME("Cant have COMBINE4 and COMBINE in efferct together, alphaop=%d\n", op);
return;
}
}
#endif
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
return;
}
/* Other texture operations require special extensions: */
#if defined(GL_NV_texture_env_combine4)
if (isAlpha) {
invopr = GL_ONE_MINUS_SRC_ALPHA;
src3_target = GL_SOURCE3_ALPHA_NV;
opr3_target = GL_OPERAND3_ALPHA_NV;
}
else {
invopr = GL_ONE_MINUS_SRC_COLOR;
src3_target = GL_SOURCE3_RGB_NV;
opr3_target = GL_OPERAND3_RGB_NV;
}
Handled = TRUE; /* Again, assume handled */
switch (op) {
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: opr1 = GL_ONE_MINUS_SRC_COLOR; break;
case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_SRC_COLOR; break;
case GL_SRC_ALPHA: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_ALPHA: opr1 = GL_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
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 (opr1) {
case GL_SRC_COLOR: opr1 = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
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: opr1 = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
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: opr1 = GL_SRC_ALPHA; break;
case GL_ONE_MINUS_SRC_COLOR: opr1 = GL_ONE_MINUS_SRC_ALPHA; break;
}
glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
checkGLcall("GL_TEXTURE_ENV, opr2_target, opr1");
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, 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, src3);
checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr3);
checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
break;
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");
return;
}
#endif /* GL_NV_texture_env_combine4 */
/* After all the extensions, if still unhandled, report fixme */
FIXME("Unhandled texture operation %d\n", op);
}
#endif