| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program 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 General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WW3D *
- * *
- * $Archive:: /Commando/Code/ww3d2/texture.cpp $*
- * *
- * $Author:: Steve_t $*
- * *
- * $Modtime:: 1/09/02 2:57p $*
- * *
- * $Revision:: 83 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * FileListTextureClass::Load_Frame_Surface -- Load source texture *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "texture.h"
- #include <d3d8.h>
- #include <stdio.h>
- #include <D3dx8core.h>
- #include "dx8wrapper.h"
- #include "targa.h"
- #include <nstrdup.h>
- #include "w3d_file.h"
- #include "assetmgr.h"
- #include "formconv.h"
- #include "textureloader.h"
- #include "missingtexture.h"
- #include "ffactory.h"
- #include "dx8caps.h"
- #include "dx8texman.h"
- #include "meshmatdesc.h"
- #include "texturethumbnail.h"
- const unsigned DEFAULT_INACTIVATION_TIME=20000;
- /*
- ** Definitions of static members:
- */
- static unsigned unused_texture_id;
- unsigned _MinTextureFilters[MAX_TEXTURE_STAGES][TextureClass::FILTER_TYPE_COUNT];
- unsigned _MagTextureFilters[MAX_TEXTURE_STAGES][TextureClass::FILTER_TYPE_COUNT];
- unsigned _MipMapFilters[MAX_TEXTURE_STAGES][TextureClass::FILTER_TYPE_COUNT];
- // ----------------------------------------------------------------------------
- static int Calculate_Texture_Memory_Usage(const TextureClass* texture,int red_factor=0)
- {
- // Set performance statistics
- int size=0;
- IDirect3DTexture8* d3d_texture=const_cast<TextureClass*>(texture)->Peek_DX8_Texture();
- if (!d3d_texture) return 0;
- for (unsigned i=red_factor;i<d3d_texture->GetLevelCount();++i) {
- D3DSURFACE_DESC desc;
- DX8_ErrorCode(d3d_texture->GetLevelDesc(i,&desc));
- size+=desc.Size;
- }
- return size;
- }
- /*************************************************************************
- ** TextureClass
- *************************************************************************/
- TextureClass::TextureClass(unsigned width, unsigned height, WW3DFormat format, MipCountType mip_level_count, PoolType pool,bool rendertarget)
- :
- D3DTexture(NULL),
- texture_id(unused_texture_id++),
- Initialized(true),
- TextureMinFilter(FILTER_TYPE_DEFAULT),
- TextureMagFilter(FILTER_TYPE_DEFAULT),
- MipMapFilter((mip_level_count!=MIP_LEVELS_1) ? FILTER_TYPE_DEFAULT : FILTER_TYPE_NONE),
- UAddressMode(TEXTURE_ADDRESS_REPEAT),
- VAddressMode(TEXTURE_ADDRESS_REPEAT),
- MipLevelCount(mip_level_count),
- Pool(pool),
- Dirty(false),
- IsLightmap(false),
- IsProcedural(true),
- Name(""),
- TextureFormat(format),
- IsCompressionAllowed(false),
- TextureLoadTask(NULL),
- ThumbnailLoadTask(NULL),
- Width(width),
- Height(height),
- InactivationTime(0), // Don't inactivate!
- ExtendedInactivationTime(0),
- LastInactivationSyncTime(0)
- {
- switch (format) {
- case WW3D_FORMAT_DXT1:
- case WW3D_FORMAT_DXT2:
- case WW3D_FORMAT_DXT3:
- case WW3D_FORMAT_DXT4:
- case WW3D_FORMAT_DXT5:
- IsCompressionAllowed=true;
- break;
- default:
- break;
- }
- D3DPOOL d3dpool=(D3DPOOL) 0;
- switch(pool)
- {
- case POOL_DEFAULT:
- d3dpool=D3DPOOL_DEFAULT;
- break;
- case POOL_MANAGED:
- d3dpool=D3DPOOL_MANAGED;
- break;
- case POOL_SYSTEMMEM:
- d3dpool=D3DPOOL_SYSTEMMEM;
- break;
- default:
- WWASSERT(0);
- }
- D3DTexture = DX8Wrapper::_Create_DX8_Texture(width, height, format, mip_level_count,d3dpool,rendertarget);
- if (pool==POOL_DEFAULT)
- {
- Dirty=true;
- DX8TextureTrackerClass *track=new
- DX8TextureTrackerClass(width, height, format, mip_level_count,rendertarget,
- this);
- DX8TextureManagerClass::Add(track);
- }
- LastAccessed=WW3D::Get_Sync_Time();
- }
- // ----------------------------------------------------------------------------
- TextureClass::TextureClass(
- const char *name,
- const char *full_path,
- MipCountType mip_level_count,
- WW3DFormat texture_format,
- bool allow_compression)
- :
- D3DTexture(NULL),
- texture_id(unused_texture_id++),
- Initialized(false),
- TextureMinFilter(FILTER_TYPE_DEFAULT),
- TextureMagFilter(FILTER_TYPE_DEFAULT),
- MipMapFilter((mip_level_count!=MIP_LEVELS_1) ? FILTER_TYPE_DEFAULT : FILTER_TYPE_NONE),
- UAddressMode(TEXTURE_ADDRESS_REPEAT),
- VAddressMode(TEXTURE_ADDRESS_REPEAT),
- MipLevelCount(mip_level_count),
- Pool(POOL_MANAGED),
- Dirty(false),
- IsLightmap(false),
- IsProcedural(false),
- TextureFormat(texture_format),
- IsCompressionAllowed(allow_compression),
- TextureLoadTask(NULL),
- ThumbnailLoadTask(NULL),
- Width(0),
- Height(0),
- InactivationTime(DEFAULT_INACTIVATION_TIME), // Default inactivation time 30 seconds
- ExtendedInactivationTime(0),
- LastInactivationSyncTime(0)
- {
- switch (TextureFormat) {
- case WW3D_FORMAT_DXT1:
- case WW3D_FORMAT_DXT2:
- case WW3D_FORMAT_DXT3:
- case WW3D_FORMAT_DXT4:
- case WW3D_FORMAT_DXT5:
- IsCompressionAllowed=true;
- break;
- case WW3D_FORMAT_U8V8: // Bumpmap
- case WW3D_FORMAT_L6V5U5: // Bumpmap
- case WW3D_FORMAT_X8L8V8U8: // Bumpmap
- // If requesting bumpmap format that isn't available we'll just return the surface in whatever color
- // format the texture file is in. (This is illegal case, the format support should always be queried
- // before creating a bump texture!)
- if (!DX8Wrapper::Is_Initted() || !DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(TextureFormat)) {
- TextureFormat=WW3D_FORMAT_UNKNOWN;
- }
- // If bump format is valid, make sure compression is not allowed so that we don't even attempt to load
- // from a compressed file (quality isn't good enough for bump map). Also disable mipmapping.
- else {
- IsCompressionAllowed=false;
- MipLevelCount=MIP_LEVELS_1;
- MipMapFilter=FILTER_TYPE_NONE;
- }
- break;
- default:
- break;
- }
- WWASSERT_PRINT(name && name[0], "TextureClass CTor: NULL or empty texture name\n");
- int len=strlen(name);
- for (int i=0;i<len;++i) {
- if (name[i]=='+') {
- IsLightmap=true;
- // Set bilinear filtering for lightmaps (they are very stretched and
- // low detail so we don't care for anisotropic or trilinear filtering...)
- TextureMinFilter=FILTER_TYPE_FAST;
- TextureMagFilter=FILTER_TYPE_FAST;
- if (mip_level_count!=MIP_LEVELS_1) MipMapFilter=FILTER_TYPE_FAST;
- break;
- }
- }
- Set_Texture_Name(name);
- Set_Full_Path(full_path);
- WWASSERT(name[0]!='\0');
- if (!WW3D::Is_Texturing_Enabled()) {
- Initialized=true;
- D3DTexture=0;
- }
- // Find original size from the thumbnail (but don't create thumbnail texture yet!)
- ThumbnailClass* thumb=NULL;
- ThumbnailManagerClass* thumb_man=ThumbnailManagerClass::Peek_List().Head();
- while (thumb_man) {
- thumb=thumb_man->Peek_Thumbnail_Instance(Get_Full_Path());
- if (thumb) {
- Width=thumb->Get_Original_Texture_Width();
- Height=thumb->Get_Original_Texture_Height();
- break;
- }
- thumb_man=thumb_man->Succ();
- }
- LastAccessed=WW3D::Get_Sync_Time();
- // If the thumbnails are not enabled, init the texture at this point to avoid stalling when the
- // mesh is rendered.
- if (!WW3D::Get_Thumbnail_Enabled()) {
- if (TextureLoader::Is_DX8_Thread()) {
- Init();
- }
- }
- }
- // ----------------------------------------------------------------------------
- TextureClass::TextureClass(SurfaceClass *surface, MipCountType mip_level_count)
- :
- D3DTexture(NULL),
- texture_id(unused_texture_id++),
- Initialized(true),
- TextureMinFilter(FILTER_TYPE_DEFAULT),
- TextureMagFilter(FILTER_TYPE_DEFAULT),
- MipMapFilter((mip_level_count!=MIP_LEVELS_1) ? FILTER_TYPE_DEFAULT : FILTER_TYPE_NONE),
- UAddressMode(TEXTURE_ADDRESS_REPEAT),
- VAddressMode(TEXTURE_ADDRESS_REPEAT),
- MipLevelCount(mip_level_count),
- Pool(POOL_MANAGED),
- Dirty(false),
- IsLightmap(false),
- Name(""),
- IsProcedural(true),
- TextureFormat(surface->Get_Surface_Format()),
- IsCompressionAllowed(false),
- TextureLoadTask(NULL),
- ThumbnailLoadTask(NULL),
- Width(0),
- Height(0),
- InactivationTime(0), // Don't inactivate
- ExtendedInactivationTime(0),
- LastInactivationSyncTime(0)
- {
- SurfaceClass::SurfaceDescription sd;
- surface->Get_Description(sd);
- Width=sd.Width;
- Height=sd.Height;
- switch (sd.Format) {
- case WW3D_FORMAT_DXT1:
- case WW3D_FORMAT_DXT2:
- case WW3D_FORMAT_DXT3:
- case WW3D_FORMAT_DXT4:
- case WW3D_FORMAT_DXT5:
- IsCompressionAllowed=true;
- break;
- default:
- break;
- }
- D3DTexture = DX8Wrapper::_Create_DX8_Texture(surface->Peek_D3D_Surface(), mip_level_count);
- LastAccessed=WW3D::Get_Sync_Time();
- }
- // ----------------------------------------------------------------------------
- TextureClass::TextureClass(IDirect3DTexture8* d3d_texture)
- :
- D3DTexture(d3d_texture),
- texture_id(unused_texture_id++),
- Initialized(true),
- TextureMinFilter(FILTER_TYPE_DEFAULT),
- TextureMagFilter(FILTER_TYPE_DEFAULT),
- MipMapFilter((d3d_texture->GetLevelCount()!=1) ? FILTER_TYPE_DEFAULT : FILTER_TYPE_NONE),
- UAddressMode(TEXTURE_ADDRESS_REPEAT),
- VAddressMode(TEXTURE_ADDRESS_REPEAT),
- MipLevelCount((MipCountType)d3d_texture->GetLevelCount()),
- Pool(POOL_MANAGED),
- Dirty(false),
- IsLightmap(false),
- Name(""),
- IsProcedural(true),
- IsCompressionAllowed(false),
- TextureLoadTask(NULL),
- ThumbnailLoadTask(NULL),
- Width(0),
- Height(0),
- InactivationTime(0), // Don't inactivate!
- ExtendedInactivationTime(0),
- LastInactivationSyncTime(0)
- {
- D3DTexture->AddRef();
- IDirect3DSurface8* surface;
- DX8_ErrorCode(D3DTexture->GetSurfaceLevel(0,&surface));
- D3DSURFACE_DESC d3d_desc;
- ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC));
- DX8_ErrorCode(surface->GetDesc(&d3d_desc));
- Width=d3d_desc.Width;
- Height=d3d_desc.Height;
- TextureFormat=D3DFormat_To_WW3DFormat(d3d_desc.Format);
- switch (TextureFormat) {
- case WW3D_FORMAT_DXT1:
- case WW3D_FORMAT_DXT2:
- case WW3D_FORMAT_DXT3:
- case WW3D_FORMAT_DXT4:
- case WW3D_FORMAT_DXT5:
- IsCompressionAllowed=true;
- break;
- default:
- break;
- }
- LastAccessed=WW3D::Get_Sync_Time();
- }
- // ----------------------------------------------------------------------------
- TextureClass::~TextureClass(void)
- {
- delete TextureLoadTask;
- TextureLoadTask=NULL;
- delete ThumbnailLoadTask;
- ThumbnailLoadTask=NULL;
- if (D3DTexture) {
- D3DTexture->Release();
- D3DTexture = NULL;
- }
- DX8TextureManagerClass::Remove(this);
- }
- void TextureClass::Invalidate_Old_Unused_Textures(unsigned invalidation_time_override)
- {
- unsigned synctime=WW3D::Get_Sync_Time();
- HashTemplateIterator<StringClass,TextureClass*> ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- TextureClass* tex=ite.Peek_Value();
- // Consider invalidating if texture has been initialized and defines inactivation time
- if (tex->Initialized && tex->InactivationTime) {
- unsigned age=synctime-tex->LastAccessed;
- if (invalidation_time_override) {
- if (age>invalidation_time_override) {
- tex->Invalidate();
- tex->LastInactivationSyncTime=synctime;
- }
- }
- else {
- // Not used in the last n milliseconds?
- if (age>(tex->InactivationTime+tex->ExtendedInactivationTime)) {
- tex->Invalidate();
- tex->LastInactivationSyncTime=synctime;
- }
- }
- }
- }
- }
- // ----------------------------------------------------------------------------
- void TextureClass::Init()
- {
- // If the texture has already been initialised we should exit now
- if (Initialized) return;
- // If the texture has recently been inactivated, increase the inactivation time (this texture obviously
- // should not have been inactivated yet).
- if (InactivationTime && LastInactivationSyncTime) {
- if ((WW3D::Get_Sync_Time()-LastInactivationSyncTime)<InactivationTime) {
- ExtendedInactivationTime=3*InactivationTime;
- }
- LastInactivationSyncTime=0;
- }
- if (!D3DTexture) {
- if (!WW3D::Get_Thumbnail_Enabled() || MipLevelCount==MIP_LEVELS_1) {
- // if (MipLevelCount==MIP_LEVELS_1) {
- TextureLoader::Request_Foreground_Loading(this);
- }
- else {
- WW3DFormat format=TextureFormat;
- Load_Locked_Surface();
- TextureFormat=format;
- }
- }
- if (!Initialized) {
- TextureLoader::Request_Background_Loading(this);
- }
- LastAccessed=WW3D::Get_Sync_Time();
- }
- void TextureClass::Invalidate()
- {
- if (TextureLoadTask) {
- return;
- }
- if (ThumbnailLoadTask) {
- return;
- }
- // Don't invalidate procedural textures
- if (IsProcedural) {
- return;
- }
- if (D3DTexture) {
- D3DTexture->Release();
- D3DTexture = NULL;
- }
- Initialized=false;
- LastAccessed=WW3D::Get_Sync_Time();
- }
- // ----------------------------------------------------------------------------
- void TextureClass::Load_Locked_Surface()
- {
- if (D3DTexture) D3DTexture->Release();
- D3DTexture=0;
- TextureLoader::Request_Thumbnail(this);
- Initialized=false;
- }
- // ----------------------------------------------------------------------------
- bool TextureClass::Is_Missing_Texture()
- {
- bool flag = false;
- IDirect3DTexture8 *missing_texture = MissingTexture::_Get_Missing_Texture();
- if(D3DTexture == missing_texture)
- flag = true;
- if(missing_texture) {
- missing_texture->Release();
- }
- return flag;
- }
- // ----------------------------------------------------------------------------
- void TextureClass::Set_Texture_Name(const char * name)
- {
- Name=name;
- }
- // ----------------------------------------------------------------------------
- unsigned int TextureClass::Get_Mip_Level_Count(void)
- {
- if (!D3DTexture) {
- WWASSERT_PRINT(0, "Get_Mip_Level_Count: D3DTexture is NULL!\n");
- return 0;
- }
- return D3DTexture->GetLevelCount();
- }
- // ----------------------------------------------------------------------------
- SurfaceClass *TextureClass::Get_Surface_Level(unsigned int level)
- {
- if (!D3DTexture) {
- WWASSERT_PRINT(0, "Get_Surface_Level: D3DTexture is NULL!\n");
- return 0;
- }
- IDirect3DSurface8 *d3d_surface = NULL;
- DX8_ErrorCode(D3DTexture->GetSurfaceLevel(level, &d3d_surface));
- SurfaceClass *surface = new SurfaceClass(d3d_surface);
- d3d_surface->Release();
- return surface;
- }
- // ----------------------------------------------------------------------------
- IDirect3DSurface8 *TextureClass::Get_D3D_Surface_Level(unsigned int level)
- {
- if (!D3DTexture) {
- WWASSERT_PRINT(0, "Get_D3D_Surface_Level: D3DTexture is NULL!\n");
- return 0;
- }
- IDirect3DSurface8 *d3d_surface = NULL;
- DX8_ErrorCode(D3DTexture->GetSurfaceLevel(level, &d3d_surface));
- return d3d_surface;
- }
- // ----------------------------------------------------------------------------
- unsigned int TextureClass::Get_Priority(void)
- {
- if (!D3DTexture) {
- WWASSERT_PRINT(0, "Get_Priority: D3DTexture is NULL!\n");
- return 0;
- }
- return D3DTexture->GetPriority();
- }
- // ----------------------------------------------------------------------------
- unsigned int TextureClass::Set_Priority(unsigned int priority)
- {
- if (!D3DTexture) {
- WWASSERT_PRINT(0, "Set_Priority: D3DTexture is NULL!\n");
- return 0;
- }
- return D3DTexture->SetPriority(priority);
- }
- // ----------------------------------------------------------------------------
- void TextureClass::Set_Mip_Mapping(FilterType mipmap)
- {
- if (mipmap != FILTER_TYPE_NONE && Get_Mip_Level_Count() <= 1) {
- WWASSERT_PRINT(0, "Trying to enable MipMapping on texture w/o Mip levels!\n");
- return;
- }
- MipMapFilter=mipmap;
- }
- unsigned TextureClass::Get_Reduction() const
- {
- if (MipLevelCount==MIP_LEVELS_1) return 0;
- int reduction=WW3D::Get_Texture_Reduction();
- if (MipLevelCount && reduction>MipLevelCount) {
- reduction=MipLevelCount;
- }
- return reduction;
- }
- // ----------------------------------------------------------------------------
- void TextureClass::Apply(unsigned int stage)
- {
- if (!Initialized) {
- Init();
- }
- LastAccessed=WW3D::Get_Sync_Time();
- DX8_RECORD_TEXTURE(this);
- // Set texture itself
- if (WW3D::Is_Texturing_Enabled()) {
- DX8Wrapper::Set_DX8_Texture(stage, D3DTexture);
- } else {
- DX8Wrapper::Set_DX8_Texture(stage, NULL);
- }
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage,D3DTSS_MINFILTER,_MinTextureFilters[stage][TextureMinFilter]);
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage,D3DTSS_MAGFILTER,_MagTextureFilters[stage][TextureMagFilter]);
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage,D3DTSS_MIPFILTER,_MipMapFilters[stage][MipMapFilter]);
- switch (Get_U_Addr_Mode()) {
- case TEXTURE_ADDRESS_REPEAT:
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
- break;
- case TEXTURE_ADDRESS_CLAMP:
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
- break;
- }
- switch (Get_V_Addr_Mode()) {
- case TEXTURE_ADDRESS_REPEAT:
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
- break;
- case TEXTURE_ADDRESS_CLAMP:
- DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
- break;
- }
- }
- // ----------------------------------------------------------------------------
- void TextureClass::Apply_Null(unsigned int stage)
- {
- // This function sets the render states for a "NULL" texture
- DX8Wrapper::Set_DX8_Texture(stage, NULL);
- }
- // ----------------------------------------------------------------------------
- void TextureClass::Apply_New_Surface(IDirect3DTexture8* d3d_texture,bool initialized)
- {
- if (D3DTexture) D3DTexture->Release();
- D3DTexture=d3d_texture;//TextureLoadTask->Peek_D3D_Texture();
- D3DTexture->AddRef();
- if (initialized) Initialized=true;
- WWASSERT(D3DTexture);
- IDirect3DSurface8* surface;
- DX8_ErrorCode(D3DTexture->GetSurfaceLevel(0,&surface));
- D3DSURFACE_DESC d3d_desc;
- ::ZeroMemory(&d3d_desc, sizeof(D3DSURFACE_DESC));
- DX8_ErrorCode(surface->GetDesc(&d3d_desc));
- if (initialized) {
- TextureFormat=D3DFormat_To_WW3DFormat(d3d_desc.Format);
- Width=d3d_desc.Width;
- Height=d3d_desc.Height;
- }
- surface->Release();
- }
- // ----------------------------------------------------------------------------
- unsigned TextureClass::Get_Texture_Memory_Usage() const
- {
- if (!Initialized) return Calculate_Texture_Memory_Usage(this,0);
- return Calculate_Texture_Memory_Usage(this,0);
- }
- // ----------------------------------------------------------------------------
- int TextureClass::_Get_Total_Locked_Surface_Size()
- {
- int total_locked_surface_size=0;
- HashTemplateIterator<StringClass,TextureClass*> ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- // Get the current texture
- TextureClass* tex=ite.Peek_Value();
- if (!tex->Initialized) {
- total_locked_surface_size+=tex->Get_Texture_Memory_Usage();
- }
- }
- return total_locked_surface_size;
- }
- // ----------------------------------------------------------------------------
- int TextureClass::_Get_Total_Texture_Size()
- {
- int total_texture_size=0;
- HashTemplateIterator<StringClass,TextureClass*> ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- // Get the current texture
- TextureClass* tex=ite.Peek_Value();
- total_texture_size+=tex->Get_Texture_Memory_Usage();
- }
- return total_texture_size;
- }
- // ----------------------------------------------------------------------------
- int TextureClass::_Get_Total_Lightmap_Texture_Size()
- {
- int total_texture_size=0;
- HashTemplateIterator<StringClass,TextureClass*> ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- // Get the current texture
- TextureClass* tex=ite.Peek_Value();
- if (tex->Is_Lightmap()) {
- total_texture_size+=tex->Get_Texture_Memory_Usage();
- }
- }
- return total_texture_size;
- }
- // ----------------------------------------------------------------------------
- int TextureClass::_Get_Total_Procedural_Texture_Size()
- {
- int total_texture_size=0;
- HashTemplateIterator<StringClass,TextureClass*> ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- // Get the current texture
- TextureClass* tex=ite.Peek_Value();
- if (tex->Is_Procedural()) {
- total_texture_size+=tex->Get_Texture_Memory_Usage();
- }
- }
- return total_texture_size;
- }
- // ----------------------------------------------------------------------------
- int TextureClass::_Get_Total_Texture_Count()
- {
- int texture_count=0;
- HashTemplateIterator<StringClass,TextureClass*> ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- texture_count++;
- }
- return texture_count;
- }
- // ----------------------------------------------------------------------------
- int TextureClass::_Get_Total_Lightmap_Texture_Count()
- {
- int texture_count=0;
- HashTemplateIterator<StringClass,TextureClass*> ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- if (ite.Peek_Value()->Is_Lightmap()) {
- texture_count++;
- }
- }
- return texture_count;
- }
- // ----------------------------------------------------------------------------
- int TextureClass::_Get_Total_Procedural_Texture_Count()
- {
- int texture_count=0;
- HashTemplateIterator<StringClass,TextureClass*> ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- if (ite.Peek_Value()->Is_Procedural()) {
- texture_count++;
- }
- }
- return texture_count;
- }
- // ----------------------------------------------------------------------------
- int TextureClass::_Get_Total_Locked_Surface_Count()
- {
- int texture_count=0;
- HashTemplateIterator<StringClass,TextureClass*> ite(WW3DAssetManager::Get_Instance()->Texture_Hash());
- // Loop through all the textures in the manager
- for (ite.First ();!ite.Is_Done();ite.Next ()) {
- // Get the current texture
- TextureClass* tex=ite.Peek_Value();
- if (!tex->Initialized) {
- texture_count++;
- }
- }
- return texture_count;
- }
- void TextureClass::_Init_Filters(TextureClass::TextureFilterMode filter_type)
- {
- const D3DCAPS8& dx8caps=DX8Wrapper::Get_Current_Caps()->Get_DX8_Caps();
- _MinTextureFilters[0][FILTER_TYPE_NONE]=D3DTEXF_POINT;
- _MagTextureFilters[0][FILTER_TYPE_NONE]=D3DTEXF_POINT;
- _MipMapFilters[0][FILTER_TYPE_NONE]=D3DTEXF_NONE;
- _MinTextureFilters[0][FILTER_TYPE_FAST]=D3DTEXF_LINEAR;
- _MagTextureFilters[0][FILTER_TYPE_FAST]=D3DTEXF_LINEAR;
- _MipMapFilters[0][FILTER_TYPE_FAST]=D3DTEXF_POINT;
- _MagTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_POINT;
- _MinTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_POINT;
- _MipMapFilters[0][FILTER_TYPE_BEST]=D3DTEXF_POINT;
- if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MAGFLINEAR) _MagTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_LINEAR;
- if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MINFLINEAR) _MinTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_LINEAR;
- // Set anisotropic filtering only if requested and available
- if (filter_type==TextureClass::TEXTURE_FILTER_ANISOTROPIC) {
- if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MAGFANISOTROPIC) _MagTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_ANISOTROPIC;
- if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MINFANISOTROPIC) _MinTextureFilters[0][FILTER_TYPE_BEST]=D3DTEXF_ANISOTROPIC;
- }
- // Set linear mip filter only if requested trilinear or anisotropic, and linear available
- if (filter_type==TextureClass::TEXTURE_FILTER_ANISOTROPIC || filter_type==TextureClass::TEXTURE_FILTER_TRILINEAR) {
- if (dx8caps.TextureFilterCaps&D3DPTFILTERCAPS_MIPFLINEAR) _MipMapFilters[0][FILTER_TYPE_BEST]=D3DTEXF_LINEAR;
- }
- // For stages above zero, set best filter to the same as the stage zero, except if anisotropic
- for (int i=1;i<MAX_TEXTURE_STAGES;++i) {
- /* _MinTextureFilters[i][FILTER_TYPE_NONE]=D3DTEXF_POINT;
- _MagTextureFilters[i][FILTER_TYPE_NONE]=D3DTEXF_POINT;
- _MipMapFilters[i][FILTER_TYPE_NONE]=D3DTEXF_NONE;
- _MinTextureFilters[i][FILTER_TYPE_FAST]=D3DTEXF_LINEAR;
- _MagTextureFilters[i][FILTER_TYPE_FAST]=D3DTEXF_LINEAR;
- _MipMapFilters[i][FILTER_TYPE_FAST]=D3DTEXF_POINT;
- _MagTextureFilters[i][FILTER_TYPE_BEST]=D3DTEXF_LINEAR;
- _MinTextureFilters[i][FILTER_TYPE_BEST]=D3DTEXF_LINEAR;
- _MipMapFilters[i][FILTER_TYPE_BEST]=D3DTEXF_POINT;
- */
- _MinTextureFilters[i][FILTER_TYPE_NONE]=_MinTextureFilters[i-1][FILTER_TYPE_NONE];
- _MagTextureFilters[i][FILTER_TYPE_NONE]=_MagTextureFilters[i-1][FILTER_TYPE_NONE];
- _MipMapFilters[i][FILTER_TYPE_NONE]=_MipMapFilters[i-1][FILTER_TYPE_NONE];
- _MinTextureFilters[i][FILTER_TYPE_FAST]=_MinTextureFilters[i-1][FILTER_TYPE_FAST];
- _MagTextureFilters[i][FILTER_TYPE_FAST]=_MagTextureFilters[i-1][FILTER_TYPE_FAST];
- _MipMapFilters[i][FILTER_TYPE_FAST]=_MipMapFilters[i-1][FILTER_TYPE_FAST];
- if (_MagTextureFilters[i-1][FILTER_TYPE_BEST]==D3DTEXF_ANISOTROPIC) {
- _MagTextureFilters[i][FILTER_TYPE_BEST]=D3DTEXF_LINEAR;
- }
- else {
- _MagTextureFilters[i][FILTER_TYPE_BEST]=_MagTextureFilters[i-1][FILTER_TYPE_BEST];
- }
- if (_MinTextureFilters[i-1][FILTER_TYPE_BEST]==D3DTEXF_ANISOTROPIC) {
- _MinTextureFilters[i][FILTER_TYPE_BEST]=D3DTEXF_LINEAR;
- }
- else {
- _MinTextureFilters[i][FILTER_TYPE_BEST]=_MinTextureFilters[i-1][FILTER_TYPE_BEST];
- }
- _MipMapFilters[i][FILTER_TYPE_BEST]=_MipMapFilters[i-1][FILTER_TYPE_BEST];
- }
- // Set default to best. The level of best filter mode is controlled by the input parameter.
- for (i=0;i<MAX_TEXTURE_STAGES;++i) {
- _MinTextureFilters[i][FILTER_TYPE_DEFAULT]=_MinTextureFilters[i][FILTER_TYPE_BEST];
- _MagTextureFilters[i][FILTER_TYPE_DEFAULT]=_MagTextureFilters[i][FILTER_TYPE_BEST];
- _MipMapFilters[i][FILTER_TYPE_DEFAULT]=_MipMapFilters[i][FILTER_TYPE_BEST];
- DX8Wrapper::Set_DX8_Texture_Stage_State(i,D3DTSS_MAXANISOTROPY,2);
- }
- }
- void TextureClass::_Set_Default_Min_Filter(FilterType filter)
- {
- for (int i=0;i<MAX_TEXTURE_STAGES;++i) {
- _MinTextureFilters[i][FILTER_TYPE_DEFAULT]=_MinTextureFilters[i][filter];
- }
- }
- void TextureClass::_Set_Default_Mag_Filter(FilterType filter)
- {
- for (int i=0;i<MAX_TEXTURE_STAGES;++i) {
- _MagTextureFilters[i][FILTER_TYPE_DEFAULT]=_MagTextureFilters[i][filter];
- }
- }
- void TextureClass::_Set_Default_Mip_Filter(FilterType filter)
- {
- for (int i=0;i<MAX_TEXTURE_STAGES;++i) {
- _MipMapFilters[i][FILTER_TYPE_DEFAULT]=_MipMapFilters[i][filter];
- }
- }
- // Utility functions
- TextureClass *Load_Texture(ChunkLoadClass & cload)
- {
- // Assume failure
- TextureClass *newtex = NULL;
- char name[256];
- if (cload.Open_Chunk () && (cload.Cur_Chunk_ID () == W3D_CHUNK_TEXTURE)) {
- W3dTextureInfoStruct texinfo;
- bool hastexinfo = false;
- /*
- ** Read in the texture filename, and a possible texture info structure.
- */
- while (cload.Open_Chunk()) {
- switch (cload.Cur_Chunk_ID()) {
- case W3D_CHUNK_TEXTURE_NAME:
- cload.Read(&name,cload.Cur_Chunk_Length());
- break;
- case W3D_CHUNK_TEXTURE_INFO:
- cload.Read(&texinfo,sizeof(W3dTextureInfoStruct));
- hastexinfo = true;
- break;
- };
- cload.Close_Chunk();
- }
- cload.Close_Chunk();
- /*
- ** Get the texture from the asset manager
- */
- if (hastexinfo) {
- TextureClass::MipCountType mipcount;
- bool no_lod = ((texinfo.Attributes & W3DTEXTURE_NO_LOD) == W3DTEXTURE_NO_LOD);
- if (no_lod) {
- mipcount = TextureClass::MIP_LEVELS_1;
- } else {
- switch (texinfo.Attributes & W3DTEXTURE_MIP_LEVELS_MASK) {
- case W3DTEXTURE_MIP_LEVELS_ALL:
- mipcount = TextureClass::MIP_LEVELS_ALL;
- break;
- case W3DTEXTURE_MIP_LEVELS_2:
- mipcount = TextureClass::MIP_LEVELS_2;
- break;
- case W3DTEXTURE_MIP_LEVELS_3:
- mipcount = TextureClass::MIP_LEVELS_3;
- break;
- case W3DTEXTURE_MIP_LEVELS_4:
- mipcount = TextureClass::MIP_LEVELS_4;
- break;
- default:
- WWASSERT (false);
- mipcount = TextureClass::MIP_LEVELS_ALL;
- break;
- }
- }
- WW3DFormat format=WW3D_FORMAT_UNKNOWN;
- switch (texinfo.Attributes & W3DTEXTURE_TYPE_MASK) {
- case W3DTEXTURE_TYPE_COLORMAP:
- // Do nothing.
- break;
- case W3DTEXTURE_TYPE_BUMPMAP:
- {
- if (DX8Wrapper::Is_Initted() && DX8Wrapper::Get_Current_Caps()->Support_Bump_Envmap()) {
- // No mipmaps to bumpmap for now
- mipcount=TextureClass::MIP_LEVELS_1;
- if (DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(WW3D_FORMAT_U8V8)) format=WW3D_FORMAT_U8V8;
- else if (DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(WW3D_FORMAT_X8L8V8U8)) format=WW3D_FORMAT_X8L8V8U8;
- else if (DX8Wrapper::Get_Current_Caps()->Support_Texture_Format(WW3D_FORMAT_L6V5U5)) format=WW3D_FORMAT_L6V5U5;
- }
- break;
- }
- default:
- WWASSERT (false);
- break;
- }
- newtex = WW3DAssetManager::Get_Instance()->Get_Texture (name, mipcount, format);
- if (no_lod) {
- newtex->Set_Mip_Mapping(TextureClass::FILTER_TYPE_NONE);
- }
- bool u_clamp = ((texinfo.Attributes & W3DTEXTURE_CLAMP_U) != 0);
- newtex->Set_U_Addr_Mode(u_clamp ? TextureClass::TEXTURE_ADDRESS_CLAMP : TextureClass::TEXTURE_ADDRESS_REPEAT);
- bool v_clamp = ((texinfo.Attributes & W3DTEXTURE_CLAMP_V) != 0);
- newtex->Set_V_Addr_Mode(v_clamp ? TextureClass::TEXTURE_ADDRESS_CLAMP : TextureClass::TEXTURE_ADDRESS_REPEAT);
- } else {
- newtex = WW3DAssetManager::Get_Instance()->Get_Texture(name);
- }
- WWASSERT(newtex);
- }
- // Return a pointer to the new texture
- return newtex;
- }
- // Utility function used by Save_Texture
- void setup_texture_attributes(TextureClass * tex, W3dTextureInfoStruct * texinfo)
- {
- texinfo->Attributes = 0;
- if (tex->Get_Mip_Mapping() == TextureClass::FILTER_TYPE_NONE) texinfo->Attributes |= W3DTEXTURE_NO_LOD;
- if (tex->Get_U_Addr_Mode() == TextureClass::TEXTURE_ADDRESS_CLAMP) texinfo->Attributes |= W3DTEXTURE_CLAMP_U;
- if (tex->Get_V_Addr_Mode() == TextureClass::TEXTURE_ADDRESS_CLAMP) texinfo->Attributes |= W3DTEXTURE_CLAMP_V;
- }
- void Save_Texture(TextureClass * texture,ChunkSaveClass & csave)
- {
- const char * filename;
- W3dTextureInfoStruct texinfo;
- memset(&texinfo,0,sizeof(texinfo));
- filename = texture->Get_Full_Path();
- setup_texture_attributes(texture, &texinfo);
- csave.Begin_Chunk(W3D_CHUNK_TEXTURE_NAME);
- csave.Write(filename,strlen(filename)+1);
- csave.End_Chunk();
- if ((texinfo.Attributes != 0) || (texinfo.AnimType != 0) || (texinfo.FrameCount != 0)) {
- csave.Begin_Chunk(W3D_CHUNK_TEXTURE_INFO);
- csave.Write(&texinfo, sizeof(texinfo));
- csave.End_Chunk();
- }
- }
|