Exemplos Dx9

Aqui estão alguns programas de exemplo em DirectX 9. Eles foram retirados do DirectX SDK de fevereiro de 2010, sendo que a alteração realizada foi a tradução dos comentários de inglês para português.
Esta aplicação foi feita criando-se um novo projeto no MSVC++ Express 2008 escolhendo a opção programa Win32 e projeto vazio. Contudo, para facilitar o próprio DirectX SDK já traz esta amostra pronta. Basta instalá-la diretamente do navegador de amostras e incluir os caminhos do DirectX onde necessários nas propriedades do projeto.
Obs: Alguns tutoriais requerem arquivos extras como modelos .x e figuras .bmp. Provavelmente eles serão colocados aqui em outra oportunidade

Tutorial 1 do DX 9 no DX SDK - Criação de janela D3D

#include <d3d9.h>
#include <strsafe.h>
#include <windows.h>
 
//#pragma warning( disable : 4996 ) // disable deprecated warnings
 
LPDIRECT3D9        g_pD3D = NULL;
LPDIRECT3DDEVICE9    g_pd3dDevice = NULL;
 
HRESULT InitD3D( HWND hWnd ){
    // cria o objeto D3D, que é necessário para criar o D3DDeevice.
    if( NULL == (g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;
 
    // Configura a estrutura usada para criar o D3DDevice. A maioria dos parâmetros são
    // zerados. Nós configuraremos Windowed para TRUE, desde que nós queremos D3D em uma
    // janela, e então configuraremos o SwapEffect para "descarte", que é o método mais
    // eficiente de apresentar o buffer de trás (back buffer) para a exibição. E nós 
    // requisitamos um formato do buffer traseiro que combina o atual formato de
    // exibição do desktop
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
 
    // Crie o dispositivo Direct3D. Aqui nós estamos usando o adaptador padrão ( A maioria dos
    // sistemas tem só um, a menos que eles tenham múltiplos placas de hardware gráficas
    // instalados ) e pedimos ao HAL ( que é dizer que nós queremos o dispositivo de hardware 
    // ao invés de um de software ). Processamento vértice de software é especificado desde que
    // nós sabemos que ele funcionará em todas as placas. Contudo, nas placas que suportam processamento
    // vértice por hardware, nós veríamos um grande ganho de desempenho por especificar processamento
    // de vértice por hardware.
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
        D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ){
            return E_FAIL;
    }
 
    // Estado do dispositivo normalmente seria colocado aqui
 
    return S_OK;
}
 
// Libera todos os objetos inicializados anteriormente
VOID Cleanup(){
    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();
 
    if( g_pD3D != NULL )
        g_pD3D->Release();
}
 
// Desenha a cena
VOID Render(){
    if( NULL == g_pd3dDevice )
        return ;
 
    // limpa o buffer de trás para uma cor azul
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );
 
    // Inicia a cena
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // renderização dos objetos da cena pode acontecer aqui
 
        // termina a cena
        g_pd3dDevice->EndScene();
    }
 
    // Apresenta os conteúdos do buffer de trás para a exibição
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
 
// o tratador de mensagem da janela
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){
    switch( msg ){
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
 
        case WM_PAINT:
            Render();
            ValidateRect( hWnd, NULL );
            return 0;
    }
 
    return DefWindowProc( hWnd, msg, wParam, lParam );
}
 
