Exemplos Dx10

Esta página contém diversos exemplos DirectX10. Eles foram tirados de um tutorial de iniciante em DirectX10 da Microsoft, porém os comentários foram traduzidos para o português.

Obs: Há alguns erros na tradução e em alguns lugares talvez eu tenha esquecido de traduzir
Obs2: O código funciona desde que as dependências tenham sido postas nos seus devidos lugares. Eu me certifiquei disso por iniciar um projeto vazio para o primeiro tutorial e reusar tal projeto para os tutoriais subsequentes, cuidando para que o código fosse executado corretamente. Futuramente vou colocar um link apontando para os arquivos de projeto nesta página
Obs3: Futuramente colocarei estes tutoriais em páginas separadas e explicarei alguns detalhes deles. Até lá veja a explicação nos arquivos de ajuda do DirectX.

Tutorial 00 - DXSDK - Criando uma Janela Win32

Este tutorial básico ensino a criar uma janela Win32 o que é o básico para ser exibido na tela. Em cima de tal janela que o DirectX funcionará em tutoriais posteriores.

// Este tutorial configura uma aplicação Windows com uma janela e um 
// procedimento para verificar as mensagens do sistema
 
#include <windows.h>
 
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
 
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
    if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
        return 0;
 
    // Loop principal de mensagens
    MSG msg = {0};
    while( GetMessage( &msg, NULL, 0, 0 ) ){
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
 
    return (int) msg.wParam;
}
 
// Registra classe e cria janela
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ){
    // Registra a classe
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof( WNDCLASSEX );
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    //wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIcon = NULL;
    wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"TutorialWindowClass";
    //wcex.hIconSm = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIconSm = NULL;
 
    if( !RegisterClassEx( &wcex ) )
        return E_FAIL;
 
    // Cria a janela
    g_hInst = hInstance;
    RECT rc = { 0, 0, 640, 480 };
    AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
    g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 10 Tutorial 0: Configurando uma Janela",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
        NULL, NULL, hInstance, NULL );
 
    if( !g_hWnd )
        return E_FAIL;
 
    ShowWindow( g_hWnd, nCmdShow );
 
    return S_OK;
}
 
// Chamado toda vez que a aplicação recebe uma mensagem
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){
    PAINTSTRUCT ps;
    HDC hdc;
 
    switch( message ){
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            EndPaint( hWnd, &ps );
            break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;
 
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }
 
    return 0;
}

Tutorial 01 - DXSDK - Básicos do D3D 10

Este tutorial demonstra como anexar um dispositivo D3D10 à janela

// Esta aplicação demonstra como criar um dispositivo Direct3D10
 
#include <windows.h>
#include <d3d10.h>
#include <d3dx10.h>
 
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
D3D10_DRIVER_TYPE g_driverType = D3D10_DRIVER_TYPE_NULL;
ID3D10Device*    g_pd3dDevice = NULL;
IDXGISwapChain*    g_pSwapChain = NULL;
ID3D10RenderTargetView*    g_pRenderTargetView = NULL;
 
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
    if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
        return 0;
 
    if( FAILED( InitDevice() ) ){
        CleanupDevice();
        return 0;
    }
 
    // Loop principal de mensagens
    MSG msg = {0};
    while( WM_QUIT != msg.message ){
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ){
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        } else {
            Render();
        }
    }
 
    return (int) msg.wParam;
}
 
// Registra classe e cria janela
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ){
    // Registra a classe
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof( WNDCLASSEX );
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    //wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIcon = NULL;
    wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"TutorialWindowClass";
    //wcex.hIconSm = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIconSm = NULL;
 
    if( !RegisterClassEx( &wcex ) )
        return E_FAIL;
 
    // Cria a janela
    g_hInst = hInstance;
    RECT rc = { 0, 0, 640, 480 };
    AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
    g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 10 Tutorial 1: Básicos do Direct3D 10",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
        NULL, NULL, hInstance, NULL );
 
    if( !g_hWnd )
        return E_FAIL;
 
    ShowWindow( g_hWnd, nCmdShow );
 
    return S_OK;
}
 
// Chamado toda vez que a aplicação recebe uma mensagem
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){
    PAINTSTRUCT ps;
    HDC hdc;
 
    switch( message ){
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            EndPaint( hWnd, &ps );
            break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;
 
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }
 
    return 0;
}
 
// Cria o dispositivo Direct3D e a cadeia de troca
HRESULT InitDevice(){
    HRESULT hr = S_OK;
 
    RECT rc;
    GetClientRect( g_hWnd, &rc );
    UINT width = rc.right - rc.left;
    UINT height = rc.bottom - rc.top;
 
    UINT createDeviceFlags = 0;
 
#ifdef _DEBUG
    createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
 
    D3D10_DRIVER_TYPE driverTypes[] = {
        D3D10_DRIVER_TYPE_HARDWARE,
        D3D10_DRIVER_TYPE_REFERENCE
    };
 
    UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory( &sd, sizeof( sd ) );
    sd.BufferCount = 1;
    sd.BufferDesc.Width = width;
    sd.BufferDesc.Height = height;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Numerator = 1;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = g_hWnd;
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;
 
    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ){
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D10CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags,
            D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice );
 
        if( SUCCEEDED( hr ) )
            break;
    }
 
    if( FAILED( hr ) )
        return hr;
 
    // cria uma visão de renderização alvo (Render Target)
    ID3D10Texture2D* pBackBuffer;
    hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID *) &pBackBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
    pBackBuffer->Release();
 
    if( FAILED( hr ) )
        return hr;
 
    g_pd3dDevice->OMSetRenderTargets( 1, & g_pRenderTargetView, NULL );
 
    // Configure o viewport
    D3D10_VIEWPORT vp;
    vp.Width = width;
    vp.Height = height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = vp.TopLeftY = 0;
    g_pd3dDevice->RSSetViewports( 1, &vp );
 
    return S_OK;
}
 
// Renderiza o quadro
void Render(){
    // Apenas limpe o buffer de trás
    float ClearColor[4] = {0.0f, 0.125f, 0.3f, 1.0f};
    g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
    g_pSwapChain->Present(0,0);
}
 
// Limpa os objetos que nós criamos
void CleanupDevice(){
    if( g_pd3dDevice ) g_pd3dDevice->Release();
 
    if( g_pRenderTargetView ) g_pRenderTargetView->Release();
    if( g_pSwapChain ) g_pSwapChain->Release();
    if( g_pd3dDevice ) g_pd3dDevice->Release();
}

Tutorial 02 - DXSDK - Renderizando um triângulo

Este tutorial demonstra como renderizar um triângulo na tela.

// Esta aplicação exibe um triângulo usando Direct3D10
 
#include <windows.h>
#include <d3d10.h>
#include <d3dx10.h>
 
struct SimpleVertex{
    D3DXVECTOR3 Pos;
};
 
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
D3D10_DRIVER_TYPE g_driverType = D3D10_DRIVER_TYPE_NULL;
ID3D10Device*    g_pd3dDevice = NULL;
IDXGISwapChain*    g_pSwapChain = NULL;
ID3D10RenderTargetView*    g_pRenderTargetView = NULL;
ID3D10Effect*    g_pEffect = NULL;
ID3D10EffectTechnique*    g_pTechnique = NULL;
ID3D10InputLayout*    g_pVertexLayout = NULL;
ID3D10Buffer*    g_pVertexBuffer = NULL;
 
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
    if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
        return 0;
 
    if( FAILED( InitDevice() ) ){
        CleanupDevice();
        return 0;
    }
 
    // Loop principal de mensagens
    MSG msg = {0};
    while( WM_QUIT != msg.message ){
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ){
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        } else {
            Render();
        }
    }
 
    return (int) msg.wParam;
}
 
// Registra classe e cria janela
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ){
    // Registra a classe
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof( WNDCLASSEX );
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    //wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIcon = NULL;
    wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"TutorialWindowClass";
    //wcex.hIconSm = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIconSm = NULL;
 
    if( !RegisterClassEx( &wcex ) )
        return E_FAIL;
 
    // Cria a janela
    g_hInst = hInstance;
    RECT rc = { 0, 0, 640, 480 };
    AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
    g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 10 Tutorial 2: Renderizando um triângulo",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
        NULL, NULL, hInstance, NULL );
 
    if( !g_hWnd )
        return E_FAIL;
 
    ShowWindow( g_hWnd, nCmdShow );
 
    return S_OK;
}
 
// Chamado toda vez que a aplicação recebe uma mensagem
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){
    PAINTSTRUCT ps;
    HDC hdc;
 
    switch( message ){
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            EndPaint( hWnd, &ps );
            break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;
 
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }
 
    return 0;
}
 
// Cria o dispositivo Direct3D e a cadeia de troca
HRESULT InitDevice(){
    HRESULT hr = S_OK;
 
    RECT rc;
    GetClientRect( g_hWnd, &rc );
    UINT width = rc.right - rc.left;
    UINT height = rc.bottom - rc.top;
 
    UINT createDeviceFlags = 0;
 
#ifdef _DEBUG
    createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
 
    D3D10_DRIVER_TYPE driverTypes[] = {
        D3D10_DRIVER_TYPE_HARDWARE,
        D3D10_DRIVER_TYPE_REFERENCE
    };
 
    UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory( &sd, sizeof( sd ) );
    sd.BufferCount = 1;
    sd.BufferDesc.Width = width;
    sd.BufferDesc.Height = height;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Numerator = 1;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = g_hWnd;
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;
 
    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ){
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D10CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags,
            D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice );
 
        if( SUCCEEDED( hr ) )
            break;
    }
 
    if( FAILED( hr ) )
        return hr;
 
    // cria uma visão de renderização alvo (Render Target)
    ID3D10Texture2D* pBackBuffer;
    hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID *) &pBackBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
    pBackBuffer->Release();
 
    if( FAILED( hr ) )
        return hr;
 
    g_pd3dDevice->OMSetRenderTargets( 1, & g_pRenderTargetView, NULL );
 
    // Configure o viewport
    D3D10_VIEWPORT vp;
    vp.Width = width;
    vp.Height = height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = vp.TopLeftY = 0;
    g_pd3dDevice->RSSetViewports( 1, &vp );
 
    //Crie o efeito
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Configure a opção D3D10_SHADER_DEBUG para embutir informação de debug nos shaders.
    // Configurar esta opção melhora a debugação do shader, mas ainda permite aos
    // shaders serem otimizados e executarem da maneira que eles executarão na 
    // configuração release deste programa
    dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif
 
    hr = D3DX10CreateEffectFromFile( L"..\\Tutorial02.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0,
        g_pd3dDevice, NULL, NULL, &g_pEffect, NULL, NULL );
 
    if( FAILED( hr ) ){
        MessageBox( g_hWnd, L"O arquivo fx não pôde ser localizado. Por favor execute este executável do diretório que contém o arquivo FX", 
            L"Erro", MB_OK );
 
        return hr;
    }
 
    // Obtenha a técnica
    g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
 
    // Defina o leiaute de entrada
    D3D10_INPUT_ELEMENT_DESC layout[] = {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Crie o leiaute de entrada
    D3D10_PASS_DESC PassDesc;
    g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    hr = g_pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
        PassDesc.IAInputSignatureSize, &g_pVertexLayout );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o leiaute de entrada
    g_pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Crie o buffer de vértice
    SimpleVertex vertices[] = {
        D3DXVECTOR3( 0.0f, 0.5f, 0.5f ),
        D3DXVECTOR3( 0.5f, -0.5f, 0.5f ),
        D3DXVECTOR3( -0.5f, -0.5f, 0.5f )
    };
    D3D10_BUFFER_DESC bd;
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * 3;
    bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = vertices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o buffer de vértice
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    g_pd3dDevice->IASetVertexBuffers( 0,1, &g_pVertexBuffer, &stride, &offset );
 
    // Configure a topologia primitiva
    g_pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
 
    return S_OK;
}
 
// Renderiza o quadro
void Render(){
    // Limpe o buffer de trás
    float ClearColor[4] = {0.0f, 0.125f, 0.3f, 1.0f};    // vermelho, verde, azul, alfa
    g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
 
    // Renderize um triângulo
    D3D10_TECHNIQUE_DESC techDesc;
    g_pTechnique->GetDesc( &techDesc );
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        g_pTechnique->GetPassByIndex( p )->Apply( 0 );
        g_pd3dDevice->Draw( 3, 0 );
    }
 
    // Apresenta a informação renderizada no buffer de trás para o buffer da frente (a tela)
    g_pSwapChain->Present(0,0);
}
 
// Limpa os objetos que nós criamos
void CleanupDevice(){
    if( g_pd3dDevice ) g_pd3dDevice->ClearState();
 
    if( g_pVertexBuffer ) g_pVertexBuffer->Release();
    if( g_pVertexLayout ) g_pVertexLayout->Release();
    if( g_pEffect ) g_pEffect->Release();
    if( g_pRenderTargetView ) g_pRenderTargetView->Release();
    if( g_pSwapChain ) g_pSwapChain->Release();
    if( g_pd3dDevice ) g_pd3dDevice->Release();
}

Tutorial 03 - DXSDK - Shaders e sistema de efeito

Este tutorial usa o mesmo código que o exemplo anterior. A mudança está na documentação do DXSDK que explica ao invés do código DirectX que renderiza o triângulo, o código do arquivo de efeito usado. O arquivo de efeito é uma maneira simples e compacta de usar shaders. Apesar de vital importância ele não vai ser explicado aqui. Numa outra oportunidade será colocado sua explicação, provavelmente na seção de shaders e quando isto acontecer esta seção será atualizada para apontar para ele. Neste tempo o que será colocado aqui é o arquivo de efeito apenas para vocês terem uma idéia de como ele é formado.

//--------------------------------------------------------------------------------------
// File: Tutorial02.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
float4 VS( float4 Pos : POSITION ) : SV_POSITION
{
    return Pos;
}
 
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( float4 Pos : SV_POSITION ) : SV_Target
{
    return float4( 1.0f, 1.0f, 0.0f, 1.0f );    // Yellow, with Alpha = 1
}
 
//--------------------------------------------------------------------------------------
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}

Tutorial 04 - DXSDK - Renderizando um cubo

Neste tutorial ao invés de um triângulo são renderizados vários triângulos, formando um cubo. Este cubo fica girando através do eixo Y. O propósito do tutorial é introduzir os espaços 3D (Objeto, Mundo, Olho, Espaço de Recorte de coordenadas da tela).

// Esta aplicação exibe um cubo 3D usando Direct3D10
 
#include <windows.h>
#include <d3d10.h>
#include <d3dx10.h>
 
struct SimpleVertex{
    D3DXVECTOR3 Pos;
    D3DXVECTOR4 Color;
};
 
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
D3D10_DRIVER_TYPE g_driverType = D3D10_DRIVER_TYPE_NULL;
ID3D10Device*    g_pd3dDevice = NULL;
IDXGISwapChain*    g_pSwapChain = NULL;
ID3D10RenderTargetView*    g_pRenderTargetView = NULL;
ID3D10Effect*    g_pEffect = NULL;
ID3D10EffectTechnique*    g_pTechnique = NULL;
ID3D10InputLayout*    g_pVertexLayout = NULL;
ID3D10Buffer*    g_pVertexBuffer = NULL;
ID3D10Buffer*    g_pIndexBuffer = NULL;
ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
D3DXMATRIX    g_World;
D3DXMATRIX    g_View;
D3DXMATRIX    g_Projection;
 
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
    if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
        return 0;
 
    if( FAILED( InitDevice() ) ){
        CleanupDevice();
        return 0;
    }
 
    // Loop principal de mensagens
    MSG msg = {0};
    while( WM_QUIT != msg.message ){
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ){
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        } else {
            Render();
        }
    }
 
    return (int) msg.wParam;
}
 
// Registra classe e cria janela
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ){
    // Registra a classe
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof( WNDCLASSEX );
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    //wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIcon = NULL;
    wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"TutorialWindowClass";
    //wcex.hIconSm = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIconSm = NULL;
 
    if( !RegisterClassEx( &wcex ) )
        return E_FAIL;
 
    // Cria a janela
    g_hInst = hInstance;
    RECT rc = { 0, 0, 640, 480 };
    AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
    g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 10 Tutorial 4: Espaços 3D",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
        NULL, NULL, hInstance, NULL );
 
    if( !g_hWnd )
        return E_FAIL;
 
    ShowWindow( g_hWnd, nCmdShow );
 
    return S_OK;
}
 
// Chamado toda vez que a aplicação recebe uma mensagem
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){
    PAINTSTRUCT ps;
    HDC hdc;
 
    switch( message ){
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            EndPaint( hWnd, &ps );    
            break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;
 
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }
 
    return 0;
}
 
// Cria o dispositivo Direct3D e a cadeia de troca
HRESULT InitDevice(){
    HRESULT hr = S_OK;
 
    RECT rc;
    GetClientRect( g_hWnd, &rc );
    UINT width = rc.right - rc.left;
    UINT height = rc.bottom - rc.top;
 
    UINT createDeviceFlags = 0;
 
#ifdef _DEBUG
    createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
 
    D3D10_DRIVER_TYPE driverTypes[] = {
        D3D10_DRIVER_TYPE_HARDWARE,
        D3D10_DRIVER_TYPE_REFERENCE
    };
 
    UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory( &sd, sizeof( sd ) );
    sd.BufferCount = 1;
    sd.BufferDesc.Width = width;
    sd.BufferDesc.Height = height;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = g_hWnd;
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;
 
    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ){
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D10CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags,
            D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice );
 
        if( SUCCEEDED( hr ) )
            break;
    }
 
    if( FAILED( hr ) )
        return hr;
 
    // cria uma visão de renderização alvo (Render Target)
    ID3D10Texture2D* pBackBuffer;
    hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID *) &pBackBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
    pBackBuffer->Release();
 
    if( FAILED( hr ) )
        return hr;
 
    g_pd3dDevice->OMSetRenderTargets( 1, & g_pRenderTargetView, NULL );
 
    // Configure o viewport
    D3D10_VIEWPORT vp;
    vp.Width = width;
    vp.Height = height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = vp.TopLeftY = 0;
    g_pd3dDevice->RSSetViewports( 1, &vp );
 
    //Crie o efeito
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Configure a opção D3D10_SHADER_DEBUG para embutir informação de debug nos shaders.
    // Configurar esta opção melhora a debugação do shader, mas ainda permite aos
    // shaders serem otimizados e executarem da maneira que eles executarão na 
    // configuração release deste programa
    dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif
 
    hr = D3DX10CreateEffectFromFile( L"..\\Tutorial04.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0,
        g_pd3dDevice, NULL, NULL, &g_pEffect, NULL, NULL );
 
    if( FAILED( hr ) ){
        MessageBox( g_hWnd, L"O arquivo fx não pôde ser localizado. Por favor execute este executável do diretório que contém o arquivo FX", 
            L"Erro", MB_OK );
 
        return hr;
    }
 
    // Obtem a técnica
    g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
 
    // Obtém as variáveis
    g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
    g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
    g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
 
    // Defina o leiaute de entrada
    D3D10_INPUT_ELEMENT_DESC layout[] = {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Cria o leiaute de entrada
    D3D10_PASS_DESC PassDesc;
    g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    hr = g_pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
        PassDesc.IAInputSignatureSize, &g_pVertexLayout );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o leiaute de entrada
    g_pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Crie o buffer de vértice
    SimpleVertex vertices[] = {
        { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 1.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 0.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 0.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 1.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 0.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f ) },
    };
    D3D10_BUFFER_DESC bd;
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * 8;
    bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = vertices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o buffer de vértice
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    g_pd3dDevice->IASetVertexBuffers( 0,1, &g_pVertexBuffer, &stride, &offset );
 
    // Cria o buffer de índice
    DWORD indices[] = {
        3,1,0,
        2,1,3,
 
        0,5,4,
        1,5,0,
 
        3,4,7,
        0,4,3,
 
        1,6,5,
        2,6,1,
 
        2,7,6,
        3,7,2,
 
        6,4,5,
        7,4,6,
    };
 
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( DWORD ) * 36;    // 36 vértices necessários para 12 triângulos em uma lista de triângulos
    bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
    bd.CPUAccessFlags = bd.MiscFlags = 0;
    InitData.pSysMem = indices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
    if( FAILED( hr ) )
        return hr;
 
    // Configura o buffer de índice
    g_pd3dDevice->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
 
    // Configure a topologia primitiva
    g_pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
 
    // Inicialize a matriz do mundo
    D3DXVECTOR3 Eye( 0.0f, 1.0f, -5.0f );
    D3DXVECTOR3 At( 0.0f, 1.0f, 0.0f );
    D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &g_View, &Eye, &At, &Up );
 
    // Inicializa a matriz de projeção
    D3DXMatrixPerspectiveFovLH( &g_Projection, (float) D3DX_PI * 0.5f, width / (FLOAT) height, 0.1f, 100.0f );
 
    return S_OK;
}
 
// Renderiza o quadro
void Render(){
    // Atualize nosso tempo
    static float t = 0.0f;
    if( g_driverType == D3D10_DRIVER_TYPE_REFERENCE ){
        t += (float) D3DX_PI * 0.0125f;
    } else {
        static DWORD dwTimeStart = 0;
        DWORD dwTimeCur = GetTickCount();
        if( dwTimeStart == 0 )
            dwTimeStart = dwTimeCur;
        t = ( dwTimeCur - dwTimeStart ) / 1000.0f;
    }
 
    // Anime o cubo
    D3DXMatrixRotationY( &g_World, t );
 
    // Limpe o buffer de trás
    float ClearColor[4] = {0.0f, 0.125f, 0.3f, 1.0f};    // vermelho, verde, azul, alfa
    g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
 
    // Atualize as variáveis
    g_pWorldVariable->SetMatrix( (float* )&g_World );
    g_pViewVariable->SetMatrix( (float* )&g_View );
    g_pProjectionVariable->SetMatrix( (float* )&g_Projection );
 
    // Renderize um triângulo
    D3D10_TECHNIQUE_DESC techDesc;    
    g_pTechnique->GetDesc( &techDesc );
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        g_pTechnique->GetPassByIndex( p )->Apply( 0 );
        g_pd3dDevice->DrawIndexed( 36, 0, 0 );    // 36 vértices necessários para 12 triângulos em uma lista de triângulos
    }
 
    // Apresenta a informação renderizada no buffer de trás para o buffer da frente (a tela)
    g_pSwapChain->Present(0,0);
}
 
// Limpa os objetos que nós criamos
void CleanupDevice(){
    if( g_pd3dDevice ) g_pd3dDevice->ClearState();
 
    if( g_pVertexBuffer ) g_pVertexBuffer->Release();
    if( g_pIndexBuffer ) g_pIndexBuffer->Release();
    if( g_pVertexLayout ) g_pVertexLayout->Release();
    if( g_pEffect ) g_pEffect->Release();
    if( g_pRenderTargetView ) g_pRenderTargetView->Release();
    if( g_pSwapChain ) g_pSwapChain->Release();
    if( g_pd3dDevice ) g_pd3dDevice->Release();
}

O shader que ele faz uso é o seguinte:

//--------------------------------------------------------------------------------------
// File: Tutorial04.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
matrix World;
matrix View;
matrix Projection;
 
//--------------------------------------------------------------------------------------
struct VS_OUTPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR0;
};
 
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VS( float4 Pos : POSITION, float4 Color : COLOR )
{
    VS_OUTPUT output = (VS_OUTPUT)0;
    output.Pos = mul( Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Color = Color;
    return output;
}
 
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( VS_OUTPUT input ) : SV_Target
{
    return input.Color;
}
 
//--------------------------------------------------------------------------------------
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}

Tutorial 05 - DXSDK - Animando cubos

Neste tutorial ocorre a animação de dois cubos. O intuito principal dele é mostrar como usar o buffer de profundidade para que os cubos sejam desenhados apropriadamente na tela

// Esta aplicação demonstra animação usando transformações de matriz
 
#include <windows.h>
#include <d3d10.h>
#include <d3dx10.h>
 
struct SimpleVertex{
    D3DXVECTOR3 Pos;
    D3DXVECTOR4 Color;
};
 
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
D3D10_DRIVER_TYPE g_driverType = D3D10_DRIVER_TYPE_NULL;
ID3D10Device*    g_pd3dDevice = NULL;
IDXGISwapChain*    g_pSwapChain = NULL;
ID3D10RenderTargetView*    g_pRenderTargetView = NULL;
ID3D10Texture2D*    g_pDepthStencil = NULL;
ID3D10DepthStencilView*    g_pDepthStencilView = NULL;
ID3D10Effect*    g_pEffect = NULL;
ID3D10EffectTechnique*    g_pTechnique = NULL;
ID3D10InputLayout*    g_pVertexLayout = NULL;
ID3D10Buffer*    g_pVertexBuffer = NULL;
ID3D10Buffer*    g_pIndexBuffer = NULL;
ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
D3DXMATRIX    g_World1;
D3DXMATRIX    g_World2;
D3DXMATRIX    g_View;
D3DXMATRIX    g_Projection;
 
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
    if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
        return 0;
 
    if( FAILED( InitDevice() ) ){
        CleanupDevice();
        return 0;
    }
 
    // Loop principal de mensagens
    MSG msg = {0};
    while( WM_QUIT != msg.message ){
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ){
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        } else {
            Render();
        }
    }
 
    return (int) msg.wParam;
}
 
// Registra classe e cria janela
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ){
    // Registra a classe
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof( WNDCLASSEX );
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    //wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIcon = NULL;
    wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"TutorialWindowClass";
    //wcex.hIconSm = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIconSm = NULL;
 
    if( !RegisterClassEx( &wcex ) )
        return E_FAIL;
 
    // Cria a janela
    g_hInst = hInstance;
    RECT rc = { 0, 0, 640, 480 };
    AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
    g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 10 Tutorial 5",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
        NULL, NULL, hInstance, NULL );
 
    if( !g_hWnd )
        return E_FAIL;
 
    ShowWindow( g_hWnd, nCmdShow );
 
    return S_OK;
}
 
// Chamado toda vez que a aplicação recebe uma mensagem
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){
    PAINTSTRUCT ps;
    HDC hdc;
 
    switch( message ){
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            EndPaint( hWnd, &ps );    
            break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;
 
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }
 
    return 0;
}
 
