Query opengl to ensure it supports multitexture, and honour the number
of supported texture units. Especially important for NVidia drivers which only support 2 texture units.
This commit is contained in:
parent
4feb257eed
commit
13ee7cd154
|
@ -314,6 +314,10 @@ struct IDirect3DDevice8Impl
|
|||
Display *display;
|
||||
Window win;
|
||||
|
||||
/* OpenGL Extension related */
|
||||
BOOL isMultiTexture;
|
||||
UINT TextureUnits;
|
||||
|
||||
UINT dummyTextureName[8];
|
||||
};
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
|
|||
|
||||
} else {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
checkGLcall("glMatrixMode");
|
||||
checkGLcall("glMatrixMode");
|
||||
glLoadMatrixf((float *) &This->StateBlock.transforms[D3DTS_PROJECTION].u.m[0][0]);
|
||||
checkGLcall("glLoadMatrixf");
|
||||
|
||||
|
@ -301,6 +301,11 @@ void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
|
|||
|
||||
float s,t,r,q;
|
||||
|
||||
if (!(This->isMultiTexture) && textureNo>0) {
|
||||
FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Query tex coords */
|
||||
if (This->StateBlock.textures[textureNo] != NULL) {
|
||||
switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->StateBlock.textures[textureNo])) {
|
||||
|
@ -310,7 +315,11 @@ void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
|
|||
t = *(float *)curPos;
|
||||
curPos = curPos + sizeof(float);
|
||||
TRACE("tex:%d, s,t=%f,%f\n", textureNo, s,t);
|
||||
glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
|
||||
if (This->isMultiTexture) {
|
||||
glMultiTexCoord2fARB(GL_TEXTURE0_ARB + textureNo, s, t);
|
||||
} else {
|
||||
glTexCoord2f(s, t);
|
||||
}
|
||||
break;
|
||||
|
||||
case D3DRTYPE_VOLUMETEXTURE:
|
||||
|
@ -321,7 +330,11 @@ void DrawPrimitiveI(LPDIRECT3DDEVICE8 iface,
|
|||
r = *(float *)curPos;
|
||||
curPos = curPos + sizeof(float);
|
||||
TRACE("tex:%d, s,t,r=%f,%f,%f\n", textureNo, s,t,r);
|
||||
glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
|
||||
if (This->isMultiTexture) {
|
||||
glMultiTexCoord3fARB(GL_TEXTURE0_ARB + textureNo, s, t, r);
|
||||
} else {
|
||||
glTexCoord3f(s, t, r);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -535,8 +548,12 @@ void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage) {
|
|||
float col[4];
|
||||
|
||||
/* Make appropriate texture active */
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
|
||||
checkGLcall("glActiveTextureARB");
|
||||
if (This->isMultiTexture) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
|
||||
checkGLcall("glActiveTextureARB");
|
||||
} else if (Stage>0) {
|
||||
FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
|
||||
}
|
||||
|
||||
TRACE("-----------------------> Updating the texture at stage %ld to have new texture state information\n", Stage);
|
||||
for (i=1; i<HIGHEST_TEXTURE_STATE; i++) {
|
||||
|
@ -1901,12 +1918,16 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetRenderState(LPDIRECT3DDEVICE8 iface, D3
|
|||
checkGLcall("glBlendColor");
|
||||
|
||||
/* And now the default texture color as well */
|
||||
for (i=0; i<8; i++) {
|
||||
for (i=0; i<This->TextureUnits; i++) {
|
||||
|
||||
/* Note the D3DRS value applies to all textures, but GL has one
|
||||
per texture, so apply it now ready to be used! */
|
||||
checkGLcall("Activate texture.. to update const color");
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + i);
|
||||
if (This->isMultiTexture) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + i);
|
||||
checkGLcall("Activate texture.. to update const color");
|
||||
} else if (i>0) {
|
||||
FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
|
||||
}
|
||||
|
||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
|
||||
checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
|
||||
|
@ -2283,7 +2304,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, D
|
|||
}
|
||||
|
||||
/* Texture */
|
||||
for (j=0; j<8; j++) {
|
||||
for (j=0; j<This->TextureUnits; j++) {
|
||||
for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
|
||||
|
||||
if (pSB->Set.texture_state[j][i] && pSB->Changed.texture_state[j][i])
|
||||
|
@ -2304,7 +2325,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, D
|
|||
|
||||
}
|
||||
|
||||
for (j=0; j<8; i++) {
|
||||
for (j=0; j<This->TextureUnits; i++) {
|
||||
for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
|
||||
|
||||
if (pSB->Set.texture_state[j][SavedPixelStates_T[i]] &&
|
||||
|
@ -2321,7 +2342,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_ApplyStateBlock(LPDIRECT3DDEVICE8 iface, D
|
|||
|
||||
}
|
||||
|
||||
for (j=0; j<8; i++) {
|
||||
for (j=0; j<This->TextureUnits; i++) {
|
||||
for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
|
||||
|
||||
if (pSB->Set.texture_state[j][SavedVertexStates_T[i]] &&
|
||||
|
@ -2457,7 +2478,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_CaptureStateBlock(LPDIRECT3DDEVICE8 iface,
|
|||
}
|
||||
|
||||
/* Texture */
|
||||
for (j=0; j<8; j++) {
|
||||
for (j=0; j<This->TextureUnits; j++) {
|
||||
for (i=0; i<HIGHEST_TEXTURE_STATE; i++) {
|
||||
|
||||
if (updateBlock->Set.texture_state[j][i] && (updateBlock->texture_state[j][i] !=
|
||||
|
@ -2522,7 +2543,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface,
|
|||
for (i=0; i<NUM_SAVEDPIXELSTATES_R; i++) {
|
||||
s->Changed.renderstate[SavedPixelStates_R[i]] = TRUE;
|
||||
}
|
||||
for (j=0; j<8; i++) {
|
||||
for (j=0; j<This->TextureUnits; i++) {
|
||||
for (i=0; i<NUM_SAVEDPIXELSTATES_T; i++) {
|
||||
s->Changed.texture_state[j][SavedPixelStates_T[i]] = TRUE;
|
||||
}
|
||||
|
@ -2538,7 +2559,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreateStateBlock(LPDIRECT3DDEVICE8 iface,
|
|||
for (i=0; i<NUM_SAVEDVERTEXSTATES_R; i++) {
|
||||
s->Changed.renderstate[SavedVertexStates_R[i]] = TRUE;
|
||||
}
|
||||
for (j=0; j<8; i++) {
|
||||
for (j=0; j<This->TextureUnits; i++) {
|
||||
for (i=0; i<NUM_SAVEDVERTEXSTATES_T; i++) {
|
||||
s->Changed.texture_state[j][SavedVertexStates_T[i]] = TRUE;
|
||||
}
|
||||
|
@ -2592,8 +2613,12 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD
|
|||
}
|
||||
|
||||
/* Make appropriate texture active */
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
|
||||
checkGLcall("glActiveTextureARB");
|
||||
if (This->isMultiTexture) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
|
||||
checkGLcall("glActiveTextureARB");
|
||||
} else if (Stage>0) {
|
||||
FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
|
||||
}
|
||||
|
||||
/* Decrement the count of the previous texture */
|
||||
/* FIXME PERF: If old == new and not dirty then skip all this */
|
||||
|
@ -2765,8 +2790,12 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTextureStageState(LPDIRECT3DDEVICE8 ifa
|
|||
|
||||
/* Make appropriate texture active */
|
||||
TRACE("Activating appropriate texture state %ld\n", Stage);
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
|
||||
checkGLcall("glActiveTextureARB");
|
||||
if (This->isMultiTexture) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + Stage);
|
||||
checkGLcall("glActiveTextureARB");
|
||||
} else if (Stage>0) {
|
||||
FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
|
||||
}
|
||||
|
||||
switch (Type) {
|
||||
|
||||
|
@ -3687,7 +3716,7 @@ void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
|
|||
IDirect3DDevice8Impl_SetRenderState(iface, D3DRS_NORMALORDER, D3DORDER_LINEAR);
|
||||
|
||||
/* Texture Stage States - Put directly into state block, we will call function below */
|
||||
for (i=0; i<8;i++) {
|
||||
for (i=0; i<This->TextureUnits;i++) {
|
||||
This->StateBlock.texture_state[i][D3DTSS_COLOROP ] = (i==0)? D3DTOP_MODULATE : D3DTOP_DISABLE;
|
||||
This->StateBlock.texture_state[i][D3DTSS_COLORARG1 ] = D3DTA_TEXTURE;
|
||||
This->StateBlock.texture_state[i][D3DTSS_COLORARG2 ] = D3DTA_CURRENT;
|
||||
|
@ -3719,11 +3748,11 @@ void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
|
|||
|
||||
/* Under DirectX you can have texture stage operations even if no texture is
|
||||
bound, whereas opengl will only do texture operations when a valid texture is
|
||||
bound. We emulate this by creating 8 dummy textures and binding them to each
|
||||
bound. We emulate this by creating dummy textures and binding them to each
|
||||
texture stage, but disable all stages by default. Hence if a stage is enabled
|
||||
then the default texture will kick in until replaced by a SetTexture call */
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
for (i=0; i<This->TextureUnits; i++) {
|
||||
GLubyte white = 255;
|
||||
|
||||
/* Note this avoids calling settexture, so pretend it has been called */
|
||||
|
@ -3732,8 +3761,12 @@ void CreateStateBlock(LPDIRECT3DDEVICE8 iface) {
|
|||
This->StateBlock.textures[i] = NULL;
|
||||
|
||||
/* Make appropriate texture active */
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + i);
|
||||
checkGLcall("glActiveTextureARB");
|
||||
if (This->isMultiTexture) {
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + i);
|
||||
checkGLcall("glActiveTextureARB");
|
||||
} else if (i>0) {
|
||||
FIXME("Program using multiple concurrent textures which this opengl implementation doesnt support\n");
|
||||
}
|
||||
|
||||
/* Generate an opengl texture name */
|
||||
glGenTextures(1, &This->dummyTextureName[i]);
|
||||
|
|
|
@ -343,8 +343,14 @@ HRESULT WINAPI IDirect3D8Impl_GetDeviceCaps (LPDIRECT3D8 iface,
|
|||
|
||||
pCaps->FVFCaps = D3DFVFCAPS_PSIZE | 0x80000;
|
||||
pCaps->TextureOpCaps = 0xFFFFFFFF;
|
||||
pCaps->MaxTextureBlendStages = 256;
|
||||
pCaps->MaxSimultaneousTextures = 256;
|
||||
|
||||
{
|
||||
GLint gl_max_texture_units_arb;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max_texture_units_arb);
|
||||
TRACE("GLCaps: GL_MAX_TEXTURE_UNITS_ARB=%d\n", gl_max_texture_units_arb);
|
||||
pCaps->MaxTextureBlendStages = min(8, gl_max_texture_units_arb);
|
||||
pCaps->MaxSimultaneousTextures = min(8, gl_max_texture_units_arb);
|
||||
}
|
||||
|
||||
pCaps->VertexProcessingCaps = D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_TEXGEN;
|
||||
|
||||
|
@ -538,8 +544,9 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
|
|||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||
checkGLcall("glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);");
|
||||
|
||||
/* Setup all the devices defaults */
|
||||
CreateStateBlock((LPDIRECT3DDEVICE8) object);
|
||||
/* Initialize openGL extension related variables */
|
||||
object->isMultiTexture = FALSE;
|
||||
object->TextureUnits = 1;
|
||||
|
||||
/* Parse the gl supported features, in theory enabling parts of our code appropriately */
|
||||
GL_Extensions = glGetString(GL_EXTENSIONS);
|
||||
|
@ -551,13 +558,22 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
|
|||
while (*GL_Extensions!=0x00) {
|
||||
const char *Start = GL_Extensions;
|
||||
char ThisExtn[256];
|
||||
|
||||
|
||||
memset(ThisExtn, 0x00, sizeof(ThisExtn));
|
||||
while (*GL_Extensions!=' ' && *GL_Extensions!=0x00) {
|
||||
GL_Extensions++;
|
||||
GL_Extensions++;
|
||||
}
|
||||
memcpy(ThisExtn, Start, (GL_Extensions-Start));
|
||||
TRACE (" %s\n", ThisExtn);
|
||||
|
||||
if (strcmp(ThisExtn, "GL_ARB_multitexture")==0) {
|
||||
GLint gl_max_texture_units_arb;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max_texture_units_arb);
|
||||
object->isMultiTexture = TRUE;
|
||||
object->TextureUnits = min(8, gl_max_texture_units_arb);
|
||||
TRACE("FOUND: Multitexture support - GL_MAX_TEXTURE_UNITS_ARB=%d\n", gl_max_texture_units_arb);
|
||||
}
|
||||
|
||||
if (*GL_Extensions==' ') GL_Extensions++;
|
||||
}
|
||||
}
|
||||
|
@ -571,10 +587,10 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
|
|||
while (*GLX_Extensions!=0x00) {
|
||||
const char *Start = GLX_Extensions;
|
||||
char ThisExtn[256];
|
||||
|
||||
|
||||
memset(ThisExtn, 0x00, sizeof(ThisExtn));
|
||||
while (*GLX_Extensions!=' ' && *GLX_Extensions!=0x00) {
|
||||
GLX_Extensions++;
|
||||
GLX_Extensions++;
|
||||
}
|
||||
memcpy(ThisExtn, Start, (GLX_Extensions-Start));
|
||||
TRACE (" %s\n", ThisExtn);
|
||||
|
@ -582,13 +598,10 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
|
|||
}
|
||||
}
|
||||
|
||||
LEAVE_GL();
|
||||
/* Setup all the devices defaults */
|
||||
CreateStateBlock((LPDIRECT3DDEVICE8) object);
|
||||
|
||||
{
|
||||
GLint gl_max_texture_units_arb;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max_texture_units_arb);
|
||||
TRACE("GLCaps: GL_MAX_TEXTURE_UNITS_ARB=%d\n", gl_max_texture_units_arb);
|
||||
}
|
||||
LEAVE_GL();
|
||||
|
||||
{ /* Set a default viewport */
|
||||
D3DVIEWPORT8 vp;
|
||||
|
|
Loading…
Reference in New Issue