// o ponto de entrada da aplicação
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE prevInstance, LPSTR CmdLine, INT nShowCmd ){
    // Registra a classe da janela
    WNDCLASSEX wc = {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
        L"Direct3D Tutorial", NULL 
    };
 
    RegisterClassEx( &wc );
 
    // Cria a janela da aplicação
    HWND hWnd = CreateWindow( L"Direct3D Tutorial", L"Direct3D Tutorial 01: CreateDevice",
        WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
        GetDesktopWindow(), NULL, wc.hInstance, NULL );
 
    // Inicializa Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) ){
        // Mostre a janela
        ShowWindow( hWnd, SW_SHOWDEFAULT );
        UpdateWindow( hWnd );
 
        // Entre no loop de mensagem
        MSG msg;
        while( GetMessage( &msg, NULL, 0, 0) ){
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    }
 
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

Tutorial 2 DX9 - DX SDK - Criação de um triângulo

//#include <cstdio>
#include <d3d9.h>
#include <strsafe.h>
#include <windows.h>
 
//#pragma warning( disable : 4996 ) // disable deprecated warnings
 
LPDIRECT3D9        g_pD3D = NULL;    // Usada para criar o D3DDevice
LPDIRECT3DDEVICE9    g_pd3dDevice = NULL; // Nosso dispositivo de renderização
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;    // Buffer para armazenar vértices
 
// Uma estrutura para nosso tipo de vértice customizado
struct CUSTOMVERTEX{
    FLOAT x, y, z, rhw;        // A posição transformada para o vértice
    DWORD color;            // A cor do vértice
};
 
// Nosso FVF (Formato de Vértice Flexível) customizado que descreve
// nossa estrutura de vértice customizada
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
 
HRESULT InitD3D( HWND hWnd ){
    // cria o objeto D3D, que é necessário para criar o D3DDeevice.
    if( NULL == (g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;
 
    // Configura a estrutura usada para criar o D3DDevice. A maioria dos parâmetros são
    // zerados. Nós configuraremos Windowed para TRUE, desde que nós queremos D3D em uma
    // janela, e então configuraremos o SwapEffect para "descarte", que é o método mais
    // eficiente de apresentar o buffer de trás (back buffer) para a exibição. E nós 
    // requisitamos um formato do buffer traseiro que combina o atual formato de
    // exibição do desktop
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
 
    // Crie o dispositivo Direct3D. Aqui nós estamos usando o adaptador padrão ( A maioria dos
    // sistemas tem só um, a menos que eles tenham múltiplos placas de hardware gráficas
    // instalados ) e pedimos ao HAL ( que é dizer que nós queremos o dispositivo de hardware 
    // ao invés de um de software ). Processamento vértice de software é especificado desde que
    // nós sabemos que ele funcionará em todas as placas. Contudo, nas placas que suportam processamento
    // vértice por hardware, nós veríamos um grande ganho de desempenho por especificar processamento
    // de vértice por hardware.
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
        D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ){
            return E_FAIL;
    }
 
    // Estado do dispositivo normalmente seria colocado aqui
 
    return S_OK;
}
 
// Cria um buffer de vértice e preenche ele com nossos vértices. O buffer de vértice é basicamente
// apenas um pedaço de memória que armazena vértices. Depois de criá-lo, nós devemos  travar 
// ( Lock() )/ e destravar ( Unlock() ) ele para preenchê-lo. Para índices, D3D também usa buffers de 
// índice. A coisa especial sobre vértice e buffers de índice é que eles podem ser criados na memória 
// do dispositivo, permitindo algumas placas processá-los em hardware, resultando em um ganho de 
// desempenho dramático.
HRESULT InitVB(){
    // Inicializa três vértices para renderizar um triângulo
    CUSTOMVERTEX vertices[] = {
        { 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, },
        { 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
        { 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, }
    };
 
    // Cria o buffer de vértices. Aqui nós estamos alocando memória (do pool padrão) para armazenar
    // todos os nossos 3 vértices. Onde nós também especificamos o FVF, então o buffer de vértice
    // conhece que dado ele contém
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3 * sizeof( CUSTOMVERTEX ),
        0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) ) ){
            return E_FAIL;
    }
 
    // Agora nós preenchemos o buffer de vértice. Para fazer isso, nós precisamos travar ( lock() )
    // o VB para ganhar acesso aos vértices. Este mecanismo é requerido porque buffers de 
    // vértice podem estar na memória do equipamento
    VOID *pVertices;
    if( FAILED( g_pVB->Lock( 0, sizeof( vertices ), ( void** ) &pVertices, 0 ) ) )
        return E_FAIL;
 
    memcpy( pVertices, vertices, sizeof( vertices ) );
    g_pVB->Unlock();
 
    return S_OK;
}
 
// Libera todos os objetos inicializados anteriormente
VOID Cleanup(){
    if( g_pVB != NULL )
        g_pVB->Release();
 
    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();
 
    if( g_pD3D != NULL )
        g_pD3D->Release();
}
 
// Desenha a cena
VOID Render(){
    if( NULL == g_pd3dDevice )
        return ;
 
    // limpa o buffer de trás para uma cor azul
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );
 
    // Inicia a cena
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // Desenha os triângulos no buffer de vértice. Isto é quebrado em alguns passos.
        // Nós estamos passando o vértice abaixo para um "fluxo", então primeiro nós
        // precisamos especificar a origem daquele fluxo, que é nosso buffer de vértice.
        // Então nós precisamos deixar D3D saber qual shader vértice usar. Shader vértice
        // completo, customizado são um tópico avançado, mas na maioria dos casos o shader
        // vértice é apenas o FVF, para que D3D saiba que tipo de vértices nós estamos
        // lidando. Finalmente, nós chamamos DrawPrimitive() que faz a renderização
        // verdadeira de nossa geometria (neste caso, apenas um triângulo)
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
 
        // termina a cena
        g_pd3dDevice->EndScene();
    }
 
    // Apresenta os conteúdos do buffer de trás para a exibição
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
 
// o tratador de mensagem da janela
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){
    switch( msg ){
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
    }
 
    return DefWindowProc( hWnd, msg, wParam, lParam );
}
 
// o ponto de entrada da aplicação
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE prevInstance, LPSTR CmdLine, INT nShowCmd ){
    // Registra a classe da janela
    WNDCLASSEX wc = {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
        L"Direct3D Tutorial", NULL 
    };
 
    RegisterClassEx( &wc );
 
    // Cria a janela da aplicação
    HWND hWnd = CreateWindow( L"Direct3D Tutorial", L"Direct3D Tutorial 02: Vertices",
        WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
        NULL, NULL, wc.hInstance, NULL );
 
    // Inicializa Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) ){
 
        // Cria o buffer de vértice
        if( SUCCEEDED( InitVB() ) ){
            // Mostre a janela
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );
 
            // Entre no loop de mensagem
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT ){
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ){
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                } else{
                    Render();
                }
            }
        }
    }
 
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

Tutorial 3 DX9 - DXSDK - Matrizes

// Este arquivo contém uma aplicação Win32 que cria uma janela e
// um D3D9 Device 
 
//#include <cstdio>
#include <d3dx9.h>
#include <strsafe.h>
#include <windows.h>
 
//#pragma warning( disable : 4996 ) // disable deprecated warnings
 