// Cria o dispositivo Direct3D e a cadeia de troca
HRESULT InitDevice(){
    HRESULT hr = S_OK;
 
    RECT rc;
    GetClientRect( g_hWnd, &rc );
    UINT width = rc.right - rc.left;
    UINT height = rc.bottom - rc.top;
 
    UINT createDeviceFlags = 0;
 
#ifdef _DEBUG
    createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
 
    D3D10_DRIVER_TYPE driverTypes[] = {
        D3D10_DRIVER_TYPE_HARDWARE,
        D3D10_DRIVER_TYPE_REFERENCE
    };
 
    UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory( &sd, sizeof( sd ) );
    sd.BufferCount = 1;
    sd.BufferDesc.Width = width;
    sd.BufferDesc.Height = height;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = g_hWnd;
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;
 
    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ){
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D10CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags,
            D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice );
 
        if( SUCCEEDED( hr ) )
            break;
    }
 
    if( FAILED( hr ) )
        return hr;
 
    // cria uma visão de renderização alvo (Render Target)
    ID3D10Texture2D* pBackBuffer;
    hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID *) &pBackBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
    pBackBuffer->Release();
 
    if( FAILED( hr ) )
        return hr;
 
    // Cria textura stencil de profundidade
    D3D10_TEXTURE2D_DESC descDepth;
    descDepth.Width = width;
    descDepth.Height = height;
    descDepth.MipLevels = 1;
    descDepth.ArraySize = 1;
    descDepth.Format = DXGI_FORMAT_D32_FLOAT;
    descDepth.SampleDesc.Count = 1;
    descDepth.SampleDesc.Quality = 0;
    descDepth.Usage = D3D10_USAGE_DEFAULT;
    descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL;
    descDepth.CPUAccessFlags = descDepth.MiscFlags = 0;
    hr = g_pd3dDevice->CreateTexture2D( &descDepth, NULL, &g_pDepthStencil );
 
    if( FAILED( hr ) )
        return hr;
 
    // Cria a visão stencil de profundidade
    D3D10_DEPTH_STENCIL_VIEW_DESC descDSV;
    descDSV.Format = descDepth.Format;
    descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
    descDSV.Texture2D.MipSlice = 0;
 
    hr = g_pd3dDevice->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView );
    pBackBuffer->Release();
 
    if( FAILED( hr ) )
        return hr;
 
    g_pd3dDevice->OMSetRenderTargets( 1, & g_pRenderTargetView, g_pDepthStencilView );
 
    // Configure o viewport
    D3D10_VIEWPORT vp;
    vp.Width = width;
    vp.Height = height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = vp.TopLeftY = 0;
    g_pd3dDevice->RSSetViewports( 1, &vp );
 
    //Cria o efeito
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Configure a opção D3D10_SHADER_DEBUG para embutir informação de debug nos shaders.
    // Configurar esta opção melhora a debugação do shader, mas ainda permite aos
    // shaders serem otimizados e executarem da maneira que eles executarão na 
    // configuração release deste programa
    dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif
 
    hr = D3DX10CreateEffectFromFile( L"..\\Tutorial05.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0,
        g_pd3dDevice, NULL, NULL, &g_pEffect, NULL, NULL );
 
    if( FAILED( hr ) ){
        MessageBox( g_hWnd, L"O arquivo fx não pôde ser localizado. Por favor execute este executável do diretório que contém o arquivo FX", 
            L"Erro", MB_OK );
 
        return hr;
    }
 
    // Obtem a técnica
    g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
 
    // Obtém as variáveis
    g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
    g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
    g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
 
    // Defina o leiaute de entrada
    D3D10_INPUT_ELEMENT_DESC layout[] = {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Cria o leiaute de entrada
    D3D10_PASS_DESC PassDesc;
    g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    hr = g_pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
        PassDesc.IAInputSignatureSize, &g_pVertexLayout );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o leiaute de entrada
    g_pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Crie o buffer de vértice
    SimpleVertex vertices[] = {
        { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 1.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 0.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 0.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 1.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 0.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f ) },
    };
    D3D10_BUFFER_DESC bd;
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * 8;
    bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = vertices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o buffer de vértice
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    g_pd3dDevice->IASetVertexBuffers( 0,1, &g_pVertexBuffer, &stride, &offset );
 
    // Cria o buffer de índice
    DWORD indices[] = {
        3,1,0,
        2,1,3,
 
        0,5,4,
        1,5,0,
 
        3,4,7,
        0,4,3,
 
        1,6,5,
        2,6,1,
 
        2,7,6,
        3,7,2,
 
        6,4,5,
        7,4,6,
    };
 
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( DWORD ) * 36;    // 36 vértices necessários para 12 triângulos em uma lista de triângulos
    bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
    bd.CPUAccessFlags = bd.MiscFlags = 0;
    InitData.pSysMem = indices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
    if( FAILED( hr ) )
        return hr;
 
    // Configura o buffer de índice
    g_pd3dDevice->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
 
    // Configure a topologia primitiva
    g_pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
 
    // Inicialize a matriz do mundo
    D3DXMatrixIdentity( &g_World1 );
    D3DXMatrixIdentity( &g_World2 );
 
    // Inicialize a matriz visão
    D3DXVECTOR3 Eye( 0.0f, 1.0f, -10.0f );
    D3DXVECTOR3 At( 0.0f, 1.0f, 0.0f );
    D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &g_View, &Eye, &At, &Up );
 
    // Inicializa a matriz de projeção
    D3DXMatrixPerspectiveFovLH( &g_Projection, (float) D3DX_PI * 0.25f, width / (FLOAT) height, 0.1f, 100.0f );
 
    return TRUE;
}
 
// Renderiza um quadro
void Render(){
    // Atualize nosso tempo
    static float t = 0.0f;
    if( g_driverType == D3D10_DRIVER_TYPE_REFERENCE ){
        t += (float) D3DX_PI * 0.0125f;
    } else {
        static DWORD dwTimeStart = 0;
        DWORD dwTimeCur = GetTickCount();
        if( dwTimeStart == 0 )
            dwTimeStart = dwTimeCur;
        t = ( dwTimeCur - dwTimeStart ) / 1000.0f;
    }
 
    // Primeiro cubo: Rotacione ao redor da origem
    D3DXMatrixRotationY( &g_World1, t );
 
    // Segundo cubo: Rotacione ao redor da origem
    D3DXMATRIX mTranslate;
    D3DXMATRIX mOrbit;
    D3DXMATRIX mSpin;
    D3DXMATRIX mScale;
    D3DXMatrixRotationZ( &mSpin, -t );
    D3DXMatrixRotationY( &mOrbit, -t * 2.0f );
    D3DXMatrixTranslation( &mTranslate, -4.0f, 0.0f, 0.0f );
    D3DXMatrixScaling( &mScale, 0.3f, 0.3f, 0.3f );
 
    D3DXMatrixMultiply( &g_World2, &mScale, &mSpin );
    D3DXMatrixMultiply( &g_World2, &g_World2, &mTranslate );
    D3DXMatrixMultiply( &g_World2, &g_World2, &mOrbit );
 
    // Limpe o buffer de trás
    float ClearColor[4] = {0.0f, 0.125f, 0.3f, 1.0f};    // vermelho, verde, azul, alfa
    g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
 
    // limpe o buffer de profundidade para 1.0 (profundidade máxima)
    g_pd3dDevice->ClearDepthStencilView( g_pDepthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0 );
 
    // Atualize as variáveis para o primeiro cubo
    g_pWorldVariable->SetMatrix( (float* )&g_World1 );
    g_pViewVariable->SetMatrix( (float* )&g_View );
    g_pProjectionVariable->SetMatrix( (float* )&g_Projection );
 
    // Renderize o primeiro cubo
    D3D10_TECHNIQUE_DESC techDesc;    
    g_pTechnique->GetDesc( &techDesc );
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        g_pTechnique->GetPassByIndex( p )->Apply( 0 );
        g_pd3dDevice->DrawIndexed( 36, 0, 0 );    // 36 vértices necessários para 12 triângulos em uma lista de triângulos
    }
 
    // Atualize as variáveis para o segundo cubo
    g_pWorldVariable->SetMatrix( (float* )&g_World2 );
    g_pViewVariable->SetMatrix( (float* )&g_View );
    g_pProjectionVariable->SetMatrix( (float* )&g_Projection );
 
    // Renderize o segundo cubo
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        g_pTechnique->GetPassByIndex( p )->Apply( 0 );
        g_pd3dDevice->DrawIndexed( 36, 0, 0 );    // 36 vértices necessários para 12 triângulos em uma lista de triângulos
    }
 
    // Apresenta a informação renderizada no buffer de trás para o buffer da frente (a tela)
    g_pSwapChain->Present(0,0);
}
 
// Limpa os objetos que nós criamos
void CleanupDevice(){
    if( g_pd3dDevice ) g_pd3dDevice->ClearState();
 
    if( g_pVertexBuffer ) g_pVertexBuffer->Release();
    if( g_pIndexBuffer ) g_pIndexBuffer->Release();
    if( g_pVertexLayout ) g_pVertexLayout->Release();
    if( g_pEffect ) g_pEffect->Release();
    if( g_pRenderTargetView ) g_pRenderTargetView->Release();
    if( g_pSwapChain ) g_pSwapChain->Release();
    if( g_pd3dDevice ) g_pd3dDevice->Release();
}

Este tutorial usa o mesmo arquivo de efeito que o anterior:

//--------------------------------------------------------------------------------------
// File: Tutorial05.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
matrix World;
matrix View;
matrix Projection;
 
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
    float4 Pos : POSITION;
    float4 Color : COLOR;
};
 
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR;
};
 
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Color = input.Color;
 
    return output;
}
 
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
    return input.Color;
}
 
//--------------------------------------------------------------------------------------
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}

Tutorial 06 - DXSDK - Luzes

// Esta aplicação demonstra animação usando transformações de matriz
 
#include <windows.h>
#include <d3d10.h>
#include <d3dx10.h>
 
struct SimpleVertex{
    D3DXVECTOR3 Pos;
    D3DXVECTOR3 Normal;
};
 
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
D3D10_DRIVER_TYPE g_driverType = D3D10_DRIVER_TYPE_NULL;
ID3D10Device*    g_pd3dDevice = NULL;
IDXGISwapChain*    g_pSwapChain = NULL;
ID3D10RenderTargetView*    g_pRenderTargetView = NULL;
ID3D10Texture2D*    g_pDepthStencil = NULL;
ID3D10DepthStencilView*    g_pDepthStencilView = NULL;
ID3D10Effect*    g_pEffect = NULL;
ID3D10EffectTechnique*    g_pTechniqueRender = NULL;
ID3D10EffectTechnique*    g_pTechniqueRenderLight = NULL;
ID3D10InputLayout*    g_pVertexLayout = NULL;
ID3D10Buffer*    g_pVertexBuffer = NULL;
ID3D10Buffer*    g_pIndexBuffer = NULL;
ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
ID3D10EffectVectorVariable* g_pLightDirVariable = NULL;
ID3D10EffectVectorVariable* g_pLightColorVariable = NULL;
ID3D10EffectVectorVariable* g_pOutputColorVariable = NULL;
D3DXMATRIX    g_World;
D3DXMATRIX    g_View;
D3DXMATRIX    g_Projection;
 
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
    if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
        return 0;
 
    if( FAILED( InitDevice() ) ){
        CleanupDevice();
        return 0;
    }
 
    // Loop principal de mensagens
    MSG msg = {0};
    while( WM_QUIT != msg.message ){
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ){
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        } else {
            Render();
        }
    }
 
    return (int) msg.wParam;
}
 
// Registra classe e cria janela
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ){
    // Registra a classe
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof( WNDCLASSEX );
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    //wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIcon = NULL;
    wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"TutorialWindowClass";
    //wcex.hIconSm = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIconSm = NULL;
 
    if( !RegisterClassEx( &wcex ) )
        return E_FAIL;
 
    // Cria a janela
    g_hInst = hInstance;
    RECT rc = { 0, 0, 640, 480 };
    AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
    g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 10 Tutorial 6",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
        NULL, NULL, hInstance, NULL );
 
    if( !g_hWnd )
        return E_FAIL;
 
    ShowWindow( g_hWnd, nCmdShow );
 
    return S_OK;
}
 
// Chamado toda vez que a aplicação recebe uma mensagem
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){
    PAINTSTRUCT ps;
    HDC hdc;
 
    switch( message ){
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            EndPaint( hWnd, &ps );    
            break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;
 
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }
 
    return 0;
}
 
// Cria o dispositivo Direct3D e a cadeia de troca
HRESULT InitDevice(){
    HRESULT hr = S_OK;
 
    RECT rc;
    GetClientRect( g_hWnd, &rc );
    UINT width = rc.right - rc.left;
    UINT height = rc.bottom - rc.top;
 
    UINT createDeviceFlags = 0;
 
#ifdef _DEBUG
    createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
 
    D3D10_DRIVER_TYPE driverTypes[] = {
        D3D10_DRIVER_TYPE_HARDWARE,
        D3D10_DRIVER_TYPE_REFERENCE
    };
 
    UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory( &sd, sizeof( sd ) );
    sd.BufferCount = 1;
    sd.BufferDesc.Width = width;
    sd.BufferDesc.Height = height;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = g_hWnd;
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;
 
    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ){
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D10CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags,
            D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice );
 
        if( SUCCEEDED( hr ) )
            break;
    }
 
    if( FAILED( hr ) )
        return hr;
 
    // cria uma visão de renderização alvo (Render Target)
    ID3D10Texture2D* pBackBuffer;
    hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID *) &pBackBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
    pBackBuffer->Release();
 
    if( FAILED( hr ) )
        return hr;
 
    // Cria textura stencil de profundidade
    D3D10_TEXTURE2D_DESC descDepth;
    descDepth.Width = width;
    descDepth.Height = height;
    descDepth.MipLevels = 1;
    descDepth.ArraySize = 1;
    descDepth.Format = DXGI_FORMAT_D32_FLOAT;
    descDepth.SampleDesc.Count = 1;
    descDepth.SampleDesc.Quality = 0;
    descDepth.Usage = D3D10_USAGE_DEFAULT;
    descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL;
    descDepth.CPUAccessFlags = descDepth.MiscFlags = 0;
    hr = g_pd3dDevice->CreateTexture2D( &descDepth, NULL, &g_pDepthStencil );
 
    if( FAILED( hr ) )
        return hr;
 
    // Cria a visão stencil de profundidade
    D3D10_DEPTH_STENCIL_VIEW_DESC descDSV;
    descDSV.Format = descDepth.Format;
    descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
    descDSV.Texture2D.MipSlice = 0;
 
    hr = g_pd3dDevice->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView );
    pBackBuffer->Release();
 
    if( FAILED( hr ) )
        return hr;
 
    g_pd3dDevice->OMSetRenderTargets( 1, & g_pRenderTargetView, g_pDepthStencilView );
 
    // Configure o viewport
    D3D10_VIEWPORT vp;
    vp.Width = width;
    vp.Height = height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = vp.TopLeftY = 0;
    g_pd3dDevice->RSSetViewports( 1, &vp );
 
    //Cria o efeito
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Configure a opção D3D10_SHADER_DEBUG para embutir informação de debug nos shaders.
    // Configurar esta opção melhora a debugação do shader, mas ainda permite aos
    // shaders serem otimizados e executarem da maneira que eles executarão na 
    // configuração release deste programa
    dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif
 
    hr = D3DX10CreateEffectFromFile( L"..\\Tutorial06.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0,
        g_pd3dDevice, NULL, NULL, &g_pEffect, NULL, NULL );
 
    if( FAILED( hr ) ){
        MessageBox( g_hWnd, L"O arquivo fx não pôde ser localizado. Por favor execute este executável do diretório que contém o arquivo FX", 
            L"Erro", MB_OK );
 
        return hr;
    }
 
    // Obtem as técnicas
    g_pTechniqueRender = g_pEffect->GetTechniqueByName( "Render" );
    g_pTechniqueRenderLight = g_pEffect->GetTechniqueByName( "RenderLight" );
 
    // Obtém as variáveis
    g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
    g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
    g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
    g_pLightDirVariable = g_pEffect->GetVariableByName( "vLightDir" )->AsVector();
    g_pLightColorVariable = g_pEffect->GetVariableByName( "vLightColor" )->AsVector();
    g_pOutputColorVariable = g_pEffect->GetVariableByName( "vOutputColor" )->AsVector();
 
    // Defina o leiaute de entrada
    D3D10_INPUT_ELEMENT_DESC layout[] = {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA },
        { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Cria o leiaute de entrada
    D3D10_PASS_DESC PassDesc;
    g_pTechniqueRender->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    hr = g_pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
        PassDesc.IAInputSignatureSize, &g_pVertexLayout );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o leiaute de entrada
    g_pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Crie o buffer de vértice
    SimpleVertex vertices[] =
    {
        { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR3( 0.0f, -1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR3( 0.0f, -1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR3( 0.0f, -1.0f, 0.0f ) },
        { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR3( 0.0f, -1.0f, 0.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR3( -1.0f, 0.0f, 0.0f ) },
        { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR3( -1.0f, 0.0f, 0.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR3( -1.0f, 0.0f, 0.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR3( -1.0f, 0.0f, 0.0f ) },
 
        { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR3( 1.0f, 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR3( 1.0f, 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR3( 1.0f, 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR3( 1.0f, 0.0f, 0.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR3( 0.0f, 0.0f, -1.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR3( 0.0f, 0.0f, -1.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR3( 0.0f, 0.0f, -1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR3( 0.0f, 0.0f, -1.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR3( 0.0f, 0.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR3( 0.0f, 0.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR3( 0.0f, 0.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR3( 0.0f, 0.0f, 1.0f ) },
    };
    D3D10_BUFFER_DESC bd;
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * 24;
    bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = vertices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o buffer de vértice
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    g_pd3dDevice->IASetVertexBuffers( 0,1, &g_pVertexBuffer, &stride, &offset );
 
    // Cria o buffer de índice
    // Cria o buffer de vértice
    DWORD indices[] =
    {
        3,1,0,
        2,1,3,
 
        6,4,5,
        7,4,6,
 
        11,9,8,
        10,9,11,
 
        14,12,13,
        15,12,14,
 
        19,17,16,
        18,17,19,
 
        22,20,21,
        23,20,22
    };
 
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( DWORD ) * 36;    
    bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
    bd.CPUAccessFlags = bd.MiscFlags = 0;
    InitData.pSysMem = indices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
    if( FAILED( hr ) )
        return hr;
 
    // Configura o buffer de índice
    g_pd3dDevice->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
 
    // Configure a topologia primitiva
    g_pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
 
    // Inicialize a matriz do mundo
    D3DXMatrixIdentity( &g_World );
 
    // Inicialize a matriz visão
    D3DXVECTOR3 Eye( 0.0f, 4.0f, -10.0f );
    D3DXVECTOR3 At( 0.0f, 1.0f, 0.0f );
    D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &g_View, &Eye, &At, &Up );
 
    // Inicializa a matriz de projeção
    D3DXMatrixPerspectiveFovLH( &g_Projection, (float) D3DX_PI * 0.25f, width / (FLOAT) height, 0.1f, 100.0f );
 
    return TRUE;
}
 
// Renderiza um quadro
void Render(){
    // Atualize nosso tempo
    static float t = 0.0f;
    if( g_driverType == D3D10_DRIVER_TYPE_REFERENCE ){
        t += (float) D3DX_PI * 0.0125f;
    } else {
        static DWORD dwTimeStart = 0;
        DWORD dwTimeCur = GetTickCount();
        if( dwTimeStart == 0 )
            dwTimeStart = dwTimeCur;
        t = ( dwTimeCur - dwTimeStart ) / 1000.0f;
    }
 
    // Rotacione o cubo ao redor da origem
    D3DXMatrixRotationY( &g_World, t );
 
    // Configura nossos parâmetros de iluminação
    D3DXVECTOR4 vLightDirs[2] = {
        D3DXVECTOR4( -0.577f, 0.577f, -0.577f, 1.0f ),
        D3DXVECTOR4( 0.0f, 0.0f, -1.0f, 1.0f ),
    };
    D3DXVECTOR4 vLightColors[2] = {
        D3DXVECTOR4( 0.5f, 0.5f, 0.5f, 1.0f ),
        D3DXVECTOR4( 0.5f, 0.0f, 0.0f, 1.0f )
    };
 
    // Rotaciona a segunda luz ao redor da origem
    D3DXMATRIX mRotate;
    D3DXVECTOR4 vOutDir;
    D3DXMatrixRotationY( &mRotate, -t * 2.0f );
    D3DXVec3Transform( &vLightDirs[1], (D3DXVECTOR3*) &vLightDirs[1], &mRotate );
 
    // Limpe o buffer de trás
    float ClearColor[4] = {0.0f, 0.125f, 0.3f, 1.0f};    // vermelho, verde, azul, alfa
    g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
 
    // limpe o buffer de profundidade para 1.0 (profundidade máxima)
    g_pd3dDevice->ClearDepthStencilView( g_pDepthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0 );
 
    // Atualiza as variáveis matriz
    g_pWorldVariable->SetMatrix( (float* )&g_World );
    g_pViewVariable->SetMatrix( (float* )&g_View );
    g_pProjectionVariable->SetMatrix( (float* )&g_Projection );
 
    // Atualiza as variáveis de iluminação
    g_pLightDirVariable->SetFloatVectorArray( (float*) vLightDirs, 0, 2 );
    g_pLightColorVariable->SetFloatVectorArray( (float*) vLightColors, 0, 2 );
 
    // Renderiza o cubo
    D3D10_TECHNIQUE_DESC techDesc;    
    g_pTechniqueRender->GetDesc( &techDesc );
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        g_pTechniqueRender->GetPassByIndex( p )->Apply( 0 );
        g_pd3dDevice->DrawIndexed( 36, 0, 0 );    // 36 vértices necessários para 12 triângulos em uma lista de triângulos
    }
 
    // Renderiza cada luz
    for( int m = 0; m < 2; ++m ){
        D3DXMATRIX mLight;
        D3DXMATRIX mLightScale;
        D3DXVECTOR3 vLightPos = vLightDirs[m] * 5.0f;
        D3DXMatrixTranslation( &mLight, vLightPos.x, vLightPos.y, vLightPos.z );
        D3DXMatrixScaling( &mLightScale, 0.2f, 0.2f, 0.2f );
        mLight = mLightScale * mLight;
 
        // Atualiza a variável do mundo para refeltir a luz atual
        g_pWorldVariable->SetMatrix( (float*) &mLight );
        g_pOutputColorVariable->SetFloatVector( (float*) &vLightColors[m] );
 
        g_pTechniqueRender->GetDesc( &techDesc );
        for( UINT p = 0; p < techDesc.Passes; ++p ){
            g_pTechniqueRenderLight->GetPassByIndex( p )->Apply( 0 );
            g_pd3dDevice->DrawIndexed( 36, 0, 0 );    // 36 vértices necessários para 12 triângulos em uma lista de triângulos
        }
    }
 
    // Apresenta nosso buffer de trás para o buffer da frente
    g_pSwapChain->Present(0,0);
}
 
// Limpa os objetos que nós criamos
void CleanupDevice(){
    if( g_pd3dDevice ) g_pd3dDevice->ClearState();
 
    if( g_pVertexBuffer ) g_pVertexBuffer->Release();
    if( g_pIndexBuffer ) g_pIndexBuffer->Release();
    if( g_pVertexLayout ) g_pVertexLayout->Release();
    if( g_pEffect ) g_pEffect->Release();
    if( g_pRenderTargetView ) g_pRenderTargetView->Release();
    if( g_pDepthStencil ) g_pDepthStencil->Release();
    if( g_pDepthStencilView ) g_pDepthStencilView->Release();
    if( g_pSwapChain ) g_pSwapChain->Release();
    if( g_pd3dDevice ) g_pd3dDevice->Release();
}

O shader para este exemplo é o sgeuinte:

//--------------------------------------------------------------------------------------
// File: Tutorial06.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
matrix World;
matrix View;
matrix Projection;
float4 vLightDir[2];
float4 vLightColor[2];
float4 vOutputColor;
 
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
    float4 Pos : POSITION;
    float3 Norm : NORMAL;
};
 
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float3 Norm : TEXCOORD0;
};
 
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Norm = mul( input.Norm, World );
 
    return output;
}
 
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
    float4 finalColor = 0;
 
    //do NdotL lighting for 2 lights
    for(int i=0; i<2; i++)
    {
        finalColor += saturate( dot( (float3)vLightDir[i],input.Norm) * vLightColor[i] );
    }
    finalColor.a = 1;
    return finalColor;
}
 
//--------------------------------------------------------------------------------------
// PSSolid - render a solid color
//--------------------------------------------------------------------------------------
float4 PSSolid( PS_INPUT input) : SV_Target
{
    return vOutputColor;
}
 
//--------------------------------------------------------------------------------------
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}
 
//--------------------------------------------------------------------------------------
technique10 RenderLight
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PSSolid() ) );
    }
}

Tutorial 07 - DXSDK - Mapeamento de textura

// Esta aplicação demonstra animação usando transformações de matriz
 
#include <windows.h>
#include <d3d10.h>
#include <d3dx10.h>
 
struct SimpleVertex{
    D3DXVECTOR3 Pos;
    D3DXVECTOR2 Tex;
};
 
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
D3D10_DRIVER_TYPE g_driverType = D3D10_DRIVER_TYPE_NULL;
ID3D10Device*    g_pd3dDevice = NULL;
IDXGISwapChain*    g_pSwapChain = NULL;
ID3D10RenderTargetView*    g_pRenderTargetView = NULL;
ID3D10Effect*    g_pEffect = NULL;
ID3D10EffectTechnique*    g_pTechnique = NULL;
ID3D10InputLayout*    g_pVertexLayout = NULL;
ID3D10Buffer*    g_pVertexBuffer = NULL;
ID3D10Buffer*    g_pIndexBuffer = NULL;
ID3D10ShaderResourceView*    g_pTextureRV = NULL;
ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
ID3D10EffectVectorVariable* g_pMeshColorVariable = NULL;
ID3D10EffectShaderResourceVariable* g_pDiffuseVariable = NULL;
D3DXMATRIX    g_World;
D3DXMATRIX    g_View;
D3DXMATRIX    g_Projection;
D3DXVECTOR4    g_vMeshColor( 0.7f, 0.7f, 0.7f, 1.0f );
 
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
    if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
        return 0;
 
    if( FAILED( InitDevice() ) ){
        CleanupDevice();
        return 0;
    }
 
    // Loop principal de mensagens
    MSG msg = {0};
    while( WM_QUIT != msg.message ){
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ){
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        } else {
            Render();
        }
    }
 
    return (int) msg.wParam;
}
 
// Registra classe e cria janela
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ){
    // Registra a classe
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof( WNDCLASSEX );
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    //wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIcon = NULL;
    wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"TutorialWindowClass";
    //wcex.hIconSm = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
    wcex.hIconSm = NULL;
 
    if( !RegisterClassEx( &wcex ) )
        return E_FAIL;
 
    // Cria a janela
    g_hInst = hInstance;
    RECT rc = { 0, 0, 640, 480 };
    AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
    g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 10 Tutorial 7",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
        NULL, NULL, hInstance, NULL );
 
    if( !g_hWnd )
        return E_FAIL;
 
    ShowWindow( g_hWnd, nCmdShow );
 
    return S_OK;
}
 
