Sweden-Number/dlls/wined3d/utils.c

1522 lines
76 KiB
C
Raw Normal View History

/*
* Utility functions for the WineD3D Library
*
* Copyright 2002-2004 Jason Edmeades
* Copyright 2003-2004 Raphael Junqueira
* Copyright 2004 Christian Costa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wined3d_private.h"
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
FMT_TO_STR(D3DFMT_UNKNOWN);
FMT_TO_STR(D3DFMT_R8G8B8);
FMT_TO_STR(D3DFMT_A8R8G8B8);
FMT_TO_STR(D3DFMT_X8R8G8B8);
FMT_TO_STR(D3DFMT_R5G6B5);
FMT_TO_STR(D3DFMT_X1R5G5B5);
FMT_TO_STR(D3DFMT_A1R5G5B5);
FMT_TO_STR(D3DFMT_A4R4G4B4);
FMT_TO_STR(D3DFMT_R3G3B2);
FMT_TO_STR(D3DFMT_A8);
FMT_TO_STR(D3DFMT_A8R3G3B2);
FMT_TO_STR(D3DFMT_X4R4G4B4);
FMT_TO_STR(D3DFMT_A8P8);
FMT_TO_STR(D3DFMT_P8);
FMT_TO_STR(D3DFMT_L8);
FMT_TO_STR(D3DFMT_A8L8);
FMT_TO_STR(D3DFMT_A4L4);
FMT_TO_STR(D3DFMT_V8U8);
FMT_TO_STR(D3DFMT_L6V5U5);
FMT_TO_STR(D3DFMT_X8L8V8U8);
FMT_TO_STR(D3DFMT_Q8W8V8U8);
FMT_TO_STR(D3DFMT_V16U16);
FMT_TO_STR(D3DFMT_W11V11U10);
FMT_TO_STR(D3DFMT_UYVY);
FMT_TO_STR(D3DFMT_YUY2);
FMT_TO_STR(D3DFMT_DXT1);
FMT_TO_STR(D3DFMT_DXT2);
FMT_TO_STR(D3DFMT_DXT3);
FMT_TO_STR(D3DFMT_DXT4);
FMT_TO_STR(D3DFMT_DXT5);
FMT_TO_STR(D3DFMT_D16_LOCKABLE);
FMT_TO_STR(D3DFMT_D32);
FMT_TO_STR(D3DFMT_D15S1);
FMT_TO_STR(D3DFMT_D24S8);
FMT_TO_STR(D3DFMT_D16);
FMT_TO_STR(D3DFMT_D24X8);
FMT_TO_STR(D3DFMT_D24X4S4);
FMT_TO_STR(D3DFMT_VERTEXDATA);
FMT_TO_STR(D3DFMT_INDEX16);
FMT_TO_STR(D3DFMT_INDEX32);
#undef FMT_TO_STR
default:
FIXME("Unrecognized %u D3DFORMAT!\n", fmt);
return "unrecognized";
}
}
const char* debug_d3ddevicetype(D3DDEVTYPE devtype) {
switch (devtype) {
#define DEVTYPE_TO_STR(dev) case dev: return #dev
DEVTYPE_TO_STR(D3DDEVTYPE_HAL);
DEVTYPE_TO_STR(D3DDEVTYPE_REF);
DEVTYPE_TO_STR(D3DDEVTYPE_SW);
#undef DEVTYPE_TO_STR
default:
FIXME("Unrecognized %u D3DDEVTYPE!\n", devtype);
return "unrecognized";
}
}
const char* debug_d3dusage(DWORD usage) {
switch (usage) {
#define D3DUSAGE_TO_STR(u) case u: return #u
D3DUSAGE_TO_STR(D3DUSAGE_RENDERTARGET);
D3DUSAGE_TO_STR(D3DUSAGE_DEPTHSTENCIL);
D3DUSAGE_TO_STR(D3DUSAGE_WRITEONLY);
D3DUSAGE_TO_STR(D3DUSAGE_SOFTWAREPROCESSING);
D3DUSAGE_TO_STR(D3DUSAGE_DONOTCLIP);
D3DUSAGE_TO_STR(D3DUSAGE_POINTS);
D3DUSAGE_TO_STR(D3DUSAGE_RTPATCHES);
D3DUSAGE_TO_STR(D3DUSAGE_NPATCHES);
D3DUSAGE_TO_STR(D3DUSAGE_DYNAMIC);
#undef D3DUSAGE_TO_STR
case 0: return "none";
default:
FIXME("Unrecognized %lu Usage!\n", usage);
return "unrecognized";
}
}
const char* debug_d3dresourcetype(D3DRESOURCETYPE res) {
switch (res) {
#define RES_TO_STR(res) case res: return #res;
RES_TO_STR(D3DRTYPE_SURFACE);
RES_TO_STR(D3DRTYPE_VOLUME);
RES_TO_STR(D3DRTYPE_TEXTURE);
RES_TO_STR(D3DRTYPE_VOLUMETEXTURE);
RES_TO_STR(D3DRTYPE_CUBETEXTURE);
RES_TO_STR(D3DRTYPE_VERTEXBUFFER);
RES_TO_STR(D3DRTYPE_INDEXBUFFER);
#undef RES_TO_STR
default:
FIXME("Unrecognized %u D3DRESOURCETYPE!\n", res);
return "unrecognized";
}
}
const char* debug_d3dprimitivetype(D3DPRIMITIVETYPE PrimitiveType) {
switch (PrimitiveType) {
#define PRIM_TO_STR(prim) case prim: return #prim;
PRIM_TO_STR(D3DPT_POINTLIST);
PRIM_TO_STR(D3DPT_LINELIST);
PRIM_TO_STR(D3DPT_LINESTRIP);
PRIM_TO_STR(D3DPT_TRIANGLELIST);
PRIM_TO_STR(D3DPT_TRIANGLESTRIP);
PRIM_TO_STR(D3DPT_TRIANGLEFAN);
#undef PRIM_TO_STR
default:
FIXME("Unrecognized %u D3DPRIMITIVETYPE!\n", 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;
}
}