LPDIRECT3D9        g_pD3D = NULL;    // Usada para criar o D3DDevice
LPDIRECT3DDEVICE9    g_pd3dDevice = NULL; // Nosso dispositivo de renderização
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;    // Buffer para armazenar vértices
 
// Uma estrutura para nosso tipo de vértice customizado
struct CUSTOMVERTEX{
    FLOAT x, y, z;        // A posição transformada para o vértice
    DWORD color;            // A cor do vértice
};
 
// Nosso FVF (Formato de Vértice Flexível) customizado que descreve
// nossa estrutura de vértice customizada
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
 
HRESULT InitD3D( HWND hWnd ){
    // cria o objeto D3D, que é necessário para criar o D3DDeevice.
    if( NULL == (g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;
 
    // Configura a estrutura usada para criar o D3DDevice. A maioria dos parâmetros são
    // zerados. Nós configuraremos Windowed para TRUE, desde que nós queremos D3D em uma
    // janela, e então configuraremos o SwapEffect para "descarte", que é o método mais
    // eficiente de apresentar o buffer de trás (back buffer) para a exibição. E nós 
    // requisitamos um formato do buffer traseiro que combina o atual formato de
    // exibição do desktop
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
 
    // Crie o dispositivo Direct3D. Aqui nós estamos usando o adaptador padrão ( A maioria dos
    // sistemas tem só um, a menos que eles tenham múltiplos placas de hardware gráficas
    // instalados ) e pedimos ao HAL ( que é dizer que nós queremos o dispositivo de hardware 
    // ao invés de um de software ). Processamento vértice de software é especificado desde que
    // nós sabemos que ele funcionará em todas as placas. Contudo, nas placas que suportam processamento
    // vértice por hardware, nós veríamos um grande ganho de desempenho por especificar processamento
    // de vértice por hardware.
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
        D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ){
            return E_FAIL;
    }
 
    // Desativa o culling, então nós vemos a frente a traseira do triângulo
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
 
    // Desativa a iluminação do D3D, desde que nós estamos fornecendo nossas próprias cores de vértice
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
 
    return S_OK;
}
 
// cria a geometria da cena
HRESULT InitGeometry(){
    // Inicializa três vértices para renderizar um triângulo
    CUSTOMVERTEX g_Vertices[] = {
        { -1.0f, -1.0f, 0.0f, 0xffff0000, },
        { 1.0f, -1.0f, 0.0f, 0xff0000ff, },
        { 0.0f, 1.0f, 0.0f, 0xffffffff, }
    };
 
    // Cria o buffer de vértices. 
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3 * sizeof( CUSTOMVERTEX ),
        0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) ) ){
            return E_FAIL;
    }
 
    // Preenche o buffer de vértice. 
    VOID *pVertices;
    if( FAILED( g_pVB->Lock( 0, sizeof( g_Vertices ), ( void** ) &pVertices, 0 ) ) )
        return E_FAIL;
 
    memcpy( pVertices, g_Vertices, sizeof( g_Vertices ) );
    g_pVB->Unlock();
 
    return S_OK;
}
 
// Libera todos os objetos inicializados anteriormente
VOID Cleanup(){
    if( g_pVB != NULL )
        g_pVB->Release();
 
    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();
 
    if( g_pD3D != NULL )
        g_pD3D->Release();
}
 
// Configura as matriz de transformação de projeção, visão e de mundo
VOID SetupMatrices(){
    // Para nossa matriz de mundo, nós simplesmente rotacionaremos o objeto
    // ao redor do eixo y
    D3DXMATRIXA16 matWorld;
 
    // Configura a matriz de rotação para gerar 1 rotação completa (2*PI radianos)
    // a cada 1000 ms. Para evitar a perda de precisão inerente em números de ponto
    // flutuante muito altos, o tempo do sistema é modulado pelo período da rotação
    // antes da conversão para um ângulo de radianos;
    UINT iTime = timeGetTime() % 1000;
    float fAngle = iTime * ( 2.0f * D3DX_PI ) / 1000.0f;
    D3DXMatrixRotationY( &matWorld, fAngle );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
 
    // Configure nossa matriz de visualização. Uma matriz de visualização pode ser definida
    // dado uma posição do olho, um ponto para o qual olhar, e uma direção a qual aponta
    // para cima. Aqui nós configuramos o olho cinco unidades atrás do  eixo z e para cima 
    // três unidades, olhar na origem, e definimos que "para cima" está na direção do eixo y
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f, -5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
 
    // para a matriz de projeção, nós configuramos uma transformação perspectiva (que transforma
    // geometria do espaço de visão 3D para o espaço de porto de visão (viewport) 2D, com uma
    // divisão perspectiva fazendo objetos menores à distância). Para construir uma transformação
    // perspectiva, nós precisamos do campo de visão (1/4 de pi é comum), a taxa de aspecto, e os
    // planos de recorte near e far (que definem a qual distância as geometrias não deveriam mais
    // ser renderizadas).
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
 
// Desenha a cena
VOID Render(){
    // limpa o buffer de trás para uma cor preta
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 );
 
    // Inicia a cena
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // Configura as matrizes de projeção, mundo e visão
        SetupMatrices();
 
        // Desenha os triângulos no buffer de vértice. Isto é quebrado em alguns passos.
        // Nós estamos passando o vértice abaixo para um "fluxo", então primeiro nós
        // precisamos especificar a origem daquele fluxo, que é nosso buffer de vértice.
        // Então nós precisamos deixar D3D saber qual shader vértice usar. Shader vértice
        // completo, customizado são um tópico avançado, mas na maioria dos casos o shader
        // vértice é apenas o FVF, para que D3D saiba que tipo de vértices nós estamos
        // lidando. Finalmente, nós chamamos DrawPrimitive() que faz a renderização
        // verdadeira de nossa geometria (neste caso, apenas um triângulo)
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );
 
        // termina a cena
        g_pd3dDevice->EndScene();
    }
 
    // Apresenta os conteúdos do buffer de trás para a exibição
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
 
