Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
101 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

3. Initialization code

So you've got your Direct3D object, presented your parameters, created your device, whatever. All you need to do now is add a couple lines and you'll be drawing textured quads in no time.

First things first, you need to make a vertex buffer. In the same scope your IDirect3DDevice9 pointer is located, add:

IDirect3DVertexBuffer9* vertexBuffer;

Groovy. Now, in your initalization function, AFTER the device is created, add the following:

//Set vertex shader
DEVICE->SetVertexShader(NULL);
DEVICE->SetFVF(D3DFVF_TLVERTEX);

//Create vertex buffer
DEVICE->CreateVertexBuffer(sizeof(TLVERTEX) * 4, NULL,
    D3DFVF_TLVERTEX, D3DPOOL_MANAGED, &vertexBuffer, NULL);
DEVICE->SetStreamSource(0, vertexBuffer, 0, sizeof(TLVERTEX));

NOTE 1: Replace DEVICE with the name of your IDirect3DDevice9* object
NOTE 2: This code does not have to be directly after the CreateDevice() call; as long as the device is created, it should work fine

Also the following render states should be set if they are not:

DEVICE->SetRenderState(D3DRS_LIGHTING, FALSE);
DEVICE->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
DEVICE->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
DEVICE->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
DEVICE->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

NOTE: Replace DEVICE with the name of your IDirect3DDevice9* object

Alright, now we're ready to go. Let's load some textures.

4. Loading a texture

Using D3DX this is incredibly simple. Here's a code dump:

//Load texture from file with D3DX
//Supported formats: BMP, PPM, DDS, JPG, PNG, TGA, DIB
IDirect3DTexture9 *LoadTexture(char *fileName)
{
  IDirect3DTexture9 *d3dTexture;
  D3DXIMAGE_INFO SrcInfo;      //Optional

  //Use a magenta colourkey
  D3DCOLOR colorkey = 0xFFFF00FF;

  // Load image from file
  if (FAILED(D3DXCreateTextureFromFileEx (DEVICE, fileName, 0, 0, 1, 0, 
        D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT, 
        colorkey, &SrcInfo, NULL, &d3dTexture)))
  {
    return NULL;
  }

  //Return the newly made texture
  return d3dTexture;
}

NOTE: Replace DEVICE with the name of your IDirect3DDevice9* object

You pass it a graphics file, it passes you a pointer to a texture. Couldn't be easier. Upon failure, a NULL pointer is returned. While the loaded graphics file will retain its own alpha map, there is also a magenta colour key, meaning all pixels with a colour value of 0xFFFF00FF will be given an alpha value of 0 upon loading.

Please note that if you load an image file whose dimensions are not powers of 2, and your video card cannot support non-power-of-2 textures, this function will automatically put the image in a texture with dimensions that are powers of 2. For example, if you tried to load a 100x100 image, it would be put into a 128x128 texture. The extra space on the texture will have an alpha value of 0, so it will not show up when the texture is drawn. However, it will cause the drawing functions below to draw the image with a scaled size. That is, if you tried to draw the 100x100 image in a 100x100 square on screen, the drawing function would have to scale the 128x128 texture to fit inside it. This would make the image appear smaller than it actually is. Using the drawing functions in the CTexture class (provided at the end of the article) will prevent this scaling. Even so, I urge the reader to avoid the whole mess and use square, power-of-2-sized graphics.



Drawing a texture

Contents
  The concept
  Initialization code
  Drawing a texture
  The CTexture class
  Appendix

  Source code
  Printable version
  Discuss this article