2004-12-07 15:29:12 +01:00
/*
* IWineD3DBaseTexture Implementation
*
* Copyright 2002 - 2004 Jason Edmeades
2005-03-14 11:12:52 +01:00
* Copyright 2002 - 2004 Raphael Junqueira
* Copyright 2005 Oliver Stieber
2008-10-18 19:21:20 +02:00
* Copyright 2007 - 2008 Stefan Dösinger for CodeWeavers
2004-12-07 15:29:12 +01:00
*
* 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
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2004-12-07 15:29:12 +01:00
*/
# include "config.h"
# include "wined3d_private.h"
2005-08-03 13:00:28 +02:00
WINE_DEFAULT_DEBUG_CHANNEL ( d3d_texture ) ;
2007-06-09 14:27:41 +02:00
# define GLINFO_LOCATION This->resource.wineD3DDevice->adapter->gl_info
2004-12-07 15:29:12 +01:00
2009-01-12 10:17:50 +01:00
void basetexture_init ( struct IWineD3DBaseTextureClass * texture , UINT levels , DWORD usage )
{
texture - > levels = levels ;
texture - > filterType = ( usage & WINED3DUSAGE_AUTOGENMIPMAP ) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE ;
texture - > LOD = 0 ;
texture - > dirty = TRUE ;
2009-01-16 16:22:09 +01:00
texture - > srgbDirty = TRUE ;
2009-01-12 10:17:50 +01:00
texture - > is_srgb = FALSE ;
2009-03-26 03:12:50 +01:00
texture - > pow2Matrix_identity = TRUE ;
2009-01-12 10:17:50 +01:00
}
2008-12-02 18:41:32 +01:00
void basetexture_cleanup ( IWineD3DBaseTexture * iface )
{
2005-03-29 21:01:00 +02:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2007-03-17 23:00:39 +01:00
IWineD3DDeviceImpl * device = This - > resource . wineD3DDevice ;
2005-06-24 13:53:07 +02:00
TRACE ( " (%p) : textureName(%d) \n " , This , This - > baseTexture . textureName ) ;
2005-03-29 21:01:00 +02:00
if ( This - > baseTexture . textureName ! = 0 ) {
2007-03-17 23:00:39 +01:00
ActivateContext ( device , device - > lastActiveRenderTarget , CTXUSAGE_RESOURCELOAD ) ;
2007-08-06 16:27:08 +02:00
ENTER_GL ( ) ;
2005-06-24 13:53:07 +02:00
TRACE ( " (%p) : Deleting texture %d \n " , This , This - > baseTexture . textureName ) ;
2005-03-29 21:01:00 +02:00
glDeleteTextures ( 1 , & This - > baseTexture . textureName ) ;
2009-01-16 16:22:09 +01:00
glDeleteTextures ( 1 , & This - > baseTexture . srgbTextureName ) ;
2005-03-29 21:01:00 +02:00
LEAVE_GL ( ) ;
}
2008-12-02 18:41:33 +01:00
resource_cleanup ( ( IWineD3DResource * ) iface ) ;
2005-03-29 21:01:00 +02:00
}
2008-12-02 18:41:32 +01:00
void basetexture_unload ( IWineD3DBaseTexture * iface )
{
2008-01-25 18:18:06 +01:00
IWineD3DTextureImpl * This = ( IWineD3DTextureImpl * ) iface ;
IWineD3DDeviceImpl * device = This - > resource . wineD3DDevice ;
if ( This - > baseTexture . textureName ) {
ActivateContext ( device , device - > lastActiveRenderTarget , CTXUSAGE_RESOURCELOAD ) ;
ENTER_GL ( ) ;
glDeleteTextures ( 1 , & This - > baseTexture . textureName ) ;
2009-01-16 16:22:09 +01:00
glDeleteTextures ( 1 , & This - > baseTexture . srgbTextureName ) ;
2008-01-25 18:18:06 +01:00
This - > baseTexture . textureName = 0 ;
2009-01-16 16:22:09 +01:00
This - > baseTexture . srgbTextureName = 0 ;
2008-01-25 18:18:06 +01:00
LEAVE_GL ( ) ;
}
2008-01-25 18:18:55 +01:00
This - > baseTexture . dirty = TRUE ;
2009-01-16 16:22:09 +01:00
This - > baseTexture . srgbDirty = TRUE ;
2008-01-12 22:56:30 +01:00
}
2008-01-23 15:16:30 +01:00
/* There is no OpenGL equivalent of setLOD, getLOD. All they do anyway is prioritize texture loading
2005-03-14 11:12:52 +01:00
* so just pretend that they work unless something really needs a failure . */
2008-12-02 18:41:32 +01:00
DWORD basetexture_set_lod ( IWineD3DBaseTexture * iface , DWORD LODNew )
{
2004-12-07 15:29:12 +01:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2005-06-23 18:44:19 +02:00
2006-03-28 14:20:47 +02:00
if ( This - > resource . pool ! = WINED3DPOOL_MANAGED ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-06-23 18:44:19 +02:00
}
2005-03-14 11:12:52 +01:00
if ( LODNew > = This - > baseTexture . levels )
LODNew = This - > baseTexture . levels - 1 ;
This - > baseTexture . LOD = LODNew ;
2005-06-23 18:44:19 +02:00
2005-11-10 13:14:56 +01:00
TRACE ( " (%p) : set bogus LOD to %d \n " , This , This - > baseTexture . LOD ) ;
2005-06-23 18:44:19 +02:00
2005-03-14 11:12:52 +01:00
return This - > baseTexture . LOD ;
2004-12-07 15:29:12 +01:00
}
2008-12-02 18:41:32 +01:00
DWORD basetexture_get_lod ( IWineD3DBaseTexture * iface )
{
2004-12-07 15:29:12 +01:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2005-06-23 18:44:19 +02:00
2006-03-28 14:20:47 +02:00
if ( This - > resource . pool ! = WINED3DPOOL_MANAGED ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-03-14 11:12:52 +01:00
}
2005-06-23 18:44:19 +02:00
2005-11-10 13:14:56 +01:00
TRACE ( " (%p) : returning %d \n " , This , This - > baseTexture . LOD ) ;
2005-06-23 18:44:19 +02:00
2005-03-14 11:12:52 +01:00
return This - > baseTexture . LOD ;
2004-12-07 15:29:12 +01:00
}
2008-12-02 18:41:32 +01:00
DWORD basetexture_get_level_count ( IWineD3DBaseTexture * iface )
{
2004-12-07 15:29:12 +01:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2005-06-23 18:44:19 +02:00
TRACE ( " (%p) : returning %d \n " , This , This - > baseTexture . levels ) ;
2004-12-07 15:29:12 +01:00
return This - > baseTexture . levels ;
}
2008-12-02 18:41:32 +01:00
HRESULT basetexture_set_autogen_filter_type ( IWineD3DBaseTexture * iface , WINED3DTEXTUREFILTERTYPE FilterType )
{
2004-12-07 15:29:12 +01:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2007-08-31 20:56:15 +02:00
IWineD3DDeviceImpl * device = This - > resource . wineD3DDevice ;
UINT textureDimensions = IWineD3DBaseTexture_GetTextureDimensions ( iface ) ;
2005-03-14 11:12:52 +01:00
2007-05-03 21:00:25 +02:00
if ( ! ( This - > resource . usage & WINED3DUSAGE_AUTOGENMIPMAP ) ) {
2005-03-14 11:12:52 +01:00
TRACE ( " (%p) : returning invalid call \n " , This ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2005-03-14 11:12:52 +01:00
}
2007-08-31 20:56:15 +02:00
if ( This - > baseTexture . filterType ! = FilterType ) {
/* What about multithreading? Do we want all the context overhead just to set this value?
* Or should we delay the applying until the texture is used for drawing ? For now , apply
* immediately .
*/
ActivateContext ( device , device - > lastActiveRenderTarget , CTXUSAGE_RESOURCELOAD ) ;
ENTER_GL ( ) ;
glBindTexture ( textureDimensions , This - > baseTexture . textureName ) ;
checkGLcall ( " glBindTexture " ) ;
switch ( FilterType ) {
case WINED3DTEXF_NONE :
case WINED3DTEXF_POINT :
glTexParameteri ( textureDimensions , GL_GENERATE_MIPMAP_HINT_SGIS , GL_FASTEST ) ;
checkGLcall ( " glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_FASTEST) " ) ;
2008-04-14 17:16:25 +02:00
break ;
2007-08-31 20:56:15 +02:00
case WINED3DTEXF_LINEAR :
glTexParameteri ( textureDimensions , GL_GENERATE_MIPMAP_HINT_SGIS , GL_NICEST ) ;
checkGLcall ( " glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST) " ) ;
2008-04-14 17:16:25 +02:00
break ;
2007-08-31 20:56:15 +02:00
default :
WARN ( " Unexpected filter type %d, setting to GL_NICEST \n " , FilterType ) ;
glTexParameteri ( textureDimensions , GL_GENERATE_MIPMAP_HINT_SGIS , GL_NICEST ) ;
checkGLcall ( " glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST) " ) ;
}
LEAVE_GL ( ) ;
}
2005-03-14 11:12:52 +01:00
This - > baseTexture . filterType = FilterType ;
2005-11-10 13:14:56 +01:00
TRACE ( " (%p) : \n " , This ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-12-07 15:29:12 +01:00
}
2008-12-02 18:41:32 +01:00
WINED3DTEXTUREFILTERTYPE basetexture_get_autogen_filter_type ( IWineD3DBaseTexture * iface )
{
2004-12-07 15:29:12 +01:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
FIXME ( " (%p) : stub \n " , This ) ;
2007-05-03 21:00:25 +02:00
if ( ! ( This - > resource . usage & WINED3DUSAGE_AUTOGENMIPMAP ) ) {
2006-04-06 19:02:16 +02:00
return WINED3DTEXF_NONE ;
2005-03-14 11:12:52 +01:00
}
return This - > baseTexture . filterType ;
2004-12-07 15:29:12 +01:00
}
2008-12-02 18:41:32 +01:00
void basetexture_generate_mipmaps ( IWineD3DBaseTexture * iface )
{
2004-12-07 15:29:12 +01:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2005-06-23 18:44:19 +02:00
/* TODO: implement filters using GL_SGI_generate_mipmaps http://oss.sgi.com/projects/ogl-sample/registry/SGIS/generate_mipmap.txt */
2004-12-07 15:29:12 +01:00
FIXME ( " (%p) : stub \n " , This ) ;
return ;
}
2008-12-02 18:41:32 +01:00
BOOL basetexture_set_dirty ( IWineD3DBaseTexture * iface , BOOL dirty )
{
2005-01-09 18:37:02 +01:00
BOOL old ;
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2009-01-16 16:22:09 +01:00
old = This - > baseTexture . dirty | | This - > baseTexture . srgbDirty ;
2005-01-09 18:37:02 +01:00
This - > baseTexture . dirty = dirty ;
2009-01-16 16:22:09 +01:00
This - > baseTexture . srgbDirty = dirty ;
2005-01-09 18:37:02 +01:00
return old ;
}
2008-12-02 18:41:32 +01:00
BOOL basetexture_get_dirty ( IWineD3DBaseTexture * iface )
{
2005-01-17 14:44:57 +01:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2009-01-16 16:22:09 +01:00
return This - > baseTexture . dirty | | This - > baseTexture . srgbDirty ;
2005-01-17 14:44:57 +01:00
}
2009-01-16 16:22:09 +01:00
HRESULT basetexture_bind ( IWineD3DBaseTexture * iface , BOOL srgb , BOOL * set_surface_desc )
2008-12-02 18:41:32 +01:00
{
2005-03-14 11:12:52 +01:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2006-04-07 12:51:12 +02:00
HRESULT hr = WINED3D_OK ;
2005-03-29 21:01:00 +02:00
UINT textureDimensions ;
2005-07-18 11:07:17 +02:00
BOOL isNewTexture = FALSE ;
2009-01-16 16:22:09 +01:00
GLuint * texture ;
DWORD * states ;
2005-03-29 21:01:00 +02:00
TRACE ( " (%p) : About to bind texture \n " , This ) ;
2009-01-16 16:22:09 +01:00
This - > baseTexture . is_srgb = srgb ; /* SRGB mode cache for PreLoad calls outside drawprim */
if ( srgb ) {
texture = & This - > baseTexture . srgbTextureName ;
states = This - > baseTexture . srgbstates ;
} else {
texture = & This - > baseTexture . textureName ;
states = This - > baseTexture . states ;
}
2005-06-23 18:44:19 +02:00
textureDimensions = IWineD3DBaseTexture_GetTextureDimensions ( iface ) ;
2005-03-29 21:01:00 +02:00
ENTER_GL ( ) ;
/* Generate a texture name if we don't already have one */
2009-01-16 16:22:09 +01:00
if ( * texture = = 0 ) {
* set_surface_desc = TRUE ;
glGenTextures ( 1 , texture ) ;
2005-03-29 21:01:00 +02:00
checkGLcall ( " glGenTextures " ) ;
2009-01-16 16:22:09 +01:00
TRACE ( " Generated texture %d \n " , * texture ) ;
2006-03-28 14:20:47 +02:00
if ( This - > resource . pool = = WINED3DPOOL_DEFAULT ) {
2005-03-29 21:01:00 +02:00
/* Tell opengl to try and keep this texture in video ram (well mostly) */
GLclampf tmp ;
tmp = 0.9f ;
2009-01-16 16:22:09 +01:00
glPrioritizeTextures ( 1 , texture , & tmp ) ;
2005-08-03 13:00:28 +02:00
}
2005-11-23 20:14:43 +01:00
/* Initialise the state of the texture object
2005-08-03 13:00:28 +02:00
to the openGL defaults , not the directx defaults */
2009-01-16 16:22:09 +01:00
states [ WINED3DTEXSTA_ADDRESSU ] = WINED3DTADDRESS_WRAP ;
states [ WINED3DTEXSTA_ADDRESSV ] = WINED3DTADDRESS_WRAP ;
states [ WINED3DTEXSTA_ADDRESSW ] = WINED3DTADDRESS_WRAP ;
states [ WINED3DTEXSTA_BORDERCOLOR ] = 0 ;
states [ WINED3DTEXSTA_MAGFILTER ] = WINED3DTEXF_LINEAR ;
states [ WINED3DTEXSTA_MINFILTER ] = WINED3DTEXF_POINT ; /* GL_NEAREST_MIPMAP_LINEAR */
states [ WINED3DTEXSTA_MIPFILTER ] = WINED3DTEXF_LINEAR ; /* GL_NEAREST_MIPMAP_LINEAR */
states [ WINED3DTEXSTA_MAXMIPLEVEL ] = 0 ;
states [ WINED3DTEXSTA_MAXANISOTROPY ] = 0 ;
states [ WINED3DTEXSTA_SRGBTEXTURE ] = 0 ;
states [ WINED3DTEXSTA_ELEMENTINDEX ] = 0 ;
states [ WINED3DTEXSTA_DMAPOFFSET ] = 0 ;
states [ WINED3DTEXSTA_TSSADDRESSW ] = WINED3DTADDRESS_WRAP ;
2005-06-23 18:44:19 +02:00
IWineD3DBaseTexture_SetDirty ( iface , TRUE ) ;
2005-07-18 11:07:17 +02:00
isNewTexture = TRUE ;
2007-08-31 20:56:15 +02:00
if ( This - > resource . usage & WINED3DUSAGE_AUTOGENMIPMAP ) {
/* This means double binding the texture at creation, but keeps the code simpler all
* in all , and the run - time path free from additional checks
*/
2009-01-16 16:22:09 +01:00
glBindTexture ( textureDimensions , * texture ) ;
2007-08-31 20:56:15 +02:00
checkGLcall ( " glBindTexture " ) ;
glTexParameteri ( textureDimensions , GL_GENERATE_MIPMAP_SGIS , GL_TRUE ) ;
checkGLcall ( " glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_SGIS, GL_TRUE) " ) ;
}
2009-01-16 16:22:09 +01:00
} else {
* set_surface_desc = FALSE ;
2005-03-29 21:01:00 +02:00
}
/* Bind the texture */
2009-01-16 16:22:09 +01:00
if ( * texture ! = 0 ) {
glBindTexture ( textureDimensions , * texture ) ;
2005-03-29 21:01:00 +02:00
checkGLcall ( " glBindTexture " ) ;
2005-08-03 21:49:05 +02:00
if ( isNewTexture ) {
2006-10-15 17:05:01 +02:00
/* For a new texture we have to set the textures levels after binding the texture.
2007-11-27 22:25:07 +01:00
* In theory this is all we should ever have to do , but because ATI ' s drivers are broken , we
* also need to set the texture dimensions before the texture is set
2008-07-09 01:59:10 +02:00
* Beware that texture rectangles do not support mipmapping , but set the maxmiplevel if we ' re
* relying on the partial GL_ARB_texture_non_power_of_two emulation with texture rectangles
* ( ie , do not care for cond_np2 here , just look for GL_TEXTURE_RECTANGLE_ARB )
2007-11-27 22:25:07 +01:00
*/
if ( textureDimensions ! = GL_TEXTURE_RECTANGLE_ARB ) {
TRACE ( " Setting GL_TEXTURE_MAX_LEVEL to %d \n " , This - > baseTexture . levels - 1 ) ;
glTexParameteri ( textureDimensions , GL_TEXTURE_MAX_LEVEL , This - > baseTexture . levels - 1 ) ;
checkGLcall ( " glTexParameteri(textureDimensions, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels) " ) ;
}
2007-03-10 14:37:28 +01:00
if ( textureDimensions = = GL_TEXTURE_CUBE_MAP_ARB ) {
2008-01-09 20:37:05 +01:00
/* Cubemaps are always set to clamp, regardless of the sampler state. */
2007-03-10 14:37:28 +01:00
glTexParameteri ( textureDimensions , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
glTexParameteri ( textureDimensions , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
glTexParameteri ( textureDimensions , GL_TEXTURE_WRAP_R , GL_CLAMP_TO_EDGE ) ;
}
2005-08-22 12:07:10 +02:00
}
2005-03-29 21:01:00 +02:00
} else { /* this only happened if we've run out of openGL textures */
WARN ( " This texture doesn't have an openGL texture assigned to it \n " ) ;
2006-04-07 12:51:12 +02:00
hr = WINED3DERR_INVALIDCALL ;
2005-03-29 21:01:00 +02:00
}
2005-06-23 18:44:19 +02:00
LEAVE_GL ( ) ;
return hr ;
2005-03-14 11:12:52 +01:00
}
2005-06-23 18:44:19 +02:00
2009-05-14 19:40:56 +02:00
/* GL locking is done by the caller */
2008-07-09 01:59:10 +02:00
static inline void apply_wrap ( const GLint textureDimensions , const DWORD state , const GLint type ,
BOOL cond_np2 ) {
2007-08-12 13:37:17 +02:00
GLint wrapParm ;
if ( state < minLookup [ WINELOOKUP_WARPPARAM ] | | state > maxLookup [ WINELOOKUP_WARPPARAM ] ) {
FIXME ( " Unrecognized or unsupported WINED3DTADDRESS_U value %d \n " , state ) ;
} else {
if ( textureDimensions = = GL_TEXTURE_CUBE_MAP_ARB ) {
2008-01-23 15:16:30 +01:00
/* Cubemaps are always set to clamp, regardless of the sampler state. */
2007-08-12 13:37:17 +02:00
wrapParm = GL_CLAMP_TO_EDGE ;
2008-07-09 01:59:10 +02:00
} else if ( cond_np2 ) {
2008-02-01 01:16:45 +01:00
if ( state = = WINED3DTADDRESS_WRAP ) {
wrapParm = GL_CLAMP_TO_EDGE ;
} else {
wrapParm = stateLookup [ WINELOOKUP_WARPPARAM ] [ state - minLookup [ WINELOOKUP_WARPPARAM ] ] ;
}
2007-08-12 13:37:17 +02:00
} else {
wrapParm = stateLookup [ WINELOOKUP_WARPPARAM ] [ state - minLookup [ WINELOOKUP_WARPPARAM ] ] ;
}
TRACE ( " Setting WRAP_S to %d for %x \n " , wrapParm , textureDimensions ) ;
glTexParameteri ( textureDimensions , type , wrapParm ) ;
checkGLcall ( " glTexParameteri(..., type, wrapParm) " ) ;
}
}
2009-05-14 19:40:56 +02:00
/* GL locking is done by the caller (state handler) */
2008-12-02 18:41:32 +01:00
void basetexture_apply_state_changes ( IWineD3DBaseTexture * iface ,
const DWORD textureStates [ WINED3D_HIGHEST_TEXTURE_STATE + 1 ] ,
const DWORD samplerStates [ WINED3D_HIGHEST_SAMPLER_STATE + 1 ] )
{
2005-08-03 13:00:28 +02:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2009-01-16 16:22:09 +01:00
DWORD state , * states ;
2005-08-03 13:00:28 +02:00
GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions ( iface ) ;
2008-07-09 01:59:10 +02:00
BOOL cond_np2 = IWineD3DBaseTexture_IsCondNP2 ( iface ) ;
2007-08-12 13:37:17 +02:00
2009-05-12 16:19:55 +02:00
TRACE ( " iface %p, textureStates %p, samplerStates %p \n " , iface , textureStates , samplerStates ) ;
2009-01-16 16:22:09 +01:00
if ( This - > baseTexture . is_srgb ) {
states = This - > baseTexture . srgbstates ;
} else {
states = This - > baseTexture . states ;
}
2009-05-12 16:19:55 +02:00
/* This function relies on the correct texture being bound and loaded. */
2007-08-12 13:37:17 +02:00
2009-01-16 16:22:09 +01:00
if ( samplerStates [ WINED3DSAMP_ADDRESSU ] ! = states [ WINED3DTEXSTA_ADDRESSU ] ) {
2007-08-12 13:37:17 +02:00
state = samplerStates [ WINED3DSAMP_ADDRESSU ] ;
2008-07-09 01:59:10 +02:00
apply_wrap ( textureDimensions , state , GL_TEXTURE_WRAP_S , cond_np2 ) ;
2009-01-16 16:22:09 +01:00
states [ WINED3DTEXSTA_ADDRESSU ] = state ;
2007-08-12 13:37:17 +02:00
}
2009-01-16 16:22:09 +01:00
if ( samplerStates [ WINED3DSAMP_ADDRESSV ] ! = states [ WINED3DTEXSTA_ADDRESSV ] ) {
2007-08-12 13:37:17 +02:00
state = samplerStates [ WINED3DSAMP_ADDRESSV ] ;
2008-07-09 01:59:10 +02:00
apply_wrap ( textureDimensions , state , GL_TEXTURE_WRAP_T , cond_np2 ) ;
2009-01-16 16:22:09 +01:00
states [ WINED3DTEXSTA_ADDRESSV ] = state ;
2007-08-12 13:37:17 +02:00
}
2009-01-16 16:22:09 +01:00
if ( samplerStates [ WINED3DSAMP_ADDRESSW ] ! = states [ WINED3DTEXSTA_ADDRESSW ] ) {
2007-08-12 13:37:17 +02:00
state = samplerStates [ WINED3DSAMP_ADDRESSW ] ;
2008-07-09 01:59:10 +02:00
apply_wrap ( textureDimensions , state , GL_TEXTURE_WRAP_R , cond_np2 ) ;
2009-01-16 16:22:09 +01:00
states [ WINED3DTEXSTA_ADDRESSW ] = state ;
2007-08-12 13:37:17 +02:00
}
2009-01-16 16:22:09 +01:00
if ( samplerStates [ WINED3DSAMP_BORDERCOLOR ] ! = states [ WINED3DTEXSTA_BORDERCOLOR ] ) {
2007-08-12 13:37:17 +02:00
float col [ 4 ] ;
state = samplerStates [ WINED3DSAMP_BORDERCOLOR ] ;
D3DCOLORTOGLFLOAT4 ( state , col ) ;
TRACE ( " Setting border color for %u to %x \n " , textureDimensions , state ) ;
glTexParameterfv ( textureDimensions , GL_TEXTURE_BORDER_COLOR , & col [ 0 ] ) ;
checkGLcall ( " glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...) " ) ;
2009-01-16 16:22:09 +01:00
states [ WINED3DTEXSTA_BORDERCOLOR ] = state ;
2007-08-12 13:37:17 +02:00
}
2009-01-16 16:22:09 +01:00
if ( samplerStates [ WINED3DSAMP_MAGFILTER ] ! = states [ WINED3DTEXSTA_MAGFILTER ] ) {
2007-08-12 13:37:17 +02:00
GLint glValue ;
state = samplerStates [ WINED3DSAMP_MAGFILTER ] ;
2008-05-09 23:32:32 +02:00
if ( state > WINED3DTEXF_ANISOTROPIC ) {
2007-08-12 13:37:17 +02:00
FIXME ( " Unrecognized or unsupported MAGFILTER* value %d \n " , state ) ;
2008-04-16 22:54:28 +02:00
} else {
2008-11-26 16:14:40 +01:00
glValue = This - > baseTexture . magLookup [ state - WINED3DTEXF_NONE ] ;
2008-04-16 22:54:28 +02:00
TRACE ( " ValueMAG=%d setting MAGFILTER to %x \n " , state , glValue ) ;
glTexParameteri ( textureDimensions , GL_TEXTURE_MAG_FILTER , glValue ) ;
/* We need to reset the Anisotropic filtering state when we change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentation to see how it should be switched off. */
if ( GL_SUPPORT ( EXT_TEXTURE_FILTER_ANISOTROPIC ) & & WINED3DTEXF_ANISOTROPIC = = state & &
2008-07-09 01:59:10 +02:00
! cond_np2 ) {
2008-04-16 22:54:28 +02:00
glTexParameteri ( textureDimensions , GL_TEXTURE_MAX_ANISOTROPY_EXT , samplerStates [ WINED3DSAMP_MAXANISOTROPY ] ) ;
}
2009-01-16 16:22:09 +01:00
states [ WINED3DTEXSTA_MAGFILTER ] = state ;
2007-08-12 13:37:17 +02:00
}
}
2009-01-16 16:22:09 +01:00
if ( ( samplerStates [ WINED3DSAMP_MINFILTER ] ! = states [ WINED3DTEXSTA_MINFILTER ] | |
samplerStates [ WINED3DSAMP_MIPFILTER ] ! = states [ WINED3DTEXSTA_MIPFILTER ] | |
samplerStates [ WINED3DSAMP_MAXMIPLEVEL ] ! = states [ WINED3DTEXSTA_MAXMIPLEVEL ] ) ) {
2007-08-12 13:37:17 +02:00
GLint glValue ;
2009-01-16 16:22:09 +01:00
states [ WINED3DTEXSTA_MIPFILTER ] = samplerStates [ WINED3DSAMP_MIPFILTER ] ;
states [ WINED3DTEXSTA_MINFILTER ] = samplerStates [ WINED3DSAMP_MINFILTER ] ;
states [ WINED3DTEXSTA_MAXMIPLEVEL ] = samplerStates [ WINED3DSAMP_MAXMIPLEVEL ] ;
2007-08-12 13:37:17 +02:00
2009-01-16 16:22:09 +01:00
if ( states [ WINED3DTEXSTA_MINFILTER ] > WINED3DTEXF_ANISOTROPIC | |
states [ WINED3DTEXSTA_MIPFILTER ] > WINED3DTEXF_LINEAR )
2007-08-12 13:37:17 +02:00
{
FIXME ( " Unrecognized or unsupported D3DSAMP_MINFILTER value %d D3DSAMP_MIPFILTER value %d \n " ,
2009-01-16 16:22:09 +01:00
states [ WINED3DTEXSTA_MINFILTER ] ,
states [ WINED3DTEXSTA_MIPFILTER ] ) ;
2007-08-12 13:37:17 +02:00
}
2008-11-26 16:14:40 +01:00
glValue = This - > baseTexture . minMipLookup
2008-07-08 23:55:33 +02:00
[ min ( max ( samplerStates [ WINED3DSAMP_MINFILTER ] , WINED3DTEXF_NONE ) , WINED3DTEXF_ANISOTROPIC ) ]
2008-11-26 16:14:40 +01:00
. mip [ min ( max ( samplerStates [ WINED3DSAMP_MIPFILTER ] , WINED3DTEXF_NONE ) , WINED3DTEXF_LINEAR ) ] ;
2007-08-12 13:37:17 +02:00
TRACE ( " ValueMIN=%d, ValueMIP=%d, setting MINFILTER to %x \n " ,
samplerStates [ WINED3DSAMP_MINFILTER ] ,
samplerStates [ WINED3DSAMP_MIPFILTER ] , glValue ) ;
glTexParameteri ( textureDimensions , GL_TEXTURE_MIN_FILTER , glValue ) ;
checkGLcall ( " glTexParameter GL_TEXTURE_MIN_FILTER, ... " ) ;
2008-07-09 01:59:10 +02:00
if ( ! cond_np2 ) {
2009-01-16 16:22:09 +01:00
if ( states [ WINED3DTEXSTA_MIPFILTER ] = = WINED3DTEXF_NONE ) {
2008-07-09 01:59:10 +02:00
glValue = 0 ;
2009-01-16 16:22:09 +01:00
} else if ( states [ WINED3DTEXSTA_MAXMIPLEVEL ] > = This - > baseTexture . levels ) {
2008-07-09 01:59:10 +02:00
glValue = This - > baseTexture . levels - 1 ;
} else {
2009-01-16 16:22:09 +01:00
glValue = states [ WINED3DTEXSTA_MAXMIPLEVEL ] ;
2008-07-09 01:59:10 +02:00
}
glTexParameteri ( textureDimensions , GL_TEXTURE_BASE_LEVEL , glValue ) ;
2007-08-12 13:37:17 +02:00
}
}
2009-01-16 16:22:09 +01:00
if ( samplerStates [ WINED3DSAMP_MAXANISOTROPY ] ! = states [ WINED3DTEXSTA_MAXANISOTROPY ] ) {
2008-07-09 01:59:10 +02:00
if ( GL_SUPPORT ( EXT_TEXTURE_FILTER_ANISOTROPIC ) & & ! cond_np2 ) {
2007-08-12 13:37:17 +02:00
glTexParameteri ( textureDimensions , GL_TEXTURE_MAX_ANISOTROPY_EXT , samplerStates [ WINED3DSAMP_MAXANISOTROPY ] ) ;
checkGLcall ( " glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ... " ) ;
} else {
WARN ( " Unsupported in local OpenGL implementation: glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT \n " ) ;
2005-08-03 13:00:28 +02:00
}
2009-01-16 16:22:09 +01:00
states [ WINED3DTEXSTA_MAXANISOTROPY ] = samplerStates [ WINED3DSAMP_MAXANISOTROPY ] ;
2005-08-03 13:00:28 +02:00
}
}