| 
 Immediate Mode: Textures 
By: Carl Warwick [Email] [Web: Freeride Designs] 
                                Written: July 11 2000 
 
Contents 
 
 
 
Introduction 
Today I'm going to show you how to load a texture and use
it on our pyramid, and we'll use bilinear filtering to make our textures look smooth even
if the are stretched or shrunk. We will also set-up 3 lights to light up the pyramid. 
This is quite a simple tutorial, loading a texture is
very similiar to making a normal surface in DDraw, so most of this should be familiar to
you. 
 
Declarations 
                                        
                                          
                                          
                                            
                                              
                                                
                                                  
                                                    
                                                      
                                                        
                                                          
                                                            
                                                              
                                                                
                                                                  
                                                                    
                                                                      
                                                                        Public
                                                                          PyramidVertex(5)
                                                                          As
                                                                          D3DVERTEX       	'Array of vertices of the pyramid
                                                                           
                                                                          Public
                                                                          BaseVertex(3)
                                                                          As
                                                                          D3DVERTEX               	'Array of vertices for square base
                                                                           
                                                                           
                                                                          Public
                                                                          PyramidTexture
                                                                          As
                                                                          DirectDrawSurface7 	'Holds the pyramids texture
                                                                           
                                                                          Public
                                                                          BaseTexture
                                                                          As
                                                                          DirectDrawSurface7 	'Holds the base texture | 
                                                                       
                                                                    
                                                                   
                                                                 | 
                                                               
                                                            
                                                           
                                                         | 
                                                       
                                                    
                                                   
                                                 | 
                                               
                                            
                                           
                                          
                                         
  We have two arrays of vertices, one to make our pyramid and one to make the 
  base of our pyramid. 
Then we have two DirectDrawSurface7 objects that store
the textures. 
 
Making the
pyramid 
We set up our objects just like normal, but this time we
need to set the tu and tv values, these two values are the x and y texture coordinates. 
The above image shows a top-down view of our pyramid, the
numbers show the texture coordinates (tu, tv) at each vertex. As you can see our square
texture will be mapped straight down onto the pyramid. Heres the code to set the vertices,
and to create the textures. 
                                        
                                          
                                          
                                            
                                              
                                                
                                                  
                                                    
                                                      
                                                        
                                                          
                                                            
                                                              
                                                                
                                                                  
                                                                    
                                                                      
                                                                        Public
                                                                          Sub
                                                                          Initialise_Geometry() 
                                                                             
    'Make the Pyramid, Make all the vertices white, so the texture
    colours 
        'don't get messed up.
                                                                           
                                                                             
                                                                          Call
                                                                          DX.CreateD3DVertex(0,
                                                                          5, 0,
                                                                          0, 1,
                                                                          0,
                                                                          0.5,
                                                                          0.5,
                                                                          PyramidVertex(0)) 
                                                                             
                                                                          Call
                                                                          DX.CreateD3DVertex(0,
                                                                          -5,
                                                                          10, 0,
                                                                          0, 1,
                                                                          0, 0,
                                                                          PyramidVertex(1)) 
                                                                             
                                                                          Call
                                                                          DX.CreateD3DVertex(10,
                                                                          -5, 0,
                                                                          1, 0,
                                                                          0, 1,
                                                                          0,
                                                                          PyramidVertex(2)) 
                                                                             
                                                                          Call
                                                                          DX.CreateD3DVertex(0,
                                                                          -5,
                                                                          -10,
                                                                          0, 0,
                                                                          -1, 1,
                                                                          1,
                                                                          PyramidVertex(3)) 
                                                                             
                                                                          Call
                                                                          DX.CreateD3DVertex(-10,
                                                                          -5, 0,
                                                                          -1, 0,
                                                                          0, 0,
                                                                          1,
                                                                          PyramidVertex(4)) 
                                                                             
                                                                          Call
                                                                          DX.CreateD3DVertex(0,
                                                                          -5,
                                                                          10, 0,
                                                                          0, 1,
                                                                          0, 0,
                                                                          PyramidVertex(5)) 
                                                                               
                                                                             
    'Create our texture for the pyramid
                                                                           
                                                                             
                                                                          Set
                                                                          PyramidTexture
                                                                          =
                                                                          CreateTextureSurface(App.Path
                                                                          &
                                                                          "\PyramidTexture.bmp",
                                                                          256,
                                                                          256) 
                                                                           
                                                                           
                                                                             
    'Make the base of the pyramid
                                                                           
                                                                             
                                                                          Call
                                                                          DX.CreateD3DVertex(10,
                                                                          -5, 0,
                                                                          0, -1,
                                                                          0, 0,
                                                                          0,
                                                                          BaseVertex(0)) 
                                                                             
                                                                          Call
                                                                          DX.CreateD3DVertex(0,
                                                                          -5,
                                                                          10, 0,
                                                                          -1, 0,
                                                                          1, 0,
                                                                          BaseVertex(1)) 
                                                                             
                                                                          Call
                                                                          DX.CreateD3DVertex(0,
                                                                          -5,
                                                                          -10,
                                                                          0, -1,
                                                                          0, 0,
                                                                          1,
                                                                          BaseVertex(2)) 
                                                                             
                                                                          Call
                                                                          DX.CreateD3DVertex(-10,
                                                                          -5, 0,
                                                                          0, -1,
                                                                          0, 1,
                                                                          1,
                                                                          BaseVertex(3)) 
                                                                           
                                                                             
    'Create our texture for the base
                                                                           
                                                                             
                                                                          Set
                                                                          BaseTexture
                                                                          =
                                                                          CreateTextureSurface(App.Path
                                                                          &
                                                                          "\BaseTexture.bmp",
                                                                          128,
                                                                          128) 
                                                                           
                                                                             
    'Set the Pyramid to its normal size
                                                                           
                                                                             
                                                                          ObjectScale
                                                                          =
                                                                          MakeVector(1,
                                                                          1, 1) 
                                                                          End
                                                                          Sub | 
                                                                       
                                                                    
                                                                   
                                                                 | 
                                                               
                                                            
                                                           
                                                         | 
                                                       
                                                    
                                                   
                                                 | 
                                               
                                            
                                           
                                          
                                         
  Take note of the normals, once again these are used for lighting the object. 
 