// o tratador de mensagem da janela
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){
    switch( msg ){
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
    }
 
    return DefWindowProc( hWnd, msg, wParam, lParam );
}
 
// o ponto de entrada da aplicação
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE prevInstance, LPSTR CmdLine, INT nShowCmd ){
    // Registra a classe da janela
    WNDCLASSEX wc = {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
        L"Direct3D Tutorial", NULL 
    };
 
    RegisterClassEx( &wc );
 
    // Cria a janela da aplicação
    HWND hWnd = CreateWindow( L"Direct3D Tutorial", L"Direct3D Tutorial 03: Matrices",
        WS_OVERLAPPEDWINDOW, 100, 100, 256, 256,
        NULL, NULL, wc.hInstance, NULL );
 
    // Inicializa Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) ){
 
        // Cria o buffer de vértice
        if( SUCCEEDED( InitGeometry() ) ){
            // Mostre a janela
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );
 
            // Entre no loop de mensagem
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT ){
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ){
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                } else{
                    Render();
                }
            }
        }
    }
 
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

Tutorial 4 DX 9 - DXSDK - Luzes

// Este arquivo contém uma aplicação Win32 que cria uma janela e
// um D3D9 Device 
 
//#include <cstdio>
#include <d3dx9.h>
#include <strsafe.h>
#include <windows.h>
#include <mmsystem.h>
 
//#pragma warning( disable : 4996 ) // disable deprecated warnings
 
LPDIRECT3D9        g_pD3D = NULL;    // Usada para criar o D3DDevice
LPDIRECT3DDEVICE9    g_pd3dDevice = NULL; // Nosso dispositivo de renderização
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;    // Buffer para armazenar vértices
 
// Uma estrutura para nosso tipo de vértice customizado
struct CUSTOMVERTEX{
    D3DXVECTOR3     position;    // A posição 3D para o vértice
    D3DXVECTOR3 normal;            // A cor do vértice
};
 
// Nosso FVF (Formato de Vértice Flexível) customizado que descreve
// nossa estrutura de vértice customizada
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)
 
// Inicializa Direct3D
HRESULT InitD3D( HWND hWnd ){
    // cria o objeto D3D
    if( NULL == (g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;
 
    // Configura a estrutura usada para criar o D3DDevice. Desde que agora nós estamos
    // usando geometria mais complexa, nós criaremos um dispositivo com zbuffer
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
 
    // Cria o dispositivo Direct3D. 
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
        D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ){
            return E_FAIL;
    }
 
    // Desativa o culling, então nós vemos a frente a traseira do triângulo
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
 
    // Ativa o zbuffer
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
 
    return S_OK;
}
 
// cria a geometria da cena
HRESULT InitGeometry(){
 
    // Cria o buffer de vértice
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50 * 2 * sizeof( CUSTOMVERTEX ),
        0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) ) ){
            return E_FAIL;
    }
 
    // Preenche o buffer de vértice. Nós estamos algoritmicamente gerando um cilindro
    // aqui, incluindo as normais, que são usadas para iluminação
    CUSTOMVERTEX* pVertices;
    if( FAILED( g_pVB->Lock( 0, 0, ( void** ) &pVertices, 0 ) ) )
        return E_FAIL;
    for( DWORD i = 0; i < 50; i++ ){
        FLOAT theta = (2 * D3DX_PI * i ) / (50 - 1);
        pVertices[ 2 * i + 0 ].position = D3DXVECTOR3( sinf(theta), -1.0f, cosf( theta ));
        pVertices[ 2 * i + 0 ].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf( theta ));
        pVertices[ 2 * i + 1 ].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf( theta ));
        pVertices[ 2 * i + 1 ].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf( theta ));
    }    
 
    g_pVB->Unlock();
 
    return S_OK;
}
 
// Libera todos os objetos inicializados anteriormente
VOID Cleanup(){
    if( g_pVB != NULL )
        g_pVB->Release();
 
    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();
 
    if( g_pD3D != NULL )
        g_pD3D->Release();
}
 
