Post

 Resources 

Console

Texture Resource Manangement


Well here goes my first attempt at writing a tutorial in visual basic, aimed at game programming with DirectX9. For my first tutorial I will be creating an optimization module for textures. In other words, the module that will follow is not necessary for game development but it does create a more efficient game, such as with the rpg I'm working on. With the addition of this manager the memory usage dropped from 30 mb to 26 mb which may not seem like much; but when you realize that this is only about 1% of the final product you're looking at a lot more memory savings.

This module keeps track of all the textures that are in use so as to prevent the program from loading the same texture many times, which happens a lot, especially when you start to use textured meshes.

Where to start...


  1. Public Textures(1) As Texture
  2. Public iTextures As Integer = 1
  3. Public uTextures(1) As Int16
  4. Dim sTextures(1) As String
  5. Dim wTextures(1) As Long
  6. Dim hTextures(1) As Long


The textures() array contains the actual textures, pretty simple. The itextures probably doesnít need to be public; it just says how large all the arrays are. uTextures() is the usage of the texture, I'll get to that latter. stextures(1) is the path and filename of the texture. wTextures() is the width and htextures() is the height.

GetTextureId


  1. Public Function GetTextureId(ByVal fPath As String, ByValfname As String, ByVal width As Long, ByVal height As Long, OptionalByVal sizeSpecific As Boolean = False) As Integer


Ok here starts the fun stuff, this is the function called when you want to load a texture. It will return an address to the texture which I will show you how to use near the end of this tutorial. First the fPath and fName variables are the file path and file name, pretty self explanitory. The only intresting one is the sizeSpecific, you can add other criteria here to make the texturemanager suit your needs, however for us this is currently all we needed. This variable simply states whether the dimensions of the texture must mach the height and width provided (note if you pass height and width as -1 it will load the textures actual dimensions.

This portion of the code checks to see if we already have loaded the texture.
  1. Dim icount As Int16
  2. For icount = 0 To iTextures Ė 1  'For every texture
  3.   If fPath & fname = sTextures(icount) Then 'If the filename matches
  4.    If (Not sizeSpecific) Or (width = wTextures(icount) And height = hTextures(icount)) Then 'If its not sizeSpecific or the sizes matchreturn that textures id and exit the function
  5.       uTextures(icount) += 1 'increase usage count
  6.       Return icount
  7.       Exit Function
  8.     End If
  9.   End If
  10. Next


Ok if its made it here we donít have the needed texture, so lets see if we have any texture variables that are = nothing.

  1. For icount = 0 To iTextures - 1
  2.   If Textures(icount) Is Nothing Then 'The texture is loaded here to save time and space
  3. loadTexture2(fPath, fname, width, height, icount)
  4.     uTextures(icount) += 1 'increase usage count
  5.     Return icount
  6.     Exit Function
  7.   End If
  8. Next


Ok if its made it this far the texture doesnít exist and theres no empty texture variables, so we must enlarge the arrays
  1. iTextures += 1
  2. ReDim Preserve Textures(iTextures)
  3. ReDim Preserve uTextures(iTextures)
  4. ReDim Preserve sTextures(iTextures)
  5. ReDim Preserve wTextures(iTextures)
  6. ReDim Preserve hTextures(iTextures)
  7. loadTexture2(fPath, fname, width, height, iTextures)
  8. uTextures(iTextures) += 1 'increase usage count
  9. Return iTextures
  10. End Function


loadTexture2


First the only reason its called loadtexture2 and not loadtexture is because I had loadtexture already in my program, so you can omit the 2 in your version of the module, it's private because it doesnít get called outside the module.
  1. Private FunctionloadTexture2(ByVal fpath As String, ByVal fname As String, ByVal widthAs Long, ByVal height As Long, ByVal Id As Long)
  2.   Textures(Id)= TextureLoader.FromFile(D3DDevice, fpath & fname, width, height,1, 0, 21, Pool.Default, Filter.Point, Filter.Linear,System.Drawing.Color.Black.ToArgb)
  3.   sTextures(Id) = fpath & fname
  4.   wTextures(Id) = width
  5.   hTextures(Id) = height
  6. End Function


Pretty self explanatory, it uses the d3ddevice and colorformat A8R8G8B8, those could easily be changed though as could a variable be added to describe the transparent color.

RemoveTexture

The remove texture part I havenít actually used yet, but it should work.

  1. Public Function RemoveTexture(ByVal id As Long)
  2.   If id = -1 Then 'remove all textures.
  3.     iTextures = 0
  4.     ReDim Preserve Textures(iTextures)
  5.     ReDim Preserve uTextures(iTextures)
  6.     ReDim Preserve sTextures(iTextures)
  7.     ReDim Preserve wTextures(iTextures)
  8.     ReDim Preserve hTextures(iTextures)
  9.     Exit Function
  10.   End If
  11.   uTextures(id) -= 1 'decrease usage count
  12.   If uTextures(id) = 0 Then 'no more references to this texture, so lets remove it
  13.     Textures(id) = Nothing
  14.     uTextures(id) = 0
  15.     sTextures(id) = ""
  16.     wTextures(id) = 0
  17.     hTextures(id) = 0
  18.     If id = iTextures - 1 Then
  19.       Dim icount As Long
  20.       icount = iTextures - 2
  21.       Do Until (Not Textures(icount) Is Nothing) Or icount = 0
  22.         icount -= 1
  23.       Loop
  24.       iTextures = icount + 1
  25.       ReDim Preserve Textures(iTextures)
  26.       ReDim Preserve uTextures(iTextures)
  27.       ReDim Preserve sTextures(iTextures)
  28.       ReDim Preserve wTextures(iTextures)
  29.       ReDim Preserve hTextures(iTextures)
  30.     End If
  31.   End If
  32. End Function


For this function, you tell it which texture you want to remove and it decreases the usage count, and will sets the texture equal to nothing if there are no more references to the texture, which frees up memory. It then checks if the end of the array is equal to nothing in which case it shortens the array until the last member of the array is not nothing or the array has a dimension of one.

On using this module

To create a texture you would call something like this
TextureId = TextureManager.GetTextureId("BackGround.bmp", 300, 300, Application.StartupPath & " exturesmenu", True)
This will give you an address of the texture you want. And to use the texture,
D3ddevice.settexture(0,texturemanager.textures(Textureid))



Post a Comment

Tutorial Console

Tutorial by:

Harry


Date: 2003 Nov 22


Post a Comment



Printer Friendly



Copyright © 2002 - 2004 Eric Coleman, Peter Kuchnio , et. al.
There have been 30 visitors within the last 20 minutes
RSS News Feed