// Chamado toda vez que a aplicação recebe uma mensagem
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){
    PAINTSTRUCT ps;
    HDC hdc;
 
    switch( message ){
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            EndPaint( hWnd, &ps );    
            break;
        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;
 
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }
 
    return 0;
}
 
// Cria o dispositivo Direct3D e a cadeia de troca
HRESULT InitDevice(){
    HRESULT hr = S_OK;
 
    RECT rc;
    GetClientRect( g_hWnd, &rc );
    UINT width = rc.right - rc.left;
    UINT height = rc.bottom - rc.top;
 
    UINT createDeviceFlags = 0;
 
#ifdef _DEBUG
    createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
 
    D3D10_DRIVER_TYPE driverTypes[] = {
        D3D10_DRIVER_TYPE_HARDWARE,
        D3D10_DRIVER_TYPE_REFERENCE
    };
 
    UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );
    DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory( &sd, sizeof( sd ) );
    sd.BufferCount = 1;
    sd.BufferDesc.Width = width;
    sd.BufferDesc.Height = height;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = g_hWnd;
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;
 
    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ){
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D10CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags,
            D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice );
 
        if( SUCCEEDED( hr ) )
            break;
    }
 
    if( FAILED( hr ) )
        return hr;
 
    // cria uma visão de renderização alvo (Render Target)
    ID3D10Texture2D* pBackBuffer;
    hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID *) &pBackBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
    pBackBuffer->Release();
 
    if( FAILED( hr ) )
        return hr;
 
    g_pd3dDevice->OMSetRenderTargets( 1, & g_pRenderTargetView, NULL );
 
    // Configure o viewport
    D3D10_VIEWPORT vp;
    vp.Width = width;
    vp.Height = height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = vp.TopLeftY = 0;
    g_pd3dDevice->RSSetViewports( 1, &vp );
 
    //Cria o efeito
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Configure a opção D3D10_SHADER_DEBUG para embutir informação de debug nos shaders.
    // Configurar esta opção melhora a debugação do shader, mas ainda permite aos
    // shaders serem otimizados e executarem da maneira que eles executarão na 
    // configuração release deste programa
    dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif
 
    hr = D3DX10CreateEffectFromFile( L"..\\Tutorial07.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0,
        g_pd3dDevice, NULL, NULL, &g_pEffect, NULL, NULL );
 
    if( FAILED( hr ) ){
        MessageBox( g_hWnd, L"O arquivo fx não pôde ser localizado. Por favor execute este executável do diretório que contém o arquivo FX", 
            L"Erro", MB_OK );
 
        return hr;
    }
 
    // Obtem as técnicas
    g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
 
    // Obtém as variáveis
    g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
    g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
    g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
    g_pMeshColorVariable = g_pEffect->GetVariableByName( "vMeshColor" )->AsVector();
    g_pDiffuseVariable = g_pEffect->GetVariableByName( "txDiffuse" )->AsShaderResource();
 
    // Defina o leiaute de entrada
    D3D10_INPUT_ELEMENT_DESC layout[] = {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA,0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA,0 },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Cria o leiaute de entrada
    D3D10_PASS_DESC PassDesc;
    g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    hr = g_pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
        PassDesc.IAInputSignatureSize, &g_pVertexLayout );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o leiaute de entrada
    g_pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Crie o buffer de vértice
    SimpleVertex vertices[] =
    {
        { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
 
        { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
    };
 
    D3D10_BUFFER_DESC bd;
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * 24;
    bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = vertices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o buffer de vértice
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    g_pd3dDevice->IASetVertexBuffers( 0,1, &g_pVertexBuffer, &stride, &offset );
 
    // Cria o buffer de índice
    // Cria o buffer de vértice
    DWORD indices[] =
    {
        3,1,0,
        2,1,3,
 
        6,4,5,
        7,4,6,
 
        11,9,8,
        10,9,11,
 
        14,12,13,
        15,12,14,
 
        19,17,16,
        18,17,19,
 
        22,20,21,
        23,20,22
    };
 
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( DWORD ) * 36;    
    bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
    bd.CPUAccessFlags = bd.MiscFlags = 0;
    InitData.pSysMem = indices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
    if( FAILED( hr ) )
        return hr;
 
    // Configura o buffer de índice
    g_pd3dDevice->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
 
    // Configura a topologia primitiva
    g_pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
 
    // Carrega a textura
    hr = D3DX10CreateShaderResourceViewFromFile( g_pd3dDevice, L"..\\seafloor.dds", NULL, NULL,
        &g_pTextureRV, NULL );
    if( FAILED( hr ) )
        return hr;
 
    // Inicializa a matriz do mundo
    D3DXMatrixIdentity( &g_World );
 
    // Inicializa a matriz visão
    D3DXVECTOR3 Eye( 0.0f, 3.0f, -6.0f );
    D3DXVECTOR3 At( 0.0f, 1.0f, 0.0f );
    D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &g_View, &Eye, &At, &Up );
 
    // Inicializa a matriz de projeção
    D3DXMatrixPerspectiveFovLH( &g_Projection, (float) D3DX_PI * 0.25f, width / (FLOAT) height, 0.1f, 100.0f );
 
    // Atualize variáveis que nunca mudarão
    g_pViewVariable->SetMatrix( (float*) &g_View );
    g_pProjectionVariable->SetMatrix( (float*) &g_Projection );
    g_pDiffuseVariable->SetResource( g_pTextureRV );
 
    return S_OK;
}
 
// Renderiza um quadro
void Render(){
    // Atualize nosso tempo
    static float t = 0.0f;
    if( g_driverType == D3D10_DRIVER_TYPE_REFERENCE ){
        t += (float) D3DX_PI * 0.0125f;
    } else {
        static DWORD dwTimeStart = 0;
        DWORD dwTimeCur = GetTickCount();
        if( dwTimeStart == 0 )
            dwTimeStart = dwTimeCur;
        t = ( dwTimeCur - dwTimeStart ) / 1000.0f;
    }
 
    // Rotacione o cubo ao redor da origem
    D3DXMatrixRotationY( &g_World, t );
 
    // Modifica a cor
    g_vMeshColor.x = ( sinf( t*1.0f ) + 1.0f ) * 0.5f;
    g_vMeshColor.y = ( cosf( t*3.0f ) + 1.0f ) * 0.5f;
    g_vMeshColor.z = ( sinf( t*5.0f ) + 1.0f ) * 0.5f;
 
    // Limpa o buffer de trás
    float ClearColor[4] = {0.0f, 0.125f, 0.3f, 1.0f};    // vermelho, verde, azul, alfa
    g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
 
    // Atualiza as variáveis que mudam uma vez por quadro
    g_pWorldVariable->SetMatrix( (float* )&g_World );
    g_pMeshColorVariable->SetFloatVector( (float*) g_vMeshColor);
 
    // Renderiza o cubo
    D3D10_TECHNIQUE_DESC techDesc;    
    g_pTechnique->GetDesc( &techDesc );
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        g_pTechnique->GetPassByIndex( p )->Apply( 0 );
        g_pd3dDevice->DrawIndexed( 36, 0, 0 );    // 36 vértices necessários para 12 triângulos em uma lista de triângulos
    }
 
    // Apresenta nosso buffer de trás para o buffer da frente
    g_pSwapChain->Present(0,0);
}
 
// Limpa os objetos que nós criamos
void CleanupDevice(){
    if( g_pd3dDevice ) g_pd3dDevice->ClearState();
 
    if( g_pVertexBuffer ) g_pVertexBuffer->Release();
    if( g_pIndexBuffer ) g_pIndexBuffer->Release();
    if( g_pVertexLayout ) g_pVertexLayout->Release();
    if( g_pEffect ) g_pEffect->Release();
    if( g_pRenderTargetView ) g_pRenderTargetView->Release();
    if( g_pSwapChain ) g_pSwapChain->Release();
    if( g_pd3dDevice ) g_pd3dDevice->Release();
}

E o código para o arquivo de efeito é:

//--------------------------------------------------------------------------------------
// File: Tutorial07.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
Texture2D txDiffuse;
SamplerState samLinear
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
 
cbuffer cbNeverChanges
{
    matrix View;
};
 
cbuffer cbChangeOnResize
{
    matrix Projection;
};
 
cbuffer cbChangesEveryFrame
{
    matrix World;
    float4 vMeshColor;
};
 
struct VS_INPUT
{
    float4 Pos : POSITION;
    float2 Tex : TEXCOORD;
};
 
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float2 Tex : TEXCOORD0;
};
 
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Tex = input.Tex;
 
    return output;
}
 
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
    return txDiffuse.Sample( samLinear, input.Tex ) * vMeshColor;
}
 
//--------------------------------------------------------------------------------------
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}

Tutorial 08 - DXSDK - Introdução ao DXUT

Este tutorial aborda uma introdução ao DXUT. Nele são vistos quais as principais funções de callback que devem ser configuradas para que uma aplicação use das facilidades fornecidas por esta biblioteca utilitária. Ps: A funcionalidade é a mesma do tutorial 07.

// Introdução básica ao DXUT
 
#include <windows.h>
#include "DXUT\Core\DXUT.h"
#include "DXUT\Core\DXUTmisc.h"
 
#define DEG2RAD( a ) ( a * D3DX_PI / 180.0f )
 
struct SimpleVertex{
    D3DXVECTOR3 Pos;
    D3DXVECTOR2 Tex;
};
 
ID3D10Effect*    g_pEffect = NULL;
ID3D10InputLayout*    g_pVertexLayout = NULL;
ID3D10EffectTechnique*    g_pTechnique = NULL;
ID3D10Buffer*    g_pVertexBuffer = NULL;
ID3D10Buffer*    g_pIndexBuffer = NULL;
ID3D10ShaderResourceView*    g_pTextureRV = NULL;
ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
ID3D10EffectVectorVariable* g_pMeshColorVariable = NULL;
ID3D10EffectShaderResourceVariable* g_pDiffuseVariable = NULL;
D3DXMATRIX    g_World;
D3DXMATRIX    g_View;
D3DXMATRIX    g_Projection;
D3DXVECTOR4    g_vMeshColor( 0.7f, 0.7f, 0.7f, 1.0f );
 
// Protótipos das funções
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext );
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc, 
                                     void* pUserContext);
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain* pSwapChain,
                    const DXGI_SURFACE_DESC* pBufferSurfaceDesc, void* pUserContext);
void CALLBACK OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
void CALLBACK OnD3D10ReleasingSwapChain( void* pUserContext );
void CALLBACK OnD3D10DestroyDevice( void* pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool *pbNoFurtherProcessing,
                         void* pUserContext);
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext );
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUserContext );
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void *pUserContext );
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
#if defined( DEBUG ) | defined( _DEBUG )
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
 
    // DXUT criará e usará o melhor equipamento disponível (ou D3D9 ou D3D10)
    // isto é dependente do sistema disponível no qual os CALLBACKS do D3D são configurados abaixo
 
    // Configure callbacks DXUT
    DXUTSetCallbackD3D10DeviceAcceptable( IsD3D10DeviceAcceptable );
    DXUTSetCallbackD3D10DeviceCreated( OnD3D10CreateDevice );
    DXUTSetCallbackD3D10SwapChainResized( OnD3D10ResizeSwapChain );
    DXUTSetCallbackD3D10SwapChainReleasing( OnD3D10ReleasingSwapChain );
    DXUTSetCallbackD3D10DeviceDestroyed( OnD3D10DestroyDevice );
    DXUTSetCallbackD3D10FrameRender( OnD3D10FrameRender );
 
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackKeyboard( OnKeyboard );
    DXUTSetCallbackFrameMove( OnFrameMove );
    DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
 
    DXUTInit( true, true, NULL );    // Parse da linha de comando, mostra caixas de mensagem no erro, sem parâmetros de linha de comando extra
    DXUTSetCursorSettings(true, true );    // Mostre o cursor e recorte ele (clip) quando em modo de tela cheia
    DXUTCreateWindow( L"Tutorial08" );
    DXUTCreateDevice( true, 640, 480 );
    DXUTMainLoop();    // Entra dentro do loop de renderização DXUT
 
    return DXUTGetExitCode();
}
 
// Rejeita qualquer equipamento D3D10 que não é aceitável por retornar falso
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext ){
      return true;
}
 
// Crie quaisquer recursos que não são dependentes do buffer de trás
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc,
                                     void *pUserContext ){
    HRESULT hr = S_OK;
 
    // Lê o arquivo de efeito D3DX
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined(DEBUG) || defined(_DEBUG)
    // Coloque a opção D3D10_SHADER_DEBUG para embutir informação de debug nos shaders.
    // Colocar estaopção melhora a experiência de debugação dos shaders, mas ainda permite
    // os shaders serem otimizados e executarem apropriadamente da maneira que eles
    // executarão na configuração release deste programa
    dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif
 
    hr = D3DX10CreateEffectFromFile( L"..\\Tutorial08.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0, pd3dDevice, NULL,
        NULL, &g_pEffect, NULL, NULL );
 
    if( FAILED( hr ) ){
        MessageBox( NULL, L"O arquivo fx não pôde ser localizado. Por favor execute este executável do diretório que contém o arquivo FX", 
            L"Erro", MB_OK );
 
        V_RETURN( hr );
    }
 
    // Obtem as técnicas
    g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
 
    // Obtém as variáveis
    g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
    g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
    g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
    g_pMeshColorVariable = g_pEffect->GetVariableByName( "vMeshColor" )->AsVector();
    g_pDiffuseVariable = g_pEffect->GetVariableByName( "txDiffuse" )->AsShaderResource();
 
    // Defina o leiaute de entrada
    D3D10_INPUT_ELEMENT_DESC layout[] = {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA,0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA,0 },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Cria o leiaute de entrada
    D3D10_PASS_DESC PassDesc;
    g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    hr = pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
        PassDesc.IAInputSignatureSize, &g_pVertexLayout );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o leiaute de entrada
    pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Crie o buffer de vértice
    SimpleVertex vertices[] =
    {
        { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
 
        { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
 
        { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },
        { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },
        { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
    };
 
    D3D10_BUFFER_DESC bd;
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * 24;
    bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;
    D3D10_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = vertices;
    hr = pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
 
    if( FAILED( hr ) )
        return hr;
 
    // Configure o buffer de vértice
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    pd3dDevice->IASetVertexBuffers( 0,1, &g_pVertexBuffer, &stride, &offset );
 
    // Cria o buffer de índice
    // Cria o buffer de vértice
    DWORD indices[] =
    {
        3,1,0,
        2,1,3,
 
        6,4,5,
        7,4,6,
 
        11,9,8,
        10,9,11,
 
        14,12,13,
        15,12,14,
 
        19,17,16,
        18,17,19,
 
        22,20,21,
        23,20,22
    };
 
    bd.Usage = D3D10_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( DWORD ) * 36;    
    bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
    bd.CPUAccessFlags = bd.MiscFlags = 0;
    InitData.pSysMem = indices;
    V_RETURN( pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer ) );
 
    // Configura o buffer de índice
    pd3dDevice->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
 
    // Configura a topologia primitiva
    pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
 
    // Carrega a textura
    hr = D3DX10CreateShaderResourceViewFromFile( pd3dDevice, L"..\\seafloor.dds", NULL, NULL,
        &g_pTextureRV, NULL );
 
    // Inicializa a matriz do mundo
    D3DXMatrixIdentity( &g_World );
 
    // Inicializa a matriz visão
    D3DXVECTOR3 Eye( 0.0f, 3.0f, -6.0f );
    D3DXVECTOR3 At( 0.0f, 1.0f, 0.0f );
    D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &g_View, &Eye, &At, &Up );
 
    // Atualize variáveis que nunca mudarão
    g_pViewVariable->SetMatrix( (float*) &g_View );
    g_pDiffuseVariable->SetResource( g_pTextureRV );
 
    return S_OK;
}
 
// Crie quaisquer recursos D3D10 que dependam do buffer de trás
// Crie e configure a textura stencial de profundidade se necessário
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain *pSwapChain,
                                        const DXGI_SURFACE_DESC *pBufferSurfaceDesc, void *pUserContext){
    // Configura os parâmetros de projeção de novo
    float fAspect = static_cast<float>( pBufferSurfaceDesc->Width) / static_cast<float>( pBufferSurfaceDesc->Height );
    D3DXMatrixPerspectiveFovLH( &g_Projection, (float) D3DX_PI * 0.25f, fAspect, 0.1f, 100.0f );
    g_pProjectionVariable->SetMatrix( (float*) &g_Projection );
 
    return S_OK;
}
 
// Renderiza a cena usando o dispositivo D3D10
void CALLBACK OnD3D10FrameRender( ID3D10Device *pd3dDevice, double fTime, float fElapsedTime, void *pUserContext )
{
    // Limpa o buffer de trás
    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };    // vermelho, verde, azul, alfa
    ID3D10RenderTargetView *pRTV = DXUTGetD3D10RenderTargetView();
    pd3dDevice->ClearRenderTargetView(pRTV, ClearColor );
 
    // limpa o stencil de profundidade
    ID3D10DepthStencilView *pDSV = DXUTGetD3D10DepthStencilView();
    pd3dDevice->ClearDepthStencilView( pDSV, D3D10_CLEAR_DEPTH, 1.0, 0 );
 
    // Atualiza as variáveis que mudam uma vez por quadro
    g_pWorldVariable->SetMatrix( (float* )&g_World );
    g_pMeshColorVariable->SetFloatVector( (float*) g_vMeshColor);
 
    // Renderiza o cubo
    D3D10_TECHNIQUE_DESC techDesc;    
    g_pTechnique->GetDesc( &techDesc );
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        g_pTechnique->GetPassByIndex( p )->Apply( 0 );
        pd3dDevice->DrawIndexed( 36, 0, 0 );    // 36 vértices necessários para 12 triângulos em uma lista de triângulos
    }
}
 
// Libera recursos D3D10 criados em OnD3D10ResizedSwapChain 
void CALLBACK OnD3D10ReleasingSwapChain( void *pUserContext ){
}
 
// Libera recursos D3D10 criados em OnD3D10CreateDevice 
void CALLBACK OnD3D10DestroyDevice( void *pUserContext ){
    SAFE_RELEASE( g_pVertexBuffer );
    SAFE_RELEASE( g_pIndexBuffer );
    SAFE_RELEASE( g_pVertexLayout );
    SAFE_RELEASE( g_pTextureRV );
    SAFE_RELEASE( g_pEffect );
}
 
// Chamado imediatamente antes de criar um dispositivo D3D9 oy D3D10, permitindo o aplicativo modificar
// as configurações do dispositivo como necessário
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings *pDeviceSettings, void *pUserContext ){
    return true;
}
 
// Trata das atualizações na cena. Isto é chamado indiferentemente de qual API D3D é usada
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUsetContex ){
    // Rotaciona p cubo ao redor da origem
    D3DXMatrixRotationY( &g_World, 60.0f * DEG2RAD( (float) fTime ) );
 
    // Modifique a cor
    g_vMeshColor.x = ( sinf( (float) fTime *1.0f ) + 1.0f) * 0.5f;
    g_vMeshColor.y = ( cosf( (float) fTime *3.0f ) + 1.0f) * 0.5f;
    g_vMeshColor.z = ( sinf( (float) fTime *5.0f ) + 1.0f) * 0.5f;
}
 
// Manuseia as mensagens para a aplicação
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                         bool *pbNoFurtherProcessing, void *pUserContext )
{
    return 0;
}
 
// Manuseia pressionamentos do teclado
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext  ){
    if( bKeyDown ){
        switch( nChar ){
            case VK_F1:    // Change as needed
                break;
        }
    }
}

O shader relacionado (Tutorial08.fx) é igual ao apresentado no Tutorial 07.

//--------------------------------------------------------------------------------------
// File: Tutorial08.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
Texture2D txDiffuse;
SamplerState samLinear
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
 
cbuffer cbNeverChanges
{
    matrix View;
};
 
cbuffer cbChangeOnResize
{
    matrix Projection;
};
 
cbuffer cbChangesEveryFrame
{
    matrix World;
    float4 vMeshColor;
};
 
struct VS_INPUT
{
    float4 Pos : POSITION;
    float2 Tex : TEXCOORD;
};
 
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float2 Tex : TEXCOORD0;
};
 
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Tex = input.Tex;
 
    return output;
}
 
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
    return txDiffuse.Sample( samLinear, input.Tex ) * vMeshColor;
}
 
//--------------------------------------------------------------------------------------
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}

Tutorial 09 - DXSDK - usando uma malha com DXUT

Este arquivo mostra como renderizar uma malha .x usando DXUT

// Carregamento de malha através do DXUT
 
#include <windows.h>
#include "DXUT.h"
#include "DXUTmisc.h"
#include "SDKmisc.h"
#include "SDKmesh.h"
 
#define DEG2RAD( a ) ( a * D3DX_PI / 180.0f )
 
ID3D10Effect*    g_pEffect = NULL;
ID3D10InputLayout*    g_pVertexLayout = NULL;
ID3D10EffectTechnique*    g_pTechnique = NULL;
CDXUTSDKMesh    g_Mesh;
ID3D10EffectShaderResourceVariable*    g_ptxDiffuseVariable = NULL;
ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
D3DXMATRIX    g_World;
D3DXMATRIX    g_View;
D3DXMATRIX    g_Projection;
 
// Protótipos das funções
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext );
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc, 
                                     void* pUserContext);
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain* pSwapChain,
                    const DXGI_SURFACE_DESC* pBufferSurfaceDesc, void* pUserContext);
void CALLBACK OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
void CALLBACK OnD3D10ReleasingSwapChain( void* pUserContext );
void CALLBACK OnD3D10DestroyDevice( void* pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool *pbNoFurtherProcessing,
                         void* pUserContext);
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext );
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUserContext );
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void *pUserContext );
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
#if defined( DEBUG ) | defined( _DEBUG )
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
 
    // DXUT criará e usará o melhor equipamento disponível (ou D3D9 ou D3D10)
    // isto é dependente do sistema disponível no qual os CALLBACKS do D3D são configurados abaixo
 
    // Configure callbacks DXUT
    DXUTSetCallbackD3D10DeviceAcceptable( IsD3D10DeviceAcceptable );
    DXUTSetCallbackD3D10DeviceCreated( OnD3D10CreateDevice );
    DXUTSetCallbackD3D10SwapChainResized( OnD3D10ResizeSwapChain );
    DXUTSetCallbackD3D10SwapChainReleasing( OnD3D10ReleasingSwapChain );
    DXUTSetCallbackD3D10DeviceDestroyed( OnD3D10DestroyDevice );
    DXUTSetCallbackD3D10FrameRender( OnD3D10FrameRender );
 
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackKeyboard( OnKeyboard );
    DXUTSetCallbackFrameMove( OnFrameMove );
    DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
 
    DXUTInit( true, true, NULL );    // Parse da linha de comando, mostra caixas de mensagem no erro, sem parâmetros de linha de comando extra
    DXUTSetCursorSettings(true, true );    // Mostre o cursor e recorte ele (clip) quando em modo de tela cheia
    DXUTCreateWindow( L"Tutorial09" );
    DXUTCreateDevice( true, 640, 480 );
    DXUTMainLoop();    // Entra dentro do loop de renderização DXUT
 
    return DXUTGetExitCode();
}
 
// Rejeita qualquer equipamento D3D10 que não é aceitável por retornar falso
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext ){
      return true;
}
 
// Crie quaisquer recursos que não são dependentes do buffer de trás
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc,
                                      void* pUserContext )
{
    HRESULT hr;
 
    // Find the D3DX effect file
    WCHAR str[MAX_PATH];
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"..\\Tutorial09.fx" ) );
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders.
    // Setting this flag improves the shader debugging experience, but still allows 
    // the shaders to be optimized and to run exactly the way they will run in 
    // the release configuration of this program.
    dwShaderFlags |= D3D10_SHADER_DEBUG;
    #endif
    V_RETURN( D3DX10CreateEffectFromFile( str, NULL, NULL, "fx_4_0", dwShaderFlags, 0, pd3dDevice, NULL,
                                              NULL, &g_pEffect, NULL, NULL ) );
 
    // Obtain the technique
    g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
    g_ptxDiffuseVariable = g_pEffect->GetVariableByName( "g_txDiffuse" )->AsShaderResource();
    g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
    g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
    g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
 
    // Define the input layout
    const D3D10_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Create the input layout
    D3D10_PASS_DESC PassDesc;
    g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    V_RETURN( pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
                                             PassDesc.IAInputSignatureSize, &g_pVertexLayout ) );
 
    // Set the input layout
    pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Load the mesh
    V_RETURN( g_Mesh.Create( pd3dDevice, L"..\\Media\\Tiny\\tiny.sdkmesh", true ) );
 
    // Initialize the world matrices
    D3DXMatrixIdentity( &g_World );
 
    // Initialize the view matrix
    D3DXVECTOR3 Eye( 0.0f, 3.0f, -500.0f );
    D3DXVECTOR3 At( 0.0f, 1.0f, 0.0f );
    D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &g_View, &Eye, &At, &Up );
 
    // Update Variables that never change
    g_pViewVariable->SetMatrix( ( float* )&g_View );
 
    return S_OK;
}
 