// Configura as matriz de transformação de projeção, visão e de mundo
VOID SetupMatrices(){
    // Configura a matriz do mundo
    D3DXMATRIXA16 matWorld;
    D3DXMatrixIdentity( &matWorld );
    D3DXMatrixRotationX( &matWorld, timeGetTime() / 500.0f );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
 
    // Configure nossa matriz de visualização. Uma matriz de visualização pode ser definida
    // dado uma posição do olho, um ponto para o qual olhar, e uma direção a qual aponta
    // para cima. Aqui nós configuramos o olho cinco unidades atrás do  eixo z e para cima 
    // três unidades, olhar na origem, e definimos que "para cima" está na direção do eixo y
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f, -5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
 
    // para a matriz de projeção, nós configuramos uma transformação perspectiva (que transforma
    // geometria do espaço de visão 3D para o espaço de porto de visão (viewport) 2D, com uma
    // divisão perspectiva fazendo objetos menores à distância). Para construir uma transformação
    // perspectiva, nós precisamos do campo de visão (1/4 de pi é comum), a taxa de aspecto, e os
    // planos de recorte near e far (que definem a qual distância as geometrias não deveriam mais
    // ser renderizadas).
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
 
// configura as luzes e materiais para a cena
VOID SetupLights(){
    // Configura um material. O material aqui tem apenas as cores difusa e ambiente 
    // configuradas para amarelo. Note que somente um material pode ser usado por vez.
    D3DMATERIAL9 mtrl;
    ZeroMemory( &mtrl, sizeof( D3DMATERIAL9 ) );
    mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
    mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
    mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
    mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
    g_pd3dDevice->SetMaterial( &mtrl );
 
    // Configura uma luz direcional, branca, com uma direção de oscilação.
    // Note que muitas luzes podem estar ativas por vez (mas cada uma 
    // torna mais lenta a renderização de nossa cena). Entretanto, nós
    // estamos aqui usando apenas uma. Também, nós precisamos configurar
    // o estado de renderização D3DRS_LIGHTING para habilitar a iluminação
    D3DXVECTOR3 vecDir;
    D3DLIGHT9 light;
    ZeroMemory( &light, sizeof( D3DLIGHT9 ) );
    light.Type = D3DLIGHT_DIRECTIONAL;
    light.Diffuse.r = light.Diffuse.g = light.Diffuse.b = 1.0f;
    vecDir = D3DXVECTOR3( cosf( timeGetTime() / 350.0f ), 1.0f, 
        sinf( timeGetTime() / 350.0f ) );
    D3DXVec3Normalize( (D3DXVECTOR3 *)&light.Direction, &vecDir );
    light.Range = 1000.0f;
    g_pd3dDevice->SetLight( 0, &light );
    g_pd3dDevice->LightEnable( 0, TRUE );
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
 
    // Finalmente ativa alguma luz ambiente
    g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );
}
 
// Desenha a cena
VOID Render(){
    // limpa o buffer de trás e o zbuffer
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
        D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );
 
    // Inicia a cena
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // Configura as luzes e materiais
        SetupLights();
 
        // Configura as matrizes de projeção, mundo e visão
        SetupMatrices();
 
        // Renderiza os conteúdos do buffer de vcértice
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50 - 2 );
 
        // termina a cena
        g_pd3dDevice->EndScene();
    }
 
    // Apresenta os conteúdos do buffer de trás para a exibição
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
 
// o tratador de mensagem da janela
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){
    switch( msg ){
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
    }
 
    return DefWindowProc( hWnd, msg, wParam, lParam );
}
 
// o ponto de entrada da aplicação
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE prevInstance, LPSTR CmdLine, INT nShowCmd ){
    // Registra a classe da janela
    WNDCLASSEX wc = {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
        L"Direct3D Tutorial", NULL 
    };
 
    RegisterClassEx( &wc );
 
    // Cria a janela da aplicação
    HWND hWnd = CreateWindow( L"Direct3D Tutorial", L"Direct3D Tutorial 04: Lights",
        WS_OVERLAPPEDWINDOW, 100, 100, 256, 256,
        NULL, NULL, wc.hInstance, NULL );
 
    // Inicializa Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) ){
 
        // Cria o buffer de vértice
        if( SUCCEEDED( InitGeometry() ) ){
            // Mostre a janela
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );
 
            // Entre no loop de mensagem
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT ){
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ){
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                } else{
                    Render();
                }
            }
        }
    }
 
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

Tutorial 5 DX9 - DXSDK - Colocando Texturas na cena

// Este arquivo contém uma aplicação Win32 que cria uma janela e
// um D3D9 Device 
 
//#include <cstdio>
#include <d3dx9.h>
#include <strsafe.h>
#include <windows.h>
#include <mmsystem.h>
 
//#pragma warning( disable : 4996 ) // disable deprecated warnings
 
LPDIRECT3D9        g_pD3D = NULL;    // Usada para criar o D3DDevice
LPDIRECT3DDEVICE9    g_pd3dDevice = NULL; // Nosso dispositivo de renderização
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;    // Buffer para armazenar vértices
LPDIRECT3DTEXTURE9 g_pTexture = NULL;    // Nossa textura
 
// #define SHOW_HOW_TO_USE_TC1 // descomente esta linha para ver TexCoords no espaço da câmera
 
// Uma estrutura para nosso tipo de vértice customizado
struct CUSTOMVERTEX{
    D3DXVECTOR3     position;    // A posição 
    D3DCOLOR color;            // A cor 
#ifndef SHOW_HOW_TO_USE_TC1
    FLOAT tu, tv;            // As coordenadas de textura
#endif
};
 
// Nosso FVF (Formato de Vértice Flexível) customizado que descreve
// nossa estrutura de vértice customizada
#ifdef SHOW_HOW_TO_USE_TC1
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
#else
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
#endif
 