Creating the
textures 
This is my texture creating function. 
                                        
                                          
                                          
                                            
                                              
                                                
                                                  
                                                    
                                                      
                                                        
                                                          
                                                            
                                                              
                                                                
                                                                  
                                                                    
                                                                      
                                                                        Public
                                                                          Function
                                                                          CreateTextureSurface(sFile
                                                                          As
                                                                          String,
                                                                          pWidth
                                                                          As
                                                                          Long,
                                                                          pHeight
                                                                          As
                                                                          Long,
                                                                          _ 
                                                                                                                         
                                                                          Optional
                                                                          ColKey
                                                                          As
                                                                          Integer
                                                                          = 0)
                                                                          As
                                                                          DirectDrawSurface7 
                                                                           
                                                                             
                                                                          Dim
                                                                          bOK As
                                                                          Boolean 
                                                                             
                                                                          Dim
                                                                          enumTex
                                                                          As
                                                                          Direct3DEnumPixelFormats 
                                                                             
                                                                          Dim
                                                                          sLoadFile
                                                                          As
                                                                          String 
                                                                             
                                                                          Dim i
                                                                          As
                                                                          Long 
                                                                             
                                                                          Dim
                                                                          ddsd
                                                                          As
                                                                          DDSURFACEDESC2 
                                                                             
                                                                          Dim
                                                                          SurfaceObject
                                                                          As
                                                                          DirectDrawSurface7 
                                                                             
                                                                          Dim
                                                                          Init
                                                                          As
                                                                          Boolean 
                                                                           
                                                                             
    'Set our flags to tell the surface its a texture
                                                                           
                                                                             
                                                                          ddsd.lFlags
                                                                          =
                                                                          DDSD_CAPS
                                                                          Or
                                                                          DDSD_TEXTURESTAGE
                                                                          Or
                                                                          DDSD_PIXELFORMAT 
                                                                               
                                                                             
    'If width and height were specified then make our texture that
    size, 
        'otherwise it will be its normal size
                                                                           
                                                                             
                                                                          If ((pHeight
                                                                          <>
                                                                          0) And
                                                                          (pWidth
                                                                          <>
                                                                          0))
                                                                          Then 
                                                                                 
                                                                          ddsd.lFlags
                                                                          =
                                                                          ddsd.lFlags
                                                                          Or
                                                                          DDSD_HEIGHT
                                                                          Or
                                                                          DDSD_WIDTH 
                                                                                 
                                                                          ddsd.lHeight
                                                                          =
                                                                          pHeight 
                                                                                 
                                                                          ddsd.lWidth
                                                                          =
                                                                          pWidth 
                                                                             
                                                                          End If 
                                                                               
                                                                             
                                                                          Set
                                                                          enumTex
                                                                          =
                                                                          Device.GetTextureFormatsEnum() 
                                                                           
                                                                             
    'check if device supports 16bit surfaces
                                                                           
                                                                             
                                                                          For i
                                                                          = 1 To
                                                                          enumTex.GetCount() 
                                                                                 
                                                                          bOK =
                                                                          True 
                                                                                 
                                                                          Call
                                                                          enumTex.GetItem(i,
                                                                          ddsd.ddpfPixelFormat) 
                                                                           
                                                                                 
                                                                          With
                                                                          ddsd.ddpfPixelFormat 
                                                                                     
                                                                          If .lRGBBitCount
                                                                          <>
                                                                          16
                                                                          Then
                                                                          bOK =
                                                                          False 
                                                                                 
                                                                          End
                                                                          With 
                                                                                 
                                                                          If bOK
                                                                          = True
                                                                          Then
                                                                          Exit
                                                                          For 
                                                                             
                                                                          Next 
                                                                           
                                                                             
                                                                          If bOK
                                                                          =
                                                                          False
                                                                          Then 
                                                                                 
                                                                          Debug.Print
                                                                          "Unable
                                                                          to
                                                                          find
                                                                          16bit
                                                                          surface
                                                                          support
                                                                          on
                                                                          your
                                                                          hardware
                                                                          -
                                                                          exiting" 
                                                                                 
                                                                          Init =
                                                                          False 
                                                                             
                                                                          End If 
                                                                           
                                                                             
    'set some texture surface flags
                                                                           
                                                                             
                                                                          If
                                                                          Device.GetDeviceGuid()
                                                                          =
                                                                          "IID_IDirect3DHALDevice"
                                                                          Then 
                                                                                     
                                                                          ddsd.ddsCaps.lCaps
                                                                          =
                                                                          DDSCAPS_TEXTURE 
                                                                                     
                                                                          ddsd.ddsCaps.lCaps2
                                                                          =
                                                                          DDSCAPS2_TEXTUREMANAGE 
                                                                                     
                                                                          ddsd.lTextureStage
                                                                          = 0 
                                                                             
                                                                          Else 
                                                                                     
                                                                          ddsd.ddsCaps.lCaps
                                                                          =
                                                                          DDSCAPS_TEXTURE 
                                                                                     
                                                                          ddsd.ddsCaps.lCaps2
                                                                          = 0 
                                                                                     
                                                                          ddsd.lTextureStage
                                                                          = 0 
                                                                             
                                                                          End If 
                                                                           
                                                                             
    'If no filename was passed then create a blank surface
                                                                           
                                                                             
                                                                          If
                                                                          sFile
                                                                          =
                                                                          ""
                                                                          Then 
                                                                                 
                                                                          Set
                                                                          SurfaceObject
                                                                          =
                                                                          DD.CreateSurface(ddsd) 
                                                                             
                                                                          Else 
                                                                                 
                                                                          Set
                                                                          SurfaceObject
                                                                          =
                                                                          DD.CreateSurfaceFromFile(sFile,
                                                                          ddsd) 
                                                                             
                                                                          End If 
                                                                           
                                                                             
                                                                          Set
                                                                          CreateTextureSurface
                                                                          =
                                                                          SurfaceObject 
                                                                           
                                                                             
    'Colour key
                                                                           
                                                                             
                                                                          Dim
                                                                          ddckColourKey
                                                                          As
                                                                          DDCOLORKEY 
                                                                             
                                                                          Dim
                                                                          ddpf
                                                                          As
                                                                          DDPIXELFORMAT 
                                                                               
                                                                             
    'Make a Black colorkey
                                                                           
                                                                             
                                                                          If
                                                                          ColKey
                                                                          = 1
                                                                          Then 
                                                                                 
                                                                          ddckColourKey.low
                                                                          = 0 
                                                                                 
                                                                          ddckColourKey.high
                                                                          = 0 
                                                                                 
                                                                          CreateTextureSurface.SetColorKey
                                                                          DDCKEY_SRCBLT,
                                                                          ddckColourKey 
                                                                               
                                                                             
    'Make a Magneta Colorkey, rgb(255,0,255)
                                                                           
                                                                             
                                                                          ElseIf
                                                                          ColKey
                                                                          = 2
                                                                          Then 
                                                                                 
                                                                          CreateTextureSurface.GetPixelFormat
                                                                          ddpf 
                                                                                 
                                                                          ddckColourKey.low
                                                                          =
                                                                          ddpf.lBBitMask
                                                                          +
                                                                          ddpf.lRBitMask 
                                                                                 
                                                                          ddckColourKey.high
                                                                          =
                                                                          ddckColourKey.low 
                                                                                 
                                                                          CreateTextureSurface.SetColorKey
                                                                          DDCKEY_SRCBLT,
                                                                          ddckColourKey 
                                                                             
                                                                          End If 
                                                                          End
                                                                          Function | 
                                                                       
                                                                    
                                                                   
                                                                 | 
                                                               
                                                            
                                                           
                                                         | 
                                                       
                                                    
                                                   
                                                 | 
                                               
                                            
                                           
                                          
                                         
  As I said before, its pretty similar to creating normal DD surfaces, but we 
  must enumerate the surface to make sure it supports 16bit surfaces. We must 
  also set the caps to include DDSCAPS_TEXTURE, this is so that the surface knows 
  it has to store a texture. If we are using a HAL device then its more efficient 
  to let the device manage the textures, this basically means that textures that 
  are going to be used are moved to video memory, and the others are put wherever 
  they fit. 