// Crie quaisquer recursos D3D10 que dependam do buffer de trás
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain *pSwapChain,
                                        const DXGI_SURFACE_DESC *pBufferSurfaceDesc, void *pUserContext)
{
    // Configura os parâmetros de projeção de novo
    float fAspect = static_cast<float>( pBufferSurfaceDesc->Width) / static_cast<float>( pBufferSurfaceDesc->Height );
    D3DXMatrixPerspectiveFovLH( &g_Projection, (float) D3DX_PI * 0.25f, fAspect, 0.5f, 1000.0f );
    g_pProjectionVariable->SetMatrix( (float*) &g_Projection );
 
    return S_OK;
}
 
// Renderiza a cena usando o dispositivo D3D10
void CALLBACK OnD3D10FrameRender( ID3D10Device *pd3dDevice, double fTime, float fElapsedTime, void *pUserContext )
{
    // Limpa o buffer de trás
    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };    // vermelho, verde, azul, alfa
    ID3D10RenderTargetView *pRTV = DXUTGetD3D10RenderTargetView();
    pd3dDevice->ClearRenderTargetView(pRTV, ClearColor );
 
    // limpa o stencil de profundidade
    ID3D10DepthStencilView *pDSV = DXUTGetD3D10DepthStencilView();
    pd3dDevice->ClearDepthStencilView( pDSV, D3D10_CLEAR_DEPTH, 1.0, 0 );
 
    // Atualiza as variáveis que mudam uma vez por quadro
    g_pWorldVariable->SetMatrix( (float* )&g_World );
 
    // Configura o leiaute de vértices
    pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Renderiza a malha
    UINT Strides[1];
    UINT Offsets[1];
    ID3D10Buffer* pVB[1];
    pVB[0] = g_Mesh.GetVB10( 0, 0 );
    Strides[0] = ( UINT ) g_Mesh.GetVertexStride(0,0);
    Offsets[0] = 0;
    pd3dDevice->IASetVertexBuffers(0, 1, pVB, Strides, Offsets);
    pd3dDevice->IASetIndexBuffer( g_Mesh.GetIB10( 0 ), g_Mesh.GetIBFormat10( 0 ), 0 );
 
    D3D10_TECHNIQUE_DESC techDesc;    
    g_pTechnique->GetDesc( &techDesc );
    SDKMESH_SUBSET* pSubset = NULL;
    ID3D10ShaderResourceView* pDiffuseRV = NULL;
    D3D10_PRIMITIVE_TOPOLOGY PrimType;
 
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        for( UINT subset = 0; subset < g_Mesh.GetNumSubsets( 0 ); ++subset ){
            pSubset = g_Mesh.GetSubset( 0, subset );
 
            PrimType = g_Mesh.GetPrimitiveType10( ( SDKMESH_PRIMITIVE_TYPE ) pSubset->PrimitiveType );
            pd3dDevice->IASetPrimitiveTopology( PrimType );
 
            pDiffuseRV = g_Mesh.GetMaterial( pSubset->MaterialID )->pDiffuseRV10;
            g_ptxDiffuseVariable->SetResource( pDiffuseRV );
 
            g_pTechnique->GetPassByIndex( p )->Apply( 0 );
            pd3dDevice->DrawIndexed( ( UINT ) pSubset->IndexCount, 0, ( UINT ) pSubset->VertexStart );
        }
    }
 
    // a classe de malha também tinha um método render que permite renderizar a malha com as opções mais comuns
    // g_pMesh.Render( pd3dDevice, g_pTechnique, g_ptxDiffuseVariable );
}
 
// Libera recursos D3D10 criados em OnD3D10ResizedSwapChain 
void CALLBACK OnD3D10ReleasingSwapChain( void *pUserContext ){
}
 
// Libera recursos D3D10 criados em OnD3D10CreateDevice 
void CALLBACK OnD3D10DestroyDevice( void *pUserContext ){
    DXUTGetGlobalResourceCache().OnDestroyDevice();
    SAFE_RELEASE( g_pVertexLayout );
    SAFE_RELEASE( g_pEffect );
    g_Mesh.Destroy();
}
 
// Chamado imediatamente antes de criar um dispositivo D3D9 oy D3D10, permitindo o aplicativo modificar
// as configurações do dispositivo como necessário
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings *pDeviceSettings, void *pUserContext ){
    return true;
}
 
// Trata das atualizações na cena. Isto é chamado indiferentemente de qual API D3D é usada
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUsetContex ){
    // Rotaciona p cubo ao redor da origem
    D3DXMatrixRotationY( &g_World, 60.0f * DEG2RAD( (float) fTime ) );
}
 
// Manuseia as mensagens para a aplicação
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                         bool *pbNoFurtherProcessing, void *pUserContext )
{
    return 0;
}
 
// Manuseia pressionamentos do teclado
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext  ){
    if( bKeyDown ){
        switch( nChar ){
            case VK_F1:    // Change as needed
                break;
        }
    }
}

O arquivo de efeito que acompanho o exemplo é mostrado logo abaixo

//--------------------------------------------------------------------------------------
// File: Tutorial08.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
Texture2D g_txDiffuse;
SamplerState samLinear
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
 
cbuffer cbConstant
{
    float3 vLightDir = float3(-0.577,0.577,-0.577);
};
 
cbuffer cbChangesOnce
{
    matrix View;
};
 
cbuffer cbChangeOnResize
{
    matrix Projection;
};
 
cbuffer cbChangesEveryFrame
{
    matrix World;
};
 
struct VS_INPUT
{
    float3 Pos          : POSITION;         //position
    float3 Norm         : NORMAL;           //normal
    float2 Tex          : TEXCOORD0;        //texture coordinate
};
 
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float3 Norm : TEXCOORD0;
    float2 Tex : TEXCOORD1;
};
 
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
    output.Pos = mul( float4(input.Pos,1), World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Norm = mul( input.Norm, World );
    output.Tex = input.Tex;
 
    return output;
}
 
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
    //calculate lighting assuming light color is <1,1,1,1>
    float fLighting = saturate( dot( input.Norm, vLightDir ) );
    float4 outputColor = g_txDiffuse.Sample( samLinear, input.Tex ) * fLighting;
    outputColor.a = 1;
    return outputColor;
}
 
//--------------------------------------------------------------------------------------
// Technique
//--------------------------------------------------------------------------------------
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}

Tutorial 10 - DXSDK - DXUT Avançado

Esta amostra foca em características avanãdas do DXUT, mostrando como se pode integrar funcionalidade GUI com DX

// Carregamento de malha através do DXUT
 
#include <windows.h>
#include "DXUT.h"
#include "DXUTcamera.h"
#include "DXUTgui.h"
#include "DXUTsettingsDlg.h"
#include "DXUTmisc.h"
#include "SDKmisc.h"
#include "SDKmesh.h"
 
#define DEG2RAD( a ) ( a * D3DX_PI / 180.0f )
 
CModelViewerCamera    g_Camera;    // Uma câmera de visualização do modelo
CDXUTDialogResourceManager    g_DialogResourceManager;    // gerente para recursos compartilhados de diálogos
CD3DSettingsDlg    g_D3DSettingsDialog;    // diálogo de configurações do dispositivo
CDXUTDialog    g_HUD;    // gerencia a UI 3D
CDXUTDialog    g_SampleUI;    // diálogo para controles específicos da amostra
 
ID3DX10Font*    g_pFont = NULL;    // Fonte para desenho de texto
ID3DX10Sprite*    g_pSprite = NULL;    // SPrite para desenho de texto em lote
CDXUTTextHelper*    g_pTxtHelper = NULL;
ID3D10Effect*    g_pEffect = NULL;    // interface de efeito D3DX
ID3D10InputLayout*    g_pVertexLayout = NULL;    // Leiaute de vértice
ID3D10EffectTechnique*    g_pTechnique = NULL;
CDXUTSDKMesh    g_Mesh;
ID3D10EffectShaderResourceVariable*    g_ptxDiffuseVariable = NULL;
ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
ID3D10EffectScalarVariable*    g_pPuffiness = NULL;
D3DXMATRIX    g_World;
float    g_fModelPuffiness;
bool g_bSpinning = true;
 
// IDs de controle da UI
#define IDC_TOGGLEFULLSCREEN    1
#define IDC_TOGGLEREF           2
#define IDC_CHANGEDEVICE        3
#define IDC_TOGGLESPIN          4
#define IDC_PUFF_SCALE          5
#define IDC_PUFF_STATIC         6
#define IDC_TOGGLEWARP          7
 
// Protótipos das funções
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext );
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc, 
                                     void* pUserContext);
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain* pSwapChain,
                    const DXGI_SURFACE_DESC* pBufferSurfaceDesc, void* pUserContext);
void CALLBACK OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
void CALLBACK OnD3D10ReleasingSwapChain( void* pUserContext );
void CALLBACK OnD3D10DestroyDevice( void* pUserContext );
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void *pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool *pbNoFurtherProcessing,
                         void* pUserContext);
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext );
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUserContext );
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void *pUserContext );
 
void RenderText();
void InitApp();
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
#if defined( DEBUG ) | defined( _DEBUG )
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
 
    // DXUT criará e usará o melhor equipamento disponível (ou D3D9 ou D3D10)
    // isto é dependente do sistema disponível no qual os CALLBACKS do D3D são configurados abaixo
 
    // Configure callbacks DXUT
    DXUTSetCallbackD3D10DeviceAcceptable( IsD3D10DeviceAcceptable );
    DXUTSetCallbackD3D10DeviceCreated( OnD3D10CreateDevice );
    DXUTSetCallbackD3D10SwapChainResized( OnD3D10ResizeSwapChain );
    DXUTSetCallbackD3D10SwapChainReleasing( OnD3D10ReleasingSwapChain );
    DXUTSetCallbackD3D10DeviceDestroyed( OnD3D10DestroyDevice );
    DXUTSetCallbackD3D10FrameRender( OnD3D10FrameRender );
 
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackKeyboard( OnKeyboard );
    DXUTSetCallbackFrameMove( OnFrameMove );
    DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
 
    DXUTInit( true, true, NULL );    // Parse da linha de comando, mostra caixas de mensagem no erro, sem parâmetros de linha de comando extra
    DXUTSetCursorSettings(true, true );    // Mostre o cursor e recorte ele (clip) quando em modo de tela cheia
 
    InitApp();
 
    DXUTCreateWindow( L"Tutorial10" );
    DXUTCreateDevice( true, 640, 480 );
    DXUTMainLoop();    // Entra dentro do loop de renderização DXUT
 
    return DXUTGetExitCode();
}
 
// Inicializa a aplicação
void InitApp()
{
    g_fModelPuffiness = 0.0f;
    g_bSpinning = true;
 
    g_D3DSettingsDialog.Init( &g_DialogResourceManager );
    g_HUD.Init( &g_DialogResourceManager );
    g_SampleUI.Init( &g_DialogResourceManager );
 
    g_HUD.SetCallback( OnGUIEvent );    int iY = 10;
    g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Mudar para tela cheia", 35, iY, 125, 22 );
    g_HUD.AddButton( IDC_CHANGEDEVICE, L"Mudar dispositivo (F2)", 35, iY += 24, 125, 22, VK_F2 );
    g_HUD.AddButton( IDC_TOGGLEREF, L"Mudar para REF (F3)", 35, iY += 24, 125, 22, VK_F3 );
    g_HUD.AddButton( IDC_TOGGLEWARP, L"Mudar para WARP( F4 )", 35, iY+= 24, 125, 22, VK_F4 );
 
    g_SampleUI.SetCallback( OnGUIEvent);    iY = 10;
 
    WCHAR sz[100];
    iY += 24;
    swprintf_s( sz, 100, L"Inchaço: %0.2f", g_fModelPuffiness );
    g_SampleUI.AddStatic( IDC_PUFF_STATIC, sz, 35, iY += 24, 125, 22 );
    g_SampleUI.AddSlider( IDC_PUFF_SCALE, 50, iY += 24, 100, 22, 0, 2000, ( int ) ( g_fModelPuffiness * 100.0f ) );
 
    iY += 24;
    g_SampleUI.AddCheckBox( IDC_TOGGLESPIN, L"Girar", 35, iY += 24, 125, 22, g_bSpinning );
}
 
// Rejeita qualquer equipamento D3D10 que não é aceitável por retornar falso
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext ){
      return true;
}
 
// Crie quaisquer recursos que não são dependentes do buffer de trás
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc,
                                      void* pUserContext )
{
    HRESULT hr;
 
    V_RETURN( g_DialogResourceManager.OnD3D10CreateDevice( pd3dDevice ) );
    V_RETURN( g_D3DSettingsDialog.OnD3D10CreateDevice( pd3dDevice ) );
    V_RETURN( D3DX10CreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
        OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
        L"Arial", &g_pFont ) );
 
    V_RETURN( D3DX10CreateSprite( pd3dDevice, 512, &g_pSprite ) );
    g_pTxtHelper = new CDXUTTextHelper( NULL, NULL, g_pFont, g_pSprite, 15 );
 
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Configura a opção D3D10_SHADER_DEBUG para embutir informãção de debug nos shaders.
    // Configurar esta opção melhora a experiência de debugação do shader, mas ainda permite
    // que os shaders sejam otimizados para executar à maneira que eles executarão na 
    // configuração release deste programa.
    dwShaderFlags |= D3D10_SHADER_DEBUG;
    #endif
 
    // Leia o arquivo de efeito D3DX
    WCHAR str[MAX_PATH];
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"..\\Tutorial10.fx" ) );
    V_RETURN( D3DX10CreateEffectFromFile( str, NULL, NULL, "fx_4_0", dwShaderFlags, 0, pd3dDevice, NULL,
                                              NULL, &g_pEffect, NULL, NULL ) );
 
    // Obtém a técnica
    g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
 
    g_ptxDiffuseVariable = g_pEffect->GetVariableByName( "g_txDiffuse" )->AsShaderResource();
    g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
    g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
    g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
    g_pPuffiness = g_pEffect->GetVariableByName( "Puffiness" )->AsScalar();
 
    // Configura o inchaço
    g_pPuffiness->SetFloat( g_fModelPuffiness );
 
    // Define o leiaute de entrada
    const D3D10_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Cria o leiaute de entrada
    D3D10_PASS_DESC PassDesc;
    g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    V_RETURN( pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
                                             PassDesc.IAInputSignatureSize, &g_pVertexLayout ) );
 
    // Configura o leiaute de entrada
    pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Carrega a malha
    V_RETURN( g_Mesh.Create( pd3dDevice, L"..\\Media\\Tiny\\tiny.sdkmesh", true ) );
 
    // Initializa as matrizes do mundo
    D3DXMatrixIdentity( &g_World );
 
    // Initializa a câmera
    D3DXVECTOR3 Eye( 0.0f, 0.0f, -800.0f );
    D3DXVECTOR3 At( 0.0f, 0.0f, 0.0f );
    g_Camera.SetViewParams( &Eye, &At );
 
    return S_OK;
}
 
// Crie quaisquer recursos D3D10 que dependam do buffer de trás
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain *pSwapChain,
                                        const DXGI_SURFACE_DESC *pBufferSurfaceDesc, void *pUserContext)
{
    HRESULT hr;
 
    V_RETURN( g_DialogResourceManager.OnD3D10ResizedSwapChain( pd3dDevice, pBufferSurfaceDesc ) );
    V_RETURN( g_D3DSettingsDialog.OnD3D10ResizedSwapChain( pd3dDevice, pBufferSurfaceDesc ) );
 
    // Configura os parâmetros de projeção da câmera
    float fAspect = static_cast<float>( pBufferSurfaceDesc->Width) / static_cast<float>( pBufferSurfaceDesc->Height );
    g_Camera.SetProjParams( D3DX_PI / 4, fAspect, 0.1f, 5000.0f );
    g_Camera.SetWindow( pBufferSurfaceDesc->Width, pBufferSurfaceDesc->Height );
    g_Camera.SetButtonMasks( MOUSE_MIDDLE_BUTTON, MOUSE_WHEEL, MOUSE_LEFT_BUTTON );
 
    g_HUD.SetLocation( pBufferSurfaceDesc->Width -170, 0 );
    g_HUD.SetSize( 170, 170 );
    g_SampleUI.SetLocation( pBufferSurfaceDesc->Width - 170, pBufferSurfaceDesc->Height - 300 );
    g_SampleUI.SetSize( 170, 300 );
 
    return S_OK;
}
 
// Renderiza a cena usando o dispositivo D3D10
void CALLBACK OnD3D10FrameRender( ID3D10Device *pd3dDevice, double fTime, float fElapsedTime, void *pUserContext )
{
    // Limpa o buffer de trás
    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };    // vermelho, verde, azul, alfa
    ID3D10RenderTargetView *pRTV = DXUTGetD3D10RenderTargetView();
    pd3dDevice->ClearRenderTargetView(pRTV, ClearColor );
 
    // Se o diálogo de configurações está sendo mostrado, então
    // renderiza ele ao invés de renderizar a cena da aplicação
    if( g_D3DSettingsDialog.IsActive() )
    {
        g_D3DSettingsDialog.OnRender( fElapsedTime );
        return;
    }
 
    // limpa o stencil de profundidade
    ID3D10DepthStencilView *pDSV = DXUTGetD3D10DepthStencilView();
    pd3dDevice->ClearDepthStencilView( pDSV, D3D10_CLEAR_DEPTH, 1.0, 0 );
 
    // Atualiza as variáveis que mudam uma vez por quadro
    g_pWorldVariable->SetMatrix( (float* )&g_World );
    g_pViewVariable->SetMatrix( (float*) g_Camera.GetViewMatrix() );
    g_pProjectionVariable->SetMatrix( (float*) g_Camera.GetProjMatrix() );
 
    // Configura o leiaute de vértices
    pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Renderiza a malha
    UINT Strides[1];
    UINT Offsets[1];
    ID3D10Buffer* pVB[1];
    pVB[0] = g_Mesh.GetVB10( 0, 0 );
    Strides[0] = ( UINT ) g_Mesh.GetVertexStride(0,0);
    Offsets[0] = 0;
    pd3dDevice->IASetVertexBuffers(0, 1, pVB, Strides, Offsets);
    pd3dDevice->IASetIndexBuffer( g_Mesh.GetIB10( 0 ), g_Mesh.GetIBFormat10( 0 ), 0 );
 
    D3D10_TECHNIQUE_DESC techDesc;    
    g_pTechnique->GetDesc( &techDesc );
    SDKMESH_SUBSET* pSubset = NULL;
    ID3D10ShaderResourceView* pDiffuseRV = NULL;
    D3D10_PRIMITIVE_TOPOLOGY PrimType;
 
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        for( UINT subset = 0; subset < g_Mesh.GetNumSubsets( 0 ); ++subset ){
            pSubset = g_Mesh.GetSubset( 0, subset );
 
            PrimType = g_Mesh.GetPrimitiveType10( ( SDKMESH_PRIMITIVE_TYPE ) pSubset->PrimitiveType );
            pd3dDevice->IASetPrimitiveTopology( PrimType );
 
            pDiffuseRV = g_Mesh.GetMaterial( pSubset->MaterialID )->pDiffuseRV10;
            g_ptxDiffuseVariable->SetResource( pDiffuseRV );
 
            g_pTechnique->GetPassByIndex( p )->Apply( 0 );
            pd3dDevice->DrawIndexed( ( UINT ) pSubset->IndexCount, 0, ( UINT ) pSubset->VertexStart );
        }
    }
 
    // a classe de malha também tinha um método render que permite renderizar a malha com as opções mais comuns
    // g_pMesh.Render( pd3dDevice, g_pTechnique, g_ptxDiffuseVariable );
 
    // Renderiza a UI
    g_HUD.OnRender( fElapsedTime );
    g_SampleUI.OnRender( fElapsedTime );
 
    RenderText();
}
 
// Renderiza a ajuda e o texto das estatísticas
void RenderText()
{
    g_pTxtHelper->Begin();
    g_pTxtHelper->SetInsertionPos( 2, 0 );
    g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
    g_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) );
    g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );
    g_pTxtHelper->End();
}
 
// Libera recursos D3D10 criados em OnD3D10ResizedSwapChain 
void CALLBACK OnD3D10ReleasingSwapChain( void *pUserContext ){
    g_DialogResourceManager.OnD3D10ReleasingSwapChain();
}
 
// Libera recursos D3D10 criados em OnD3D10CreateDevice 
void CALLBACK OnD3D10DestroyDevice( void *pUserContext ){
    g_DialogResourceManager.OnD3D10DestroyDevice();
    g_D3DSettingsDialog.OnD3D10DestroyDevice();
    DXUTGetGlobalResourceCache().OnDestroyDevice();
    SAFE_RELEASE( g_pFont );
    SAFE_RELEASE( g_pSprite );
    SAFE_DELETE( g_pTxtHelper );
    SAFE_RELEASE( g_pVertexLayout );
    SAFE_RELEASE( g_pEffect );
    g_Mesh.Destroy();
}
 
// Chamado imediatamente antes de criar um dispositivo D3D9 oy D3D10, permitindo o aplicativo modificar
// as configurações do dispositivo como necessário
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings *pDeviceSettings, void *pUserContext ){
    return true;
}
 
// Esta função de callback será chamada uma vez no início de todo quadro. Isto é o melhor
// local para sua aplicação manusear atualizações para a cena, mas sua intenção não é
// conter chamadas de renderização verdadeiras, que deveriam ser colocadas por sua vez
// no callback OnFrameRender
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUsetContex ){
    // Atualiza a posição da câmera baseada na entrada do usuário
    g_Camera.FrameMove( fElapsedTime );
 
    if( g_bSpinning ){
        D3DXMatrixRotationY( &g_World, 60.0f * DEG2RAD( (float) fTime ) );
    } else {
        D3DXMatrixRotationY( &g_World, DEG2RAD( 180.0f ) );
    }
 
    D3DXMATRIX mRot;
    D3DXMatrixRotationX( &mRot, DEG2RAD( -90.0f ) );
    g_World = mRot *= g_World;
}
 
// Manuseia as mensagens para a aplicação
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                         bool *pbNoFurtherProcessing, void *pUserContext )
{
    // Passa as mensagens para as chamadas do gerenciador de recurso de diálogo para que
    // o estado da GUI seja atualizado corretamente
    *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
 
    if( *pbNoFurtherProcessing ) return 0;
 
    // Passe as mensagens para a configuração de diálogo se ela ainda estiver ativa
    if( g_D3DSettingsDialog.IsActive() ){
        g_D3DSettingsDialog.MsgProc( hWnd, uMsg, wParam, lParam );
        return 0;
    }
 
    // Dê aos diálogos uma chance de manusear a mensagem primeiro
    *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing ) return 0;
    *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing ) return 0;
 
    // Passe todas as mensagens de janela restantes para a cãmera para que ela possa respodner à entrada do usuário
    g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
 
    return 0;
}
 
// Manuseia pressionamentos do teclado
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext  ){
    if( bKeyDown ){
        switch( nChar ){
            case VK_F1:    // Change as needed
                break;
        }
    }
}
 
// Manuseia os eventos da GUI
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl *pControl, void *pUserContext )
{
    switch( nControlID ){
        case IDC_TOGGLEFULLSCREEN:
            DXUTToggleFullScreen(); break;
        case IDC_TOGGLEREF:
            DXUTToggleREF(); break;
        case IDC_CHANGEDEVICE:
            g_D3DSettingsDialog.SetActive( !g_D3DSettingsDialog.IsActive() ); break;
        case IDC_TOGGLEWARP:
            DXUTToggleWARP(); break;
        case IDC_TOGGLESPIN:{
            g_bSpinning = g_SampleUI.GetCheckBox( IDC_TOGGLESPIN )->GetChecked();
            break;
        }
 
        case IDC_PUFF_SCALE:
        {
            WCHAR sz[100];
            g_fModelPuffiness = (float) (g_SampleUI.GetSlider( IDC_PUFF_SCALE )->GetValue() * 0.01f );
            swprintf_s( sz, 100, L"Inchaço: %0.2f", g_fModelPuffiness );
            g_SampleUI.GetStatic( IDC_PUFF_STATIC )->SetText( sz );
            g_pPuffiness->SetFloat( g_fModelPuffiness );
            break;
        }
    }
}

E o shader acompanhante que é responsável pelo efeito de inchaço da malha:

//--------------------------------------------------------------------------------------
// File: Tutorial10.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
Texture2D g_txDiffuse;
SamplerState samLinear
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
 
cbuffer cbConstant
{
    float3 vLightDir = float3(-0.577,0.577,-0.577);
};
 
cbuffer cbChangesEveryFrame
{
    matrix World;
    matrix View;
    matrix Projection;
};
 
cbuffer cbUserChanges
{
    float Puffiness;
};
 
struct VS_INPUT
{
    float3 Pos          : POSITION;         //position
    float3 Norm         : NORMAL;           //normal
    float2 Tex          : TEXCOORD0;        //texture coordinate
};
 
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float3 Norm : TEXCOORD0;
    float2 Tex : TEXCOORD1;
};
 
//--------------------------------------------------------------------------------------
// DepthStates
//--------------------------------------------------------------------------------------
DepthStencilState EnableDepth
{
    DepthEnable = TRUE;
    DepthWriteMask = ALL;
    DepthFunc = LESS_EQUAL;
};
 
BlendState NoBlending
{
    AlphaToCoverageEnable = FALSE;
    BlendEnable[0] = FALSE;
};
 
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
 
    input.Pos += input.Norm*Puffiness;
 
    output.Pos = mul( float4(input.Pos,1), World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Norm = mul( input.Norm, World );
    output.Tex = input.Tex;
 
    return output;
}
 
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
    // Calculate lighting assuming light color is <1,1,1,1>
    float fLighting = saturate( dot( input.Norm, vLightDir ) );
    float4 outputColor = g_txDiffuse.Sample( samLinear, input.Tex ) * fLighting;
    outputColor.a = 1;
    return outputColor;
}
 
//--------------------------------------------------------------------------------------
// Technique
//--------------------------------------------------------------------------------------
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );        
 
        SetDepthStencilState( EnableDepth, 0 );
        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}

Tutorial 11 - DXSDK - Vertex Shader

Mesma aplicação que o Tutorial 10. A única mudança é o Vertex shader, usado para fazer um efeito de ondulação no espaço da tela.

// Carregamento de malha através do DXUT
 
#include "DXUT.h"
#include "DXUTcamera.h"
#include "DXUTgui.h"
#include "DXUTsettingsDlg.h"
#include "DXUTmisc.h"
#include "SDKmisc.h"
#include "SDKmesh.h"
 
