wined3d: Enable the loading and reloading of gamma corrected textures.

This commit is contained in:
Phil Costin 2007-06-06 23:13:16 +00:00 committed by Alexandre Julliard
parent e7578dca36
commit 622f62d352
6 changed files with 82 additions and 18 deletions

View File

@ -105,6 +105,8 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
BOOL setGlTextureDesc = FALSE;
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
BOOL srgb_mode = This->baseTexture.is_srgb;
BOOL srgb_was_toggled = FALSE;
TRACE("(%p) : About to load texture: dirtified(%d)\n", This, This->baseTexture.dirty);
@ -120,23 +122,46 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
ENTER_GL();
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
LEAVE_GL();
} else if (GL_SUPPORT(EXT_TEXTURE_SRGB) && This->baseTexture.bindCount > 0) {
srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
srgb_was_toggled = (This->baseTexture.is_srgb != srgb_mode);
This->baseTexture.is_srgb = srgb_mode;
}
IWineD3DCubeTexture_BindTexture(iface);
ENTER_GL();
/* If were dirty then reload the surfaces */
/* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */
if (This->baseTexture.dirty) {
for (i = 0; i < This->baseTexture.levels; i++) {
for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
if(setGlTextureDesc)
IWineD3DSurface_SetGlTextureDesc(This->surfaces[j][i], This->baseTexture.textureName, cube_targets[j]);
IWineD3DSurface_LoadTexture(This->surfaces[j][i], FALSE);
IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
}
}
/* No longer dirty */
This->baseTexture.dirty = FALSE;
} else if (srgb_was_toggled) {
/* Loop is repeated in the else block with the extra AddDirtyRect line to avoid the alternative of
* checking srgb_was_toggled in every iteration, even when the texture is just dirty
*/
if (This->baseTexture.srgb_mode_change_count < 20)
++This->baseTexture.srgb_mode_change_count;
else
FIXME("Cubetexture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
for (i = 0; i < This->baseTexture.levels; i++) {
for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
IWineD3DSurfaceImpl_AddDirtyRect(This->surfaces[j][i], NULL);
IWineD3DSurface_SetGlTextureDesc(This->surfaces[j][i], This->baseTexture.textureName, cube_targets[j]);
IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
}
}
} else {
TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
}
LEAVE_GL();
/* No longer dirty */
This->baseTexture.dirty = FALSE;
return ;
}

View File

@ -138,6 +138,10 @@ static void WINAPI IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3
_basetexture.filterType = (Usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE; \
_basetexture.LOD = 0; \
_basetexture.dirty = TRUE; \
_basetexture.is_srgb = FALSE; \
_basetexture.srgb_mode_change_count = 0; \
_basetexture.is_srgb = FALSE; \
_basetexture.srgb_mode_change_count = 0; \
}
/**********************************************************

View File

@ -1052,7 +1052,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
This->samplerState[i][WINED3DSAMP_MIPMAPLODBIAS ] = 0;
This->samplerState[i][WINED3DSAMP_MAXMIPLEVEL ] = 0;
This->samplerState[i][WINED3DSAMP_MAXANISOTROPY ] = 1;
This->samplerState[i][WINED3DSAMP_SRGBTEXTURE ] = 0; /* TODO: Gamma correction value*/
This->samplerState[i][WINED3DSAMP_SRGBTEXTURE ] = 0;
This->samplerState[i][WINED3DSAMP_ELEMENTINDEX ] = 0; /* TODO: Indicates which element of a multielement texture to use */
This->samplerState[i][WINED3DSAMP_DMAPOFFSET ] = 0; /* TODO: Vertex offset in the presampled displacement map */
}

View File

@ -98,6 +98,8 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
BOOL setGlTextureDesc = FALSE;
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
BOOL srgb_mode = This->baseTexture.is_srgb;
BOOL srgb_was_toggled = FALSE;
TRACE("(%p) : About to load texture\n", This);
@ -110,26 +112,40 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
ENTER_GL();
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
LEAVE_GL();
} else if (GL_SUPPORT(EXT_TEXTURE_SRGB) && This->baseTexture.bindCount > 0) {
srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
srgb_was_toggled = This->baseTexture.is_srgb != srgb_mode;
This->baseTexture.is_srgb = srgb_mode;
}
IWineD3DTexture_BindTexture(iface);
ENTER_GL();
/* If were dirty then reload the surfaces */
if(This->baseTexture.dirty) {
/* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */
if (This->baseTexture.dirty) {
for (i = 0; i < This->baseTexture.levels; i++) {
if(setGlTextureDesc)
IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], This->baseTexture.textureName, IWineD3DTexture_GetTextureDimensions(iface));
IWineD3DSurface_LoadTexture(This->surfaces[i], FALSE);
IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
}
} else if (srgb_was_toggled) {
if (This->baseTexture.srgb_mode_change_count < 20)
++This->baseTexture.srgb_mode_change_count;
else
FIXME("Texture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
/* No longer dirty */
This->baseTexture.dirty = FALSE;
for (i = 0; i < This->baseTexture.levels; i++) {
IWineD3DSurfaceImpl_AddDirtyRect(This->surfaces[i], NULL);
IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], This->baseTexture.textureName, IWineD3DTexture_GetTextureDimensions(iface));
IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
}
} else {
TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
}
LEAVE_GL();
/* No longer dirty */
This->baseTexture.dirty = FALSE;
return ;
}

View File

@ -95,6 +95,8 @@ static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *ifac
int i;
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
BOOL srgb_mode = This->baseTexture.is_srgb;
BOOL srgb_was_toggled = FALSE;
TRACE("(%p) : About to load texture\n", This);
@ -103,18 +105,33 @@ static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *ifac
ENTER_GL();
if(!device->isInDraw) {
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
} else if (GL_SUPPORT(EXT_TEXTURE_SRGB) && This->baseTexture.bindCount > 0) {
srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
srgb_was_toggled = This->baseTexture.is_srgb != srgb_mode;
This->baseTexture.is_srgb = srgb_mode;
}
/* If were dirty then reload the volumes */
if(This->baseTexture.dirty) {
for (i = 0; i < This->baseTexture.levels; i++) {
IWineD3DVolume_LoadTexture(This->volumes[i], i, FALSE);
}
/* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */
if (This->baseTexture.dirty) {
for (i = 0; i < This->baseTexture.levels; i++)
IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
} else if (srgb_was_toggled) {
if (This->baseTexture.srgb_mode_change_count < 20)
++This->baseTexture.srgb_mode_change_count;
else
FIXME("Volumetexture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
/* No longer dirty */
This->baseTexture.dirty = FALSE;
for (i = 0; i < This->baseTexture.levels; i++) {
IWineD3DVolume_AddDirtyBox(This->volumes[i], NULL);
IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
}
} else {
TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
}
LEAVE_GL();
/* No longer dirty */
This->baseTexture.dirty = FALSE;
return ;
}

View File

@ -883,6 +883,8 @@ typedef struct IWineD3DBaseTextureClass
DWORD states[MAX_WINETEXTURESTATES];
LONG bindCount;
DWORD sampler;
BOOL is_srgb;
UINT srgb_mode_change_count;
} IWineD3DBaseTextureClass;
typedef struct IWineD3DBaseTextureImpl