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-03-29 02:36:13 +01:00
* Copyright 2007 - 2008 Stefan D <EFBFBD> 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
/* *******************************************
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
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : AddRef increasing from %d \n " , This , ref - 1 ) ;
2005-01-19 17:59:01 +01:00
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 ) ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : Releasing from %d \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 ;
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 ) ;
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 ) {
2007-06-06 23:40:30 +02:00
IWineD3DResourceImpl_PreLoad ( ( IWineD3DResource * ) iface ) ;
2004-12-07 15:29:12 +01:00
}
2008-01-12 22:56:30 +01:00
void WINAPI IWineD3DBaseTextureImpl_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 ) ;
This - > baseTexture . textureName = 0 ;
LEAVE_GL ( ) ;
}
2008-01-25 18:18:55 +01:00
This - > baseTexture . dirty = TRUE ;
2008-01-12 22:56:30 +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
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 . */
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 ;
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) " ) ;
case WINED3DTEXF_LINEAR :
glTexParameteri ( textureDimensions , GL_GENERATE_MIPMAP_HINT_SGIS , GL_NICEST ) ;
checkGLcall ( " glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST) " ) ;
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
}
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 ) ;
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
}
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 ( ) ;
/* 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 */
2006-10-24 12:03:18 +02:00
This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSU ] = WINED3DTADDRESS_WRAP ;
This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSV ] = WINED3DTADDRESS_WRAP ;
This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSW ] = WINED3DTADDRESS_WRAP ;
2005-08-03 13:00:28 +02:00
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 ;
2006-10-24 12:03:18 +02:00
This - > baseTexture . 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
*/
glBindTexture ( textureDimensions , This - > baseTexture . textureName ) ;
checkGLcall ( " glBindTexture " ) ;
glTexParameteri ( textureDimensions , GL_GENERATE_MIPMAP_SGIS , GL_TRUE ) ;
checkGLcall ( " glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_SGIS, GL_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 ) {
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
* Beware that texture rectangles do not support mipmapping .
*/
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-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 ;
}
}
2007-08-12 13:37:17 +02:00
static inline void apply_wrap ( const GLint textureDimensions , const DWORD state , const GLint type ) {
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-02-01 01:16:45 +01:00
} else if ( textureDimensions = = GL_TEXTURE_RECTANGLE_ARB ) {
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) " ) ;
}
}
2005-08-03 13:00:28 +02:00
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 ;
2007-08-12 13:37:17 +02:00
DWORD state ;
2005-08-03 13:00:28 +02:00
GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions ( iface ) ;
2007-08-12 13:37:17 +02:00
2005-08-03 13:00:28 +02:00
IWineD3DBaseTexture_PreLoad ( iface ) ;
2007-08-12 13:37:17 +02:00
if ( samplerStates [ WINED3DSAMP_ADDRESSU ] ! = This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSU ] ) {
state = samplerStates [ WINED3DSAMP_ADDRESSU ] ;
apply_wrap ( textureDimensions , state , GL_TEXTURE_WRAP_S ) ;
This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSU ] = state ;
}
if ( samplerStates [ WINED3DSAMP_ADDRESSV ] ! = This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSV ] ) {
state = samplerStates [ WINED3DSAMP_ADDRESSV ] ;
apply_wrap ( textureDimensions , state , GL_TEXTURE_WRAP_T ) ;
This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSV ] = state ;
}
if ( samplerStates [ WINED3DSAMP_ADDRESSW ] ! = This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSW ] ) {
state = samplerStates [ WINED3DSAMP_ADDRESSW ] ;
apply_wrap ( textureDimensions , state , GL_TEXTURE_WRAP_R ) ;
This - > baseTexture . states [ WINED3DTEXSTA_ADDRESSW ] = state ;
}
if ( samplerStates [ WINED3DSAMP_BORDERCOLOR ] ! = This - > baseTexture . states [ WINED3DTEXSTA_BORDERCOLOR ] ) {
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, ...) " ) ;
This - > baseTexture . states [ WINED3DTEXSTA_BORDERCOLOR ] = state ;
}
if ( samplerStates [ WINED3DSAMP_MAGFILTER ] ! = This - > baseTexture . states [ WINED3DTEXSTA_MAGFILTER ] ) {
GLint glValue ;
state = samplerStates [ WINED3DSAMP_MAGFILTER ] ;
if ( state < minLookup [ WINELOOKUP_MAGFILTER ] | | state > maxLookup [ WINELOOKUP_MAGFILTER ] ) {
FIXME ( " Unrecognized or unsupported MAGFILTER* value %d \n " , state ) ;
}
glValue = stateLookup [ WINELOOKUP_MAGFILTER ] [ state - minLookup [ WINELOOKUP_MAGFILTER ] ] ;
TRACE ( " ValueMAG=%d setting MAGFILTER to %x \n " , state , glValue ) ;
glTexParameteri ( textureDimensions , GL_TEXTURE_MAG_FILTER , glValue ) ;
2008-01-23 15:16:30 +01:00
/* 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. */
2007-11-27 22:25:07 +01:00
if ( GL_SUPPORT ( EXT_TEXTURE_FILTER_ANISOTROPIC ) & & WINED3DTEXF_ANISOTROPIC = = state & &
textureDimensions ! = GL_TEXTURE_RECTANGLE_ARB ) {
2007-08-12 13:37:17 +02:00
glTexParameteri ( textureDimensions , GL_TEXTURE_MAX_ANISOTROPY_EXT , samplerStates [ WINED3DSAMP_MAXANISOTROPY ] ) ;
}
This - > baseTexture . states [ WINED3DTEXSTA_MAGFILTER ] = state ;
}
2007-11-27 22:25:07 +01:00
if ( textureDimensions ! = GL_TEXTURE_RECTANGLE_ARB & &
( samplerStates [ WINED3DSAMP_MINFILTER ] ! = This - > baseTexture . states [ WINED3DTEXSTA_MINFILTER ] | |
samplerStates [ WINED3DSAMP_MIPFILTER ] ! = This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] | |
samplerStates [ WINED3DSAMP_MAXMIPLEVEL ] ! = This - > baseTexture . states [ WINED3DTEXSTA_MAXMIPLEVEL ] ) ) {
2007-08-12 13:37:17 +02:00
GLint glValue ;
This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] = samplerStates [ WINED3DSAMP_MIPFILTER ] ;
This - > baseTexture . states [ WINED3DTEXSTA_MINFILTER ] = samplerStates [ WINED3DSAMP_MINFILTER ] ;
This - > baseTexture . states [ WINED3DTEXSTA_MAXMIPLEVEL ] = samplerStates [ WINED3DSAMP_MAXMIPLEVEL ] ;
2007-12-29 09:32:43 +01:00
if ( This - > baseTexture . states [ WINED3DTEXSTA_MINFILTER ] > WINED3DTEXF_ANISOTROPIC | |
2007-08-12 13:37:17 +02:00
This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] > WINED3DTEXF_LINEAR )
{
FIXME ( " Unrecognized or unsupported D3DSAMP_MINFILTER value %d D3DSAMP_MIPFILTER value %d \n " ,
This - > baseTexture . states [ WINED3DTEXSTA_MINFILTER ] ,
This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] ) ;
}
glValue = minMipLookup [ min ( max ( samplerStates [ WINED3DSAMP_MINFILTER ] , WINED3DTEXF_NONE ) , WINED3DTEXF_ANISOTROPIC ) ]
[ min ( max ( samplerStates [ WINED3DSAMP_MIPFILTER ] , WINED3DTEXF_NONE ) , WINED3DTEXF_LINEAR ) ] ;
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, ... " ) ;
if ( This - > baseTexture . states [ WINED3DTEXSTA_MIPFILTER ] = = WINED3DTEXF_NONE ) {
glValue = 0 ;
} else if ( This - > baseTexture . states [ WINED3DTEXSTA_MAXMIPLEVEL ] > = This - > baseTexture . levels ) {
glValue = This - > baseTexture . levels - 1 ;
} else {
glValue = This - > baseTexture . states [ WINED3DTEXSTA_MAXMIPLEVEL ] ;
}
glTexParameteri ( textureDimensions , GL_TEXTURE_BASE_LEVEL , glValue ) ;
}
if ( samplerStates [ WINED3DSAMP_MAXANISOTROPY ] ! = This - > baseTexture . states [ WINED3DTEXSTA_MAXANISOTROPY ] ) {
2007-11-27 22:25:07 +01:00
if ( GL_SUPPORT ( EXT_TEXTURE_FILTER_ANISOTROPIC ) & & textureDimensions ! = GL_TEXTURE_RECTANGLE_ARB ) {
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
}
2007-08-12 13:37:17 +02:00
This - > baseTexture . states [ WINED3DTEXSTA_MAXANISOTROPY ] = samplerStates [ WINED3DSAMP_MAXANISOTROPY ] ;
2005-08-03 13:00:28 +02:00
}
}
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 ,
2008-01-12 22:56:30 +01:00
IWineD3DBaseTextureImpl_UnLoad ,
2004-12-07 15:29:12 +01:00
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
} ;