#define DEG2RAD( a ) ( a * D3DX_PI / 180.0f )
 
// Variáveis globais específicas do DXUT
CModelViewerCamera    g_Camera;    // Uma câmera de visualização do modelo
CDXUTDialogResourceManager    g_DialogResourceManager;    // gerente para recursos compartilhados de diálogos
CD3DSettingsDlg    g_D3DSettingsDialog;    // diálogo de configurações do dispositivo
CDXUTDialog    g_HUD;    // gerencia a UI 3D
CDXUTDialog    g_SampleUI;    // diálogo para controles específicos da amostra
 
// Variáveis globais específicas da aplicação
ID3DX10Font*    g_pFont = NULL;    // Fonte para desenho de texto
ID3DX10Sprite*    g_pSprite = NULL;    // SPrite para desenho de texto em lote
CDXUTTextHelper*    g_pTxtHelper = NULL;
ID3D10Effect*    g_pEffect = NULL;    // interface de efeito D3DX
ID3D10InputLayout*    g_pVertexLayout = NULL;    // Leiaute de vértice
ID3D10EffectTechnique*    g_pTechnique = NULL;
CDXUTSDKMesh    g_Mesh;
ID3D10EffectShaderResourceVariable*    g_ptxDiffuseVariable = NULL;
ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
ID3D10EffectScalarVariable*    g_pWavinessVariable = NULL;
ID3D10EffectScalarVariable*    g_pTimeVariable = NULL;
D3DXMATRIX    g_World;
float    g_fModelWaviness;
bool g_bSpinning = true;
 
// IDs de controle da UI
#define IDC_TOGGLEFULLSCREEN    1
#define IDC_TOGGLEREF           2
#define IDC_CHANGEDEVICE        3
#define IDC_TOGGLESPIN          4
#define IDC_PUFF_SCALE          5
#define IDC_PUFF_STATIC         6
#define IDC_TOGGLEWARP          7
 
// Protótipos das funções
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext );
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc, 
                                     void* pUserContext);
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain* pSwapChain,
                    const DXGI_SURFACE_DESC* pBufferSurfaceDesc, void* pUserContext);
void CALLBACK OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
void CALLBACK OnD3D10ReleasingSwapChain( void* pUserContext );
void CALLBACK OnD3D10DestroyDevice( void* pUserContext );
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void *pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool *pbNoFurtherProcessing,
                         void* pUserContext);
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext );
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUserContext );
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void *pUserContext );
 
void RenderText();
void InitApp();
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
    // Habilita checagem de memória em tempo de execução para construções debug.
#if defined( DEBUG ) | defined( _DEBUG )
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
 
    // DXUT criará e usará o melhor equipamento disponível (ou D3D9 ou D3D10)
    // isto é dependente do sistema disponível no qual os CALLBACKS do D3D são configurados abaixo
 
    // Configure callbacks DXUT
    DXUTSetCallbackD3D10DeviceAcceptable( IsD3D10DeviceAcceptable );
    DXUTSetCallbackD3D10DeviceCreated( OnD3D10CreateDevice );
    DXUTSetCallbackD3D10SwapChainResized( OnD3D10ResizeSwapChain );
    DXUTSetCallbackD3D10SwapChainReleasing( OnD3D10ReleasingSwapChain );
    DXUTSetCallbackD3D10DeviceDestroyed( OnD3D10DestroyDevice );
    DXUTSetCallbackD3D10FrameRender( OnD3D10FrameRender );
 
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackKeyboard( OnKeyboard );
    DXUTSetCallbackFrameMove( OnFrameMove );
    DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
 
    InitApp();
 
    DXUTInit( true, true, NULL );    // Parse da linha de comando, mostra caixas de mensagem no erro, sem parâmetros de linha de comando extra
    DXUTSetCursorSettings(true, true );    // Mostre o cursor e recorte ele (clip) quando em modo de tela cheia
    DXUTCreateWindow( L"Tutorial11" );
    DXUTCreateDevice( true, 640, 480 );
    DXUTMainLoop();    // Entra dentro do loop de renderização DXUT
 
    return DXUTGetExitCode();
}
 
// Inicializa a aplicação
void InitApp()
{
    g_fModelWaviness = 0.0f;
    g_bSpinning = true;
 
    g_D3DSettingsDialog.Init( &g_DialogResourceManager );
    g_HUD.Init( &g_DialogResourceManager );
    g_SampleUI.Init( &g_DialogResourceManager );
 
    g_HUD.SetCallback( OnGUIEvent );    int iY = 10;
    g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Mudar para tela cheia", 35, iY, 125, 22 );
    g_HUD.AddButton( IDC_CHANGEDEVICE, L"Mudar dispositivo (F2)", 35, iY += 24, 125, 22, VK_F2 );
    g_HUD.AddButton( IDC_TOGGLEREF, L"Mudar para REF (F3)", 35, iY += 24, 125, 22, VK_F3 );
    g_HUD.AddButton( IDC_TOGGLEWARP, L"Mudar para WARP( F4 )", 35, iY+= 24, 125, 22, VK_F4 );
 
    g_SampleUI.SetCallback( OnGUIEvent);    iY = 10;
 
    WCHAR sz[100];
    iY += 24;
    swprintf_s( sz, 100, L"Ondulação: %0.2f", g_fModelWaviness );
    g_SampleUI.AddStatic( IDC_PUFF_STATIC, sz, 35, iY += 24, 125, 22 );
    g_SampleUI.AddSlider( IDC_PUFF_SCALE, 50, iY += 24, 100, 22, 0, 2000, ( int ) ( g_fModelWaviness * 100.0f ) );
 
    iY += 24;
    g_SampleUI.AddCheckBox( IDC_TOGGLESPIN, L"Girar", 35, iY += 24, 125, 22, g_bSpinning );
}
 
// Rejeita qualquer equipamento D3D10 que não é aceitável por retornar falso
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext ){
      return true;
}
 
// Crie quaisquer recursos que não são dependentes do buffer de trás
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc,
                                      void* pUserContext )
{
    HRESULT hr;
 
    V_RETURN( g_DialogResourceManager.OnD3D10CreateDevice( pd3dDevice ) );
    V_RETURN( g_D3DSettingsDialog.OnD3D10CreateDevice( pd3dDevice ) );
    V_RETURN( D3DX10CreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
        OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
        L"Arial", &g_pFont ) );
 
    V_RETURN( D3DX10CreateSprite( pd3dDevice, 512, &g_pSprite ) );
    g_pTxtHelper = new CDXUTTextHelper( NULL, NULL, g_pFont, g_pSprite, 15 );
 
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Configura a opção D3D10_SHADER_DEBUG para embutir informãção de debug nos shaders.
    // Configurar esta opção melhora a experiência de debugação do shader, mas ainda permite
    // que os shaders sejam otimizados para executar à maneira que eles executarão na 
    // configuração release deste programa.
    dwShaderFlags |= D3D10_SHADER_DEBUG;
    #endif
 
    // Ache o arquivo de efeito D3DX
    WCHAR str[MAX_PATH];
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"..\\Tutorial11.fx" ) );
    V_RETURN( D3DX10CreateEffectFromFile( str, NULL, NULL, "fx_4_0", dwShaderFlags, 0, pd3dDevice, NULL,
                                              NULL, &g_pEffect, NULL, NULL ) );
 
    // Obtém a técnica
    g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
 
    // Obtém as variáveis
    g_ptxDiffuseVariable = g_pEffect->GetVariableByName( "g_txDiffuse" )->AsShaderResource();
    g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
    g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
    g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
    g_pWavinessVariable = g_pEffect->GetVariableByName( "Waviness" )->AsScalar();
    g_pTimeVariable = g_pEffect->GetVariableByName( "Time" )->AsScalar();
 
    // Configura a ondulação
    g_pWavinessVariable->SetFloat( g_fModelWaviness );
 
    // Define o leiaute de entrada
    const D3D10_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Cria o leiaute de entrada
    D3D10_PASS_DESC PassDesc;
    g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    V_RETURN( pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
                                             PassDesc.IAInputSignatureSize, &g_pVertexLayout ) );
 
    // Configura o leiaute de entrada
    pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Carrega a malha
    V_RETURN( g_Mesh.Create( pd3dDevice, L"..\\Media\\Tiny\\tiny.sdkmesh", true ) );
 
    // Initializa as matrizes do mundo
    D3DXMatrixIdentity( &g_World );
 
    // Initializa a câmera
    D3DXVECTOR3 Eye( 0.0f, 0.0f, -800.0f );
    D3DXVECTOR3 At( 0.0f, 0.0f, 0.0f );
    g_Camera.SetViewParams( &Eye, &At );
 
    return S_OK;
}
 
// Crie quaisquer recursos D3D10 que dependam do buffer de trás
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain *pSwapChain,
                                        const DXGI_SURFACE_DESC *pBufferSurfaceDesc, void *pUserContext)
{
    HRESULT hr;
 
    V_RETURN( g_DialogResourceManager.OnD3D10ResizedSwapChain( pd3dDevice, pBufferSurfaceDesc ) );
    V_RETURN( g_D3DSettingsDialog.OnD3D10ResizedSwapChain( pd3dDevice, pBufferSurfaceDesc ) );
 
    // Configura os parâmetros de projeção da câmera
    float fAspect = static_cast<float>( pBufferSurfaceDesc->Width) / static_cast<float>( pBufferSurfaceDesc->Height );
    g_Camera.SetProjParams( D3DX_PI / 4, fAspect, 0.1f, 5000.0f );
    g_Camera.SetWindow( pBufferSurfaceDesc->Width, pBufferSurfaceDesc->Height );
    g_Camera.SetButtonMasks( MOUSE_MIDDLE_BUTTON, MOUSE_WHEEL, MOUSE_LEFT_BUTTON );
 
    g_HUD.SetLocation( pBufferSurfaceDesc->Width -170, 0 );
    g_HUD.SetSize( 170, 170 );
    g_SampleUI.SetLocation( pBufferSurfaceDesc->Width - 170, pBufferSurfaceDesc->Height - 300 );
    g_SampleUI.SetSize( 170, 300 );
 
    return S_OK;
}
 
// Renderiza a cena usando o dispositivo D3D10
void CALLBACK OnD3D10FrameRender( ID3D10Device *pd3dDevice, double fTime, float fElapsedTime, void *pUserContext )
{
    // Se o diálogo de configurações está sendo mostrado, então
    // renderiza ele ao invés de renderizar a cena da aplicação
    if( g_D3DSettingsDialog.IsActive() )
    {
        g_D3DSettingsDialog.OnRender( fElapsedTime );
        return;
    }
 
    // Limpa o buffer de trás
    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };    // vermelho, verde, azul, alfa
    ID3D10RenderTargetView *pRTV = DXUTGetD3D10RenderTargetView();
    pd3dDevice->ClearRenderTargetView(pRTV, ClearColor );
 
    // limpa o stencil de profundidade
    ID3D10DepthStencilView *pDSV = DXUTGetD3D10DepthStencilView();
    pd3dDevice->ClearDepthStencilView( pDSV, D3D10_CLEAR_DEPTH, 1.0, 0 );
 
    // Atualiza as variáveis que mudam uma vez por quadro
    g_pWorldVariable->SetMatrix( (float* )&g_World );
    g_pViewVariable->SetMatrix( (float*) g_Camera.GetViewMatrix() );
    g_pProjectionVariable->SetMatrix( (float*) g_Camera.GetProjMatrix() );
    g_pTimeVariable->SetFloat( ( float ) fTime );
 
    // Configura o leiaute de vértices
    pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Renderiza a malha
    UINT Strides[1];
    UINT Offsets[1];
    ID3D10Buffer* pVB[1];
    pVB[0] = g_Mesh.GetVB10( 0, 0 );
    Strides[0] = ( UINT ) g_Mesh.GetVertexStride(0,0);
    Offsets[0] = 0;
    pd3dDevice->IASetVertexBuffers(0, 1, pVB, Strides, Offsets);
    pd3dDevice->IASetIndexBuffer( g_Mesh.GetIB10( 0 ), g_Mesh.GetIBFormat10( 0 ), 0 );
 
    D3D10_TECHNIQUE_DESC techDesc;    
    g_pTechnique->GetDesc( &techDesc );
    SDKMESH_SUBSET* pSubset = NULL;
    ID3D10ShaderResourceView* pDiffuseRV = NULL;
    D3D10_PRIMITIVE_TOPOLOGY PrimType;
 
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        for( UINT subset = 0; subset < g_Mesh.GetNumSubsets( 0 ); ++subset ){
            pSubset = g_Mesh.GetSubset( 0, subset );
 
            PrimType = g_Mesh.GetPrimitiveType10( ( SDKMESH_PRIMITIVE_TYPE ) pSubset->PrimitiveType );
            pd3dDevice->IASetPrimitiveTopology( PrimType );
 
            pDiffuseRV = g_Mesh.GetMaterial( pSubset->MaterialID )->pDiffuseRV10;
            g_ptxDiffuseVariable->SetResource( pDiffuseRV );
 
            g_pTechnique->GetPassByIndex( p )->Apply( 0 );
            pd3dDevice->DrawIndexed( ( UINT ) pSubset->IndexCount, 0, ( UINT ) pSubset->VertexStart );
        }
    }
 
    // a classe de malha também tinha um método render que permite renderizar a malha com as opções mais comuns
    // g_pMesh.Render( pd3dDevice, g_pTechnique, g_ptxDiffuseVariable );
 
    // Renderiza a UI
    g_HUD.OnRender( fElapsedTime );
    g_SampleUI.OnRender( fElapsedTime );
 
    RenderText();
}
 
// Renderiza a ajuda e o texto das estatísticas
void RenderText()
{
    g_pTxtHelper->Begin();
    g_pTxtHelper->SetInsertionPos( 2, 0 );
    g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
    g_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) );
    g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );
    g_pTxtHelper->End();
}
 
// Libera recursos D3D10 criados em OnD3D10ResizedSwapChain 
void CALLBACK OnD3D10ReleasingSwapChain( void *pUserContext ){
    g_DialogResourceManager.OnD3D10ReleasingSwapChain();
}
 
// Libera recursos D3D10 criados em OnD3D10CreateDevice 
void CALLBACK OnD3D10DestroyDevice( void *pUserContext ){
    g_DialogResourceManager.OnD3D10DestroyDevice();
    g_D3DSettingsDialog.OnD3D10DestroyDevice();
    DXUTGetGlobalResourceCache().OnDestroyDevice();
    SAFE_RELEASE( g_pFont );
    SAFE_RELEASE( g_pSprite );
    SAFE_DELETE( g_pTxtHelper );
    SAFE_RELEASE( g_pVertexLayout );
    SAFE_RELEASE( g_pEffect );
    g_Mesh.Destroy();
}
 
// Chamado imediatamente antes de criar um dispositivo D3D9 oy D3D10, permitindo o aplicativo modificar
// as configurações do dispositivo como necessário
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings *pDeviceSettings, void *pUserContext ){
    return true;
}
 
// Esta função de callback será chamada uma vez no início de todo quadro. Isto é o melhor
// local para sua aplicação manusear atualizações para a cena, mas sua intenção não é
// conter chamadas de renderização verdadeiras, que deveriam ser colocadas por sua vez
// no callback OnFrameRender
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUsetContex ){
    // Atualiza a posição da câmera baseada na entrada do usuário
    g_Camera.FrameMove( fElapsedTime );
 
    if( g_bSpinning ){
        D3DXMatrixRotationY( &g_World, 60.0f * DEG2RAD( (float) fTime ) );
    } else {
        D3DXMatrixRotationY( &g_World, DEG2RAD( 180.0f ) );
    }
 
    D3DXMATRIX mRot;
    D3DXMatrixRotationX( &mRot, DEG2RAD( -90.0f ) );
    g_World = mRot * g_World;
}
 
// Manuseia as mensagens para a aplicação
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                         bool *pbNoFurtherProcessing, void *pUserContext )
{
    // Passa as mensagens para as chamadas do gerenciador de recurso de diálogo para que
    // o estado da GUI seja atualizado corretamente
    *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
 
    if( *pbNoFurtherProcessing ) return 0;
 
    // Passe as mensagens para a configuração de diálogo se ela ainda estiver ativa
    if( g_D3DSettingsDialog.IsActive() ){
        g_D3DSettingsDialog.MsgProc( hWnd, uMsg, wParam, lParam );
        return 0;
    }
 
    // Dê aos diálogos uma chance de manusear a mensagem primeiro
    *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing ) return 0;
    *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing ) return 0;
 
    // Passe todas as mensagens de janela restantes para a cãmera para que ela possa respodner à entrada do usuário
    g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
 
    return 0;
}
 
// Manuseia pressionamentos do teclado
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext  ){
}
 
// Manuseia os eventos da GUI
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl *pControl, void *pUserContext )
{
    switch( nControlID ){
        case IDC_TOGGLEFULLSCREEN:
            DXUTToggleFullScreen(); break;
        case IDC_TOGGLEREF:
            DXUTToggleREF(); break;
        case IDC_CHANGEDEVICE:
            g_D3DSettingsDialog.SetActive( !g_D3DSettingsDialog.IsActive() ); break;
        case IDC_TOGGLEWARP:
            DXUTToggleWARP(); break;
        case IDC_TOGGLESPIN:{
            g_bSpinning = g_SampleUI.GetCheckBox( IDC_TOGGLESPIN )->GetChecked();
            break;
        }
 
        case IDC_PUFF_SCALE:
        {
            WCHAR sz[100];
            g_fModelWaviness = (float) (g_SampleUI.GetSlider( IDC_PUFF_SCALE )->GetValue() * 0.01f );
            swprintf_s( sz, 100, L"Ondulação: %0.2f", g_fModelWaviness );
            g_SampleUI.GetStatic( IDC_PUFF_STATIC )->SetText( sz );
            g_pWavinessVariable->SetFloat( g_fModelWaviness );
            break;
        }
    }
}

E o arquivo de efeito responsável pela ondulação:

//--------------------------------------------------------------------------------------
// File: Tutorial11.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
Texture2D g_txDiffuse;
SamplerState samLinear
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
 
cbuffer cbConstant
{
    float3 vLightDir = float3(-0.577,0.577,-0.577);
};
 
cbuffer cbChangesEveryFrame
{
    matrix World;
    matrix View;
    matrix Projection;
    float Time;
};
 
cbuffer cbUserChanges
{
    float Waviness;
};
 
struct VS_INPUT
{
    float3 Pos          : POSITION;        
    float3 Norm         : NORMAL;          
    float2 Tex          : TEXCOORD0;       
};
 
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float3 Norm : TEXCOORD0;
    float2 Tex : TEXCOORD1;
};
 
//--------------------------------------------------------------------------------------
// DepthStates
//--------------------------------------------------------------------------------------
DepthStencilState EnableDepth
{
    DepthEnable = TRUE;
    DepthWriteMask = ALL;
    DepthFunc = LESS_EQUAL;
};
 
BlendState NoBlending
{
    AlphaToCoverageEnable = FALSE;
    BlendEnable[0] = FALSE;
};
 
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
 
    output.Pos = mul( float4(input.Pos,1), World );
 
    output.Pos.x += sin( output.Pos.y*0.1f + Time )*Waviness;
 
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Norm = mul( input.Norm, World );
    output.Tex = input.Tex;
 
    return output;
}
 
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
    // Calculate lighting assuming light color is <1,1,1,1>
    float fLighting = saturate( dot( input.Norm, vLightDir ) );
    float4 outputColor = g_txDiffuse.Sample( samLinear, input.Tex ) * fLighting;
    outputColor.a = 1;
    return outputColor;
}
 
//--------------------------------------------------------------------------------------
// Technique
//--------------------------------------------------------------------------------------
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );        
 
        SetDepthStencilState( EnableDepth, 0 );
        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}

Tutorial 12 - DXSDK - Pixel Shader

Este tutorial tem código muito similar aos outros dois anteriores, diferenciando-se principalmente em relação ao efeito aplicado. O efeito deste tutorial usa um mapa ambiente (Environment Map) para simular reflexões.

// Carregamento de malha através do DXUT
 
#include "DXUT.h"
#include "DXUTcamera.h"
#include "DXUTgui.h"
#include "DXUTsettingsDlg.h"
#include "DXUTmisc.h"
#include "SDKmisc.h"
#include "SDKmesh.h"
 
#define DEG2RAD( a ) ( a * D3DX_PI / 180.0f )
 
// Variáveis globais específicas do DXUT
CModelViewerCamera    g_Camera;    // Uma câmera de visualização do modelo
CDXUTDialogResourceManager    g_DialogResourceManager;    // gerente para recursos compartilhados de diálogos
CD3DSettingsDlg    g_D3DSettingsDialog;    // diálogo de configurações do dispositivo
CDXUTDialog    g_HUD;    // gerencia a UI 3D
CDXUTDialog    g_SampleUI;    // diálogo para controles específicos da amostra
 
// Variáveis globais específicas da aplicação
ID3DX10Font*    g_pFont = NULL;    // Fonte para desenho de texto
ID3DX10Sprite*    g_pSprite = NULL;    // SPrite para desenho de texto em lote
CDXUTTextHelper*    g_pTxtHelper = NULL;
ID3D10Effect*    g_pEffect = NULL;    // interface de efeito D3DX
ID3D10InputLayout*    g_pVertexLayout = NULL;    // Leiaute de vértice
ID3D10EffectTechnique*    g_pTechnique = NULL;
CDXUTSDKMesh    g_Mesh;
ID3D10ShaderResourceView*    g_pEnvMapSRV;
ID3D10EffectShaderResourceVariable*    g_ptxDiffuseVariable = NULL;
ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
ID3D10EffectShaderResourceVariable*    g_pEnvMapVariable = NULL;
D3DXMATRIX    g_World;
bool g_bSpinning = true;
 
// IDs de controle da UI
#define IDC_TOGGLEFULLSCREEN    1
#define IDC_TOGGLEREF           2
#define IDC_CHANGEDEVICE        3
#define IDC_TOGGLESPIN          4
#define IDC_TOGGLEWARP          5
 
// Protótipos das funções
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext );
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc, 
                                     void* pUserContext);
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain* pSwapChain,
                    const DXGI_SURFACE_DESC* pBufferSurfaceDesc, void* pUserContext);
void CALLBACK OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
void CALLBACK OnD3D10ReleasingSwapChain( void* pUserContext );
void CALLBACK OnD3D10DestroyDevice( void* pUserContext );
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void *pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool *pbNoFurtherProcessing,
                         void* pUserContext);
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext );
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUserContext );
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void *pUserContext );
 
void RenderText();
void InitApp();
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
    // Habilita checagem de memória em tempo de execução para construções debug.
#if defined( DEBUG ) | defined( _DEBUG )
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
 
    // DXUT criará e usará o melhor equipamento disponível (ou D3D9 ou D3D10)
    // isto é dependente do sistema disponível no qual os CALLBACKS do D3D são configurados abaixo
 
    // Configure callbacks DXUT
    DXUTSetCallbackD3D10DeviceAcceptable( IsD3D10DeviceAcceptable );
    DXUTSetCallbackD3D10DeviceCreated( OnD3D10CreateDevice );
    DXUTSetCallbackD3D10SwapChainResized( OnD3D10ResizeSwapChain );
    DXUTSetCallbackD3D10SwapChainReleasing( OnD3D10ReleasingSwapChain );
    DXUTSetCallbackD3D10DeviceDestroyed( OnD3D10DestroyDevice );
    DXUTSetCallbackD3D10FrameRender( OnD3D10FrameRender );
 
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackKeyboard( OnKeyboard );
    DXUTSetCallbackFrameMove( OnFrameMove );
    DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
 
    InitApp();
 
    DXUTInit( true, true, NULL );    // Parse da linha de comando, mostra caixas de mensagem no erro, sem parâmetros de linha de comando extra
    DXUTSetCursorSettings(true, true );    // Mostre o cursor e recorte ele (clip) quando em modo de tela cheia
    DXUTCreateWindow( L"Tutorial12" );
    DXUTCreateDevice( true, 640, 480 );
    DXUTMainLoop();    // Entra dentro do loop de renderização DXUT
 
    return DXUTGetExitCode();
}
 
// Inicializa a aplicação
void InitApp()
{
    g_bSpinning = true;
 
    g_D3DSettingsDialog.Init( &g_DialogResourceManager );
    g_HUD.Init( &g_DialogResourceManager );
    g_SampleUI.Init( &g_DialogResourceManager );
 
    g_HUD.SetCallback( OnGUIEvent );    int iY = 10;
    g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Mudar para tela cheia", 35, iY, 125, 22 );
    g_HUD.AddButton( IDC_CHANGEDEVICE, L"Mudar dispositivo (F2)", 35, iY += 24, 125, 22, VK_F2 );
    g_HUD.AddButton( IDC_TOGGLEREF, L"Mudar para REF (F3)", 35, iY += 24, 125, 22, VK_F3 );
    g_HUD.AddButton( IDC_TOGGLEWARP, L"Mudar para WARP( F4 )", 35, iY+= 24, 125, 22, VK_F4 );
 
    g_SampleUI.SetCallback( OnGUIEvent);    iY = 10;
 
    iY += 24;
    g_SampleUI.AddCheckBox( IDC_TOGGLESPIN, L"Girar", 35, iY += 24, 125, 22, g_bSpinning );
}
 
// Rejeita qualquer equipamento D3D10 que não é aceitável por retornar falso
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext ){
      return true;
}
 