You can specify the size of the texture by passing the
width and height variable to the function, but if you want the texture to be the size its
saved as then just set these values to zero. 
Texture surfaces should have their width and height set
to lengths that are powers of 2, eg. 16x16, 32x32, 64x64, 128x128, 256x256 etc. They
should also never be larger than 256x256 because most video cards don't support textures
larger than this. Its possible to use odd shaped textures, eg. 256x128 or 32x64, but again
not all cards support these surfaces, so its best to use square textures. 
You should always try to use the smallest texture sizes
possible so that you don't use up all the video memory. 
If you wish to create a blank texture then just pass it a
blank filename ( "" ). 
The final thing that this function allows you to do is to
set a colorkey to the surface, its possible to use either no color-key (default), black
color-key or a magneta [RGB(255,0,255)] color-key. If you don't know what a color-key is
then be sure to check the DDraw tutorials. 
 
Bilinear
filtering 
If you stretch a texture too much over an object then it
will look really blocky and horrible, to solve this we will use bilinear filtering.
Bilinear filtering just blends the colours from the four closest pixels to get the correct
colour when rendering the texture. Heres the nice and simple code to enable the filtering,
just 2 lines. 
                                        
                                          
                                          
                                            
                                              
                                                
                                                  
                                                    
                                                      
                                                        
                                                          
                                                            
                                                              
                                                                
                                                                  
                                                                    
                                                                      
                                                                                   'Lets
                                                                          use
                                                                          bilinear
                                                                          filtering,
                                                                          very
                                                                          cool 
                                                                             
                                                                          'MAGFILTER
                                                                          is if
                                                                          the
                                                                          texture
                                                                          is
                                                                          stretched
                                                                           
                                                                             
                                                                          Device.SetTextureStageState
                                                                          0,
                                                                          D3DTSS_MAGFILTER,
                                                                          D3DTFG_LINEAR 
                                                                             
    'MINFILTER is if texture is made smaller
                                                                           
                                                                             
                                                                          Device.SetTextureStageState
                                                                          0,
                                                                          D3DTSS_MINFILTER,
                                                                          D3DTFN_LINEAR | 
                                                                       
                                                                    
                                                                   
                                                                 | 
                                                               
                                                            
                                                           
                                                         | 
                                                       
                                                    
                                                   
                                                 | 
                                               
                                            
                                           
                                          
                                         
 
Conclusions 
There you go, nice and simple isn't it, but its one of
those things that you have to know thats why it had its own tutorial. Texture co-ordinates
are usually exported with an object, so you don't have to worry about manually setting
them all. 
The next tutorial will cover loading .x files 
Carl Warwick
- Freeride Designs 
                                       |