Tutorial02 Dx10
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(); }
revisão da página: 0, última edição: 16 Feb 2011 15:09