// Crie quaisquer recursos que não são dependentes do buffer de trás
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc,
                                      void* pUserContext )
{
    HRESULT hr;
 
    V_RETURN( g_DialogResourceManager.OnD3D10CreateDevice( pd3dDevice ) );
    V_RETURN( g_D3DSettingsDialog.OnD3D10CreateDevice( pd3dDevice ) );
    V_RETURN( D3DX10CreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
        OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
        L"Arial", &g_pFont ) );
 
    V_RETURN( D3DX10CreateSprite( pd3dDevice, 512, &g_pSprite ) );
    g_pTxtHelper = new CDXUTTextHelper( NULL, NULL, g_pFont, g_pSprite, 15 );
 
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Configura a opção D3D10_SHADER_DEBUG para embutir informãção de debug nos shaders.
    // Configurar esta opção melhora a experiência de debugação do shader, mas ainda permite
    // que os shaders sejam otimizados para executar à maneira que eles executarão na 
    // configuração release deste programa.
    dwShaderFlags |= D3D10_SHADER_DEBUG;
    #endif
 
    // Ache o arquivo de efeito D3DX
    WCHAR str[MAX_PATH];
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"..\\Tutorial12.fx" ) );
    V_RETURN( D3DX10CreateEffectFromFile( str, NULL, NULL, "fx_4_0", dwShaderFlags, 0, pd3dDevice, NULL,
                                              NULL, &g_pEffect, NULL, NULL ) );
 
    // Obtém a técnica
    g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
 
    // Obtém as variáveis
    g_ptxDiffuseVariable = g_pEffect->GetVariableByName( "g_txDiffuse" )->AsShaderResource();
    g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
    g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
    g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
    g_pEnvMapVariable = g_pEffect->GetVariableByName( "g_txEnvMap" )->AsShaderResource();
 
    // Define o leiaute de entrada
    const D3D10_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Cria o leiaute de entrada
    D3D10_PASS_DESC PassDesc;
    g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    V_RETURN( pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
                                             PassDesc.IAInputSignatureSize, &g_pVertexLayout ) );
 
    // Configura o leiaute de entrada
    pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Carrega a malha
    V_RETURN( g_Mesh.Create( pd3dDevice, L"..\\Media\\Tiny\\tiny.sdkmesh", true ) );
 
    // Initializa as matrizes do mundo
    D3DXMatrixIdentity( &g_World );
 
    // Carrega o Mapa ambiente (Environment map)
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"..\\Media\\Lobby\\LobbyCube.dds" ) );
    hr = D3DX10CreateShaderResourceViewFromFile( pd3dDevice, str, NULL, NULL,
        &g_pEnvMapSRV, NULL );
 
    // Configura o mapa ambiente
    g_pEnvMapVariable->SetResource( g_pEnvMapSRV );
 
    // Initializa a câmera
    D3DXVECTOR3 Eye( 0.0f, 0.0f, -800.0f );
    D3DXVECTOR3 At( 0.0f, 0.0f, 0.0f );
    g_Camera.SetViewParams( &Eye, &At );
 
    return S_OK;
}
 
// Esta função de callback será chamada imediatamente quando a swapchain foi redimensionada.
// Isto é normalmente em resposta a janela ser redimensionada ou às configurações de exibição
// serem modificadas enquanto no modo de tela cheia. Isto dá a aplicação uma chance de criar
// objetos que são dependentes da swap chain.
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain *pSwapChain,
                                        const DXGI_SURFACE_DESC *pBufferSurfaceDesc, void *pUserContext)
{
    HRESULT hr;
 
    V_RETURN( g_DialogResourceManager.OnD3D10ResizedSwapChain( pd3dDevice, pBufferSurfaceDesc ) );
    V_RETURN( g_D3DSettingsDialog.OnD3D10ResizedSwapChain( pd3dDevice, pBufferSurfaceDesc ) );
 
    // Configura os parâmetros de projeção da câmera
    float fAspect = static_cast<float>( pBufferSurfaceDesc->Width) / static_cast<float>( pBufferSurfaceDesc->Height );
    g_Camera.SetProjParams( D3DX_PI / 4, fAspect, 0.1f, 5000.0f );
    g_Camera.SetWindow( pBufferSurfaceDesc->Width, pBufferSurfaceDesc->Height );
    g_Camera.SetButtonMasks( MOUSE_MIDDLE_BUTTON, MOUSE_WHEEL, MOUSE_LEFT_BUTTON );
 
    g_HUD.SetLocation( pBufferSurfaceDesc->Width -170, 0 );
    g_HUD.SetSize( 170, 170 );
    g_SampleUI.SetLocation( pBufferSurfaceDesc->Width - 170, pBufferSurfaceDesc->Height - 300 );
    g_SampleUI.SetSize( 170, 300 );
 
    return S_OK;
}
 
// Esta função de callback servirá para renderizar um quadro. A apresentação é tomada conta por
// DXUT agora, então não há chamada present nesta função
void CALLBACK OnD3D10FrameRender( ID3D10Device *pd3dDevice, double fTime, float fElapsedTime, void *pUserContext )
{
    // Se o diálogo de configurações está sendo mostrado, então
    // renderiza ele ao invés de renderizar a cena da aplicação
    if( g_D3DSettingsDialog.IsActive() )
    {
        g_D3DSettingsDialog.OnRender( fElapsedTime );
        return;
    }
 
    // Limpa o buffer de trás
    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };    // vermelho, verde, azul, alfa
    ID3D10RenderTargetView *pRTV = DXUTGetD3D10RenderTargetView();
    pd3dDevice->ClearRenderTargetView(pRTV, ClearColor );
 
    // limpa o stencil de profundidade
    ID3D10DepthStencilView *pDSV = DXUTGetD3D10DepthStencilView();
    pd3dDevice->ClearDepthStencilView( pDSV, D3D10_CLEAR_DEPTH, 1.0, 0 );
 
    // Atualiza as variáveis que mudam uma vez por quadro
    g_pWorldVariable->SetMatrix( (float* )&g_World );
    g_pViewVariable->SetMatrix( (float*) g_Camera.GetViewMatrix() );
    g_pProjectionVariable->SetMatrix( (float*) g_Camera.GetProjMatrix() );
 
    // Configura o leiaute de vértices
    pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Renderiza a malha
    UINT Strides[1];
    UINT Offsets[1];
    ID3D10Buffer* pVB[1];
    pVB[0] = g_Mesh.GetVB10( 0, 0 );
    Strides[0] = ( UINT ) g_Mesh.GetVertexStride(0,0);
    Offsets[0] = 0;
    pd3dDevice->IASetVertexBuffers(0, 1, pVB, Strides, Offsets);
    pd3dDevice->IASetIndexBuffer( g_Mesh.GetIB10( 0 ), g_Mesh.GetIBFormat10( 0 ), 0 );
 
    D3D10_TECHNIQUE_DESC techDesc;    
    g_pTechnique->GetDesc( &techDesc );
    SDKMESH_SUBSET* pSubset = NULL;
    ID3D10ShaderResourceView* pDiffuseRV = NULL;
    D3D10_PRIMITIVE_TOPOLOGY PrimType;
 
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        for( UINT subset = 0; subset < g_Mesh.GetNumSubsets( 0 ); ++subset ){
            pSubset = g_Mesh.GetSubset( 0, subset );
 
            PrimType = g_Mesh.GetPrimitiveType10( ( SDKMESH_PRIMITIVE_TYPE ) pSubset->PrimitiveType );
            pd3dDevice->IASetPrimitiveTopology( PrimType );
 
            pDiffuseRV = g_Mesh.GetMaterial( pSubset->MaterialID )->pDiffuseRV10;
            g_ptxDiffuseVariable->SetResource( pDiffuseRV );
 
            g_pTechnique->GetPassByIndex( p )->Apply( 0 );
            pd3dDevice->DrawIndexed( ( UINT ) pSubset->IndexCount, 0, ( UINT ) pSubset->VertexStart );
        }
    }
 
    // a classe de malha também tinha um método render que permite renderizar a malha com as opções mais comuns
    // g_pMesh.Render( pd3dDevice, g_pTechnique, g_ptxDiffuseVariable );
 
    // Renderiza a UI
    g_HUD.OnRender( fElapsedTime );
    g_SampleUI.OnRender( fElapsedTime );
 
    RenderText();
}
 
// Renderiza a ajuda e o texto das estatísticas
void RenderText()
{
    g_pTxtHelper->Begin();
    g_pTxtHelper->SetInsertionPos( 2, 0 );
    g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
    g_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) );
    g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );
    g_pTxtHelper->End();
}
 
// Libera recursos D3D10 criados em OnD3D10ResizedSwapChain 
void CALLBACK OnD3D10ReleasingSwapChain( void *pUserContext ){
    g_DialogResourceManager.OnD3D10ReleasingSwapChain();
}
 
// Libera recursos D3D10 criados em OnD3D10CreateDevice 
void CALLBACK OnD3D10DestroyDevice( void *pUserContext ){
    g_DialogResourceManager.OnD3D10DestroyDevice();
    g_D3DSettingsDialog.OnD3D10DestroyDevice();
    DXUTGetGlobalResourceCache().OnDestroyDevice();
    SAFE_RELEASE( g_pFont );
    SAFE_RELEASE( g_pSprite );
    SAFE_DELETE( g_pTxtHelper );
    SAFE_RELEASE( g_pVertexLayout );
    SAFE_RELEASE( g_pEffect );
    SAFE_RELEASE( g_pEnvMapSRV );
    g_Mesh.Destroy();
}
 
// Chamado imediatamente antes de criar um dispositivo D3D9 oy D3D10, permitindo o aplicativo modificar
// as configurações do dispositivo como necessário
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings *pDeviceSettings, void *pUserContext ){
    return true;
}
 
// Manuseia atualizações para a cena. Isto é chamado indiferentemente de qual API D3D é usada
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUsetContex ){
    // Atualiza a posição da câmera baseada na entrada do usuário
    g_Camera.FrameMove( fElapsedTime );
 
    if( g_bSpinning ){
        D3DXMatrixRotationY( &g_World, 60.0f * DEG2RAD( (float) fTime ) );
    } else {
        D3DXMatrixRotationY( &g_World, DEG2RAD( 180.0f ) );
    }
 
    D3DXMATRIX mRot;
    D3DXMatrixRotationX( &mRot, DEG2RAD( -90.0f ) );
    g_World = mRot * g_World;
}
 
// Manuseia as mensagens para a aplicação
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                         bool *pbNoFurtherProcessing, void *pUserContext )
{
    // Passa as mensagens para as chamadas do gerenciador de recurso de diálogo para que
    // o estado da GUI seja atualizado corretamente
    *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
 
    if( *pbNoFurtherProcessing ) return 0;
 
    // Passe as mensagens para a configuração de diálogo se ela ainda estiver ativa
    if( g_D3DSettingsDialog.IsActive() ){
        g_D3DSettingsDialog.MsgProc( hWnd, uMsg, wParam, lParam );
        return 0;
    }
 
    // Dê aos diálogos uma chance de manusear a mensagem primeiro
    *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing ) return 0;
    *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing ) return 0;
 
    // Passe todas as mensagens de janela restantes para a cãmera para que ela possa respodner à entrada do usuário
    g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
 
    return 0;
}
 
// Manuseia pressionamentos do teclado
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext  ){
}
 
// Manuseia os eventos da GUI
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl *pControl, void *pUserContext )
{
    switch( nControlID ){
        case IDC_TOGGLEFULLSCREEN:
            DXUTToggleFullScreen(); break;
        case IDC_TOGGLEREF:
            DXUTToggleREF(); break;
        case IDC_CHANGEDEVICE:
            g_D3DSettingsDialog.SetActive( !g_D3DSettingsDialog.IsActive() ); break;
        case IDC_TOGGLEWARP:
            DXUTToggleWARP(); break;
        case IDC_TOGGLESPIN:{
            g_bSpinning = g_SampleUI.GetCheckBox( IDC_TOGGLESPIN )->GetChecked();
            break;
        }
    }
}

E o shader ligado a ele

//
// Constant Buffer Variables
//
 
Texture2D g_txDiffuse;
SamplerState samLinear
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
 
TextureCube g_txEnvMap;
SamplerState samLinearClamp
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Clamp;
    AddressV = Clamp;
};
 
cbuffer cbConstant
{
    float3 vLightDir = float3(-0.577,0.577,-0.577);
};
 
cbuffer cbChangesEveryFrame
{
    matrix World;
    matrix View;
    matrix Projection;
    float Time;
};
 
cbuffer cbUserChanges
{
    float Waviness;
};
 
struct VS_INPUT
{
    float3 Pos          : POSITION;         //position
    float3 Norm         : NORMAL;           //normal
    float2 Tex          : TEXCOORD0;        //texture coordinate
};
 
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float3 Norm : TEXCOORD0;
    float2 Tex : TEXCOORD1;
    float3 ViewR : TEXCOORD2;
};
 
//--------------------------------------------------------------------------------------
// DepthStates
//--------------------------------------------------------------------------------------
DepthStencilState EnableDepth
{
    DepthEnable = TRUE;
    DepthWriteMask = ALL;
    DepthFunc = LESS_EQUAL;
};
 
BlendState NoBlending
{
    AlphaToCoverageEnable = FALSE;
    BlendEnable[0] = FALSE;
};
 
//
// Vertex Shader
//
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
 
    output.Pos = mul( float4(input.Pos,1), World );
 
    output.Pos.x += sin( output.Pos.y*0.1f + Time )*Waviness;
 
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Norm = mul( input.Norm, (float3x3)World );
    output.Tex = input.Tex;
 
    // Calculate the reflection vector
    float3 viewNorm = mul( output.Norm, (float3x3)View );
    output.ViewR = reflect( viewNorm, float3(0,0,-1.0) );
 
    return output;
}
 
//
// Pixel Shader
//
float4 PS( PS_INPUT input) : SV_Target
{
    // Calculate lighting assuming light color is <1,1,1,1>
    float fLighting = saturate( dot( input.Norm, vLightDir ) );
 
    // Load the environment map texture
    float4 cReflect = g_txEnvMap.Sample( samLinearClamp, input.ViewR );
 
    // Load the diffuse texture and multiply by the lighting amount
    float4 cDiffuse = g_txDiffuse.Sample( samLinear, input.Tex ) * fLighting;
 
    // Add diffuse to reflection and go
    float4 cTotal = cDiffuse + cReflect;
    cTotal.a = 1;
    return cTotal;
}
 
//
// Technique
//
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
 
        SetDepthStencilState( EnableDepth, 0 );
        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}

Tutorial 13 - DXSDK - Geometry Shader

Este tutorial é parecido com os outros três anteriores, diferenciando-se principalmente quanto ao arquivo de efeito que agora adiciona um Geometry Shader (Shader Geometria) para o pipeline para implementar um efeito de "explosão"

// Introdução para o Geometry Shader (Shader Geometria)
 
#include "DXUT.h"
#include "DXUTcamera.h"
#include "DXUTgui.h"
#include "DXUTsettingsDlg.h"
#include "DXUTmisc.h"
#include "SDKmisc.h"
#include "SDKmesh.h"
 
#define DEG2RAD( a ) ( a * D3DX_PI / 180.0f )
 
// Variáveis globais específicas do DXUT
CModelViewerCamera    g_Camera;    // Uma câmera de visualização do modelo
CDXUTDialogResourceManager    g_DialogResourceManager;    // gerente para recursos compartilhados de diálogos
CD3DSettingsDlg    g_D3DSettingsDialog;    // diálogo de configurações do dispositivo
CDXUTDialog    g_HUD;    // gerencia a UI 3D
CDXUTDialog    g_SampleUI;    // diálogo para controles específicos da amostra
 
// Variáveis globais específicas da aplicação
ID3DX10Font*    g_pFont = NULL;    // Fonte para desenho de texto
ID3DX10Sprite*    g_pSprite = NULL;    // SPrite para desenho de texto em lote
CDXUTTextHelper*    g_pTxtHelper = NULL;
ID3D10Effect*    g_pEffect = NULL;    // interface de efeito D3DX
ID3D10InputLayout*    g_pVertexLayout = NULL;    // Leiaute de vértice
ID3D10EffectTechnique*    g_pTechnique = NULL;
CDXUTSDKMesh    g_Mesh;
ID3D10EffectShaderResourceVariable*    g_ptxDiffuseVariable = NULL;
ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
ID3D10EffectScalarVariable*    g_pExplodeVariable = NULL;
D3DXMATRIX    g_World;
bool g_bSpinning = true;
float g_fExplode = 0.0f;
 
// IDs de controle da UI
#define IDC_TOGGLEFULLSCREEN    1
#define IDC_TOGGLEREF           2
#define IDC_CHANGEDEVICE        3
#define IDC_TOGGLESPIN          4
#define IDC_EXPLODE_SCALE       5
#define IDC_EXPLODE_STATIC      6
#define IDC_TOGGLEWARP          7
 
// Protótipos das funções
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext );
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc, 
                                     void* pUserContext);
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain* pSwapChain,
                    const DXGI_SURFACE_DESC* pBufferSurfaceDesc, void* pUserContext);
void CALLBACK OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
void CALLBACK OnD3D10ReleasingSwapChain( void* pUserContext );
void CALLBACK OnD3D10DestroyDevice( void* pUserContext );
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void *pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool *pbNoFurtherProcessing,
                         void* pUserContext);
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext );
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUserContext );
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void *pUserContext );
 
void RenderText();
void InitApp();
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
    // Habilita checagem de memória em tempo de execução para construções debug.
#if defined( DEBUG ) | defined( _DEBUG )
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
 
    // DXUT criará e usará o melhor equipamento disponível (ou D3D9 ou D3D10)
    // isto é dependente do sistema disponível no qual os CALLBACKS do D3D são configurados abaixo
 
    // Configure callbacks DXUT
    DXUTSetCallbackD3D10DeviceAcceptable( IsD3D10DeviceAcceptable );
    DXUTSetCallbackD3D10DeviceCreated( OnD3D10CreateDevice );
    DXUTSetCallbackD3D10SwapChainResized( OnD3D10ResizeSwapChain );
    DXUTSetCallbackD3D10SwapChainReleasing( OnD3D10ReleasingSwapChain );
    DXUTSetCallbackD3D10DeviceDestroyed( OnD3D10DestroyDevice );
    DXUTSetCallbackD3D10FrameRender( OnD3D10FrameRender );
 
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackKeyboard( OnKeyboard );
    DXUTSetCallbackFrameMove( OnFrameMove );
    DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
 
    InitApp();
 
    DXUTInit( true, true, NULL );    // Parse da linha de comando, mostra caixas de mensagem no erro, sem parâmetros de linha de comando extra
    DXUTSetCursorSettings(true, true );    // Mostre o cursor e recorte ele (clip) quando em modo de tela cheia
    DXUTCreateWindow( L"Tutorial13" );
    DXUTCreateDevice( true, 640, 480 );
    DXUTMainLoop();    // Entra dentro do loop de renderização DXUT
 
    return DXUTGetExitCode();
}
 
// Inicializa a aplicação
void InitApp()
{
    g_bSpinning = true;
 
    g_D3DSettingsDialog.Init( &g_DialogResourceManager );
    g_HUD.Init( &g_DialogResourceManager );
    g_SampleUI.Init( &g_DialogResourceManager );
 
    g_HUD.SetCallback( OnGUIEvent );    int iY = 10;
    g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Mudar para tela cheia", 35, iY, 125, 22 );
    g_HUD.AddButton( IDC_CHANGEDEVICE, L"Mudar dispositivo (F2)", 35, iY += 24, 125, 22, VK_F2 );
    g_HUD.AddButton( IDC_TOGGLEREF, L"Mudar para REF (F3)", 35, iY += 24, 125, 22, VK_F3 );
    g_HUD.AddButton( IDC_TOGGLEWARP, L"Mudar para WARP( F4 )", 35, iY+= 24, 125, 22, VK_F4 );
 
    g_SampleUI.SetCallback( OnGUIEvent);    iY = 10;
 
    WCHAR sz[100];
    iY += 24;
    swprintf_s( sz, 100, L"Quantia para explosão: %0.2f", g_fExplode );
    g_SampleUI.AddStatic( IDC_EXPLODE_STATIC, sz, 35, iY += 24, 125, 22 );
    g_SampleUI.AddSlider( IDC_EXPLODE_SCALE, 50, iY += 24, 100, 22, 0, 3000, ( int )( g_fExplode * 100.0f ) );
 
    iY += 24;
    g_SampleUI.AddCheckBox( IDC_TOGGLESPIN, L"Girar", 35, iY += 24, 125, 22, g_bSpinning );
}
 
// Rejeita qualquer equipamento D3D10 que não é aceitável por retornar falso
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext ){
      return true;
}
 
// Crie quaisquer recursos que não são dependentes do buffer de trás
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc,
                                      void* pUserContext )
{
    HRESULT hr;
 
    V_RETURN( g_DialogResourceManager.OnD3D10CreateDevice( pd3dDevice ) );
    V_RETURN( g_D3DSettingsDialog.OnD3D10CreateDevice( pd3dDevice ) );
    V_RETURN( D3DX10CreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
        OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
        L"Arial", &g_pFont ) );
 
    V_RETURN( D3DX10CreateSprite( pd3dDevice, 512, &g_pSprite ) );
    g_pTxtHelper = new CDXUTTextHelper( NULL, NULL, g_pFont, g_pSprite, 15 );
 
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Configura a opção D3D10_SHADER_DEBUG para embutir informãção de debug nos shaders.
    // Configurar esta opção melhora a experiência de debugação do shader, mas ainda permite
    // que os shaders sejam otimizados para executar à maneira que eles executarão na 
    // configuração release deste programa.
    dwShaderFlags |= D3D10_SHADER_DEBUG;
    #endif
 
    // Ache o arquivo de efeito D3DX
    WCHAR str[MAX_PATH];
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"..\\Tutorial13.fx" ) );
    V_RETURN( D3DX10CreateEffectFromFile( str, NULL, NULL, "fx_4_0", dwShaderFlags, 0, pd3dDevice, NULL,
                                              NULL, &g_pEffect, NULL, NULL ) );
 
    // Obtém a técnica
    g_pTechnique = g_pEffect->GetTechniqueByName( "Render" );
 
    // Obtém as variáveis
    g_ptxDiffuseVariable = g_pEffect->GetVariableByName( "g_txDiffuse" )->AsShaderResource();
    g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
    g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
    g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
    g_pExplodeVariable = g_pEffect->GetVariableByName( "Explode" )->AsScalar();
 
    // Define o leiaute de entrada
    const D3D10_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Cria o leiaute de entrada
    D3D10_PASS_DESC PassDesc;
    g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    V_RETURN( pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
                                             PassDesc.IAInputSignatureSize, &g_pVertexLayout ) );
 
    // Configura o leiaute de entrada
    pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Carrega a malha
    V_RETURN( g_Mesh.Create( pd3dDevice, L"..\\Media\\Tiny\\tiny.sdkmesh", true ) );
 
    // Initializa as matrizes do mundo
    D3DXMatrixIdentity( &g_World );
 
    // Initializa a câmera
    D3DXVECTOR3 Eye( 0.0f, 0.0f, -800.0f );
    D3DXVECTOR3 At( 0.0f, 0.0f, 0.0f );
    g_Camera.SetViewParams( &Eye, &At );
 
    return S_OK;
}
 
// Cria quaisquer recursos D3D10 que dependam do buffer de trás
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain *pSwapChain,
                                        const DXGI_SURFACE_DESC *pBufferSurfaceDesc, void *pUserContext)
{
    HRESULT hr;
 
    V_RETURN( g_DialogResourceManager.OnD3D10ResizedSwapChain( pd3dDevice, pBufferSurfaceDesc ) );
    V_RETURN( g_D3DSettingsDialog.OnD3D10ResizedSwapChain( pd3dDevice, pBufferSurfaceDesc ) );
 
    // Configura os parâmetros de projeção da câmera
    float fAspect = static_cast<float>( pBufferSurfaceDesc->Width) / static_cast<float>( pBufferSurfaceDesc->Height );
    g_Camera.SetProjParams( D3DX_PI / 4, fAspect, 0.1f, 5000.0f );
    g_Camera.SetWindow( pBufferSurfaceDesc->Width, pBufferSurfaceDesc->Height );
    g_Camera.SetButtonMasks( MOUSE_MIDDLE_BUTTON, MOUSE_WHEEL, MOUSE_LEFT_BUTTON );
 
    g_HUD.SetLocation( pBufferSurfaceDesc->Width -170, 0 );
    g_HUD.SetSize( 170, 170 );
    g_SampleUI.SetLocation( pBufferSurfaceDesc->Width - 170, pBufferSurfaceDesc->Height - 300 );
    g_SampleUI.SetSize( 170, 300 );
 
    return S_OK;
}
 
// Renderiza a cena usando o dispositivo D3D10
void CALLBACK OnD3D10FrameRender( ID3D10Device *pd3dDevice, double fTime, float fElapsedTime, void *pUserContext )
{
    // Se o diálogo de configurações está sendo mostrado, então
    // renderiza ele ao invés de renderizar a cena da aplicação
    if( g_D3DSettingsDialog.IsActive() )
    {
        g_D3DSettingsDialog.OnRender( fElapsedTime );
        return;
    }
 
    // Limpa o buffer de trás
    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };    // vermelho, verde, azul, alfa
    ID3D10RenderTargetView *pRTV = DXUTGetD3D10RenderTargetView();
    pd3dDevice->ClearRenderTargetView(pRTV, ClearColor );
 
    // limpa o stencil de profundidade
    ID3D10DepthStencilView *pDSV = DXUTGetD3D10DepthStencilView();
    pd3dDevice->ClearDepthStencilView( pDSV, D3D10_CLEAR_DEPTH, 1.0, 0 );
 
    // Atualiza as variáveis que mudam uma vez por quadro
    g_pWorldVariable->SetMatrix( (float* )&g_World );
    g_pViewVariable->SetMatrix( (float*) g_Camera.GetViewMatrix() );
    g_pProjectionVariable->SetMatrix( (float*) g_Camera.GetProjMatrix() );
 
    // Configura o leiaute de vértices
    pd3dDevice->IASetInputLayout( g_pVertexLayout );
 
    // Renderiza a malha
    UINT Strides[1];
    UINT Offsets[1];
    ID3D10Buffer* pVB[1];
    pVB[0] = g_Mesh.GetVB10( 0, 0 );
    Strides[0] = ( UINT ) g_Mesh.GetVertexStride(0,0);
    Offsets[0] = 0;
    pd3dDevice->IASetVertexBuffers(0, 1, pVB, Strides, Offsets);
    pd3dDevice->IASetIndexBuffer( g_Mesh.GetIB10( 0 ), g_Mesh.GetIBFormat10( 0 ), 0 );
 
    D3D10_TECHNIQUE_DESC techDesc;    
    g_pTechnique->GetDesc( &techDesc );
    SDKMESH_SUBSET* pSubset = NULL;
    ID3D10ShaderResourceView* pDiffuseRV = NULL;
    D3D10_PRIMITIVE_TOPOLOGY PrimType;
 
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        for( UINT subset = 0; subset < g_Mesh.GetNumSubsets( 0 ); ++subset ){
            pSubset = g_Mesh.GetSubset( 0, subset );
 
            PrimType = g_Mesh.GetPrimitiveType10( ( SDKMESH_PRIMITIVE_TYPE ) pSubset->PrimitiveType );
            pd3dDevice->IASetPrimitiveTopology( PrimType );
 
            pDiffuseRV = g_Mesh.GetMaterial( pSubset->MaterialID )->pDiffuseRV10;
            g_ptxDiffuseVariable->SetResource( pDiffuseRV );
 
            g_pTechnique->GetPassByIndex( p )->Apply( 0 );
            pd3dDevice->DrawIndexed( ( UINT ) pSubset->IndexCount, 0, ( UINT ) pSubset->VertexStart );
        }
    }
 
    // a classe de malha também tinha um método render que permite renderizar a malha com as opções mais comuns
    // g_pMesh.Render( pd3dDevice, g_pTechnique, g_ptxDiffuseVariable );
 
    // Renderiza a UI
    g_HUD.OnRender( fElapsedTime );
    g_SampleUI.OnRender( fElapsedTime );
 
    RenderText();
}
 
