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
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 ) ;
2004-12-07 15:29:12 +01:00
# define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info
2005-08-03 13:00:28 +02:00
static const Wined3dTextureStateMap textureObjectSamplerStates [ ] = {
{ WINED3DSAMP_ADDRESSU , WINED3DSAMP_ADDRESSU } ,
{ WINED3DSAMP_ADDRESSV , WINED3DSAMP_ADDRESSV } ,
{ WINED3DSAMP_ADDRESSW , WINED3DSAMP_ADDRESSW } ,
/* NOTE: Sometimes it's a good idea to disable the setting of border colour, e.g. Axis and Allies */
{ WINED3DSAMP_BORDERCOLOR , WINED3DFUNC_NOTSUPPORTED /* WINED3DSAMP_BORDERCOLOR */ } ,
{ WINED3DSAMP_MAGFILTER , WINED3DSAMP_MAGFILTER } ,
{ WINED3DSAMP_MINFILTER , WINED3DSAMP_MINFILTER } ,
{ WINED3DSAMP_MIPFILTER , WINED3DSAMP_MIPFILTER } ,
/* applies to the texture unit
WINED3DSAMP_MIPMAPLODBIAS , WINED3DSAMP_MIPMAPLODBIAS ,
*/
{ WINED3DSAMP_MAXMIPLEVEL , WINED3DSAMP_MAXMIPLEVEL } ,
#if 0
{ WINED3DSAMP_MAXANISOTROPY , GL_SUPPORTED ( EXT_TEXTURE_FILTER_ANISOTROPIC ) ? WINED3DSAMP_MAXANISOTROPY : WINED3DFUNC_NOTSUPPORTED } ,
# else
{ WINED3DSAMP_MAXANISOTROPY , WINED3DSAMP_MAXANISOTROPY } ,
# endif
{ WINED3DSAMP_SRGBTEXTURE , WINED3DFUNC_UNIMPLEMENTED } ,
{ WINED3DSAMP_ELEMENTINDEX , WINED3DFUNC_UNIMPLEMENTED } ,
{ WINED3DSAMP_DMAPOFFSET , WINED3DFUNC_UNIMPLEMENTED } ,
{ - 1 , 0 }
} ;
static const Wined3dTextureStateMap textureObjectTextureStates [ ] = {
{ WINED3DTSS_ADDRESSW , WINED3DTSS_ADDRESSW } ,
{ - 1 , 0 }
} ;
2004-12-07 15:29:12 +01:00
/* *******************************************
IWineD3DBaseTexture IUnknown parts follow
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
HRESULT WINAPI IWineD3DBaseTextureImpl_QueryInterface ( IWineD3DBaseTexture * iface , REFIID riid , LPVOID * ppobj )
{
2005-06-23 18:44:19 +02:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
TRACE ( " (%p)->(%s,%p) \n " , This , debugstr_guid ( riid ) , ppobj ) ;
if ( IsEqualGUID ( riid , & IID_IUnknown )
2006-02-06 11:32:41 +01:00
| | IsEqualGUID ( riid , & IID_IWineD3DBase )
2005-06-23 18:44:19 +02:00
| | IsEqualGUID ( riid , & IID_IWineD3DResource )
2005-03-02 14:44:58 +01:00
| | IsEqualGUID ( riid , & IID_IWineD3DBaseTexture ) ) {
IUnknown_AddRef ( iface ) ;
* ppobj = This ;
2006-04-25 23:59:12 +02:00
return S_OK ;
2005-06-23 18:44:19 +02:00
}
2006-04-25 23:59:12 +02:00
* ppobj = NULL ;
2004-12-07 15:29:12 +01:00
return E_NOINTERFACE ;
}
ULONG WINAPI IWineD3DBaseTextureImpl_AddRef ( IWineD3DBaseTexture * iface ) {
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2005-01-19 17:59:01 +01:00
ULONG ref = InterlockedIncrement ( & This - > resource . ref ) ;
2005-06-23 18:44:19 +02:00
2005-01-19 17:59:01 +01:00
TRACE ( " (%p) : AddRef increasing from %ld \n " , This , ref - 1 ) ;
return ref ;
2004-12-07 15:29:12 +01:00
}
ULONG WINAPI IWineD3DBaseTextureImpl_Release ( IWineD3DBaseTexture * iface ) {
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2005-01-19 17:59:01 +01:00
ULONG ref = InterlockedDecrement ( & This - > resource . ref ) ;
TRACE ( " (%p) : Releasing from %ld \n " , This , ref + 1 ) ;
2004-12-07 15:29:12 +01:00
if ( ref = = 0 ) {
2005-03-29 21:01:00 +02:00
IWineD3DBaseTextureImpl_CleanUp ( iface ) ;
2004-12-07 15:29:12 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , This ) ;
}
return ref ;
}
2005-03-29 21:01:00 +02:00
/* class static */
2005-06-23 18:44:19 +02:00
void IWineD3DBaseTextureImpl_CleanUp ( IWineD3DBaseTexture * iface ) {
2005-03-29 21:01:00 +02:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
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 ) {
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 ) ;
LEAVE_GL ( ) ;
}
IWineD3DResourceImpl_CleanUp ( ( IWineD3DResource * ) iface ) ;
}
2004-12-07 15:29:12 +01:00
/* ****************************************************
IWineD3DBaseTexture IWineD3DResource parts follow
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
HRESULT WINAPI IWineD3DBaseTextureImpl_GetDevice ( IWineD3DBaseTexture * iface , IWineD3DDevice * * ppDevice ) {
2005-01-17 14:44:57 +01:00
return IWineD3DResourceImpl_GetDevice ( ( IWineD3DResource * ) iface , ppDevice ) ;
2004-12-07 15:29:12 +01:00
}
HRESULT WINAPI IWineD3DBaseTextureImpl_SetPrivateData ( IWineD3DBaseTexture * iface , REFGUID refguid , CONST void * pData , DWORD SizeOfData , DWORD Flags ) {
2005-01-17 14:44:57 +01:00
return IWineD3DResourceImpl_SetPrivateData ( ( IWineD3DResource * ) iface , refguid , pData , SizeOfData , Flags ) ;
2004-12-07 15:29:12 +01:00
}
HRESULT WINAPI IWineD3DBaseTextureImpl_GetPrivateData ( IWineD3DBaseTexture * iface , REFGUID refguid , void * pData , DWORD * pSizeOfData ) {
2005-01-17 14:44:57 +01:00
return IWineD3DResourceImpl_GetPrivateData ( ( IWineD3DResource * ) iface , refguid , pData , pSizeOfData ) ;
2004-12-07 15:29:12 +01:00
}
HRESULT WINAPI IWineD3DBaseTextureImpl_FreePrivateData ( IWineD3DBaseTexture * iface , REFGUID refguid ) {
2005-01-17 14:44:57 +01:00
return IWineD3DResourceImpl_FreePrivateData ( ( IWineD3DResource * ) iface , refguid ) ;
2004-12-07 15:29:12 +01:00
}
DWORD WINAPI IWineD3DBaseTextureImpl_SetPriority ( IWineD3DBaseTexture * iface , DWORD PriorityNew ) {
2005-01-17 14:44:57 +01:00
return IWineD3DResourceImpl_SetPriority ( ( IWineD3DResource * ) iface , PriorityNew ) ;
2004-12-07 15:29:12 +01:00
}
DWORD WINAPI IWineD3DBaseTextureImpl_GetPriority ( IWineD3DBaseTexture * iface ) {
2005-01-17 14:44:57 +01:00
return IWineD3DResourceImpl_GetPriority ( ( IWineD3DResource * ) iface ) ;
2004-12-07 15:29:12 +01:00
}
void WINAPI IWineD3DBaseTextureImpl_PreLoad ( IWineD3DBaseTexture * iface ) {
2005-01-17 14:44:57 +01:00
return IWineD3DResourceImpl_PreLoad ( ( IWineD3DResource * ) iface ) ;
2004-12-07 15:29:12 +01:00
}
2006-03-09 23:21:16 +01:00
WINED3DRESOURCETYPE WINAPI IWineD3DBaseTextureImpl_GetType ( IWineD3DBaseTexture * iface ) {
2005-01-17 14:44:57 +01:00
return IWineD3DResourceImpl_GetType ( ( IWineD3DResource * ) iface ) ;
2004-12-07 15:29:12 +01:00
}
HRESULT WINAPI IWineD3DBaseTextureImpl_GetParent ( IWineD3DBaseTexture * iface , IUnknown * * pParent ) {
2005-01-17 14:44:57 +01:00
return IWineD3DResourceImpl_GetParent ( ( IWineD3DResource * ) iface , pParent ) ;
2004-12-07 15:29:12 +01:00
}
/* ******************************************************
IWineD3DBaseTexture IWineD3DBaseTexture parts follow
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-03-14 11:12:52 +01:00
/* There is no OpenGL equivilent of setLOD, getLOD, all they do it priortise testure loading
* so just pretend that they work unless something really needs a failure . */
2004-12-07 15:29:12 +01:00
DWORD WINAPI IWineD3DBaseTextureImpl_SetLOD ( IWineD3DBaseTexture * iface , DWORD LODNew ) {
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
}
DWORD WINAPI IWineD3DBaseTextureImpl_GetLOD ( IWineD3DBaseTexture * iface ) {
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
}
DWORD WINAPI IWineD3DBaseTextureImpl_GetLevelCount ( IWineD3DBaseTexture * iface ) {
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 ;
}
2006-04-06 19:02:16 +02:00
HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType ( IWineD3DBaseTexture * iface , WINED3DTEXTUREFILTERTYPE FilterType ) {
2004-12-07 15:29:12 +01:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2005-03-14 11:12:52 +01:00
2006-03-06 23:08:42 +01:00
if ( ! ( This - > baseTexture . 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
}
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
}
2006-04-06 19:02:16 +02:00
WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DBaseTextureImpl_GetAutoGenFilterType ( IWineD3DBaseTexture * iface ) {
2004-12-07 15:29:12 +01:00
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
FIXME ( " (%p) : stub \n " , This ) ;
2006-03-06 23:08:42 +01:00
if ( ! ( This - > baseTexture . 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
}
void WINAPI IWineD3DBaseTextureImpl_GenerateMipSubLevels ( IWineD3DBaseTexture * iface ) {
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 ;
}
2005-01-09 18:37:02 +01:00
/* Internal function, No d3d mapping */
BOOL WINAPI IWineD3DBaseTextureImpl_SetDirty ( IWineD3DBaseTexture * iface , BOOL dirty ) {
BOOL old ;
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
old = This - > baseTexture . dirty ;
This - > baseTexture . dirty = dirty ;
return old ;
}
2005-01-17 14:44:57 +01:00
BOOL WINAPI IWineD3DBaseTextureImpl_GetDirty ( IWineD3DBaseTexture * iface ) {
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
return This - > baseTexture . dirty ;
}
2005-03-14 11:12:52 +01:00
HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture ( IWineD3DBaseTexture * iface ) {
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 ;
2005-03-29 21:01:00 +02:00
TRACE ( " (%p) : About to bind texture \n " , This ) ;
2005-06-23 18:44:19 +02:00
textureDimensions = IWineD3DBaseTexture_GetTextureDimensions ( iface ) ;
2005-03-29 21:01:00 +02:00
ENTER_GL ( ) ;
#if 0 /* TODO: context manager support */
IWineD3DContextManager_PushState ( This - > contextManager , textureDimensions , ENABLED , NOW /* make sure the state is applied now */ ) ;
2005-06-23 18:44:19 +02:00
# else
2005-03-29 21:01:00 +02:00
glEnable ( textureDimensions ) ;
# endif
/* Generate a texture name if we don't already have one */
if ( This - > baseTexture . textureName = = 0 ) {
glGenTextures ( 1 , & This - > baseTexture . textureName ) ;
checkGLcall ( " glGenTextures " ) ;
TRACE ( " Generated texture %d \n " , This - > baseTexture . textureName ) ;
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 ;
glPrioritizeTextures ( 1 , & This - > baseTexture . textureName , & 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 */
This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSU ] = D3DTADDRESS_WRAP ;
This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSV ] = D3DTADDRESS_WRAP ;
This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSW ] = D3DTADDRESS_WRAP ;
This - > baseTexture . states [ WINED3DTEXSTA_BORDERCOLOR ] = 0 ;
2006-04-06 19:02:16 +02:00
This - > baseTexture . states [ WINED3DTEXSTA_MAGFILTER ] = WINED3DTEXF_LINEAR ;
This - > baseTexture . states [ WINED3DTEXSTA_MINFILTER ] = WINED3DTEXF_POINT ; /* GL_NEAREST_MIPMAP_LINEAR */
This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] = WINED3DTEXF_LINEAR ; /* GL_NEAREST_MIPMAP_LINEAR */
2005-08-03 13:00:28 +02:00
This - > baseTexture . states [ WINED3DTEXSTA_MAXMIPLEVEL ] = 0 ;
This - > baseTexture . states [ WINED3DTEXSTA_MAXANISOTROPY ] = 0 ;
This - > baseTexture . states [ WINED3DTEXSTA_SRGBTEXTURE ] = 0 ;
This - > baseTexture . states [ WINED3DTEXSTA_ELEMENTINDEX ] = 0 ;
This - > baseTexture . states [ WINED3DTEXSTA_DMAPOFFSET ] = 0 ;
This - > baseTexture . states [ WINED3DTEXSTA_TSSADDRESSW ] = D3DTADDRESS_WRAP ;
2005-06-23 18:44:19 +02:00
IWineD3DBaseTexture_SetDirty ( iface , TRUE ) ;
2005-07-18 11:07:17 +02:00
isNewTexture = TRUE ;
2005-03-29 21:01:00 +02:00
}
/* Bind the texture */
if ( This - > baseTexture . textureName ! = 0 ) {
glBindTexture ( textureDimensions , This - > baseTexture . textureName ) ;
checkGLcall ( " glBindTexture " ) ;
2005-08-03 21:49:05 +02:00
if ( isNewTexture ) {
2005-07-18 11:07:17 +02:00
/* For a new texture we have to set the textures levels after binding the texture,
* in theory this is all we should ever have to dom , but because ATI ' s drivers are broken we
* also need to set the texture dimensins before the texture is is set */
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) " ) ;
2005-08-22 12:07:10 +02:00
}
2005-08-03 13:00:28 +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
2005-03-14 11:12:52 +01:00
HRESULT WINAPI IWineD3DBaseTextureImpl_UnBindTexture ( IWineD3DBaseTexture * iface ) {
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
2005-03-29 21:01:00 +02:00
UINT textureDimensions ;
TRACE ( " (%p) : About to bind texture \n " , This ) ;
2005-06-23 18:44:19 +02:00
textureDimensions = IWineD3DBaseTexture_GetTextureDimensions ( iface ) ;
2005-03-29 21:01:00 +02:00
ENTER_GL ( ) ;
2005-06-23 18:44:19 +02:00
2005-03-29 21:01:00 +02:00
glBindTexture ( textureDimensions , 0 ) ;
#if 0 /* TODO: context manager support */
2005-06-23 18:44:19 +02:00
IWineD3DContextManager_PopState ( This - > contextManager , textureDimensions , ENABLED , NOW /* make sure the state is applied now */ ) ;
# else
2005-03-29 21:01:00 +02:00
glDisable ( textureDimensions ) ;
# endif
2005-06-23 18:44:19 +02:00
2005-03-29 21:01:00 +02:00
LEAVE_GL ( ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-14 11:12:52 +01:00
}
UINT WINAPI IWineD3DBaseTextureImpl_GetTextureDimensions ( IWineD3DBaseTexture * iface ) {
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
FIXME ( " (%p) : This shouldn't be called \n " , This ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2005-03-14 11:12:52 +01:00
}
2005-08-03 13:00:28 +02:00
static inline GLenum warpLookupType ( WINED3DSAMPLERSTATETYPE Type ) {
switch ( Type ) {
case WINED3DSAMP_ADDRESSU :
return GL_TEXTURE_WRAP_S ;
case WINED3DSAMP_ADDRESSV :
return GL_TEXTURE_WRAP_T ;
case WINED3DSAMP_ADDRESSW :
return GL_TEXTURE_WRAP_R ;
default :
FIXME ( " Unexpected warp type %d \n " , Type ) ;
return 0 ;
}
}
void WINAPI IWineD3DBaseTextureImpl_ApplyStateChanges ( IWineD3DBaseTexture * iface ,
const DWORD textureStates [ WINED3D_HIGHEST_TEXTURE_STATE + 1 ] ,
const DWORD samplerStates [ WINED3D_HIGHEST_SAMPLER_STATE + 1 ] ) {
IWineD3DBaseTextureImpl * This = ( IWineD3DBaseTextureImpl * ) iface ;
int i ;
DWORD * state = This - > baseTexture . states ;
GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions ( iface ) ;
IWineD3DBaseTexture_PreLoad ( iface ) ;
/* run through a couple of loops and apply and states that are different */
/* this will reduce the number of texture state changes to an absolute minimum
for multi - parameter states we pickup the first one that changes , work out the correct values for the other states
and set all the states that we ' ve just applied to their new values */
for ( i = 0 ; textureObjectSamplerStates [ i ] . state ! = - 1 ; i + + ) {
if ( * state ! = samplerStates [ textureObjectSamplerStates [ i ] . state ] ) {
/* apply the state */
2005-11-10 13:14:56 +01:00
TRACE ( " (%p) : Changing state %u from %ld to %ld \n " , This , i , * state , samplerStates [ textureObjectSamplerStates [ i ] . state ] ) ;
2005-08-03 13:00:28 +02:00
switch ( textureObjectSamplerStates [ i ] . function ) {
case WINED3DSAMP_ADDRESSU :
case WINED3DSAMP_ADDRESSV : /* fall through */
case WINED3DSAMP_ADDRESSW : /* fall through */
* state = samplerStates [ textureObjectSamplerStates [ i ] . state ] ;
if ( * state < minLookup [ WINELOOKUP_WARPPARAM ] | | * state > maxLookup [ WINELOOKUP_WARPPARAM ] ) {
FIXME ( " Unrecognized or unsupported D3DTADDRESS_* value %ld, state %d \n " , * state , textureObjectSamplerStates [ i ] . function ) ;
} else {
GLint wrapParm = stateLookup [ WINELOOKUP_WARPPARAM ] [ * state - minLookup [ WINELOOKUP_WARPPARAM ] ] ;
TRACE ( " Setting WRAP_R to %d for %x \n " , wrapParm , textureDimensions ) ;
glTexParameteri ( textureDimensions , warpLookupType ( textureObjectSamplerStates [ i ] . function ) , wrapParm ) ;
checkGLcall ( " glTexParameteri(..., GL_TEXTURE_WRAP_R, wrapParm) " ) ;
}
break ;
case WINED3DSAMP_BORDERCOLOR :
{
float col [ 4 ] ;
* state = samplerStates [ textureObjectSamplerStates [ i ] . state ] ;
D3DCOLORTOGLFLOAT4 ( * state , col ) ;
TRACE ( " Setting border color for %u to %lx \n " , textureDimensions , * state ) ;
glTexParameterfv ( textureDimensions , GL_TEXTURE_BORDER_COLOR , & col [ 0 ] ) ;
checkGLcall ( " glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...) " ) ;
}
break ;
case WINED3DSAMP_MAGFILTER :
{
GLint glValue ;
* state = samplerStates [ textureObjectSamplerStates [ i ] . state ] ;
if ( * state < minLookup [ WINELOOKUP_MAGFILTER ] | | * state > maxLookup [ WINELOOKUP_MAGFILTER ] ) {
FIXME ( " Unrecognized or unsupported MAGFILTER* value %ld, state %d \n " , * state , textureObjectSamplerStates [ i ] . function ) ;
}
glValue = stateLookup [ WINELOOKUP_MAGFILTER ] [ * state - minLookup [ WINELOOKUP_MAGFILTER ] ] ;
TRACE ( " ValueMAG=%ld setting MAGFILTER to %x \n " , * state , glValue ) ;
glTexParameteri ( textureDimensions , GL_TEXTURE_MAG_FILTER , glValue ) ;
2006-04-06 19:02:16 +02:00
/* We need to reset the Aniotropic filtering state when we change the mag filter to WINED3DTEXF_ANISOTROPIC (this seems a bit weird, check the documentataion to see how it should be switched off. */
if ( GL_SUPPORT ( EXT_TEXTURE_FILTER_ANISOTROPIC ) & & WINED3DTEXF_ANISOTROPIC = = * state ) {
2005-08-03 13:00:28 +02:00
glTexParameteri ( textureDimensions , GL_TEXTURE_MAX_ANISOTROPY_EXT , samplerStates [ WINED3DSAMP_MAXANISOTROPY ] ) ;
}
}
break ;
case WINED3DSAMP_MINFILTER :
This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] = samplerStates [ WINED3DSAMP_MIPFILTER ] ;
case WINED3DSAMP_MIPFILTER : /* fall through */
{
GLint glValue ;
* state = samplerStates [ textureObjectSamplerStates [ i ] . state ] ;
2006-04-06 19:02:16 +02:00
if ( This - > baseTexture . states [ WINED3DTEXSTA_MINFILTER ] < WINED3DTEXF_NONE | |
This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] < WINED3DTEXF_NONE | |
This - > baseTexture . states [ WINED3DTEXSTA_MINFILTER ] > WINED3DTEXF_ANISOTROPIC | |
This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] > WINED3DTEXF_LINEAR )
2005-08-03 13:00:28 +02:00
{
FIXME ( " Unrecognized or unsupported D3DSAMP_MINFILTER value %ld, state %d D3DSAMP_MIPFILTER value %ld, state %d \n " ,
This - > baseTexture . states [ WINED3DTEXSTA_MINFILTER ] ,
textureObjectSamplerStates [ WINED3DTEXSTA_MINFILTER ] . function ,
This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] ,
textureObjectSamplerStates [ WINED3DTEXSTA_MIPFILTER ] . function ) ;
}
2006-04-06 19:02:16 +02:00
glValue = minMipLookup [ min ( max ( This - > baseTexture . states [ WINED3DTEXSTA_MINFILTER ] , WINED3DTEXF_NONE ) , WINED3DTEXF_ANISOTROPIC ) ]
[ min ( max ( This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] , WINED3DTEXF_NONE ) , WINED3DTEXF_LINEAR ) ] ;
2005-08-03 13:00:28 +02:00
TRACE ( " ValueMIN=%ld, ValueMIP=%ld, setting MINFILTER to %x \n " ,
This - > baseTexture . states [ WINED3DTEXSTA_MINFILTER ] ,
This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] , glValue ) ;
glTexParameteri ( textureDimensions , GL_TEXTURE_MIN_FILTER , glValue ) ;
checkGLcall ( " glTexParameter GL_TEXTURE_MIN_FILTER, ... " ) ;
}
break ;
case WINED3DSAMP_MAXMIPLEVEL :
* state = samplerStates [ textureObjectSamplerStates [ i ] . state ] ;
/**
* Not really the same , but the more apprioprate than nothing
*/
glTexParameteri ( textureDimensions , GL_TEXTURE_BASE_LEVEL , * state ) ;
break ;
case WINED3DSAMP_MAXANISOTROPY :
* state = samplerStates [ textureObjectSamplerStates [ i ] . state ] ;
2006-08-04 18:14:41 +02:00
if ( GL_SUPPORT ( EXT_TEXTURE_FILTER_ANISOTROPIC ) ) {
glTexParameteri ( textureDimensions , GL_TEXTURE_MAX_ANISOTROPY_EXT , * state ) ;
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
break ;
case WINED3DFUNC_UNIMPLEMENTED : /* unimplemented */
TRACE ( " (%p) : stub \n " , This ) ;
* state = samplerStates [ textureObjectSamplerStates [ i ] . state ] ;
break ;
case WINED3DFUNC_NOTSUPPORTED : /* nop */
TRACE ( " (%p) : %s function is not supported by this opengl implementation \n " , This , " unknown " /* TODO: replace with debug_blah... */ ) ;
* state = samplerStates [ textureObjectSamplerStates [ i ] . state ] ;
break ;
}
}
state + + ;
}
for ( i = 0 ; textureObjectTextureStates [ i ] . state ! = - 1 ; i + + ) {
if ( * state ! = textureStates [ textureObjectTextureStates [ i ] . state ] ) {
/* apply the state */
* state = textureStates [ textureObjectTextureStates [ i ] . state ] ;
switch ( textureObjectTextureStates [ i ] . function ) {
case WINED3DTSS_ADDRESSW :
/* I'm not sure what to do if this is set as well as ADDRESSW on the sampler, how do they interact together? */
break ;
case WINED3DFUNC_UNIMPLEMENTED : /* unimplemented */
TRACE ( " (%p) : stub \n " , This ) ;
break ;
case WINED3DFUNC_NOTSUPPORTED : /* nop */
TRACE ( " (%p) : function no supported by this opengl implementation \n " , This ) ;
break ;
}
}
state + + ;
}
}
2005-06-06 21:50:35 +02:00
static const IWineD3DBaseTextureVtbl IWineD3DBaseTexture_Vtbl =
2004-12-07 15:29:12 +01:00
{
2005-07-13 16:15:54 +02:00
/* IUnknown */
2004-12-07 15:29:12 +01:00
IWineD3DBaseTextureImpl_QueryInterface ,
IWineD3DBaseTextureImpl_AddRef ,
IWineD3DBaseTextureImpl_Release ,
2005-03-14 11:12:52 +01:00
/* IWineD3DResource */
2004-12-07 15:29:12 +01:00
IWineD3DBaseTextureImpl_GetParent ,
IWineD3DBaseTextureImpl_GetDevice ,
IWineD3DBaseTextureImpl_SetPrivateData ,
IWineD3DBaseTextureImpl_GetPrivateData ,
IWineD3DBaseTextureImpl_FreePrivateData ,
IWineD3DBaseTextureImpl_SetPriority ,
IWineD3DBaseTextureImpl_GetPriority ,
IWineD3DBaseTextureImpl_PreLoad ,
IWineD3DBaseTextureImpl_GetType ,
2005-03-14 11:12:52 +01:00
/*IWineD3DBaseTexture*/
2004-12-07 15:29:12 +01:00
IWineD3DBaseTextureImpl_SetLOD ,
IWineD3DBaseTextureImpl_GetLOD ,
IWineD3DBaseTextureImpl_GetLevelCount ,
IWineD3DBaseTextureImpl_SetAutoGenFilterType ,
IWineD3DBaseTextureImpl_GetAutoGenFilterType ,
2005-01-09 18:37:02 +01:00
IWineD3DBaseTextureImpl_GenerateMipSubLevels ,
2005-01-17 14:44:57 +01:00
IWineD3DBaseTextureImpl_SetDirty ,
2005-03-14 11:12:52 +01:00
IWineD3DBaseTextureImpl_GetDirty ,
/* internal */
IWineD3DBaseTextureImpl_BindTexture ,
IWineD3DBaseTextureImpl_UnBindTexture ,
2005-08-03 13:00:28 +02:00
IWineD3DBaseTextureImpl_GetTextureDimensions ,
IWineD3DBaseTextureImpl_ApplyStateChanges
2005-03-14 11:12:52 +01:00
2004-12-07 15:29:12 +01:00
} ;