GameProgrammer.org
tutorials for dummies bug source let me google it for you my blog all about me
Using Textures
Textures are one of the most exciting parts of computer graphics that add a great deal of realism to your scenes. In this tutorial we are going to learn how to use textures in Direct3D.

#include <windows.h>
#include <d3d8.h>
#include <d3dx8.h>

HWND hWnd;
LPDIRECT3D8 pD3D;
LPDIRECT3DDEVICE8 pDevice;
LPDIRECT3DVERTEXBUFFER8 pVB;
LPDIRECT3DTEXTURE8 pTexture;

struct CUSTOMVERTEX
{
    FLOAT x, y, z; // The untransformed position for the vertex
    DWORD color; // The vertex color
    FLOAT tu, tv; // The texture coordinates
};

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)

LRESULT CALLBACK WndProc( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam)
{
    switch(message){
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd,message,wParam,lParam);
}

bool CreateSimpWindow(int width, int height)
{
    // Create A Window Class Structure
    WNDCLASSEX wc;
    wc.cbClsExtra = 0;
    wc.cbSize = sizeof(wc);
    wc.cbWndExtra = 0;
    wc.hbrBackground = NULL;
    wc.hCursor = NULL;
    wc.hIcon = NULL;
    wc.hIconSm = NULL;
    wc.hInstance = GetModuleHandle(NULL);
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = "VK3D";
    wc.lpszMenuName = NULL;
    wc.style = CS_VREDRAW|CS_HREDRAW|CS_OWNDC;
    
    // Register Window Class
    RegisterClassEx(&wc);
    
    // Create Window
    hWnd = CreateWindowEx(0,
    "VK3D", "GameProgrammer.org Tutorials",
    WS_OVERLAPPEDWINDOW|WS_VISIBLE, 100,100,width,height,
    NULL,NULL,wc.hInstance,0);
    
    return true;
}

bool InitD3D()
{
    if((pD3D = Direct3DCreate8(D3D_SDK_VERSION))==NULL){
        return false;
    }
    D3DDISPLAYMODE d3ddm;
    pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.BackBufferFormat = d3ddm.Format;
    d3dpp.Windowed = true;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    if(FAILED(pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
        hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice))){
        return false;
    }

    if(FAILED(D3DXCreateTextureFromFile(pDevice, "texture.bmp", &pTexture))){
        return false;
    }
    
    pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
    pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
    pDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

    
    CUSTOMVERTEX g_Vertices[] =
    {
        { -1.0f, 1.0f, 0.0f, 0xffff0000, 0,0}, // x, y, z, color, tu, tv
        { 1.0f, 1.0f, 0.0f, 0xffff0000, 1,0},
        { -1.0f, -1.0f, 0.0f, 0xff00ffff, 0,1},
        { 1.0f, -1.0f, 0.0f, 0xff00ff00, 1,1},
    };
    
    if( FAILED(pDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX),
        0, D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, &pVB ) ) )
    {
        return false;
    }
    
    VOID* pVertices;
    if(FAILED(pVB->Lock(0, sizeof(g_Vertices), (BYTE**)&pVertices, 0)))
        return false;
    memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );
    pVB->Unlock();
    
    return true;
}

void RenderD3DScene()
{
    pDevice->Clear(0,NULL,D3DCLEAR_TARGET,0,1,0);
    pDevice->BeginScene();
    
    D3DXMATRIX matView;
    D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 3.0f,-10.0f ),
    D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
    D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
    pDevice->SetTransform( D3DTS_VIEW, &matView );
    
    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f);
    pDevice->SetTransform( D3DTS_PROJECTION, &matProj );
    D3DXMATRIX matWorld;
    D3DXMatrixRotationY( &matWorld, timeGetTime()/1000.0f );
    pDevice->SetTransform( D3DTS_WORLD, &matWorld );
    
    pDevice->SetStreamSource( 0, pVB, sizeof(CUSTOMVERTEX) );
    pDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
    pDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

    pDevice->SetTexture( 0, pTexture );

    pDevice->EndScene();
    
    pDevice->Present(NULL,NULL,NULL,NULL);
}

void MessageLoop()
{
    MSG msg;
    while(true){
     RenderD3DScene();
     if(PeekMessage(&msg,hWnd,0,0,PM_REMOVE)){
            if(msg.message==WM_QUIT)return;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
     }
    }
}

INT WINAPI WinMain( HINSTANCE , HINSTANCE , LPSTR , INT )
{     
    if(!CreateSimpWindow(400, 400))return 1;
    if(!InitD3D())return 2;
    MessageLoop();
    return 0;
}

Compile the code and you will see a textured quad that is rotating. First difference is where we defined pTexture:

LPDIRECT3DTEXTURE8 pTexture;

pTexture is a pointer to the IDirect3DTexture8 interface which holds texture data. following the code you may find out a new vertex format:

struct CUSTOMVERTEX
{
    FLOAT x, y, z; // The untransformed position for the vertex
    DWORD color; // The vertex color
    FLOAT tu, tv; // The texture coordinates
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)

Two paramaters called tu and tv are defined in custom vertex which are specify texture coordinates for a vertex. This coordinates will be used to map texture on the polygons. D3DFVF_TEX1 flag specifies that custom vertex contains texture coordinates.

if(FAILED(D3DXCreateTextureFromFile(pDevice, "texture.bmp", &pTexture))){
    return false;
}

D3DXCreateTextureFromFile() function creates a texture from a file. First parameter is a pointer to IDirect3DDevice8 interface, second parameter is a bitmap file name and last parameter is address of a pointer to IDirect3DTexture8 interface representing the created texture object.

After loading texture file we need to specify our vertices:

CUSTOMVERTEX g_Vertices[] =
{
    { -1.0f, 1.0f, 0.0f, 0xffff0000, 0,0}, // x, y, z, color, tu, tv
    { 1.0f, 1.0f, 0.0f, 0xffff0000, 1,0},
    { -1.0f, -1.0f, 0.0f, 0xff00ffff, 0,1},
    { 1.0f, -1.0f, 0.0f, 0xff00ff00, 1,1},
};

Our vertex format has a little difference from previous tutorial, two last values in each structure specify coordinates of texture to be mapped on current vertex. This figure shows that how texture coordinates will be considered in Direct3D:

And at last we need to associate texture to the drawed polygon.

pDevice->SetTexture( 0, pTexture );

This command makes current a loaded texture object.

Too easy? Oh, sorry! OK, now go and try to change the values specially texture coordinates, This will help you to underestand texture mapping.

Good luck!

Posted on : 14 May 2004
Vahid Kazemi

Copyright © 2003-2010 Vahid Kazemi, GameProgrammer.org

iPhone Games