// Renderiza a ajuda e o texto das estatísticas
void RenderText()
{
    g_pTxtHelper->Begin();
    g_pTxtHelper->SetInsertionPos( 2, 0 );
    g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
    g_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) );
    g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );
    g_pTxtHelper->End();
}
 
// Libera recursos D3D10 criados em OnD3D10ResizedSwapChain 
void CALLBACK OnD3D10ReleasingSwapChain( void *pUserContext ){
    g_DialogResourceManager.OnD3D10ReleasingSwapChain();
}
 
// Libera recursos D3D10 criados em OnD3D10CreateDevice 
void CALLBACK OnD3D10DestroyDevice( void *pUserContext ){
    g_DialogResourceManager.OnD3D10DestroyDevice();
    g_D3DSettingsDialog.OnD3D10DestroyDevice();
    DXUTGetGlobalResourceCache().OnDestroyDevice();
    SAFE_RELEASE( g_pFont );
    SAFE_RELEASE( g_pSprite );
    SAFE_DELETE( g_pTxtHelper );
    SAFE_RELEASE( g_pVertexLayout );
    SAFE_RELEASE( g_pEffect );
    g_Mesh.Destroy();
}
 
// Chamado imediatamente antes de criar um dispositivo D3D9 oy D3D10, permitindo o aplicativo modificar
// as configurações do dispositivo como necessário
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings *pDeviceSettings, void *pUserContext ){
    return true;
}
 
// Manuseia atualizações para a cena. Isto é chamado indiferentemente de qual API D3D é usada
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUsetContex ){
    // Atualiza a posição da câmera baseada na entrada do usuário
    g_Camera.FrameMove( fElapsedTime );
 
    if( g_bSpinning ){
        D3DXMatrixRotationY( &g_World, 60.0f * DEG2RAD( (float) fTime ) );
    } else {
        D3DXMatrixRotationY( &g_World, DEG2RAD( 180.0f ) );
    }
 
    D3DXMATRIX mRot;
    D3DXMatrixRotationX( &mRot, DEG2RAD( -90.0f ) );
    g_World = mRot * g_World;
}
 
// Manuseia as mensagens para a aplicação
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                         bool *pbNoFurtherProcessing, void *pUserContext )
{
    // Passa as mensagens para as chamadas do gerenciador de recurso de diálogo para que
    // o estado da GUI seja atualizado corretamente
    *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
 
    if( *pbNoFurtherProcessing ) return 0;
 
    // Passe as mensagens para a configuração de diálogo se ela ainda estiver ativa
    if( g_D3DSettingsDialog.IsActive() ){
        g_D3DSettingsDialog.MsgProc( hWnd, uMsg, wParam, lParam );
        return 0;
    }
 
    // Dê aos diálogos uma chance de manusear a mensagem primeiro
    *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing ) return 0;
    *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing ) return 0;
 
    // Passe todas as mensagens de janela restantes para a cãmera para que ela possa respodner à entrada do usuário
    g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
 
    return 0;
}
 
// Manuseia pressionamentos do teclado
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext  ){
}
 
// Manuseia os eventos da GUI
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl *pControl, void *pUserContext )
{
    switch( nControlID ){
        case IDC_TOGGLEFULLSCREEN:
            DXUTToggleFullScreen(); break;
        case IDC_TOGGLEREF:
            DXUTToggleREF(); break;
        case IDC_CHANGEDEVICE:
            g_D3DSettingsDialog.SetActive( !g_D3DSettingsDialog.IsActive() ); break;
        case IDC_TOGGLEWARP:
            DXUTToggleWARP(); break;
        case IDC_TOGGLESPIN:{
            g_bSpinning = g_SampleUI.GetCheckBox( IDC_TOGGLESPIN )->GetChecked();
            break;
        }
        case IDC_EXPLODE_SCALE:
        {
            WCHAR sz[100];
            g_fExplode = (float) (g_SampleUI.GetSlider( IDC_EXPLODE_SCALE )->GetValue() * 0.01f );
            swprintf_s( sz, 100, L"Quantia a explodir: %0.2f", g_fExplode );
            g_SampleUI.GetStatic( IDC_EXPLODE_STATIC )->SetText( sz );
            g_pExplodeVariable->SetFloat( g_fExplode );
            break;
        }
    }
}

O arquivo de efeito dele é:

//--------------------------------------------------------------------------------------
// File: Tutorial13.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
Texture2D g_txDiffuse;
SamplerState samLinear
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
 
TextureCube g_txEnvMap;
SamplerState samLinearClamp
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Clamp;
    AddressV = Clamp;
};
 
cbuffer cbConstant
{
    float3 vLightDir = float3(-0.577,0.577,-0.577);
};
 
cbuffer cbChangesEveryFrame
{
    matrix World;
    matrix View;
    matrix Projection;
    float Time;
};
 
cbuffer cbUserChanges
{
    float Explode;
};
 
struct VS_INPUT
{
    float3 Pos          : POSITION;         
    float3 Norm         : NORMAL;           
    float2 Tex          : TEXCOORD0;        
};
 
struct GSPS_INPUT
{
    float4 Pos : SV_POSITION;
    float3 Norm : TEXCOORD0;
    float2 Tex : TEXCOORD1;
};
 
//--------------------------------------------------------------------------------------
// DepthStates
//--------------------------------------------------------------------------------------
DepthStencilState EnableDepth
{
    DepthEnable = TRUE;
    DepthWriteMask = ALL;
    DepthFunc = LESS_EQUAL;
};
 
BlendState NoBlending
{
    AlphaToCoverageEnable = FALSE;
    BlendEnable[0] = FALSE;
};
 
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
GSPS_INPUT VS( VS_INPUT input )
{
    GSPS_INPUT output = (GSPS_INPUT)0;
 
    output.Pos = mul( float4(input.Pos,1), World );
    output.Norm = mul( input.Norm, (float3x3)World );
    output.Tex = input.Tex;
 
    return output;
}
 
//--------------------------------------------------------------------------------------
// Geometry Shader
//--------------------------------------------------------------------------------------
[maxvertexcount(12)]
void GS( triangle GSPS_INPUT input[3], inout TriangleStream<GSPS_INPUT> TriStream )
{
    GSPS_INPUT output;
 
    //
    // Calculate the face normal
    //
    float3 faceEdgeA = input[1].Pos - input[0].Pos;
    float3 faceEdgeB = input[2].Pos - input[0].Pos;
    float3 faceNormal = normalize( cross(faceEdgeA, faceEdgeB) );
    float3 ExplodeAmt = faceNormal*Explode;
 
    //
    // Calculate the face center
    //
    float3 centerPos = (input[0].Pos.xyz + input[1].Pos.xyz + input[2].Pos.xyz)/3.0;
    float2 centerTex = (input[0].Tex + input[1].Tex + input[2].Tex)/3.0;
    centerPos += faceNormal*Explode;
 
    //
    // Output the pyramid
    //
    for( int i=0; i<3; i++ )
    {
        output.Pos = input[i].Pos + float4(ExplodeAmt,0);
        output.Pos = mul( output.Pos, View );
        output.Pos = mul( output.Pos, Projection );
        output.Norm = input[i].Norm;
        output.Tex = input[i].Tex;
        TriStream.Append( output );
 
        int iNext = (i+1)%3;
        output.Pos = input[iNext].Pos + float4(ExplodeAmt,0);
        output.Pos = mul( output.Pos, View );
        output.Pos = mul( output.Pos, Projection );
        output.Norm = input[iNext].Norm;
        output.Tex = input[iNext].Tex;
        TriStream.Append( output );
 
        output.Pos = float4(centerPos,1) + float4(ExplodeAmt,0);
        output.Pos = mul( output.Pos, View );
        output.Pos = mul( output.Pos, Projection );
        output.Norm = faceNormal;
        output.Tex = centerTex;
        TriStream.Append( output );
 
        TriStream.RestartStrip();
    }
 
    for( int i=2; i>=0; i-- )
    {
        output.Pos = input[i].Pos + float4(ExplodeAmt,0);
        output.Pos = mul( output.Pos, View );
        output.Pos = mul( output.Pos, Projection );
        output.Norm = -input[i].Norm;
        output.Tex = input[i].Tex;
        TriStream.Append( output );
    }
    TriStream.RestartStrip();
}
 
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( GSPS_INPUT input) : SV_Target
{
    // Calculate lighting assuming light color is <1,1,1,1>
    float fLighting = saturate( dot( input.Norm, vLightDir ) );
 
    // Load the diffuse texture and multiply by the lighting amount
    float4 cDiffuse = g_txDiffuse.Sample( samLinear, input.Tex ) * fLighting;
    cDiffuse.a = 1;
 
    // return diffuse
    return cDiffuse;
}
 
//--------------------------------------------------------------------------------------
// Technique
//--------------------------------------------------------------------------------------
technique10 Render
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( CompileShader( gs_4_0, GS() ) );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
 
        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetDepthStencilState( EnableDepth, 0 );
    }
}

Tutorial 14 - DXSDK - Gerenciamento de estados

Este tutorial demonstra como lidar com os estados do pipeline, os quais interagem com o buffer de profundidade, o buffer stencil e mudam a maneira como os primitivos da cena são renderizados

// Gerenciamento de estado de Render
 
#include "DXUT.h"
#include "DXUTcamera.h"
#include "DXUTgui.h"
#include "DXUTsettingsDlg.h"
#include "DXUTmisc.h"
#include "SDKmisc.h"
#include "SDKmesh.h"
 
#define DEG2RAD( a ) ( a * D3DX_PI / 180.0f )
 
WCHAR* g_szQuadTechniques[] = {
    L"RenderQuadSolid",
    L"RenderQuadSrcAlphaAdd",
    L"RenderQuadSrcAlphaSub",
    L"RenderQuadSrcColorAdd",
    L"RenderQuadSrcColorSub",
};
 
#define MAX_QUAD_TECHNIQUES 5
 
WCHAR* g_szDepthStencilModes[] = 
{
    L"DepthOff/StencilOff",
    L"DepthLess/StencilOff",
    L"DepthGreater/StencilOff",
 
    L"DepthOff/StencilOnFail",
    L"DepthLess/StencilOnFail",
    L"DepthGreater/StencilOnFail",
 
    L"DepthOff/StencilOnPass",
    L"DepthOff/StencilOnPass",
    L"DepthOff/StencilOnPass",
};
 
#define MAX_DEPTH_STENCIL_MODES 9
 
WCHAR* g_szRasterizerModes[] =
{
    L"CullOff/FillSolid",
    L"CullFront/FillSolid",
    L"CullBack/FillSolid",
 
    L"CullOff/FillWire",
    L"CullFront/FillWire",
    L"CullBack/FillWire",
};
 
#define MAX_RASTERIZER_MODES 6
 
/* Estaria incluso no Resource.h */
#define IDS_APP_TITLE           103
 
#define IDR_MAINFRAME           128
#define IDD_TUTORIAL1_DIALOG    102
#define IDD_ABOUTBOX            103
#define IDM_ABOUT               104
#define IDM_EXIT                105
#define IDI_TUTORIAL1           107
#define IDI_SMALL               108
#define IDC_TUTORIAL1           109
#define IDC_MYICON              2
#define IDC_STATIC              -1
 
// Variáveis globais 
CModelViewerCamera    g_Camera;    // Uma câmera de visualização do modelo
CDXUTDialogResourceManager    g_DialogResourceManager;    // gerente para recursos compartilhados de diálogos
CD3DSettingsDlg    g_D3DSettingsDialog;    // diálogo de configurações do dispositivo
CDXUTDialog    g_HUD;    // gerencia a UI 3D
CDXUTDialog    g_SampleUI;    // diálogo para controles específicos da amostra
 
ID3DX10Font*    g_pFont = NULL;    // Fonte para desenho de texto
ID3DX10Sprite*    g_pSprite = NULL;    // SPrite para desenho de texto em lote
CDXUTTextHelper*    g_pTxtHelper = NULL;
ID3D10Effect*    g_pEffect = NULL;    // interface de efeito D3DX
ID3D10InputLayout*    g_pSceneLayout = NULL;    // Leiaute de vértice da cena
ID3D10InputLayout*    g_pQuadLayout = NULL;    // Leiaute de vértice do Quad
ID3D10Buffer*    g_pScreenQuadVB = NULL;    // Quad da tela
CDXUTSDKMesh    g_Mesh;
ID3D10ShaderResourceView*    g_pScreenRV[2] = {NULL};
 
UINT    g_eSceneDepthStencilMode = 0;
ID3D10DepthStencilState*    g_pDepthStencilStates[MAX_DEPTH_STENCIL_MODES]; // estados de profundidade estêncil para não FX
// gerenciamento de estado do estêncil de profundidade
UINT    g_eSceneRasterizerMode = 0;
ID3D10RasterizerState*    g_pRasterStates[MAX_RASTERIZER_MODES];    // estados do rasterizador para não FX
// gerenciamento de estado do rasterizador
UINT    g_eQuadRenderMode = 0;
ID3D10EffectTechnique*    g_pTechniqueQuad[MAX_QUAD_TECHNIQUES];    // para técnicas de Quad do arquivo FX
// gerenciamento de estado de mistura alfa baseado em FX
ID3D10EffectTechnique*    g_pTechniqueScene = NULL;    // técnica FX para renderizar a cena
ID3D10EffectTechnique*    g_pTechniqueRenderWithStencil = NULL;    // técnica FX para renderizar usando profundidade baseada em FX
// gerenciamento de estado estêncil
 
ID3D10EffectShaderResourceVariable*    g_ptxDiffuseVariable = NULL;
ID3D10EffectMatrixVariable* g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable* g_pViewVariable = NULL;
ID3D10EffectMatrixVariable* g_pProjectionVariable = NULL;
ID3D10EffectScalarVariable*    g_pPuffiness = NULL;
D3DXMATRIX    g_World;
bool g_bSpinning = true;
float g_fModelPuffiness = 0.0f;
 
// estrutura descrevendo nosso vértice no espaço da tela
struct SCREEN_VERTEX
{
    D3DXVECTOR4 pos;
    D3DXVECTOR2 tex;
};
 
// IDs de controle da UI
#define IDC_TOGGLEFULLSCREEN    1
#define IDC_TOGGLEREF           2
#define IDC_CHANGEDEVICE        3
#define IDC_TOGGLESPIN          4
#define IDC_QUADRENDER_MODE     5
#define IDC_SCENEDEPTHSTENCIL_MODE    6
#define IDC_SCENERASTERIZER_MODE      7
#define IDC_TOGGLEWARP          8
 
// Protótipos das funções
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext );
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc, 
                                     void* pUserContext);
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain* pSwapChain,
                    const DXGI_SURFACE_DESC* pBufferSurfaceDesc, void* pUserContext);
void CALLBACK OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
void CALLBACK OnD3D10ReleasingSwapChain( void* pUserContext );
void CALLBACK OnD3D10DestroyDevice( void* pUserContext );
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void *pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool *pbNoFurtherProcessing,
                         void* pUserContext);
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext );
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUserContext );
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void *pUserContext );
 
void RenderText();
void InitApp();
void LoadQuadTechniques();
void LoadDepthStencilStates( ID3D10Device *pd3dDevice );
void LoadRasterizerStates( ID3D10Device *pd3dDevice );
 
// Ponto de entrada para o programa. Inicializa tudo e entra em um loop de processamento de
// mensagem. Tempo ocioso é usado para renderizar a cena
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){
    // Habilita checagem de memória em tempo de execução para construções debug.
#if defined( DEBUG ) | defined( _DEBUG )
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
 
    // DXUT criará e usará o melhor equipamento disponível (ou D3D9 ou D3D10)
    // que está disponível no sistema dependendo de quais 
    // CALLBACKS D3D são configurados abaixo
 
    // Configure callbacks DXUT
    DXUTSetCallbackD3D10DeviceAcceptable( IsD3D10DeviceAcceptable );
    DXUTSetCallbackD3D10DeviceCreated( OnD3D10CreateDevice );
    DXUTSetCallbackD3D10SwapChainResized( OnD3D10ResizeSwapChain );
    DXUTSetCallbackD3D10SwapChainReleasing( OnD3D10ReleasingSwapChain );
    DXUTSetCallbackD3D10DeviceDestroyed( OnD3D10DestroyDevice );
    DXUTSetCallbackD3D10FrameRender( OnD3D10FrameRender );
 
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackKeyboard( OnKeyboard );
    DXUTSetCallbackFrameMove( OnFrameMove );
    DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
 
    DXUTInit( true, true, NULL );    // Parse da linha de comando, mostra caixas de mensagem no erro, sem parâmetros de linha de comando extra
    DXUTSetCursorSettings(true, true );    // Mostre o cursor e recorte ele (clip) quando em modo de tela cheia
 
    InitApp();
 
    DXUTCreateWindow( L"Tutorial14" );
    DXUTCreateDevice( true, 640, 480 );
    DXUTMainLoop();    // Entra dentro do loop de renderização DXUT
 
    return DXUTGetExitCode();
}
 
// Inicializa a aplicação
void InitApp()
{
    g_fModelPuffiness = 0.0f;
    g_bSpinning = true;
 
    g_D3DSettingsDialog.Init( &g_DialogResourceManager );
    g_HUD.Init( &g_DialogResourceManager );
    g_SampleUI.Init( &g_DialogResourceManager );
 
    g_HUD.SetCallback( OnGUIEvent );    int iY = 10;
    g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Mudar para tela cheia", 35, iY, 125, 22 );
    g_HUD.AddButton( IDC_CHANGEDEVICE, L"Mudar dispositivo (F2)", 35, iY += 24, 125, 22, VK_F2 );
    g_HUD.AddButton( IDC_TOGGLEREF, L"Mudar para REF (F3)", 35, iY += 24, 125, 22, VK_F3 );
    g_HUD.AddButton( IDC_TOGGLEWARP, L"Mudar para WARP( F4 )", 35, iY+= 24, 125, 22, VK_F4 );
 
    g_SampleUI.SetCallback( OnGUIEvent);    
 
    CDXUTComboBox* pComboBox = NULL;
 
    iY = 0;
    g_SampleUI.AddStatic( IDC_STATIC, L"Modo de Rederizar (Q)uad", 0, iY, 200, 25 );
    iY += 25;
    g_SampleUI.AddComboBox( IDC_QUADRENDER_MODE, 0, iY, 220, 24, 'Q', false, &pComboBox );
    if( pComboBox )
        pComboBox->SetDropHeight( 150 );
 
    iY += 40;
    g_SampleUI.AddStatic( IDC_STATIC, L"Modo de(R)asterizador da cena", 0, iY, 200, 25 );
    iY += 25;
    g_SampleUI.AddComboBox( IDC_SCENERASTERIZER_MODE, 0, iY, 220, 24, 'R', false, &pComboBox );
    if( pComboBox )
        pComboBox->SetDropHeight( 150 );
 
    iY += 40;
    g_SampleUI.AddStatic( IDC_STATIC, L"Profundidade da cena/ Modo e(S)têncil", 0, iY, 200, 25 );
    iY += 25;
    g_SampleUI.AddComboBox( IDC_SCENEDEPTHSTENCIL_MODE, 0, iY, 220, 24, 'S', false, &pComboBox );
    if( pComboBox )
        pComboBox->SetDropHeight( 150 );
 
    iY += 24;
    g_SampleUI.AddCheckBox( IDC_TOGGLESPIN, L"Girar", 35, iY += 24, 125, 22, g_bSpinning );
}
 
// Rejeita quaisquer dispositivos D3D10 que não são aceitáveis por retornar falso
bool CALLBACK IsD3D10DeviceAcceptable( UINT adapter, UINT output, D3D10_DRIVER_TYPE DeviceType,
                                      DXGI_FORMAT BufferFormat, bool bWindowed, void *pUserContext ){
      return true;
}
 
// Crie quaisquer recursos que não são dependentes do buffer de trás
HRESULT CALLBACK OnD3D10CreateDevice( ID3D10Device* pd3dDevice, const DXGI_SURFACE_DESC* pBufferSurfaceDesc,
                                      void* pUserContext )
{
    HRESULT hr;
 
    V_RETURN( g_DialogResourceManager.OnD3D10CreateDevice( pd3dDevice ) );
    V_RETURN( g_D3DSettingsDialog.OnD3D10CreateDevice( pd3dDevice ) );
    V_RETURN( D3DX10CreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
        OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
        L"Arial", &g_pFont ) );
 
    V_RETURN( D3DX10CreateSprite( pd3dDevice, 512, &g_pSprite ) );
    g_pTxtHelper = new CDXUTTextHelper( NULL, NULL, g_pFont, g_pSprite, 15 );
 
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Configura a opção D3D10_SHADER_DEBUG para embutir informãção de debug nos shaders.
    // Configurar esta opção melhora a experiência de debugação do shader, mas ainda permite
    // que os shaders sejam otimizados para executar à maneira que eles executarão na 
    // configuração release deste programa.
    dwShaderFlags |= D3D10_SHADER_DEBUG;
    #endif
 
    // Ache o arquivo de efeito D3DX
    WCHAR str[MAX_PATH];
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"..\\Tutorial14.fx" ) );
    V_RETURN( D3DX10CreateEffectFromFile( str, NULL, NULL, "fx_4_0", dwShaderFlags, 0, pd3dDevice, NULL,
                                              NULL, &g_pEffect, NULL, NULL ) );
 
    // Obtém os manipuladores das técnicas
    g_pTechniqueScene = g_pEffect->GetTechniqueByName( "RenderScene" );
    g_pTechniqueRenderWithStencil = g_pEffect->GetTechniqueByName( "RenderWithStencil" );
    LoadQuadTechniques();
    LoadDepthStencilStates( pd3dDevice );
    LoadRasterizerStates( pd3dDevice );
 
    // Obtém as variáveis
    g_ptxDiffuseVariable = g_pEffect->GetVariableByName( "g_txDiffuse" )->AsShaderResource();
    g_pWorldVariable = g_pEffect->GetVariableByName( "World" )->AsMatrix();
    g_pViewVariable = g_pEffect->GetVariableByName( "View" )->AsMatrix();
    g_pProjectionVariable = g_pEffect->GetVariableByName( "Projection" )->AsMatrix();
    g_pPuffiness = g_pEffect->GetVariableByName( "Puffiness" )->AsScalar();
 
    // Configura o inchaço
    g_pPuffiness->SetFloat( g_fModelPuffiness );
 
    // Define o leiaute de entrada
    const D3D10_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = sizeof( layout ) / sizeof( layout[0] );
 
    // Cria o leiaute de entrada
    D3D10_PASS_DESC PassDesc;
    g_pTechniqueScene->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    V_RETURN( pd3dDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
        PassDesc.IAInputSignatureSize, &g_pSceneLayout ) );
 
    // Carrega a malha
    V_RETURN( g_Mesh.Create( pd3dDevice, L"..\\Media\\Tiny\\tiny.sdkmesh", true ) );
 
    // Initializa as matrizes do mundo
    D3DXMatrixIdentity( &g_World );
 
    // Cria um quad de tela
    const D3D10_INPUT_ELEMENT_DESC quadLayout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };
 
    g_pTechniqueQuad[0]->GetPassByIndex(0)->GetDesc( &PassDesc );
    V_RETURN( pd3dDevice->CreateInputLayout( quadLayout, 2, PassDesc.pIAInputSignature,  
        PassDesc.IAInputSignatureSize, &g_pQuadLayout ) );
 
    SCREEN_VERTEX svQuad[4];
    float fSize = 1.0f;
    svQuad[0].pos = D3DXVECTOR4( -fSize, fSize, 0.0f, 1.0f );
    svQuad[0].tex = D3DXVECTOR2( 0.0f, 0.0f );
    svQuad[1].pos = D3DXVECTOR4( fSize, fSize, 0.0f, 1.0f );
    svQuad[1].tex = D3DXVECTOR2( 1.0f, 0.0f );
    svQuad[2].pos = D3DXVECTOR4( -fSize, -fSize, 0.0f, 1.0f );
    svQuad[2].tex = D3DXVECTOR2( 0.0f, 1.0f );
    svQuad[3].pos = D3DXVECTOR4( fSize, -fSize, 0.0f, 1.0f );
    svQuad[3].tex = D3DXVECTOR2( 1.0f, 1.0f );
 
    D3D10_BUFFER_DESC vbdesc =
    {
        4 * sizeof( SCREEN_VERTEX ),
        D3D10_USAGE_DEFAULT,
        D3D10_BIND_VERTEX_BUFFER,
        0, 0
    };
 
    D3D10_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = svQuad;
    InitData.SysMemPitch = 0;
    InitData.SysMemSlicePitch = 0;
    V_RETURN( pd3dDevice->CreateBuffer( &vbdesc, &InitData, &g_pScreenQuadVB ) );
 
    // Carrega a txetura para o quad de tela
    WCHAR* szScreenTextures[] =
    {
        L"..\\Media\\misc\\MarbleClouds.dds",
        L"..\\Media\\misc\\NormTest.dds"
    };
 
    for( int i = 0; i < 2; i++ ){
        V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, szScreenTextures[i] ) );
        V_RETURN( D3DX10CreateShaderResourceViewFromFile( pd3dDevice, str, NULL, NULL, &g_pScreenRV[i], NULL ) );
    }
 
    // Inicializa a câmera
    D3DXVECTOR3 Eye( 0.0f, 0.0f, -800.0f );
    D3DXVECTOR3 At( 0.0f, 0.0f, 0.0f );
    g_Camera.SetViewParams( &Eye, &At );
 
    return S_OK;
}
 