// Inicializa Direct3D
HRESULT InitD3D( HWND hWnd ){
    // cria o objeto D3D
    if( NULL == (g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;
 
    // Configura a estrutura usada para criar o D3DDevice. Desde que agora nós estamos
    // usando geometria mais complexa, nós criaremos um dispositivo com zbuffer
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
 
    // Cria o dispositivo Direct3D. 
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
        D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ){
            return E_FAIL;
    }
 
    // Desativa o culling, então nós vemos a frente a traseira do triângulo
    g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
 
    // Desativa iluminação D3D
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
 
    // Ativa o zbuffer
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
 
    return S_OK;
}
 
// cria as texturas e os buffers de vértices
HRESULT InitGeometry(){
 
    // Usa D3DX para criar uma textura de uma imagem baseada em arquivo
    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"banana.bmp", &g_pTexture ) ) ){
 
        // se a textura não está na pasta atual, tente a pasta pai
        if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"..\\banana.bmp", &g_pTexture ) ) ){
            MessageBox( NULL, L"Could not find banana.bmp", L"Textures.exe", MB_OK );
            return E_FAIL;
        }
    }
 
    // Cria o buffer de vértice
    if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50 * 2 * sizeof( CUSTOMVERTEX ),
        0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) ) ){
            return E_FAIL;
    }
 
    // Preenche o buffer de vértice. Nós estamos configurando a coordenadas de textura
    // tu e tv, que vão de 0.0 para 1.0
    CUSTOMVERTEX* pVertices;
    if( FAILED( g_pVB->Lock( 0, 0, ( void** ) &pVertices, 0 ) ) )
        return E_FAIL;
    for( DWORD i = 0; i < 50; i++ ){
        FLOAT theta = (2 * D3DX_PI * i ) / (50 - 1);
 
        pVertices[ 2 * i + 0 ].position = D3DXVECTOR3( sinf(theta), -1.0f, cosf( theta ));
        pVertices[ 2 * i + 0 ].color = 0xffffffff;
#ifndef SHOW_HOW_TO_USE_TC1
        pVertices[ 2 * i + 0 ].tu = ( (FLOAT) i ) / (50 - 1);
        pVertices[ 2 * i + 0 ].tv = 1.0f;
#endif
 
        pVertices[ 2 * i + 1 ].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf( theta ));
        pVertices[ 2 * i + 1 ].color = 0xff808080;
#ifndef SHOW_HOW_TO_USE_TC1
        pVertices[ 2 * i + 1 ].tu = ( (FLOAT) i ) / (50 - 1);
        pVertices[ 2 * i + 1 ].tv = 0.0f;
#endif
    }    
 
    g_pVB->Unlock();
 
    return S_OK;
}
 
// Libera todos os objetos inicializados anteriormente
VOID Cleanup(){
    if( g_pTexture != NULL )
        g_pTexture->Release();
 
    if( g_pVB != NULL )
        g_pVB->Release();
 
    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();
 
    if( g_pD3D != NULL )
        g_pD3D->Release();
}
 
// Configura as matriz de transformação de projeção, visão e de mundo
VOID SetupMatrices(){
    // Configura a matriz do mundo
    D3DXMATRIXA16 matWorld;
    D3DXMatrixIdentity( &matWorld );
    D3DXMatrixRotationX( &matWorld, timeGetTime() / 500.0f );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
 
    // Configure nossa matriz de visualização. Uma matriz de visualização pode ser definida
    // dado uma posição do olho, um ponto para o qual olhar, e uma direção a qual aponta
    // para cima. Aqui nós configuramos o olho cinco unidades atrás do  eixo z e para cima 
    // três unidades, olhar na origem, e definimos que "para cima" está na direção do eixo y
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f, -5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
 
    // para a matriz de projeção, nós configuramos uma transformação perspectiva (que transforma
    // geometria do espaço de visão 3D para o espaço de porto de visão (viewport) 2D, com uma
    // divisão perspectiva fazendo objetos menores à distância). Para construir uma transformação
    // perspectiva, nós precisamos do campo de visão (1/4 de pi é comum), a taxa de aspecto, e os
    // planos de recorte near e far (que definem a qual distância as geometrias não deveriam mais
    // ser renderizadas).
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
 
// Desenha a cena
VOID Render(){
    // limpa o buffer de trás e o zbuffer
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
        D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );
 
    // Inicia a cena
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // Configura as matrizes de projeção, mundo e visão
        SetupMatrices();
 
        // Configure nossa textura. Usando texturas introduz o estados de estágios de textura,
        // que governam como texturas são misturadas juntas (no caso de múltiplas texturas) e
        // informação de iluminação. Neste caso, nós estamos modulando (misturando) nossa
        // textura com a cor difusa dos vértices.
        g_pd3dDevice->SetTexture( 0, g_pTexture );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
 
#ifdef SHOW_HOW_TO_USE_TC1
        // muito texto para traduzir, Fica para uma próxima :)
 
        D3DXMATRIXA16 mTextureTransform;
        D3DXMATRIXA16 mProj;
        D3DXMATRIXA16 mTrans;
        D3DXMATRIXA16 mScale;
 
        g_pd3dDevice->GetTransform( D3DTS_PROJECTION, &mProj );
        D3DXMatrixTranslation( &mTrans, 0.5f, 0.5f, 0.0f );
        D3DXMatrixScaling( &mScale, 0.5f, -0.5f, 1.0f );
        mTextureTransform = mProj * mScale * mTrans;
 
        g_pd3dDevice->SetTransform( D3DTS_TEXTURE0, &mTextureTransform );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED );
        g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION );
