Curso completo de DirectX 9 com C\C++
Gameprog - Escola de programação de jogos digitais
Contato: gameprog.br@gmail.com
Fase 10-3

index << >>


10.3 Mesh Iluminado

1.1 Visão geral
Os grandes avanços desta aplicação estão no código hlsl que vamos ver ao longo deste tópico que considera o uso de luz e das normais para produzir um mesh iluminado. O código em C# desta aplicação tornou-se mais simples em comparação com nosso primeiro projeto de hlsl pois a interface ID3DXMesh encarrega-se nos bastidores de produzir a declaração de vértice e o vertexbuffer, dispensando-nos da implementação manual destes objetos. Como as novidades estão apenas no código hlsl as costumeiras funções foram listadas apenas e acreditamos que os comentários do código bastarão para a compreensão das funcionalidades das mesmas. Em relação a aplicação anterior, prj_HLSL01, a função atualizarCamera() foi removida e suas funcionalidades foram transferidas para a função desenharObjeto() que atualiza as variáveis de movimento e câmera e introjeta-as na linha programável antes de renderizar o mesh. 1.2 Estrutura principal da aplicação
Arquivo: motor.cpp
Aspectos globais Declaração de ponteiros globais para: o objeto 3d da interface ID3DXMesh ( g_objeto3d ) o objeto efeito produzido pela interface ID3DXEffect ( g_efeito ) inicializarEfeito() inicializa os argumentos da função que produz o objeto efeito produz o objeto efeito com a função D3DXCreateEffectFromFile() que carrega o arquivo com o código hlsl, compila-o e produz o objeto efeito da interface ID3DXEffect. seleciona a técnica a ser utilizada na renderização initGfx() Configura a ocorrência do processamento de vértices no hardware. chama inicializar_Camera() para configuração inicial da câmera. chama inicializarEfeito() para carregar o programa hlsl do disco e inicializar o objeto efeito ( g_efeito ). Cria o objeto cilindro desenharObjeto() Esta função vai renderizar na tela o objeto da interface ID3DXMesh . Isso envolve a configuração das matrizes parciais de rotação, posição e escala; produzir a matriz de mundo final com as matrizes parciais. Atualiza as variáveis para produzir variação de movimento e cor Produz a matriz final de câmera combinada com a matriz final do objeto. Introjeta as variáveis atualizadas na linha programável do dispositivo gráfico. Renderiza o objeto. renderizar_Geometria() Inicializa o processo de renderização com o objeto efeito Chama desenharObjeto() para renderizar o objeto Finaliza o processo de renderização com o objeto efeito
2.1.1 Aspectos globais - Arquivo: motor.h
// ----------------------------------------------------------------------------- // Projeto: prj_HLSL02 - Arquivo: motor.h // Esta aplicação ilustra como renderizar um mesh // iluminado utilizando hlsl. By www.gameprog.com.br // ----------------------------------------------------------------------------- #ifndef motor_h #define motor_h // Estrutura para posicionamento e rotação do mesh struct Propriedades3d { D3DXVECTOR3 pos; D3DXVECTOR3 rot; }; // Esta função inicializa o Direct3D HRESULT initGfx (HWND hJanela); // Essa função libera os objetos utilizados void Limpar(); // Essa função desenha a cena void Renderizar(); // Renderiza o mesh utilizando hlsl void renderizar_Geometria (void); // Inicializa as matrizes da câmera void inicializar_Camera(void); // Inicializa o objeto efeito void inicializarEfeito(void); // Desenha o objeto 3d void desenharObjeto ( ID3DXMesh *obj3d, Propriedades3d *props); // Declaração da função que atende as mensagens da janela LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam); #endif
2.1.2 Aspectos globais - Arquivo: motor.cpp
// Representa o objeto efeito ID3DXEffect *g_efeito = NULL; // Variáveis para provocar mudanças de cor e movimento float nMovimento = 0.0f; float nVelocidade = 0.01f; float g_angulo = 0.01f; // Interface do objeto 3d ID3DXMesh *g_objeto3d = NULL; // Recipiente de cor, rotação e posição do objeto Propriedades3d g_props;
2.2 Inicialização do motor gráfico
// initGfx() - Inicializa o Direct3D HRESULT initGfx( HWND hJanela ) { // Cria o objeto Direct3D que é necessário para criar o dispositivo gráfico g_Direct3d = Direct3DCreate9( D3D_SDK_VERSION); // Verifica se o objeto Direct3D foi criado if(g_Direct3d == NULL) { MessageBox (NULL, "Falha na inialização do Direct3D", "InitGfx()", MB_OK); return E_FAIL; } // endif // Declara a variável para os parâmetros de apresentação D3DPRESENT_PARAMETERS pps; // Limpa a estrutura ZeroMemory( &pps, sizeof(pps) ); // Configura os parâmetros de apresentação // A aplicação vai ter janela pps.Windowed = TRUE; // Esse método transfere rapidamente o backbuffer para a tela imediata pps.SwapEffect = D3DSWAPEFFECT_DISCARD; // Esse formato vai procurar se encaixar no modo de video corrente pps.BackBufferFormat = D3DFMT_UNKNOWN; // Adaptador default (0) int nAdaptador = D3DADAPTER_DEFAULT; // Tipo de dispositivo Hardware ou emulador de referência (software) D3DDEVTYPE dispositivo_tipo = D3DDEVTYPE_HAL; // Flags de configuração do dispositivo DWORD create_flags = D3DCREATE_HARDWARE_VERTEXPROCESSING; // Criamos aqui o dispositivo renderizador g_hr = g_Direct3d->CreateDevice( nAdaptador, dispositivo_tipo, hJanela, create_flags, &pps, &g_device ); // Verifica se houve falha no processo if( FAILED( g_hr ) ) { MessageBox (NULL, "Falha na criação: g_device", "initGfx()", MB_OK); return E_FAIL; } // endif // Monta a geometria D3DXCreateCylinder (g_device, 0.5f, 1.0f, 5.0f, 32, 32, &g_objeto3d, NULL); g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, -5.0f); g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f); // Inicializa um objeto efeito inicializarEfeito(); // Inicializa e atualiza a configuração de câmera inicializar_Camera(); return S_OK; } // initGfx().fim
2.3 Renderização do objeto 3d
void desenharObjeto ( ID3DXMesh *obj3d, Propriedades3d *props) { // Matrizes para controlar posição e rotação do objeto 3d D3DXMATRIX obj_rot; D3DXMATRIX obj_pos; D3DXMATRIX camera; // Handle para a variáveis do shader D3DXHANDLE hMov = NULL; D3DXHANDLE hCam = NULL; // Vamos inicializar as matrizes para um valor neutro D3DXMatrixIdentity( &obj_rot ); D3DXMatrixIdentity( &obj_pos ); D3DXMatrixIdentity( &camera ); // Atualiza ângulo de rotação g_angulo += 0.02f; // Configura rotação do objeto 3d D3DXMatrixRotationYawPitchRoll(&obj_rot, props->rot.y + g_angulo, props->rot.x + g_angulo, props->rot.z); // Ajusta posição do objeto 3d; D3DXMatrixTranslation(&obj_pos, props->pos.x, props->pos.y, props->pos.z); // Tranfere posição e rotação para o g_mtxMundo D3DXMatrixMultiply (&g_mtxMundo, &obj_rot, &obj_pos); // Atualiza cor nMovimento += nVelocidade; if (nMovimento >= 1.0f) nVelocidade *= -1; if (nMovimento <= 0.0f) nVelocidade *= -1; // Atualiza a câmera camera = g_mtxMundo * g_mtxVisao * g_mtxProj; // Obtém acesso às variáveis do shader hMov = g_efeito->GetParameterByName (0, "nMovimento"); hCam = g_efeito->GetParameterByName (0, "Camera"); // Atualiza variáveis no shader g_efeito->SetValue (hMov, &nMovimento, sizeof(nMovimento) ); g_efeito->SetValue (hCam, &camera, sizeof(camera) ); // Renderiza o objeto obj3d->DrawSubset(0); } // desenharObjeto().fim
2.4 Renderização da geometria com hlsl
void renderizar_Geometria() { // Número de passos do efeito UINT nPassosQtd = 0; // Renderiza o mesh usando o efeito g_efeito->Begin(&nPassosQtd, 0); for(UINT ncx = 0; ncx < nPassosQtd; ncx++) { // Renderiza a cena passo a passo g_efeito->BeginPass (ncx); // Renderização efetiva dos vértices desenharObjeto(g_objeto3d, &g_props); // Fim do passo g_efeito->EndPass (); } // endfor // Fim do efeito g_efeito->End (); } // renderizar_Geometria().fim
2.5 Inicialização do objeto efeito
void inicializarEfeito() { // Nome do arquivo de efeito char fx_arquivo[] = "\\gameprog\\gdkmedia\\shader\\mesh_simples.fx"; // Flag de configuração DWORD create_flags = D3DXSHADER_DEBUG; // Buffer para receber informação em caso de erro ID3DXBuffer* txtErro = NULL; // Gera o efeito a partir do arquivo carregado g_hr = D3DXCreateEffectFromFile( g_device, fx_arquivo, 0, 0, create_flags, 0, &g_efeito, &txtErro); if (FAILED(g_hr)) { MessageBox(NULL, "falha: D3DXCreateEffectFromFile()", "inicializarEfeito", MB_OK); MessageBox(NULL, (char*) txtErro->GetBufferPointer(), "inicializarEfeito", MB_OK); txtErro->Release (); return; } // endif // Seleciona a técnica de renderização D3DXHANDLE htech_MovimentoCor; htech_MovimentoCor = g_efeito->GetTechniqueByName ("MovimentoCor"); g_efeito->SetTechnique(htech_MovimentoCor); // Libera o buffer de erros if (txtErro != NULL) txtErro->Release(); } // inicializarEfeito().fim
3.0 Código hlsl para renderizar o mesh iluminado: mesh_simples.fx 3.1 Variáveis globais do shader
// Estrutura de saida do Shader, posição e cor struct vsSaida { float4 pos : POSITION; float4 cor : COLOR0; }; float nMovimento; // Matriz de mundo, visualização e projeção float4x4 Camera : WORLDVIEWPROJECTION; // Direção da luz no espaço de mundo float3 DirecaoLuz = {0.0f, 0.0f, -1.0f};
Parâmetros de saída
// Estrutura de saida do Shader, posição e cor struct vsSaida { float4 pos : POSITION; float4 cor : COLOR0; };
Esta estrutura representa o valor de saida do shader que vai retornar para a aplicação uma cor e uma posição transformada. A forma de utilizar estruturas é igual a linguagem C++. float nMovimento; // Matriz de mundo, visualização e projeção float4x4 Camera : WORLDVIEWPROJECTION; Já conhecemos estas variáveis que são modificadas de dentro de nossa aplicação: nMovimento que anima a cor, e a matriz de camera. // Direção da luz no espaço de mundo float3 DirecaoLuz = {0.0f, 0.0f, -1.0f}; Esta é a variável de direção da luz. Preste atenção na forma como a variável foi declarada e inicializada fazendo uso das chaves {}. 3.2 vs_Main()
// Transforma as coordenadas em espaço de mundo vsSaida vs_Main( float4 Pos : POSITION, float3 Normal : NORMAL) { // Declaração da estrutura de retorno vsSaida saida = (vsSaida) 0; // Transforma a normal para dentro do mesmo sistema de // coordenadas. float4 normalTransformada = mul(Normal, Camera); // Configura a cor saida.cor.r = nMovimento; saida.cor.b = 1 - nMovimento; saida.cor.ga = 1.0f; // Aplica a luz na cor saida.cor = saida.cor * dot (normalTransformada, DirecaoLuz); // Transforma posição saida.pos = mul(Pos, Camera); // Retorna return saida; } // vs_Main().fim
// Transforma a normal para dentro do mesmo sistema de // coordenadas. float4 normalTransformada = mul(Normal, Camera); // Aplica a luz na cor saida.cor = saida.cor * dot (normalTransformada, DirecaoLuz); // Transforma posição saida.pos = mul(Pos, Camera);
Este aqui é o código chave para renderizar o mesh considerando a luz: a normal é puxada para o mesmo sistema de coordenada; depois ocorre uma outra multiplicação com a função dot() para embutir o efeito da luz na cor e finaliza-se com a transformação final da posição. Recomendamos guardar essa fórmula de aplicação de luz para ser utilizada em outros projetos. A repetição de uso favorece mais tarde a assimilação da enorme complexidade presente nestas três linhas que parecem simples mas que envolve a compreensão de vetores, matrizes, transformações e cálculos de iluminação. É mais prático nesse momento decorar a receita para repetí-la em outros projetos. 3.3 Técnica MovimentoCor
technique MovimentoCor { pass trataCilindro { VertexShader = compile vs_1_1 vs_Main(); PixelShader = NULL; } }
O grande destaque da técnica é que não há aparentemente a utilização do pixelshader que ficou assinalado como nulo com o retorno da cor sendo trabalhada e retornada pelo próprio vertexshader. Nós demos esse exemplo para mostrar essa possibilidade de deixar ausente o pixelshader. Note também que você pode identificar o passo com qualquer nome, porém é conveniente dar uma pista do que o passo está fazendo. 3.4 Código fonte do programa hlsl de exemplo: mesh_simples.fx
// prj_HLSL02: Renderizando mesh iluminado com hlsl // Arquivo: mesh_simples.fx // Produzido por www.gameprog.com.br // Estrutura de saida do Shader, posição e cor struct vsSaida { float4 pos : POSITION; float4 cor : COLOR0; }; float nMovimento; // Direção da luz no espaço de mundo float3 DirecaoLuz = {0.0f, 0.0f, -1.0f}; // Matriz de mundo, visualização e projeção float4x4 Camera : WORLDVIEWPROJECTION; // Transforma as coordenadas em espaço de mundo vsSaida vs_Main( float4 Pos : POSITION, float3 Normal : NORMAL) { // Declaração da estrutura de retorno vsSaida saida = (vsSaida) 0; // Transforma a normal para dentro do mesmo sistema de // coordenadas. float4 normalTransformada = mul(Normal, Camera); // Configura a cor saida.cor.r = nMovimento; saida.cor.b = 1 - nMovimento; saida.cor.ga = 1.0f; // Aplica a luz na cor saida.cor = saida.cor * dot (normalTransformada, DirecaoLuz); // Transforma posição saida.pos = mul(Pos, Camera); // Retorna return saida; } // vs_Main().fim technique MovimentoCor { pass trataCilindro { VertexShader = compile vs_1_1 vs_Main(); PixelShader = NULL; } }
4.0 Código fonte do projeto de exemplo: prj_HLSL02
// ----------------------------------------------------------------------------- // Projeto: prj_HLSL02 - Arquivo: motor.h // Esta aplicação ilustra como renderizar um mesh // iluminado utilizando hlsl. By www.gameprog.com.br // ----------------------------------------------------------------------------- #ifndef motor_h #define motor_h // Estrutura para posicionamento e rotação do mesh struct Propriedades3d { D3DXVECTOR3 pos; D3DXVECTOR3 rot; }; // Esta função inicializa o Direct3D HRESULT initGfx (HWND hJanela); // Essa função libera os objetos utilizados void Limpar(); // Essa função desenha a cena void Renderizar(); // Renderiza o mesh utilizando hlsl void renderizar_Geometria (void); // Inicializa as matrizes da câmera void inicializar_Camera(void); // Inicializa o objeto efeito void inicializarEfeito(void); // Desenha o objeto 3d void desenharObjeto ( ID3DXMesh *obj3d, Propriedades3d *props); // Declaração da função que atende as mensagens da janela LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam); #endif
// ----------------------------------------------------------------------------- // Projeto: prj_HLSL02 - arquivo: motor.cpp // Esta aplicação ilustra como renderizar um mesh // iluminado utilizando hlsl. By www.gameprog.com.br // ----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include <stdio.h> #include "motor.h" // Inclui as bibliotecas do Direct3D #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") // Variáveis globais // Representa o dispositivo Direct3D LPDIRECT3D9 g_Direct3d = NULL; // Representa o dispositivo Renderizador IDirect3DDevice9 *g_device = NULL; // Representa o objeto efeito ID3DXEffect *g_efeito = NULL; // Variáveis para provocar mudanças de cor e movimento float nMovimento = 0.0f; float nVelocidade = 0.01f; float g_angulo = 0.01f; // Interface do objeto 3d ID3DXMesh *g_objeto3d = NULL; // Recipiente de cor, rotação e posição do objeto Propriedades3d g_props; // Essa variável recebe informação de erro do Directx HRESULT g_hr = 0; // Tamanho da janela extern int g_xtela; extern int g_ytela; extern HWND hJanela; // Constante para cores const DWORD branco = 0xFFFFFFFF; const DWORD verde = 0xFF008000; // Matrizes de configuração da câmera D3DXMATRIX g_mtxMundo; D3DXMATRIX g_mtxVisao; D3DXMATRIX g_mtxProj; // initGfx() - Inicializa o Direct3D HRESULT initGfx( HWND hJanela ) { // Cria o objeto Direct3D que é necessário para criar o dispositivo gráfico g_Direct3d = Direct3DCreate9( D3D_SDK_VERSION); // Verifica se o objeto Direct3D foi criado if(g_Direct3d == NULL) { MessageBox (NULL, "Falha na inialização do Direct3D", "InitGfx()", MB_OK); return E_FAIL; } // endif // Declara a variável para os parâmetros de apresentação D3DPRESENT_PARAMETERS pps; // Limpa a estrutura ZeroMemory( &pps, sizeof(pps) ); // Configura os parâmetros de apresentação // A aplicação vai ter janela pps.Windowed = TRUE; // Esse método transfere rapidamente o backbuffer para a tela imediata pps.SwapEffect = D3DSWAPEFFECT_DISCARD; // Esse formato vai procurar se encaixar no modo de video corrente pps.BackBufferFormat = D3DFMT_UNKNOWN; // Adaptador default (0) int nAdaptador = D3DADAPTER_DEFAULT; // Tipo de dispositivo Hardware ou emulador de referência (software) D3DDEVTYPE dispositivo_tipo = D3DDEVTYPE_HAL; // Flags de configuração do dispositivo DWORD create_flags = D3DCREATE_HARDWARE_VERTEXPROCESSING; // Criamos aqui o dispositivo renderizador g_hr = g_Direct3d->CreateDevice( nAdaptador, dispositivo_tipo, hJanela, create_flags, &pps, &g_device ); // Verifica se houve falha no processo if( FAILED( g_hr ) ) { MessageBox (NULL, "Falha na criação: g_device", "initGfx()", MB_OK); return E_FAIL; } // endif // Monta a geometria D3DXCreateCylinder (g_device, 0.5f, 1.0f, 5.0f, 32, 32, &g_objeto3d, NULL); g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, -5.0f); g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f); // Inicializa um objeto efeito inicializarEfeito(); // Inicializa e atualiza a configuração de câmera inicializar_Camera(); return S_OK; } // initGfx().fim void desenharObjeto ( ID3DXMesh *obj3d, Propriedades3d *props) { // Matrizes para controlar posição e rotação do objeto 3d D3DXMATRIX obj_rot; D3DXMATRIX obj_pos; D3DXMATRIX camera; // Handle para a variáveis do shader D3DXHANDLE hMov = NULL; D3DXHANDLE hCam = NULL; // Vamos inicializar as matrizes para um valor neutro D3DXMatrixIdentity( &obj_rot ); D3DXMatrixIdentity( &obj_pos ); D3DXMatrixIdentity( &camera ); // Atualiza ângulo de rotação g_angulo += 0.02f; // Configura rotação do objeto 3d D3DXMatrixRotationYawPitchRoll(&obj_rot, props->rot.y + g_angulo, props->rot.x + g_angulo, props->rot.z); // Ajusta posição do objeto 3d; D3DXMatrixTranslation(&obj_pos, props->pos.x, props->pos.y, props->pos.z); // Tranfere posição e rotação para o g_mtxMundo D3DXMatrixMultiply (&g_mtxMundo, &obj_rot, &obj_pos); // Atualiza cor nMovimento += nVelocidade; if (nMovimento >= 1.0f) nVelocidade *= -1; if (nMovimento <= 0.0f) nVelocidade *= -1; // Atualiza a câmera camera = g_mtxMundo * g_mtxVisao * g_mtxProj; // Obtém acesso às variáveis do shader hMov = g_efeito->GetParameterByName (0, "nMovimento"); hCam = g_efeito->GetParameterByName (0, "Camera"); // Atualiza variáveis no shader g_efeito->SetValue (hMov, &nMovimento, sizeof(nMovimento) ); g_efeito->SetValue (hCam, &camera, sizeof(camera) ); // Renderiza o objeto obj3d->DrawSubset(0); } // desenharObjeto().fim void renderizar_Geometria() { // Número de passos do efeito UINT nPassosQtd = 0; // Renderiza o mesh usando o efeito g_efeito->Begin(&nPassosQtd, 0); for(UINT ncx = 0; ncx < nPassosQtd; ncx++) { // Renderiza a cena passo a passo g_efeito->BeginPass (ncx); // Renderização efetiva dos vértices desenharObjeto(g_objeto3d, &g_props); // Fim do passo g_efeito->EndPass (); } // endfor // Fim do efeito g_efeito->End (); } // renderizar_Geometria().fim // Esta função é chamada por DispatchMessage() LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam) { switch (mensagem) { case WM_DESTROY: // Coloca uma mensagem WM_QUIT na fila de mensagem Limpar(); PostQuitMessage (0); break; case WM_KEYDOWN: if (wParam == VK_ESCAPE) { Limpar(); PostQuitMessage( 0); } // endif break; // Essa mensagem vai ocorrer a todo momento case WM_PAINT: // Renderiza a cena Renderizar(); // Invalida a tela para chamar WM_PAINT novamente InvalidateRect( hJanela, NULL, false); break; // Processamento default de mensagens não tratada pela aplicação default: return DefWindowProc (hJanela, mensagem, wParam, lParam); } // endswitch return 0; } // processaJanela().fim // Limpar() - Libera todos os objetos previamente inicializados // ----------------------------------------------------------------------------- VOID Limpar() { // Libera o buffer de vértices if( g_objeto3d != NULL) g_objeto3d->Release(); if (g_efeito != NULL) g_efeito->Release(); // Libera o dispositivo gráfico if( g_device != NULL) g_device->Release(); // Libera o motor do Direct3D if( g_Direct3d != NULL) g_Direct3d->Release(); } // Limpar().fim // ----------------------------------------------------------------------------- // Renderizar() - Desenha a cena // ----------------------------------------------------------------------------- VOID Renderizar() { // Retorne se o dispositivo estiver nulo if( g_device == NULL) return; // Limpa o backbuffer com uma cor branca g_device->Clear( 0, NULL, D3DCLEAR_TARGET, verde, 1.0f, 0); // Começa a cena if( SUCCEEDED( g_device->BeginScene() ) ) { // Vamos renderizar a geometria renderizar_Geometria(); // Finalizando a cena g_device->EndScene(); } // endif // Apresenta o conteúdo do backbuffer na tela g_device->Present( NULL, NULL, NULL, NULL); } // Renderizar().fim void inicializar_Camera(void) { // *************************************************************************** // Inicializa todas as matrizes para elemento neutro D3DXMatrixIdentity( &g_mtxMundo ); D3DXMatrixIdentity( &g_mtxVisao ); D3DXMatrixIdentity( &g_mtxProj ); // *************************************************************************** // Dados para a configuração da matriz de visualização // Aonde está a câmera? - posição da câmera D3DXVECTOR3 cam_pos (0.0f, 0.0f, 5.0f); // Para aonde a câmera está apontada ou olhando? Alvo da câmera D3DXVECTOR3 cam_alvo (0.0f, 0.0f, 0); // A câmera está de cabeça pra baixo? - orientação da câmera D3DXVECTOR3 cam_vetorcima (0.0f, 1.0f, 0.0f); // Configura a matriz de visão D3DXMatrixLookAtLH( &g_mtxVisao, &cam_pos, &cam_alvo, &cam_vetorcima ); // *************************************************************************** // Argumentos de configuração da matriz de projeção // Pega o tamanho da área cliente RECT area_cliente; GetWindowRect (hJanela, &area_cliente); g_xtela = area_cliente.right; g_ytela = area_cliente.bottom; // aspecto dos gráficos float aspecto = (float) g_xtela / g_ytela; // campo de visão float campo_g_mtxVisao = D3DX_PI / 4; // Trapézio de visualização da câmera ( Frustrum ) float corte_perto = 1.0f; float corte_longe = 1000.0f; // Configura a matriz de projeção D3DXMatrixPerspectiveFovLH( &g_mtxProj, campo_g_mtxVisao, aspecto, corte_perto, corte_longe); } // inicializar_Camera().fim void inicializarEfeito() { // Nome do arquivo de efeito char fx_arquivo[] = "\\gameprog\\gdkmedia\\shader\\mesh_simples.fx"; // Flag de configuração DWORD create_flags = D3DXSHADER_DEBUG; // Buffer para receber informação em caso de erro ID3DXBuffer* txtErro = NULL; // Gera o efeito a partir do arquivo carregado g_hr = D3DXCreateEffectFromFile( g_device, fx_arquivo, 0, 0, create_flags, 0, &g_efeito, &txtErro); if (FAILED(g_hr)) { MessageBox(NULL, "falha: D3DXCreateEffectFromFile()", "inicializarEfeito", MB_OK); MessageBox(NULL, (char*) txtErro->GetBufferPointer(), "inicializarEfeito", MB_OK); txtErro->Release (); return; } // endif // Seleciona a técnica de renderização D3DXHANDLE htech_MovimentoCor; htech_MovimentoCor = g_efeito->GetTechniqueByName ("MovimentoCor"); g_efeito->SetTechnique(htech_MovimentoCor); // Libera o buffer de erros if (txtErro != NULL) txtErro->Release(); } // inicializarEfeito().fim
//----------------------------------------------------------------------------- // Projeto: prj_HLSL02 - arquivo: entrada.cpp // Esta aplicação ilustra como renderizar um mesh // iluminado utilizando hlsl. By www.gameprog.com.br //----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include "motor.h" // Variável global da classe da janela char sclasseJanela[ ] = "cls_directx"; // Dimensões da janela int g_xtela = 640; int g_ytela = 480; // alça da janela HWND hJanela; int WINAPI WinMain (HINSTANCE app_instancia, HINSTANCE app_anterior, LPSTR sComando,int nExibir) { // Estrutura de recepção das mensagens MSG mensagem; // Estrutura de descrição da janela WNDCLASSEX wcls; // Estrutura que descreve a janela wcls.hInstance = app_instancia; wcls.lpszClassName = sclasseJanela; wcls.lpfnWndProc = processaJanela; wcls.style = CS_HREDRAW | CS_VREDRAW; wcls.cbSize = sizeof (WNDCLASSEX); // O cursor e os ícones da aplicação são default wcls.hIcon = LoadIcon (NULL, IDI_APPLICATION); wcls.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wcls.hCursor = LoadCursor (NULL, IDC_ARROW); // Aplicação sem menu wcls.lpszMenuName = NULL; // Nada de espaço extra atrelado a classe da janela (wcls) wcls.cbClsExtra = 0; // Nada de espaço extra atrelado a janela wcls.cbWndExtra = 0; // Cor default da janela wcls.hbrBackground = ( HBRUSH) COLOR_BACKGROUND; // Registra a janela e retorna se esta operação falhar int status = RegisterClassEx (&wcls); if(status == 0) { MessageBox(NULL, "Registro falhou!", "WinMain()", MB_OK); return 0; } // endif // Com a classe criada pode-se criar a janela DWORD estiloExtra = 0; const char janelaTitulo[] = "prj_HLSL02"; DWORD controleEstilo = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX; int xpos = 160; int ypos = 120; HWND hjanelaPai = HWND_DESKTOP; HMENU sem_menu = NULL; LPVOID dadoExtra = NULL; // Cria a janela hJanela = CreateWindowEx(estiloExtra, sclasseJanela, janelaTitulo, controleEstilo, xpos, xpos, g_xtela, g_ytela, hjanelaPai, sem_menu, app_instancia, dadoExtra ); // Verifica se janela foi criada if(hJanela == NULL) { MessageBox(NULL, "Falha na criação da janela!", "WinMain()", MB_OK); return 0; } // endif // Essa variável recebe informação de erro do Directx HRESULT hr; // Inicia o Direct3D hr = initGfx ( hJanela ); // Encerre a aplicação se houve falha if(FAILED (hr) ) { MessageBox (hJanela, "Direct3D: falha na inicialização", "WinMain()", MB_OK); UnregisterClass( sclasseJanela, wcls.hInstance); return E_FAIL; } // endif // Mostra a janela ShowWindow(hJanela, nExibir); UpdateWindow(hJanela ); // Rode a bombeamento de mensagens até GetMessage() retornar 0 while (GetMessage(&mensagem, NULL, 0, 0)) { // Traduz mensagem de tecla virtual em mensagem de caracteres TranslateMessage( &mensagem ); // Despacha a mensagem para a função processaJanela */ DispatchMessage( &mensagem ); } // endwhile // O valor de retorno é zero(0) passado por PostQuitMessage() UnregisterClass( sclasseJanela, wcls.hInstance); return mensagem.wParam; } // WinMain().fim

index << >>

Produzido por Gameprog: Jair Pereira - Agosto/2014 © gameprog.br@gmail.com http://www.gameprog.com.br