// Cria quaisquer recursos D3D10 que dependam do buffer de trás
HRESULT CALLBACK OnD3D10ResizeSwapChain( ID3D10Device* pd3dDevice, IDXGISwapChain *pSwapChain,
                                        const DXGI_SURFACE_DESC *pBufferSurfaceDesc, void *pUserContext)
{
    HRESULT hr;
 
    V_RETURN( g_DialogResourceManager.OnD3D10ResizedSwapChain( pd3dDevice, pBufferSurfaceDesc ) );
    V_RETURN( g_D3DSettingsDialog.OnD3D10ResizedSwapChain( pd3dDevice, pBufferSurfaceDesc ) );
 
    // Configura os parâmetros de projeção da câmera
    float fAspect = static_cast<float>( pBufferSurfaceDesc->Width) / static_cast<float>( pBufferSurfaceDesc->Height );
    g_Camera.SetProjParams( D3DX_PI / 4, fAspect, 0.1f, 5000.0f );
    g_Camera.SetWindow( pBufferSurfaceDesc->Width, pBufferSurfaceDesc->Height );
    g_Camera.SetButtonMasks( MOUSE_MIDDLE_BUTTON, MOUSE_WHEEL, MOUSE_LEFT_BUTTON );
 
    g_HUD.SetLocation( pBufferSurfaceDesc->Width -170, 0 );
    g_HUD.SetSize( 170, 170 );
    g_SampleUI.SetLocation( pBufferSurfaceDesc->Width - 170, pBufferSurfaceDesc->Height - 300 );
    g_SampleUI.SetSize( 170, 300 );
 
    return S_OK;
}
 
// Renderiza a cena usando o dispositivo D3D10
void CALLBACK OnD3D10FrameRender( ID3D10Device *pd3dDevice, double fTime, float fElapsedTime, void *pUserContext )
{
    // Se o diálogo de configurações está sendo mostrado, então
    // renderiza ele ao invés de renderizar a cena da aplicação
    if( g_D3DSettingsDialog.IsActive() )
    {
        g_D3DSettingsDialog.OnRender( fElapsedTime );
        return;
    }
 
    // Limpa o buffer de trás
    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };    // vermelho, verde, azul, alfa
    ID3D10RenderTargetView *pRTV = DXUTGetD3D10RenderTargetView();
    pd3dDevice->ClearRenderTargetView(pRTV, ClearColor );
 
    // limpa o stencil de profundidade
    ID3D10DepthStencilView *pDSV = DXUTGetD3D10DepthStencilView();
    pd3dDevice->ClearDepthStencilView( pDSV, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0, 0 );
 
    // Atualiza as variáveis que mudam uma vez por quadro
    g_pWorldVariable->SetMatrix( (float* )&g_World );
    g_pViewVariable->SetMatrix( (float*) g_Camera.GetViewMatrix() );
    g_pProjectionVariable->SetMatrix( (float*) g_Camera.GetProjMatrix() );
 
    // Atualize o modo de seleção (Cull mode) (método não FX)
    pd3dDevice->RSSetState( g_pRasterStates[ g_eSceneRasterizerMode ] );
 
    // Atualiza os estados de profundidade estêncil (método não FX)
    pd3dDevice->OMSetDepthStencilState( g_pDepthStencilStates[ g_eSceneDepthStencilMode ], 0 );
 
    // Renderiza a malha
    pd3dDevice->IASetInputLayout( g_pSceneLayout );
 
    UINT Strides[1];
    UINT Offsets[1];
    ID3D10Buffer* pVB[1];
    pVB[0] = g_Mesh.GetVB10( 0, 0 );
    Strides[0] = ( UINT ) g_Mesh.GetVertexStride(0,0);
    Offsets[0] = 0;
    pd3dDevice->IASetVertexBuffers(0, 1, pVB, Strides, Offsets);
    pd3dDevice->IASetIndexBuffer( g_Mesh.GetIB10( 0 ), g_Mesh.GetIBFormat10( 0 ), 0 );
 
    D3D10_TECHNIQUE_DESC techDesc;    
    g_pTechniqueScene->GetDesc( &techDesc );
    SDKMESH_SUBSET* pSubset = NULL;
    ID3D10ShaderResourceView* pDiffuseRV = NULL;
    D3D10_PRIMITIVE_TOPOLOGY PrimType;
 
    for( UINT p = 0; p < techDesc.Passes; ++p ){
        for( UINT subset = 0; subset < g_Mesh.GetNumSubsets( 0 ); ++subset ){
            pSubset = g_Mesh.GetSubset( 0, subset );
 
            PrimType = g_Mesh.GetPrimitiveType10( ( SDKMESH_PRIMITIVE_TYPE ) pSubset->PrimitiveType );
            pd3dDevice->IASetPrimitiveTopology( PrimType );
 
            pDiffuseRV = g_Mesh.GetMaterial( pSubset->MaterialID )->pDiffuseRV10;
            g_ptxDiffuseVariable->SetResource( pDiffuseRV );
 
            g_pTechniqueScene->GetPassByIndex( p )->Apply( 0 );
            pd3dDevice->DrawIndexed( ( UINT ) pSubset->IndexCount, 0, ( UINT ) pSubset->VertexStart );
        }
    }
 
    // a classe de malha também tinha um método render que permite renderizar a malha com as opções mais comuns
    // g_pMesh.Render( pd3dDevice, g_pTechnique, g_ptxDiffuseVariable );
 
    // Reseta a transformação do Mundo
    D3DXMATRIX mWorld;
    D3DXMatrixScaling( &mWorld, 150.0f, 150.0f, 1.0f );
    g_pWorldVariable->SetMatrix( (float*) &mWorld );
 
    // Renderiza o quadrado no espaço da tela
    ID3D10EffectTechnique* pTech = g_pTechniqueQuad[ g_eQuadRenderMode ];
    g_ptxDiffuseVariable->SetResource( g_pScreenRV[0] );
    UINT strides = sizeof( SCREEN_VERTEX );
    UINT offsets = 0;
    ID3D10Buffer* pBuffers[1] = { g_pScreenQuadVB };
 
    pd3dDevice->IASetInputLayout( g_pQuadLayout );
    pd3dDevice->IASetVertexBuffers( 0, 1, pBuffers, &strides, &offsets );
    pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
 
    pTech->GetDesc( &techDesc );
 
    for( UINT uiPass = 0; uiPass < techDesc.Passes; uiPass++ ){
        pTech->GetPassByIndex( 0 )->Apply( 0 );
 
        pd3dDevice->Draw( 4, 0 );
    }
 
    // renderiza o quadrado no espaço da tela de novo, mas desta vez com uma 
    // textura diferente e somente renderize onde o buffer stencil é diferente de 0
    // Olhe no arquivo FX para as configurações de estado
    pTech = g_pTechniqueRenderWithStencil;
    g_ptxDiffuseVariable->SetResource( g_pScreenRV[1] );
    pd3dDevice->IASetInputLayout( g_pQuadLayout );
    pd3dDevice->IASetVertexBuffers( 0, 1, pBuffers, &strides, &offsets );
    pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
 
    pTech->GetDesc( &techDesc );
    for( UINT uiPass = 0; uiPass < techDesc.Passes; uiPass++ ){
        pTech->GetPassByIndex( 0 )->Apply( 0 );
 
        pd3dDevice->Draw( 4, 0 );
    }
 
    // Reconfigure nosso modo de seleção (método não FX)
    pd3dDevice->RSSetState( g_pRasterStates[ 0 ] );
 
    // Reconfigure o Estado de Profundidade Estêncil
    pd3dDevice->OMSetDepthStencilState( g_pDepthStencilStates[ 1 ], 0 );
 
    // Renderiza a UI
    g_HUD.OnRender( fElapsedTime );
    g_SampleUI.OnRender( fElapsedTime );
 
    RenderText();
}
 
// Renderiza a ajuda e o texto das estatísticas
void RenderText()
{
    g_pTxtHelper->Begin();
    g_pTxtHelper->SetInsertionPos( 2, 0 );
    g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
    g_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) );
    g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );
    g_pTxtHelper->End();
}
 
// Libera recursos D3D10 criados em OnD3D10ResizedSwapChain 
void CALLBACK OnD3D10ReleasingSwapChain( void *pUserContext ){
    g_DialogResourceManager.OnD3D10ReleasingSwapChain();
}
 
// Libera recursos D3D10 criados em OnD3D10CreateDevice 
void CALLBACK OnD3D10DestroyDevice( void *pUserContext ){
    g_DialogResourceManager.OnD3D10DestroyDevice();
    g_D3DSettingsDialog.OnD3D10DestroyDevice();
    DXUTGetGlobalResourceCache().OnDestroyDevice();
    SAFE_RELEASE( g_pFont );
    SAFE_RELEASE( g_pSprite );
    SAFE_DELETE( g_pTxtHelper );
    SAFE_RELEASE( g_pSceneLayout );
    SAFE_RELEASE( g_pQuadLayout );
    SAFE_RELEASE( g_pEffect );
    SAFE_RELEASE( g_pScreenQuadVB );
 
    for( int i = 0; i < 2; i++ ){
        SAFE_RELEASE( g_pScreenRV[i] );
    }
 
    g_Mesh.Destroy();
 
    for( UINT i = 0; i < MAX_DEPTH_STENCIL_MODES; i++ ){
        SAFE_RELEASE( g_pDepthStencilStates[i] );
    }
 
    for( UINT i = 0; i < MAX_RASTERIZER_MODES; i++ ){
        SAFE_RELEASE( g_pRasterStates[i] );
    }
}
 
// Chamado imediatamente antes de criar um dispositivo D3D9 oy D3D10, permitindo o aplicativo modificar
// as configurações do dispositivo como necessário
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings *pDeviceSettings, void *pUserContext ){
    pDeviceSettings->d3d10.AutoDepthStencilFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
    return true;
}
 
// Manuseia atualizações para a cena. Isto é chamado indiferentemente de qual API D3D é usada
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void *pUsetContex ){
    // Atualiza a posição da câmera baseada na entrada do usuário
    g_Camera.FrameMove( fElapsedTime );
 
    if( g_bSpinning ){
        D3DXMatrixRotationY( &g_World, 60.0f * DEG2RAD( (float) fTime ) );
    } else {
        D3DXMatrixRotationY( &g_World, DEG2RAD( 180.0f ) );
    }
 
    D3DXMATRIX mRot;
    D3DXMatrixRotationX( &mRot, DEG2RAD( -90.0f ) );
    g_World = mRot * g_World;
}
 
// Manuseia as mensagens para a aplicação
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                         bool *pbNoFurtherProcessing, void *pUserContext )
{
    // Passa as mensagens para as chamadas do gerenciador de recurso de diálogo para que
    // o estado da GUI seja atualizado corretamente
    *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
 
    if( *pbNoFurtherProcessing ) return 0;
 
    // Passe as mensagens para a configuração de diálogo se ela ainda estiver ativa
    if( g_D3DSettingsDialog.IsActive() ){
        g_D3DSettingsDialog.MsgProc( hWnd, uMsg, wParam, lParam );
        return 0;
    }
 
    // Dê aos diálogos uma chance de manusear a mensagem primeiro
    *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing ) return 0;
    *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing ) return 0;
 
    // Passe todas as mensagens de janela restantes para a cãmera para que ela possa respodner à entrada do usuário
    g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
 
    return 0;
}
 
// Manuseia pressionamentos do teclado
void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void *pUserContext  ){
    if( bKeyDown )
    {
        switch( nChar )
        {
        case VK_F1:
            break;
        }
    }
}
 
// Manuseia os eventos da GUI
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl *pControl, void *pUserContext )
{
    switch( nControlID ){
        case IDC_TOGGLEFULLSCREEN:
            DXUTToggleFullScreen(); break;
        case IDC_TOGGLEREF:
            DXUTToggleREF(); break;
        case IDC_CHANGEDEVICE:
            g_D3DSettingsDialog.SetActive( !g_D3DSettingsDialog.IsActive() ); break;
        case IDC_TOGGLEWARP:
            DXUTToggleWARP(); break;
        case IDC_TOGGLESPIN:{
            g_bSpinning = g_SampleUI.GetCheckBox( IDC_TOGGLESPIN )->GetChecked();
            break;
        }
        case IDC_QUADRENDER_MODE:
        {
            CDXUTComboBox* pComboBox = NULL;
            pComboBox = ( CDXUTComboBox* )pControl;
            g_eQuadRenderMode = (UINT) PtrToInt( pComboBox->GetSelectedData() );
            break;
        }
        case IDC_SCENEDEPTHSTENCIL_MODE:
        {
            CDXUTComboBox* pComboBox = NULL;
            pComboBox = ( CDXUTComboBox* )pControl;
            g_eSceneDepthStencilMode = (UINT) PtrToInt( pComboBox->GetSelectedData() );
            break;
        }
        case IDC_SCENERASTERIZER_MODE:
        {
            CDXUTComboBox* pComboBox = NULL;
            pComboBox = ( CDXUTComboBox* )pControl;
            g_eSceneRasterizerMode = (UINT) PtrToInt( pComboBox->GetSelectedData() );
            break;
        }
    }
}
 
// LoadQuadTechniques
// Carrega as técnicas para renderizar o quad do arquivo FX. As técnicas no
// arquivo FX contêm a configuração de estado de mistura alfa
void LoadQuadTechniques()
{
    for( UINT i = 0; i < MAX_QUAD_TECHNIQUES; i++ ){
        char mbstr[MAX_PATH];
        WideCharToMultiByte( CP_ACP, 0, g_szQuadTechniques[i], -1, mbstr, MAX_PATH, 0, 0 );
        g_pTechniqueQuad[i] = g_pEffect->GetTechniqueByName( mbstr );
 
        g_SampleUI.GetComboBox( IDC_QUADRENDER_MODE )->AddItem( g_szQuadTechniques[i], (void*) (UINT64) i );
    }
}
 
// LoadDepthStencilStates
// Cria um conjunto de estados de profundidade estêncil para gerenciamento de estado não-FX. Estes estados
// mais tarde serão configurados usando OMSetDepthStencilState em OnD3D10FrameRender.
void LoadDepthStencilStates( ID3D10Device* pd3dDevice ){
    BOOL bDepthEnable[ MAX_DEPTH_STENCIL_MODES ] = 
    {
        FALSE,
        TRUE,
        TRUE,
        FALSE,
        TRUE,
        TRUE,
        FALSE,
        TRUE,
        TRUE
    };
 
    BOOL bStencilEnable[ MAX_DEPTH_STENCIL_MODES ] = 
    {
        FALSE,
        FALSE,
        FALSE,
        TRUE,
        TRUE,
        TRUE,
        TRUE,
        TRUE,
        TRUE
    };
 
    D3D10_COMPARISON_FUNC compFunc[ MAX_DEPTH_STENCIL_MODES ] = 
    {
        D3D10_COMPARISON_LESS,
        D3D10_COMPARISON_LESS,
        D3D10_COMPARISON_GREATER,
        D3D10_COMPARISON_LESS,
        D3D10_COMPARISON_LESS,
        D3D10_COMPARISON_GREATER,
        D3D10_COMPARISON_LESS,
        D3D10_COMPARISON_LESS,
        D3D10_COMPARISON_GREATER,
    };
 
    D3D10_STENCIL_OP FailOp[ MAX_DEPTH_STENCIL_MODES ] =
    {
        D3D10_STENCIL_OP_KEEP,
        D3D10_STENCIL_OP_KEEP,
        D3D10_STENCIL_OP_KEEP,
 
        D3D10_STENCIL_OP_INCR,
        D3D10_STENCIL_OP_INCR,
        D3D10_STENCIL_OP_INCR,
 
        D3D10_STENCIL_OP_KEEP,
        D3D10_STENCIL_OP_KEEP,
        D3D10_STENCIL_OP_KEEP,
    };
 
    D3D10_STENCIL_OP PassOp[ MAX_DEPTH_STENCIL_MODES ] =
    {
        D3D10_STENCIL_OP_KEEP,
        D3D10_STENCIL_OP_KEEP,
        D3D10_STENCIL_OP_KEEP,
 
        D3D10_STENCIL_OP_KEEP,
        D3D10_STENCIL_OP_KEEP,
        D3D10_STENCIL_OP_KEEP,
 
        D3D10_STENCIL_OP_INCR,
        D3D10_STENCIL_OP_INCR,
        D3D10_STENCIL_OP_INCR,
    };
 
    for( UINT i = 0; i < MAX_DEPTH_STENCIL_MODES; i++ )
    {
        D3D10_DEPTH_STENCIL_DESC dsDesc;
        dsDesc.DepthEnable = bDepthEnable[i];
        dsDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
        dsDesc.DepthFunc = compFunc[i];
 
        // parâmetros de teste do estêncil
        dsDesc.StencilEnable = bStencilEnable[i];
        dsDesc.StencilReadMask = 0xFF;
        dsDesc.StencilWriteMask = 0xFF;
 
        // operações estêncil se pixel está encarando de frente
        dsDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
        dsDesc.FrontFace.StencilDepthFailOp = FailOp[i];
        dsDesc.FrontFace.StencilPassOp = PassOp[i];
        dsDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
 
        // operações estêncil se pixel está encarando de trás
        dsDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
        dsDesc.BackFace.StencilDepthFailOp = FailOp[i];
        dsDesc.BackFace.StencilPassOp = PassOp[i];
        dsDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
 
        // Cria o estado de profundidade estêncil
        pd3dDevice->CreateDepthStencilState( &dsDesc, &g_pDepthStencilStates[i] );
 
        g_SampleUI.GetComboBox( IDC_SCENEDEPTHSTENCIL_MODE )->AddItem( g_szDepthStencilModes[i],
            ( void* ) (UINT64 ) i );
    }
}
 
// LoadRasterizerStates
// Crie um conjunto de estados de rasterizador para gerenciamento de estado não-FX. Estes 
// estados serão configurados mais tarde por usar RSSetState em OND3DFrameRender.
void LoadRasterizerStates( ID3D10Device* pd3dDevice ){
    D3D10_FILL_MODE fill[MAX_RASTERIZER_MODES] = 
    {
        D3D10_FILL_SOLID,
        D3D10_FILL_SOLID,
        D3D10_FILL_SOLID,
        D3D10_FILL_WIREFRAME,
        D3D10_FILL_WIREFRAME,
        D3D10_FILL_WIREFRAME
    };
 
    D3D10_CULL_MODE cull[MAX_RASTERIZER_MODES]=
    {
        D3D10_CULL_NONE,
        D3D10_CULL_FRONT,
        D3D10_CULL_BACK,
        D3D10_CULL_NONE,
        D3D10_CULL_FRONT,
        D3D10_CULL_BACK
    };
 
    for( UINT i = 0; i < MAX_RASTERIZER_MODES; i++ ){
        D3D10_RASTERIZER_DESC rasterizerState;
        rasterizerState.FillMode = fill[i];
        rasterizerState.CullMode = cull[i];
        rasterizerState.FrontCounterClockwise = false;
        rasterizerState.DepthBias = false;
        rasterizerState.DepthBiasClamp = 0;
        rasterizerState.SlopeScaledDepthBias = 0;
        rasterizerState.DepthClipEnable = true;
        rasterizerState.ScissorEnable = false;
        rasterizerState.MultisampleEnable = false;
        rasterizerState.AntialiasedLineEnable = false;
        pd3dDevice->CreateRasterizerState( &rasterizerState, &g_pRasterStates[i] );
 
        g_SampleUI.GetComboBox( IDC_SCENERASTERIZER_MODE )->AddItem( g_szRasterizerModes[i] ,
            (void *) (UINT64) i );
    }
}

E o shader acompanhante

//--------------------------------------------------------------------------------------
// File: Tutorial14.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
Texture2D g_txDiffuse;
SamplerState samLinear
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
 
cbuffer cbConstant
{
    float3 vLightDir = float3(-0.577,0.577,-0.577);
};
 
cbuffer cbChangesEveryFrame
{
    matrix World;
    matrix View;
    matrix Projection;
};
 
struct VS_INPUT
{
    float3 Pos          : POSITION;         //position
    float3 Norm         : NORMAL;           //normal
    float2 Tex          : TEXCOORD0;        //texture coordinate
};
 
struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float3 Norm : TEXCOORD0;
    float2 Tex : TEXCOORD1;
};
 
struct QUADVS_INPUT
{
    float4 Pos : POSITION;
    float2 Tex : TEXCOORD0;
};
 
struct QUADVS_OUTPUT
{
    float4 Pos : SV_POSITION;              // Transformed position
    float2 Tex : TEXCOORD0;
};
 
//--------------------------------------------------------------------------------------
// Blending States
//--------------------------------------------------------------------------------------
BlendState NoBlending
{
    BlendEnable[0] = FALSE;
};
 
BlendState SrcAlphaBlendingAdd
{
    BlendEnable[0] = TRUE;
    SrcBlend = SRC_ALPHA;
    DestBlend = ONE;
    BlendOp = ADD;
    SrcBlendAlpha = ZERO;
    DestBlendAlpha = ZERO;
    BlendOpAlpha = ADD;
    RenderTargetWriteMask[0] = 0x0F;
};
 
BlendState SrcAlphaBlendingSub
{
    BlendEnable[0] = TRUE;
    SrcBlend = SRC_ALPHA;
    DestBlend = ONE;
    BlendOp = SUBTRACT;
    SrcBlendAlpha = ZERO;
    DestBlendAlpha = ZERO;
    BlendOpAlpha = ADD;
    RenderTargetWriteMask[0] = 0x0F;
};
 
BlendState SrcColorBlendingAdd
{
    BlendEnable[0] = TRUE;
    SrcBlend = SRC_COLOR;
    DestBlend = ONE;
    BlendOp = ADD;
    SrcBlendAlpha = ZERO;
    DestBlendAlpha = ZERO;
    BlendOpAlpha = ADD;
    RenderTargetWriteMask[0] = 0x0F;
};
 
BlendState SrcColorBlendingSub
{
    BlendEnable[0] = TRUE;
    SrcBlend = SRC_COLOR;
    DestBlend = ONE;
    BlendOp = SUBTRACT;
    SrcBlendAlpha = ZERO;
    DestBlendAlpha = ZERO;
    BlendOpAlpha = ADD;
    RenderTargetWriteMask[0] = 0x0F;
};
 
//--------------------------------------------------------------------------------------
// Depth/Stencil States
//--------------------------------------------------------------------------------------
DepthStencilState RenderWithStencilState
{
    DepthEnable = false;
    DepthWriteMask = ZERO;
    DepthFunc = Less;
 
    // Setup stencil states
    StencilEnable = true;
    StencilReadMask = 0xFF;
    StencilWriteMask = 0x00;
 
    FrontFaceStencilFunc = Not_Equal;
    FrontFaceStencilPass = Keep;
    FrontFaceStencilFail = Zero;
 
    BackFaceStencilFunc = Not_Equal;
    BackFaceStencilPass = Keep;
    BackFaceStencilFail = Zero;
};
 
//--------------------------------------------------------------------------------------
// Scene Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;
 
    output.Pos = mul( float4(input.Pos,1), World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
    output.Norm = mul( input.Norm, World );
    output.Tex = input.Tex;
 
    return output;
}
 
//-----------------------------------------------------------------------------
// Quad Vertex Shaders
//-----------------------------------------------------------------------------
QUADVS_OUTPUT QuadVS( QUADVS_INPUT Input )
{
    QUADVS_OUTPUT Output;
    Output.Pos = mul( Input.Pos, World );
    Output.Pos = mul( Output.Pos, View );
    Output.Pos = mul( Output.Pos, Projection );
    Output.Tex = Input.Tex;
    return Output;
}
 
QUADVS_OUTPUT ScreenQuadVS( QUADVS_INPUT Input )
{
    QUADVS_OUTPUT Output;
    Output.Pos = Input.Pos;
    Output.Tex = Input.Tex;
    return Output;
}
 
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
    // Calculate lighting assuming light color is <1,1,1,1>
    float fLighting = saturate( dot( input.Norm, vLightDir ) );
    float4 outputColor = g_txDiffuse.Sample( samLinear, input.Tex ) * fLighting;
    outputColor.a = 1;
    return outputColor;
}
 
//--------------------------------------------------------------------------------------
// Quad Pixel Shader
//--------------------------------------------------------------------------------------
float4 QuadPS( QUADVS_OUTPUT input) : SV_Target
{
    return g_txDiffuse.Sample( samLinear, input.Tex );
}
 
//--------------------------------------------------------------------------------------
// Scene Techniques
//--------------------------------------------------------------------------------------
technique10 RenderScene
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );        
        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}
 
//--------------------------------------------------------------------------------------
// RenderWithStencil - set the depth stencil state inside of the technique
//--------------------------------------------------------------------------------------
technique10 RenderWithStencil
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, ScreenQuadVS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, QuadPS() ) );     
 
        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetDepthStencilState( RenderWithStencilState, 0 );
    }
}
 
//--------------------------------------------------------------------------------------
// Quad Techniques:  Alpha blending state is set inside the technique
//--------------------------------------------------------------------------------------
technique10 RenderQuadSolid
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, QuadVS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, QuadPS() ) );     
 
        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}
 
//--------------------------------------------------------------------------------------
technique10 RenderQuadSrcAlphaAdd
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, QuadVS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, QuadPS() ) );   
 
        SetBlendState( SrcAlphaBlendingAdd, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}
 
//--------------------------------------------------------------------------------------
technique10 RenderQuadSrcAlphaSub
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, QuadVS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, QuadPS() ) );   
 
        SetBlendState( SrcAlphaBlendingSub, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}
 
//--------------------------------------------------------------------------------------
technique10 RenderQuadSrcColorAdd
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, QuadVS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, QuadPS() ) );   
 
        SetBlendState( SrcColorBlendingAdd, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}
 
//--------------------------------------------------------------------------------------
technique10 RenderQuadSrcColorSub
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, QuadVS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, QuadPS() ) );   
 
        SetBlendState( SrcColorBlendingSub, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    }
}

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