#endif
 
        g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
        g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
        g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50 - 2 );
 
        // termina a cena
        g_pd3dDevice->EndScene();
    }
 
    // Apresenta os conteúdos do buffer de trás para a exibição
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
 
// o tratador de mensagem da janela
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){
    switch( msg ){
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
    }
 
    return DefWindowProc( hWnd, msg, wParam, lParam );
}
 
// o ponto de entrada da aplicação
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE prevInstance, LPSTR CmdLine, INT nShowCmd ){
    // Registra a classe da janela
    WNDCLASSEX wc = {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
        L"Direct3D Tutorial", NULL 
    };
 
    RegisterClassEx( &wc );
 
    // Cria a janela da aplicação
    HWND hWnd = CreateWindow( L"Direct3D Tutorial", L"Direct3D Tutorial 05: Textures",
        WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
        NULL, NULL, wc.hInstance, NULL );
 
    // Inicializa Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) ){
 
        // Cria o buffer de vértice
        if( SUCCEEDED( InitGeometry() ) ){
            // Mostre a janela
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );
 
            // Entre no loop de mensagem
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT ){
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ){
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                } else{
                    Render();
                }
            }
        }
    }
 
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

Tutorial 6 DX9 - DXSDK - Malhas

// Este arquivo contém uma aplicação Win32 que cria uma janela e
// um D3D9 Device 
 
//#include <cstdio>
#include <d3dx9.h>
#include <strsafe.h>
#include <windows.h>
#include <mmsystem.h>
 
//#pragma warning( disable : 4996 ) // disable deprecated warnings
 
LPDIRECT3D9        g_pD3D = NULL;    // Usada para criar o D3DDevice
LPDIRECT3DDEVICE9    g_pd3dDevice = NULL; // Nosso dispositivo de renderização
 
LPD3DXMESH g_pMesh = NULL;    // Nosso objeto malha no sistema
D3DMATERIAL9*    g_pMeshMaterials = NULL;    // Materiais para nossa malha
LPDIRECT3DTEXTURE9* g_pMeshTextures = NULL;    // Texturas para nossa malha
DWORD g_dwNumMaterials = 0L;    // Número de materiais da malha
 
// Inicializa Direct3D
HRESULT InitD3D( HWND hWnd ){
    // cria o objeto D3D
    if( NULL == (g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;
 
    // Configura a estrutura usada para criar o D3DDevice. Desde que agora nós estamos
    // usando geometria mais complexa, nós criaremos um dispositivo com zbuffer
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
 
    // Cria o dispositivo Direct3D. 
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
        D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ){
            return E_FAIL;
    }
 
    // Desativa o culling, então nós vemos a frente a traseira do triângulo
    g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );
 
    // Ativa o zbuffer
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
 
    return S_OK;
}
 
// cria as texturas e os buffers de vértices
HRESULT InitGeometry(){
 
    LPD3DXBUFFER pD3DMtrlBuffer;
 
    // Carrega a malha do arquivo especificado
    if( FAILED( D3DXLoadMeshFromX( L"Tiger.x", D3DXMESH_SYSTEMMEM, g_pd3dDevice,
        NULL, &pD3DMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh) ) ){
 
        // se a textura não está na pasta atual, tente a pasta pai
        if( FAILED( D3DXLoadMeshFromX( L"..\\Tiger.x", D3DXMESH_SYSTEMMEM, g_pd3dDevice,
        NULL, &pD3DMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh) ) ){
            MessageBox( NULL, L"Could not find tiger.x", L"Meshes.exe", MB_OK );
            return E_FAIL;
        }
    }
 
    // Nós precisamos extrair as propriedades do material e os nomes de textura
    // do pD3DMtrlBuffer
    D3DXMATERIAL *d3dxMaterials = (D3DXMATERIAL*) pD3DMtrlBuffer->GetBufferPointer();
    g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials];
 
    if( g_pMeshMaterials == NULL )
        return E_OUTOFMEMORY;
    g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];
    if( g_pMeshTextures == NULL )
        return E_OUTOFMEMORY;
 
    for( DWORD i = 0; i < g_dwNumMaterials; i++ ){
        // Copie o material
        g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
 
        // Configure a cor ambiente para o material (D3DX não faz isso)
        g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;
 
        g_pMeshTextures[i] = NULL;
        if( d3dxMaterials[i].pTextureFilename != NULL &&
            lstrlenA(d3dxMaterials[i].pTextureFilename ) > 0 ){
                // Crie a textura
                if( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice, d3dxMaterials[i].pTextureFilename,
                    &g_pMeshTextures[i] ) ) ){
                        // se a textura não está na pasta atual, tente a pasta pai
                        const CHAR* strPrefix = "..\\";
                        CHAR strTexture[MAX_PATH];
                        strcpy_s( strTexture, MAX_PATH, strPrefix );
                        strcat_s( strTexture, MAX_PATH, d3dxMaterials[i].pTextureFilename );
 
                        // se a textura não está na pasta atual, tente a pasta pai
                        if( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice, strTexture,
                            &g_pMeshTextures[i] ) ) ){
                                MessageBox( NULL, L"Could not find texture map", L"Meshes.exe", MB_OK );
                        }
                }
        }
    }
 
    // Pronto com o buffer material
    pD3DMtrlBuffer->Release();
 
    return S_OK;
}
 
