1 //-----------------------------------------------------------------------------
4 // Desc: This file contains the member functions for the
5 // CD3DTextureEngine class. The class is responsible for loading and
6 // creating textures from files, as well as retrieving the
7 // corresponding ptrs and surfaces for the textures, given a
11 // Copyright (c) 1996-1998 Microsoft Corporation. All rights reserved
12 //-----------------------------------------------------------------------------
21 //-----------------------------------------------------------------------------
22 // Name: TextureContainer
23 // Desc: Linked list tructure to hold info per texture
24 //-----------------------------------------------------------------------------
25 struct TextureContainer
27 HBITMAP hbmBitmap; // Bitmap containing texture image
28 LPDIRECTDRAWSURFACE4 pddsSurface; // Surface of the texture
29 LPDIRECT3DTEXTURE2 ptexTexture; // Direct3D texture for the texture
30 DWORD dwStage; // Texture stage (for multi-textures)
31 TCHAR strName[80]; // Filename of assoc'd bitmap
35 BYTE* pSurfaceBits[10];
38 TextureContainer *pPrev, *pNext; // Ptr to next texture in linked list
46 //-----------------------------------------------------------------------------
47 // Macros, function prototypes and static variable
48 //-----------------------------------------------------------------------------
49 #define FOREACHTEXTURE(ptc) for( TextureContainer* ptc=g_ptcTextureList; \
50 NULL!=ptc; ptc=ptc->pNext )
51 inline BOOL FileExists( TCHAR* n )
52 { FILE* fp=_tfopen(n,TEXT("rb")); return fp?(0==fclose(fp)):FALSE; }
54 static TextureContainer* g_ptcTextureList = NULL; // Textures list
55 static TCHAR g_strTexturePath[512] = TEXT("MEDIA\\"); // Path for files
56 static TCHAR* g_strRegValueName = TEXT("DX6SDK Samples Path");
61 struct TEXTURESEARCHINFO
63 DWORD dwDesiredBPP; // Input for texture format search
67 BOOL bFoundGoodFormat;
69 DDPIXELFORMAT* pddpf; // Result of texture format search
75 //-----------------------------------------------------------------------------
76 // Name: TextureSearchCallback()
77 // Desc: Enumeration callback routine to find a best-matching texture format.
78 // The param data is the DDPIXELFORMAT of the best-so-far matching
79 // texture. Note: the desired BPP is passed in the dwSize field, and the
80 // default BPP is passed in the dwFlags field.
81 //-----------------------------------------------------------------------------
82 static HRESULT CALLBACK TextureSearchCallback( DDPIXELFORMAT* pddpf,
85 if( NULL==pddpf || NULL==param )
88 TEXTURESEARCHINFO* ptsi = (TEXTURESEARCHINFO*)param;
90 // Skip any funky modes
91 if( pddpf->dwFlags & (DDPF_LUMINANCE|DDPF_BUMPLUMINANCE|DDPF_BUMPDUDV) )
94 // Check for palettized formats
95 if( ptsi->bUsePalette )
97 if( !( pddpf->dwFlags & DDPF_PALETTEINDEXED8 ) )
100 // Accept the first 8-bit palettized format we get
101 memcpy( ptsi->pddpf, pddpf, sizeof(DDPIXELFORMAT) );
102 ptsi->bFoundGoodFormat = TRUE;
103 return DDENUMRET_CANCEL;
106 // Else, skip any paletized formats (all modes under 16bpp)
107 if( pddpf->dwRGBBitCount < 16 )
110 // Check for FourCC formats
111 if( ptsi->bUseFourCC )
113 if( pddpf->dwFourCC == 0 )
116 return DDENUMRET_CANCEL;
119 // Else, skip any FourCC formats
120 if( pddpf->dwFourCC != 0 )
123 // Make sure current alpha format agrees with requested format type
124 if( (ptsi->bUseAlpha==TRUE) && !(pddpf->dwFlags&DDPF_ALPHAPIXELS) )
126 if( (ptsi->bUseAlpha==FALSE) && (pddpf->dwFlags&DDPF_ALPHAPIXELS) )
129 // Check if we found a good match
130 if( pddpf->dwRGBBitCount == ptsi->dwDesiredBPP )
132 memcpy( ptsi->pddpf, pddpf, sizeof(DDPIXELFORMAT) );
133 ptsi->bFoundGoodFormat = TRUE;
134 return DDENUMRET_CANCEL;
143 //-----------------------------------------------------------------------------
144 // Name: ~TextureContainer()
145 // Desc: Destructs the contents of the texture container
146 //-----------------------------------------------------------------------------
147 TextureContainer::~TextureContainer()
149 SAFE_DELETE( pNext );
150 SAFE_RELEASE( ptexTexture );
151 SAFE_RELEASE( pddsSurface );
152 DeleteObject( hbmBitmap );
158 //-----------------------------------------------------------------------------
159 // Name: CD3DStaticTextureEngine
160 // Desc: Class used to automatically construct and destruct the static
161 // texture engine class.
162 //-----------------------------------------------------------------------------
163 class CD3DTextureEngine
167 ~CD3DTextureEngine();
168 } g_StaticTextureEngine;
173 //-----------------------------------------------------------------------------
174 // Name: CD3DTextureEngine()
175 // Desc: Constructs the texture engine. Creates a DDraw object
176 //-----------------------------------------------------------------------------
177 CD3DTextureEngine::CD3DTextureEngine()
184 //-----------------------------------------------------------------------------
185 // Name: ~CD3DTextureEngine()
186 // Desc: Deletes the internal list of textures
187 //-----------------------------------------------------------------------------
188 CD3DTextureEngine::~CD3DTextureEngine()
190 // Delete the list of textures
191 SAFE_DELETE( g_ptcTextureList );
197 //-----------------------------------------------------------------------------
198 // Name: FindTexture()
199 // Desc: Searches the internal list of textures for a texture specified by
200 // its name. Returns the structure associated with that texture.
201 //-----------------------------------------------------------------------------
202 static TextureContainer* FindTexture( TCHAR* strTextureName )
204 FOREACHTEXTURE( ptcTexture )
206 if( !lstrcmpi( strTextureName, ptcTexture->strName ) )
216 //-----------------------------------------------------------------------------
217 // Name: FindTextureFile()
218 // Desc: Looks for the specified file in the current directory, in the path
219 // specified in the environment variables, or in the path specified in
220 // the registry. After finding it, the function returns the full path.
221 //-----------------------------------------------------------------------------
222 static HRESULT FindTextureFile( TCHAR* strFilename, TCHAR* strTexturePath,
225 // First, check the current directory
226 _tcscpy( strFullPath, strFilename );
227 if( FileExists( strFullPath ) )
230 // Next, check to see if an environment variable specifies the path
231 TCHAR* strPath = _tgetenv( TEXT("D3DPATH") );
232 if( NULL != strPath )
234 _stprintf( strFullPath, TEXT("%s\\%s"), strPath, strFilename );
235 if( FileExists( strFullPath ) )
239 // Finally, check the system registry for a path
241 LONG result = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
242 TEXT("Software\\Microsoft\\DirectX"),
244 if( ERROR_SUCCESS == result )
247 DWORD type, size = 512;
248 result = RegQueryValueEx( key, g_strRegValueName, NULL, &type,
249 (BYTE*)strPath, &size );
253 if( ERROR_SUCCESS == result )
255 _stprintf( strFullPath, TEXT("%s\\D3DIM\\Media\\%s"), strPath,
257 if( FileExists( strFullPath ) )
260 _stprintf( strFullPath, TEXT("%s\\%s%s"), strPath,
261 strTexturePath, strFilename );
262 if( FileExists( strFullPath ) )
267 return DDERR_NOTFOUND;
273 //-----------------------------------------------------------------------------
274 // Name: LoadTextureImage()
275 // Desc: Loads a texture map file into a BITMAP surface.
276 //-----------------------------------------------------------------------------
277 static HRESULT LoadTextureImage( TextureContainer* ptcTexture )
279 TCHAR* strFilename = ptcTexture->strName;
281 TCHAR strPathname[256];
283 // Get the filename extension
284 if( NULL == ( strExtension = _tcsrchr( strFilename, TEXT('.') ) ) )
285 return DDERR_UNSUPPORTED;
287 // Check the executable's resource. If it's there, we're done!
288 if( NULL != ( ptcTexture->hbmBitmap = (HBITMAP)LoadImage(
289 GetModuleHandle(NULL),
290 strFilename, IMAGE_BITMAP,
291 0, 0, LR_CREATEDIBSECTION) ) )
294 // Check the current path and system registry path for the file
295 if( FAILED( FindTextureFile( strFilename, g_strTexturePath, strPathname ) ) )
296 return DDERR_NOTFOUND;
298 if( !lstrcmpi( strExtension, ".bmp" ) )
300 // Try to load the bitmap as a resource.
301 ptcTexture->hbmBitmap = (HBITMAP)LoadImage( GetModuleHandle(NULL),
302 strPathname, IMAGE_BITMAP, 0, 0,
303 LR_CREATEDIBSECTION );
305 // If the bitmap wasn't a resource, try it as a file.
306 if( NULL == ptcTexture->hbmBitmap )
307 ptcTexture->hbmBitmap = (HBITMAP)LoadImage( NULL, strPathname,
309 LR_LOADFROMFILE|LR_CREATEDIBSECTION );
311 return (ptcTexture->hbmBitmap) ? DD_OK : DDERR_NOTFOUND;
314 // Can check for other file formats here
316 return DDERR_UNSUPPORTED;
322 //-----------------------------------------------------------------------------
323 // Name: CopyBitmapToSurface()
324 // Desc: Copies the image of a bitmap into a surface
325 //-----------------------------------------------------------------------------
326 static HRESULT CopyBitmapToSurface( LPDIRECTDRAWSURFACE4 pddsTarget,
327 HBITMAP hbmBitmap, DWORD dwFlags )
329 // Get a DDraw object to create a temporary surface
331 pddsTarget->GetDDInterface( (VOID**)&pDD );
334 // Get the bitmap structure (to extract width, height, and bpp)
336 GetObject( hbmBitmap, sizeof(BITMAP), &bm );
338 // Setup the new surface desc
340 D3DUtil_InitSurfaceDesc( ddsd );
341 pddsTarget->GetSurfaceDesc( &ddsd );
342 ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|
344 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_SYSTEMMEMORY;
345 ddsd.ddsCaps.dwCaps2 = 0L;
346 ddsd.dwWidth = bm.bmWidth;
347 ddsd.dwHeight = bm.bmHeight;
349 // Create a new surface for the texture
350 LPDIRECTDRAWSURFACE4 pddsTempSurface;
352 if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTempSurface, NULL ) ) )
355 // Get a DC for the bitmap
356 HDC hdcBitmap = CreateCompatibleDC( NULL );
357 if( NULL == hdcBitmap )
359 pddsTempSurface->Release();
362 SelectObject( hdcBitmap, hbmBitmap );
364 // Handle palettized textures. Need to attach a palette
365 if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 )
367 // Create the color table and parse in the palette
369 WORD wNumColors = GetDIBColorTable( hdcBitmap, 0, 256,
371 for( WORD i=0; i<wNumColors; i++ )
373 pe[i] = 0xff000000 + RGB( GetBValue(pe[i]), GetGValue(pe[i]),
376 // Set alpha for transparent pixels
377 if( dwFlags & D3DTEXTR_TRANSPARENTBLACK )
379 if( (pe[i]&0x00ffffff) == 0x00000000 )
382 else if( dwFlags & D3DTEXTR_TRANSPARENTWHITE )
384 if( (pe[i]&0x00ffffff) == 0x00ffffff )
388 // Create & attach a palette with the bitmap's colors
389 LPDIRECTDRAWPALETTE pPalette;
390 if( dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
391 pDD->CreatePalette( DDPCAPS_8BIT|DDPCAPS_ALPHA, (PALETTEENTRY*)pe, &pPalette, NULL );
393 pDD->CreatePalette( DDPCAPS_8BIT, (PALETTEENTRY*)pe, &pPalette, NULL );
394 pddsTempSurface->SetPalette( pPalette );
395 pddsTarget->SetPalette( pPalette );
396 SAFE_RELEASE( pPalette );
399 // Copy the bitmap image to the surface.
401 if( SUCCEEDED( pddsTempSurface->GetDC( &hdcSurface ) ) )
403 BitBlt( hdcSurface, 0, 0, bm.bmWidth, bm.bmHeight, hdcBitmap, 0, 0,
405 pddsTempSurface->ReleaseDC( hdcSurface );
407 DeleteDC( hdcBitmap );
409 // Copy the temp surface to the real texture surface
410 pddsTarget->Blt( NULL, pddsTempSurface, NULL, DDBLT_WAIT, NULL );
412 if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 )
414 LPDIRECTDRAWPALETTE pPalette;
416 pddsTempSurface->GetPalette( &pPalette );
417 pPalette->GetEntries( 0, 0, 256, (PALETTEENTRY*)&pe );
420 pddsTarget->GetPalette( &pPalette );
421 pPalette->GetEntries( 0, 0, 256, (PALETTEENTRY*)&pe );
425 pddsTempSurface->Release();
427 // For textures with real alpha (not palettized), set transparent bits
428 if( ddsd.ddpfPixelFormat.dwRGBAlphaBitMask )
430 if( dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
432 // Lock the texture surface
434 D3DUtil_InitSurfaceDesc( ddsd );
435 while( pddsTarget->Lock( NULL, &ddsd, 0, NULL ) ==
436 DDERR_WASSTILLDRAWING );
438 DWORD dwAlphaMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;
439 DWORD dwRGBMask = ( ddsd.ddpfPixelFormat.dwRBitMask |
440 ddsd.ddpfPixelFormat.dwGBitMask |
441 ddsd.ddpfPixelFormat.dwBBitMask );
442 DWORD dwColorkey = 0x00000000; // Colorkey on black
443 if( dwFlags & D3DTEXTR_TRANSPARENTWHITE )
444 dwColorkey = dwRGBMask; // Colorkey on white
446 // Add an opaque alpha value to each non-colorkeyed pixel
447 for( DWORD y=0; y<ddsd.dwHeight; y++ )
449 WORD* p16 = (WORD*)((BYTE*)ddsd.lpSurface + y*ddsd.lPitch);
450 DWORD* p32 = (DWORD*)((BYTE*)ddsd.lpSurface + y*ddsd.lPitch);
452 for( DWORD x=0; x<ddsd.dwWidth; x++ )
454 if( ddsd.ddpfPixelFormat.dwRGBBitCount == 16 )
456 if( ( *p16 &= dwRGBMask ) != dwColorkey )
460 if( ddsd.ddpfPixelFormat.dwRGBBitCount == 32 )
462 if( ( *p32 &= dwRGBMask ) != dwColorkey )
468 pddsTarget->Unlock( NULL );
478 //-----------------------------------------------------------------------------
479 // Name: D3DTextr_GetSurface()
480 // Desc: Returns a pointer to a d3dSurface from the name of the texture
481 //-----------------------------------------------------------------------------
482 LPDIRECTDRAWSURFACE4 D3DTextr_GetSurface( TCHAR* strName )
484 TextureContainer* ptcTexture = FindTexture( strName );
486 return ptcTexture ? ptcTexture->pddsSurface : NULL;
492 //-----------------------------------------------------------------------------
493 // Name: D3DTextr_GetTexture()
494 // Desc: Returns a pointer to a d3dTexture from the name of the texture
495 //-----------------------------------------------------------------------------
496 LPDIRECT3DTEXTURE2 D3DTextr_GetTexture( TCHAR* strName )
498 TextureContainer* ptcTexture = FindTexture( strName );
500 return ptcTexture ? ptcTexture->ptexTexture: NULL;
506 //-----------------------------------------------------------------------------
507 // Name: D3DTextr_SetTexturePath()
508 // Desc: Enumeration callback routine to find a best-matching texture format.
509 //-----------------------------------------------------------------------------
510 VOID D3DTextr_SetTexturePath( TCHAR* strTexturePath )
512 if( NULL==strTexturePath )
513 strTexturePath = TEXT("");
514 _tcscpy( g_strTexturePath, strTexturePath );
520 //-----------------------------------------------------------------------------
521 // Name: D3DTextr_CreateTexture()
522 // Desc: Is passed a filename and creates a local Bitmap from that file.
523 // The texture can not be used until it is restored, however.
524 //-----------------------------------------------------------------------------
525 HRESULT D3DTextr_CreateTexture( TCHAR* strName, DWORD dwStage, DWORD dwFlags )
527 // Check first to see if the texture is already loaded
528 if( NULL != FindTexture( strName ) )
531 // Allocate and add the texture to the linked list of textures;
532 TextureContainer* ptcTexture = new TextureContainer();
533 if( NULL == ptcTexture )
534 return E_OUTOFMEMORY;
535 ZeroMemory( ptcTexture, sizeof(TextureContainer) );
536 lstrcpy( ptcTexture->strName, strName );
537 ptcTexture->dwStage = dwStage;
538 ptcTexture->dwFlags = dwFlags;
540 // Create a bitmap and load the texture file into it,
541 if( FAILED( LoadTextureImage( ptcTexture ) ) )
547 // Add the texture to the global linked list
548 if( g_ptcTextureList )
549 g_ptcTextureList->pPrev = ptcTexture;
550 ptcTexture->pNext = g_ptcTextureList;
551 g_ptcTextureList = ptcTexture;
559 //-----------------------------------------------------------------------------
560 // Name: RestoreFromBitmap()
561 // Desc: Invalidates the current texture objects and rebuilds new ones
562 // using the new device.
563 //-----------------------------------------------------------------------------
564 static HRESULT RestoreFromBitmap( TextureContainer* ptcTexture,
565 LPDIRECT3DDEVICE3 pd3dDevice )
567 // Get the DirectDraw interface for creating surfaces
569 if( NULL == ( pDD = D3DUtil_GetDirectDrawFromDevice( pd3dDevice ) ) )
573 // Get the device caps
574 D3DDEVICEDESC ddHwDesc, ddSwDesc;
576 ddHwDesc.dwSize = sizeof(D3DDEVICEDESC);
577 ddSwDesc.dwSize = sizeof(D3DDEVICEDESC);
578 if( FAILED( pd3dDevice->GetCaps( &ddHwDesc, &ddSwDesc ) ) )
580 if( ddHwDesc.dwFlags ) dwDeviceCaps = ddHwDesc.dpcTriCaps.dwTextureCaps;
581 else dwDeviceCaps = ddSwDesc.dpcTriCaps.dwTextureCaps;
583 // Get the bitmap structure (to extract width, height, and bpp)
585 HBITMAP hbmBitmap = ptcTexture->hbmBitmap;
586 GetObject( hbmBitmap, sizeof(BITMAP), &bm );
587 DWORD dwWidth = (DWORD)bm.bmWidth;
588 DWORD dwHeight = (DWORD)bm.bmHeight;
590 // Setup the new surface desc
592 D3DUtil_InitSurfaceDesc( ddsd );
593 ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|
594 DDSD_PIXELFORMAT|DDSD_TEXTURESTAGE;
595 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
596 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
597 ddsd.dwTextureStage = ptcTexture->dwStage;
598 ddsd.dwWidth = dwWidth;
599 ddsd.dwHeight = dwHeight;
601 // Adjust width and height, if the driver requires it
602 if( dwDeviceCaps & D3DPTEXTURECAPS_POW2 )
604 for( ddsd.dwWidth=1; dwWidth>ddsd.dwWidth; ddsd.dwWidth<<=1 );
605 for( ddsd.dwHeight=1; dwHeight>ddsd.dwHeight; ddsd.dwHeight<<=1 );
607 if( dwDeviceCaps & D3DPTEXTURECAPS_SQUAREONLY )
609 if( ddsd.dwWidth > ddsd.dwHeight ) ddsd.dwHeight = ddsd.dwWidth;
610 else ddsd.dwWidth = ddsd.dwHeight;
613 BOOL bUsePalette = ( bm.bmBitsPixel <= 8 );
614 BOOL bUseAlpha = FALSE;
616 if( ptcTexture->bHasAlpha )
619 if( ptcTexture->dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
623 if( dwDeviceCaps & D3DPTEXTURECAPS_ALPHAPALETTE )
636 // Setup the structure to be used for texture enumration.
637 TEXTURESEARCHINFO tsi;
638 tsi.pddpf = &ddsd.ddpfPixelFormat;
639 tsi.bUseAlpha = bUseAlpha;
640 tsi.bUsePalette = bUsePalette;
641 tsi.bUseFourCC = ( ddsd.ddpfPixelFormat.dwFlags & DDPF_FOURCC );
642 tsi.dwDesiredBPP = 16;
643 tsi.bFoundGoodFormat = FALSE;
644 if( ptcTexture->dwFlags & D3DTEXTR_32BITSPERPIXEL )
645 tsi.dwDesiredBPP = 32;
647 // Enumerate the texture formats, and find the closest device-supported
648 // texture pixel format
649 pd3dDevice->EnumTextureFormats( TextureSearchCallback, &tsi );
651 // If a palettized format was requested, but not found, default to a
652 // 16-bit texture format
653 if( FALSE == tsi.bFoundGoodFormat && bUsePalette )
655 tsi.bUsePalette = FALSE;
656 tsi.dwDesiredBPP = 16;
657 pd3dDevice->EnumTextureFormats( TextureSearchCallback, &tsi );
658 if( FALSE == tsi.bFoundGoodFormat )
662 // Create a new surface for the texture
664 if( FAILED( hr = pDD->CreateSurface( &ddsd, &ptcTexture->pddsSurface, NULL ) ) )
667 // Create the texture
668 if( FAILED( ptcTexture->pddsSurface->QueryInterface( IID_IDirect3DTexture2,
669 (VOID**)&ptcTexture->ptexTexture ) ) )
673 // Copy the bitmap to the texture surface
674 return CopyBitmapToSurface( ptcTexture->pddsSurface, hbmBitmap,
675 ptcTexture->dwFlags );
682 //-----------------------------------------------------------------------------
683 // Name: D3DTextr_Restore()
684 // Desc: Invalidates the current texture objects and rebuilds new ones
685 // using the new device.
686 //-----------------------------------------------------------------------------
687 HRESULT D3DTextr_Restore( TCHAR* strName, LPDIRECT3DDEVICE3 pd3dDevice )
690 if( NULL == pd3dDevice )
691 return DDERR_INVALIDPARAMS;
693 TextureContainer* ptcTexture = FindTexture( strName );
694 if( NULL == ptcTexture )
695 return DDERR_NOTFOUND;
697 // Release any previously created objects
698 SAFE_RELEASE( ptcTexture->ptexTexture );
699 SAFE_RELEASE( ptcTexture->pddsSurface );
701 // Restore the texture surface from the bitmap image. At this point, code
702 // can be added to handle other texture formats, such as those created from
703 // .dds files, .jpg files, or whatever else.
704 return RestoreFromBitmap( ptcTexture, pd3dDevice );
710 //-----------------------------------------------------------------------------
711 // Name: D3DTextr_RestoreAllTextures()
712 // Desc: This function is called when a mode is changed. It updates all
713 // texture objects to be valid with the new device.
714 //-----------------------------------------------------------------------------
715 HRESULT D3DTextr_RestoreAllTextures( LPDIRECT3DDEVICE3 pd3dDevice )
717 FOREACHTEXTURE( ptcTexture )
719 D3DTextr_Restore( ptcTexture->strName, pd3dDevice );
728 //-----------------------------------------------------------------------------
729 // Name: D3DTextr_Invalidate()
730 // Desc: Used to bump a texture out of (video) memory, this function
731 // actually destroys the d3dtexture and ddsurface of the texture
732 //-----------------------------------------------------------------------------
733 HRESULT D3DTextr_Invalidate( TCHAR* strName )
735 TextureContainer* ptcTexture = FindTexture( strName );
736 if( NULL == ptcTexture )
737 return DDERR_NOTFOUND;
739 SAFE_RELEASE( ptcTexture->ptexTexture );
740 SAFE_RELEASE( ptcTexture->pddsSurface );
748 //-----------------------------------------------------------------------------
749 // Name: D3DTextr_InvalidateAllTextures()
750 // Desc: This function is called when a mode is changed. It invalidates
751 // all texture objects so their device can be safely released.
752 //-----------------------------------------------------------------------------
753 HRESULT D3DTextr_InvalidateAllTextures()
755 FOREACHTEXTURE( ptcTexture )
757 SAFE_RELEASE( ptcTexture->ptexTexture );
758 SAFE_RELEASE( ptcTexture->pddsSurface );
767 //-----------------------------------------------------------------------------
768 // Name: D3DTextr_DestroyTexture()
769 // Desc: Frees the resources for the specified texture container
770 //-----------------------------------------------------------------------------
771 HRESULT D3DTextr_DestroyTexture( TCHAR* strName )
773 TextureContainer* ptcTexture = FindTexture( strName );
774 if( NULL == ptcTexture )
775 return DDERR_NOTFOUND;
777 // Remove the texture container from the global list
778 if( ptcTexture->pPrev )
779 ptcTexture->pPrev->pNext = ptcTexture->pNext;
781 g_ptcTextureList = ptcTexture->pNext;
782 ptcTexture->pNext = NULL;
784 SAFE_DELETE( ptcTexture );