// Libera todos os objetos inicializados anteriormente
VOID Cleanup(){
    if( g_pMeshMaterials != NULL )
        delete [] g_pMeshMaterials;
 
    if( g_pMeshTextures != NULL )
    {
        for( DWORD i = 0; i < g_dwNumMaterials; i++ ){
            if( g_pMeshTextures[i] )
                g_pMeshTextures[i]->Release();
        }
        delete[] g_pMeshTextures;
    }
 
    if( g_pMesh != NULL )
        g_pMesh->Release();
 
    if( g_pd3dDevice != NULL )
        g_pd3dDevice->Release();
 
    if( g_pD3D != NULL )
        g_pD3D->Release();
}
 
// Configura as matriz de transformação de projeção, visão e de mundo
VOID SetupMatrices(){
    // Configura a matriz do mundo
    D3DXMATRIXA16 matWorld;
    D3DXMatrixRotationY( &matWorld, timeGetTime() / 1000.0f );
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
 
    // Configure nossa matriz de visualização. Uma matriz de visualização pode ser definida
    // dado uma posição do olho, um ponto para o qual olhar, e uma direção a qual aponta
    // para cima. Aqui nós configuramos o olho cinco unidades atrás do  eixo z e para cima 
    // três unidades, olhar na origem, e definimos que "para cima" está na direção do eixo y
    D3DXVECTOR3 vEyePt( 0.0f, 3.0f, -5.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
 
    // para a matriz de projeção, nós configuramos uma transformação perspectiva (que transforma
    // geometria do espaço de visão 3D para o espaço de porto de visão (viewport) 2D, com uma
    // divisão perspectiva fazendo objetos menores à distância). Para construir uma transformação
    // perspectiva, nós precisamos do campo de visão (1/4 de pi é comum), a taxa de aspecto, e os
    // planos de recorte near e far (que definem a qual distância as geometrias não deveriam mais
    // ser renderizadas).
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
 
// Desenha a cena
VOID Render(){
    // limpa o buffer de trás e o zbuffer
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
        D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 );
 
    // Inicia a cena
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        // Configura as matrizes de projeção, mundo e visão
        SetupMatrices();
 
        // Malhas são sundivididas em subconjuntos, um para cada material. 
        // Renderize elas em um loop
        for( DWORD i = 0; i < g_dwNumMaterials; i++ ){
            // Configure o material e a textura para este subconjunto
            g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
            g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
 
            // Desenha o subconjunto da malha
            g_pMesh->DrawSubset( i );
        }
 
        // termina a cena
        g_pd3dDevice->EndScene();
    }
 
    // Apresenta os conteúdos do buffer de trás para a exibição
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
 
// o tratador de mensagem da janela
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){
    switch( msg ){
        case WM_DESTROY:
            Cleanup();
            PostQuitMessage( 0 );
            return 0;
    }
 
    return DefWindowProc( hWnd, msg, wParam, lParam );
}
 
// o ponto de entrada da aplicação
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE prevInstance, LPSTR CmdLine, INT nShowCmd ){
    // Registra a classe da janela
    WNDCLASSEX wc = {
        sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
        L"Direct3D Tutorial", NULL 
    };
 
    RegisterClassEx( &wc );
 
    // Cria a janela da aplicação
    HWND hWnd = CreateWindow( L"Direct3D Tutorial", L"Direct3D Tutorial 06: Meshes",
        WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
        NULL, NULL, wc.hInstance, NULL );
 
    // Inicializa Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) ){
 
        // Cria o buffer de vértice
        if( SUCCEEDED( InitGeometry() ) ){
            // Mostre a janela
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );
 
            // Entre no loop de mensagem
            MSG msg;
            ZeroMemory( &msg, sizeof( msg ) );
            while( msg.message != WM_QUIT ){
                if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ){
                    TranslateMessage( &msg );
                    DispatchMessage( &msg );
                } else{
                    Render();
                }
            }
        }
    }
 
    UnregisterClass( L"D3D Tutorial", wc.hInstance );
    return 0;
}

Como configurar o DX9 Para funcionar com o WxWidgets

É Só seguir o mesmo raciocínio que o dos exemplos mostrados acima. Basta para isso chamar o método GetHWND da instância de WxFrame (eu não testei se funciona nos outros controles) e fazer um cast para HWND. O código abaixo mostra uma seqüência para criar a janela WxWidgets com suporte a DX 9:

TesteWxWidgetsFrame* frame = new TesteWxWidgetsFrame(0L, _("wxWidgets Application Template"));
    frame->SetIcon(wxICON(aaaa)); // To Set App Icon
    HWND hWnd = (HWND) frame->GetHWND();
    HRESULT res = setupDirectX( hWnd );
 
    if( res != S_OK ) {
        Cleanup();
        frame->Destroy();
        exit(-1);
    }
 
    frame->Show();
 
    return true;

Para mostra o render na janela é só adicionar um paintEvent e não se esquecer da linha de criação do wxPaintDC. Caso esta linha seja esquecida a tua aplicação irá dar um erro no deixar sair, ficando travada ou simplesmente dará um crash nela.

void TesteWxWidgetsFrame::OnPaint(wxPaintEvent& event){
    wxPaintDC dc( this );
    Render();
}

Para baixar o exemplo apenas clique no link que se segue TesteWxWidgets.zip. Ele é um projeto que fiz no CodeBlocks. Você terá que alterar o local onde estão os arquivos do DirectX e do WxWidgets para refletir a sua instalação

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.