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

index << >>


03.2 Quadrado texturizado

1.1 Visão geral
O processo de texturizar consiste em mapear a textura sobre os vértices do polígono formado. A coordenada (x,y) da textura é chamada de (u,v) com u correspondente à x e v correspondente à y. As coordenadas de mapeamento de textura são expressas pelo tipo float e variam de 0.0f a 1.0f que equivalem a percentuais de largura ou altura da imagem. Por exemplo, no eixo x (expresso por u), zero (0) quer dizer extremo canto esquerdo e 1.0f extremo canto direito. No eixo y (v), zero (0) quer dizer extremo canto superior e 1.0f extremo canto inferior. E o valor 0.5f refere-se à metade do caminho. No processo de texturizar, a coordenada de textura é associada ao vértice e isso demanda naturalmente um formato de vértice que aceite as coordenadas (u, v). É interessante notar que essa forma de associar textura aos vértices, através de float's que representam percentuais da largura ou altura da imagem o directx consegue assim trabalhar com imagens de qualquer tamanho para a textura. Porém, para melhor performance da aplicação, utilize texturas quadradas com dimensões em potências da base 2, por exemplo 128x128, 256x256 etc. Isso agiliza processos internos do directx. 1.2 Estrutura principal da aplicação
Arquivo: motor.cpp
inicializar_Textura() carrega a textura via D3DXCreateTextureFromFile() configura alguns estados de texturização initGfx() chama inicializar_Textura() para montar o contexto de texturização chama montar_Geometria() para montar os quadrados texturizados chama inicializar_Camera() para a configuração inicial da câmera. montar_Geometria() Define coordenadas de texturas nomeadas Faz a montagem de cinco quadrados texturizados com cada um tendo diferentes coordenadas de textura. Define um ponteiro para cada quadrado texturizado renderizar_Geometria() Declara o formato de vértice utilizado: CustomVertex_PositionTextured_Format O temporizador seleciona um quadrado texturizado diferente a cada segundo Renderiza o quadrado selecionado com g_device->DrawIndexedPrimitiveUP() Limpar() Libera a textura utilizada Libera dispositivo renderizador Libera objeto Direct3d Configura os ponteiros para NULL
2.1.1 Aspectos globais - Arquivo: motor.h
// Projeto: prj_Textura - Arquivo: motor.h // Esse projeto ilustra como renderizar um quadrado com textura // Produzido por www.gameprog.com.br #ifndef motor_h #define motor_h // Inclui as bibliotecas do Direct3D #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") // Estrutura para suportar coordenadas de textura struct TexCoord { // Coordenada de textura float tu, tv; // Construtor default TexCoord() {} TexCoord( float _tu, float _tv) { // Configura coordenada de textura tu = _tu; tv =_tv; } }; // fim da estrutura TexCoord // Estrutura de vértice customizado struct CustomVertex_PositionTextured { // Posição do vértice float x, y, z; // Coordenada de textura float tu, tv; // Construtor default CustomVertex_PositionTextured() {} CustomVertex_PositionTextured( float _x, float _y, float _z, TexCoord texcoord) { // Configura posição x = _x; y = _y; z = _z; // Configura coordenada de textura tu = texcoord.tu; tv = texcoord.tv; } }; // fim da estrutura CustomVertex_PositionTextured // Definição do formato de vértice utilizado por esta aplicação #define CustomVertex_PositionTextured_Format(D3DFVF_XYZ | D3DFVF_TEX1) // 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(); // Essa função monta formas geométricas void montar_Geometria (void); // Renderiza os vértices em formas geométricas void renderizar_Geometria (void); // Inicializa a textura void inicializar_Textura(void); // Inicializa a câmera void inicializar_Camera(void); // Declaração da função que atende as mensagens da janela LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam); #endif
Estrutura para coordenadas de textura
// Estrutura para suportar coordenadas de textura struct TexCoord { // Coordenada de textura float tu, tv; // Construtor default TexCoord() {} TexCoord( float _tu, float _tv) { // Configura coordenada de textura tu = _tu; tv =_tv; } }; // fim da estrutura TexCoord
Esta pequena estrutura TexCoord foi desenvolvida para facilitar o trabalho com coordenadas de textura. Os elementos (tu, tv) representam naturalmente as coordenadas (u, v) de textura. Estrutura para o vértice customizado com posição e coordenada de textura
// Estrutura de vértice customizado struct CustomVertex_PositionTextured { // Posição do vértice float x, y, z; // Coordenada de textura float tu, tv; // Construtor default CustomVertex_PositionTextured() {} CustomVertex_PositionTextured( float _x, float _y, float _z, TexCoord texcoord) { // Configura posição x = _x; y = _y; z = _z; // Configura coordenada de textura tu = texcoord.tu; tv = texcoord.tv; } }; // fim da estrutura CustomVertex_PositionTextured
Esta estrutura de vértice customizado contém uma estrutura TexCoord como elemento para suportar coordenadas de textura. #define CustomVertex_PositionTextured_Format(D3DFVF_XYZ | D3DFVF_TEX1) Essa macro define o formato de vértice utilizado por esta aplicação. void Limpar(); Salientamos aqui que depois de liberar a interface utilizada com o método Release() é importante reconfigurar o ponteiro como NULL: // Libera a textura if (g_Textura != NULL) g_Textura->Release(); g_Textura = NULL; Utilize o NULL como filtro para evitar que sua aplicação entre em pane por tentar utilizar uma interface que já foi liberada. void montar_Geometria (void); Essa função monta cinco quadrados texturizados com cada um deles tendo coordenadas diferentes de textura produzindo imagens finais diferentes. Salientamos que com a compreensão desse exemplo, utilizando os recursos de textura é possível construir uma classe para manipulação de sprites com funcionalidades melhores do que as oferecidas pela interface do directx para isso. void renderizar_Geometria (void); Essa função renderiza a cada segundo um quadrado com uma texturização diferente. Essa variação periódica é obtida com o uso da função clock() que retorna o tempo de operação da aplicação em milessegundos que é convertido em segundos e restringido aos valores de 0 à 4, na sequência com esse valor selecionando o recipiente de vértices a ser renderizado. void inicializar_Textura(void); Essa função carrega a textura do disco e inicializa o contexto geral de texturização configurando alguns estados e instalando a textura carregada no dispositivo renderizador. 2.1.2 Aspectos globais - Arquivo: motor.cpp
// Interface de textura IDirect3DTexture9* g_Textura = NULL; // Controla a mudança periódica do quadrado texturizado // com diferentes coordenadas de textura UINT temporizador = 0; // Memória para os vértices CustomVertex_PositionTextured g_Verts1[4 ]; CustomVertex_PositionTextured g_Verts2[4 ]; CustomVertex_PositionTextured g_Verts3[4 ]; CustomVertex_PositionTextured g_Verts4[4 ]; CustomVertex_PositionTextured g_Verts5[4 ]; // Um ponteiro para cada conjunto de vértices CustomVertex_PositionTextured *g_pVerts[5 ];
IDirect3DTexture9* g_Textura = NULL; Declaramos nesta linha o único objeto textura que vai ser utilizado por esta aplicação. CustomVertex_PositionTextured g_Verts1[4]; // (...) CustomVertex_PositionTextured g_Verts5[4]; Declaramos aqui cinco arrays do tipo CustomVertex_PositionTextured com quatro vértices para conter cada um dos cinco quadrados texturizados. CustomVertex_PositionTextured *g_pVerts[5]; Na sequência é declarado uma array de ponteiros com um elemento para cada um dos recipientes de vértices criados na linha acima. UINT temporizador = 0; Esta variável aqui vai assumir valores de 0 à 4 e vai ser combinada com g_pVerts na forma g_pVerts[temporizador] para produzir a variação periódica do quadrado texturizado. 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; // Configuração do renderizador a ser criado // 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_SOFTWARE_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 vários quads (quadrados) com diferentes coordenadas // de textura montar_Geometria(); // Carrega a textura do disco e configura alguns estados referentes. inicializar_Textura(); // Configura a câmera inicializar_Camera(); // Habilita a iluminação default g_device->SetRenderState (D3DRS_LIGHTING, false); return S_OK; } // initGfx().fim
// Monta vários quads (quadrados) com diferentes coordenadas // de textura montar_Geometria(); // Carrega a textura do disco e configura alguns estados referentes. inicializar_Textura(); Estas funções foram descritas de forma geral no subtópico acima 2.1.1 e serão melhor detalhadas em seus respectivos subtópicos particulares. g_device->SetRenderState (D3DRS_LIGHTING, false); Configuramos esse estado como false para permitir a iluminação default provida pelo directx. 2.3 Montagem dos quadrados com textura
void montar_Geometria(void) { // *** Coordenadas de texturas *** // cima-esquerda TexCoord cimaEsq( 0.0f, 0.0f); // cima-meio TexCoord cimaMeio( 0.5f, 0.0f); // cima-direita TexCoord cimaDir( 1.0f, 0.0f); // meio-direita TexCoord meioDir( 0.0f, 0.5f); // meio-meio TexCoord meioMeio( 0.5f, 0.5f); // meio-esquerda TexCoord meioEsq( 1.0f, 0.5f); // baixo-esquerda TexCoord baixoEsq ( 0.0f, 1.0f); // baixo-meio TexCoord baixoMeio ( 0.5f, 1.0f); // baixo-direita TexCoord baixoDir ( 1.0f, 1.0f); // Posicionamento de profundidade float zpos = 1.0f; // Configuração normal dos vértices com coordenadas de textura g_Verts1[0] = CustomVertex_PositionTextured( 1.0f, 1.0f, zpos, cimaEsq); g_Verts1[1] = CustomVertex_PositionTextured(-1.0f, 1.0f, zpos, cimaDir); g_Verts1[2] = CustomVertex_PositionTextured(-1.0f, -1.0f, zpos, baixoDir); g_Verts1[3] = CustomVertex_PositionTextured( 1.0f, -1.0f, zpos, baixoEsq); // Configuração normal dos vértices com coordenadas de textura g_Verts2[0] = CustomVertex_PositionTextured( 1.0f, 1.0f, zpos, cimaEsq); g_Verts2[1] = CustomVertex_PositionTextured(-1.0f, 1.0f, zpos, cimaMeio); g_Verts2[2] = CustomVertex_PositionTextured(-1.0f, -1.0f, zpos, meioMeio); g_Verts2[3] = CustomVertex_PositionTextured( 1.0f, -1.0f, zpos, meioDir); // Configuração normal dos vértices com coordenadas de textura g_Verts3[0] = CustomVertex_PositionTextured( 1.0f, 1.0f, zpos, cimaMeio); g_Verts3[1] = CustomVertex_PositionTextured(-1.0f, 1.0f, zpos, cimaDir); g_Verts3[2] = CustomVertex_PositionTextured(-1.0f, -1.0f, zpos, meioEsq); g_Verts3[3] = CustomVertex_PositionTextured( 1.0f, -1.0f, zpos, meioMeio); // Configuração normal dos vértices com coordenadas de textura g_Verts4[0] = CustomVertex_PositionTextured( 1.0f, 1.0f, zpos, meioDir); g_Verts4[1] = CustomVertex_PositionTextured(-1.0f, 1.0f, zpos, meioMeio); g_Verts4[2] = CustomVertex_PositionTextured(-1.0f, -1.0f, zpos, baixoMeio); g_Verts4[3] = CustomVertex_PositionTextured( 1.0f, -1.0f, zpos, baixoEsq); // Configuração normal dos vértices com coordenadas de textura g_Verts5[0] = CustomVertex_PositionTextured( 1.0f, 1.0f, zpos, meioMeio); g_Verts5[1] = CustomVertex_PositionTextured(-1.0f, 1.0f, zpos, meioEsq); g_Verts5[2] = CustomVertex_PositionTextured(-1.0f, -1.0f, zpos, baixoDir); g_Verts5[3] = CustomVertex_PositionTextured( 1.0f, -1.0f, zpos, baixoMeio); // Um ponteiro para cada conjunto de vértices g_pVerts[0] = &g_Verts1[0 ]; g_pVerts[1] = &g_Verts2[0 ]; g_pVerts[2] = &g_Verts3[0 ]; g_pVerts[3] = &g_Verts4[0 ]; g_pVerts[4] = &g_Verts5[0 ]; } // montar_Geometria().fim
Coordenadas nomeadas de textura
// cima-esquerda TexCoord cimaEsq( 0.0f, 0.0f); // cima-direita TexCoord cimaDir( 1.0f, 0.0f); // baixo-direita TexCoord baixoDir ( 1.0f, 1.0f); // (...) // baixo-esquerda TexCoord baixoEsq ( 0.0f, 1.0f);
Produzimos várias coordenadas de texturas com a estrutura TexCoord para facilitar o mapeamento da textura em cada quadrado. Cada coordenada de textura representa um ponto notável referente aos meios e extremidades da imagem carregada. Montagem do quadrado texturizado
g_Verts1[0] = CustomVertex_PositionTextured( 1.0f, 1.0f, zpos, cimaEsq); g_Verts1[1] = CustomVertex_PositionTextured(-1.0f, 1.0f, zpos, cimaDir); g_Verts1[2] = CustomVertex_PositionTextured(-1.0f, -1.0f, zpos, baixoDir); g_Verts1[3] = CustomVertex_PositionTextured( 1.0f, -1.0f, zpos, baixoEsq);
Esse conjunto de vértices com essa configuração particular de coordenadas de textura pertence ao primeiro quadrado que traz estampado em sua superfície o total da textura. Os demais quadrados foram definidos de forma muito semelhante a esta amostra comentada. Guardando o endereço de cada recipiente de vértices
g_pVerts[0] = &g_Verts1[0]; g_pVerts[1] = &g_Verts2[0]; g_pVerts[2] = &g_Verts3[0]; g_pVerts[3] = &g_Verts4[0]; g_pVerts[4] = &g_Verts5[0];
Aqui em cada posição da array g_pVerts é estocado o endereço inicial de cada conjunto de vértices que produzem o seu respectivo quadrado texturizado de forma particular. Depois, colocando a variável temporizador como índice dessa array ocasiona a cada segundo um diferente buffer de vértices para o método DrawIndexedPrimitiveUP() fazer o seu trabalho de renderização, produzindo assim a cada segundo um quadrado texturizado de forma diferente. 2.4 Renderização do quadrado texturizado
void renderizar_Geometria() { // Produz a cada segundo um valor de 0 a 4. temporizador = ( clock() / 1000 ) % 5; // Argumentos da função DrawIndexedPrimitiveUP() UINT nVerticeInicial = 0; UINT nVerticeQtd = 4; UINT nContagemPrim = 2; UINT nPasso = sizeof(CustomVertex_PositionTextured); // Declara o formato de vértice utilizado pela aplicação g_device->SetFVF( CustomVertex_PositionTextured_Format); g_device->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST, nVerticeInicial, nVerticeQtd, nContagemPrim, &g_Indices, D3DFMT_INDEX16, g_pVerts[temporizador], nPasso); } // renderizar_Geometria().fim
temporizador = ( clock() / 1000 ) % 5; Esta linha simples faz o trabalho formidável de selecionar a cada segundo um dos cinco recipientes diferentes de vértices cada um com seu quadrado texturizado de forma particular. Nesta linha o valor 1000 representa o período de 1 segundo para gerar a mudança no temporizador; se você quiser um período de dois segundos basta alterar esse valor para 2000. O valor 5 depois do operador módulus (%) vai restringir o valor máximo do temporizador dado pela subtração 5 - 1. g_device->SetFVF( CustomVertex_PositionTextured_Format); Configura o formato de vértice atual no dispositivo renderizador. g_device->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST, nVerticeInicial, nVerticeQtd, nContagemPrim, &g_Indices, D3DFMT_INDEX16, g_pVerts[temporizador], nPasso); Renderiza finalmente os vértices resultando em um quadrado texturizado. 2.5 Inicialização da textura
void inicializar_Textura(void) { g_hr = D3DXCreateTextureFromFile (g_device, "\\gameprog\\gdkmedia\\bitmap\\textura2x2.png", &g_Textura); if (FAILED (g_hr)) { MessageBox(NULL, "Falha: D3DXCreateTextureFromFile()", "inicializar_Textura()", MB_OK); } // endif // Configura a textura no dispositivo g_device->SetTexture (0, g_Textura); // Corrige visualização blocada da textura - quando textura for // menor do que a superfície ( atuante nesta aplicação ) g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); // Corrige visualização blocada da textura - quando textura for // maior do que a superfície ( não atuante nesta aplicação ) g_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); } // inicializar_Textura(void).fim
g_hr = D3DXCreateTextureFromFile (g_device, "\\gameprog\\gdkmedia\\bitmap\\textura2x2.png", &g_Textura); Esta linha carrega a imagem e produz um objeto textura. g_device->SetTexture (0, g_Textura); Esta linha configura a textura no dispositivo. Para limpar a textura do dispositivo passe o valor NULL no estágio a ser limpo. Por exemplo, essa linha anula a textura do estágio 0: g_device->SetTexture (0, NULL); O estágio de textura é um canal que contém uma textura que pode ser utilizado para efeitos especiais de mistura de texturas. g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); g_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); Estas linhas fazem a correção visual da textura na ocasião em que a textura aparece blocada ou pixelizada em função do descompasso do tamanho da textura com o tamanho da área texturizada. 3. Código fonte do projeto de exemplo: prj_Textura
// Projeto: prj_Textura - Arquivo: motor.h // Esse projeto ilustra como renderizar um quadrado com textura // Produzido por www.gameprog.com.br #ifndef motor_h #define motor_h // Inclui as bibliotecas do Direct3D #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") // Estrutura para suportar coordenadas de textura struct TexCoord { // Coordenada de textura float tu, tv; // Construtor default TexCoord() {} TexCoord( float _tu, float _tv) { // Configura coordenada de textura tu = _tu; tv =_tv; } }; // fim da estrutura TexCoord // Estrutura de vértice customizado struct CustomVertex_PositionTextured { // Posição do vértice float x, y, z; // Coordenada de textura float tu, tv; // Construtor default CustomVertex_PositionTextured() {} CustomVertex_PositionTextured( float _x, float _y, float _z, TexCoord texcoord) { // Configura posição x = _x; y = _y; z = _z; // Configura coordenada de textura tu = texcoord.tu; tv = texcoord.tv; } }; // fim da estrutura CustomVertex_PositionTextured // Definição do formato de vértice utilizado por esta aplicação #define CustomVertex_PositionTextured_Format(D3DFVF_XYZ | D3DFVF_TEX1) // 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(); // Essa função monta formas geométricas void montar_Geometria (void); // Renderiza os vértices em formas geométricas void renderizar_Geometria (void); // Inicializa a textura void inicializar_Textura(void); // Inicializa a câmera void inicializar_Camera(void); // 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_Textura - arquivo: motor.cpp // Esse projeto ilustra como renderizar um quadrado com textura // Produzido por www.gameprog.com.br // ----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include "motor.h" // Vamos usar a função clock() para produzir um temporizador #include <time.h> // Variáveis globais // Representa o dispositivo Direct3D LPDIRECT3D9 g_Direct3d = NULL; // Representa o dispositivo Renderizador IDirect3DDevice9* g_device = NULL; // Matrizes de configuração da câmera // Matriz de mundo D3DXMATRIX g_mtxMundo; // Matriz de visão D3DXMATRIX g_mtxVisao; // Matriz de projeção D3DXMATRIX g_mtxProj; // 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; // Constante para cores const DWORD branco = 0xFFFFFFFF; // Buffer de índices - indica a ordem de conexão dos vértices WORD g_Indices[6] = { 0, 1, 2, 2, 3, 0 }; // Interface de textura IDirect3DTexture9* g_Textura = NULL; // Controla a mudança periódica do quadrado texturizado // com diferentes coordenadas de textura UINT temporizador = 0; // Memória para os vértices CustomVertex_PositionTextured g_Verts1[4 ]; CustomVertex_PositionTextured g_Verts2[4 ]; CustomVertex_PositionTextured g_Verts3[4 ]; CustomVertex_PositionTextured g_Verts4[4 ]; CustomVertex_PositionTextured g_Verts5[4 ]; // Um ponteiro para cada conjunto de vértices CustomVertex_PositionTextured *g_pVerts[5 ]; // 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; // Configuração do renderizador a ser criado // 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_SOFTWARE_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 vários quads (quadrados) com diferentes coordenadas // de textura montar_Geometria(); // Carrega a textura do disco e configura alguns estados referentes. inicializar_Textura(); // Configura a câmera inicializar_Camera(); // Habilita a iluminação default g_device->SetRenderState (D3DRS_LIGHTING, false); return S_OK; } // initGfx().fim void montar_Geometria(void) { // *** Coordenadas de texturas *** // cima-esquerda TexCoord cimaEsq( 0.0f, 0.0f); // cima-meio TexCoord cimaMeio( 0.5f, 0.0f); // cima-direita TexCoord cimaDir( 1.0f, 0.0f); // meio-direita TexCoord meioDir( 0.0f, 0.5f); // meio-meio TexCoord meioMeio( 0.5f, 0.5f); // meio-esquerda TexCoord meioEsq( 1.0f, 0.5f); // baixo-esquerda TexCoord baixoEsq ( 0.0f, 1.0f); // baixo-meio TexCoord baixoMeio ( 0.5f, 1.0f); // baixo-direita TexCoord baixoDir ( 1.0f, 1.0f); // Posicionamento de profundidade float zpos = 1.0f; // Configuração normal dos vértices com coordenadas de textura g_Verts1[0] = CustomVertex_PositionTextured( 1.0f, 1.0f, zpos, cimaEsq); g_Verts1[1] = CustomVertex_PositionTextured(-1.0f, 1.0f, zpos, cimaDir); g_Verts1[2] = CustomVertex_PositionTextured(-1.0f, -1.0f, zpos, baixoDir); g_Verts1[3] = CustomVertex_PositionTextured( 1.0f, -1.0f, zpos, baixoEsq); // Configuração normal dos vértices com coordenadas de textura g_Verts2[0] = CustomVertex_PositionTextured( 1.0f, 1.0f, zpos, cimaEsq); g_Verts2[1] = CustomVertex_PositionTextured(-1.0f, 1.0f, zpos, cimaMeio); g_Verts2[2] = CustomVertex_PositionTextured(-1.0f, -1.0f, zpos, meioMeio); g_Verts2[3] = CustomVertex_PositionTextured( 1.0f, -1.0f, zpos, meioDir); // Configuração normal dos vértices com coordenadas de textura g_Verts3[0] = CustomVertex_PositionTextured( 1.0f, 1.0f, zpos, cimaMeio); g_Verts3[1] = CustomVertex_PositionTextured(-1.0f, 1.0f, zpos, cimaDir); g_Verts3[2] = CustomVertex_PositionTextured(-1.0f, -1.0f, zpos, meioEsq); g_Verts3[3] = CustomVertex_PositionTextured( 1.0f, -1.0f, zpos, meioMeio); // Configuração normal dos vértices com coordenadas de textura g_Verts4[0] = CustomVertex_PositionTextured( 1.0f, 1.0f, zpos, meioDir); g_Verts4[1] = CustomVertex_PositionTextured(-1.0f, 1.0f, zpos, meioMeio); g_Verts4[2] = CustomVertex_PositionTextured(-1.0f, -1.0f, zpos, baixoMeio); g_Verts4[3] = CustomVertex_PositionTextured( 1.0f, -1.0f, zpos, baixoEsq); // Configuração normal dos vértices com coordenadas de textura g_Verts5[0] = CustomVertex_PositionTextured( 1.0f, 1.0f, zpos, meioMeio); g_Verts5[1] = CustomVertex_PositionTextured(-1.0f, 1.0f, zpos, meioEsq); g_Verts5[2] = CustomVertex_PositionTextured(-1.0f, -1.0f, zpos, baixoDir); g_Verts5[3] = CustomVertex_PositionTextured( 1.0f, -1.0f, zpos, baixoMeio); // Um ponteiro para cada conjunto de vértices g_pVerts[0] = &g_Verts1[0 ]; g_pVerts[1] = &g_Verts2[0 ]; g_pVerts[2] = &g_Verts3[0 ]; g_pVerts[3] = &g_Verts4[0 ]; g_pVerts[4] = &g_Verts5[0 ]; } // montar_Geometria().fim void renderizar_Geometria() { // Produz a cada segundo um valor de 0 a 4. temporizador = ( clock() / 1000 ) % 5; // Argumentos da função DrawIndexedPrimitiveUP() UINT nVerticeInicial = 0; UINT nVerticeQtd = 4; UINT nContagemPrim = 2; UINT nPasso = sizeof(CustomVertex_PositionTextured); // Declara o formato de vértice utilizado pela aplicação g_device->SetFVF( CustomVertex_PositionTextured_Format); g_device->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST, nVerticeInicial, nVerticeQtd, nContagemPrim, &g_Indices, D3DFMT_INDEX16, g_pVerts[temporizador], nPasso); } // 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 a textura if (g_Textura != NULL) g_Textura->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(); // Limpando os ponteiros g_Direct3d = NULL; g_device = NULL; g_Textura = NULL; } // 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, branco, 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_Textura(void) { g_hr = D3DXCreateTextureFromFile (g_device, "\\gameprog\\gdkmedia\\bitmap\\textura2x2.png", &g_Textura); if (FAILED (g_hr)) { MessageBox(NULL, "Falha: D3DXCreateTextureFromFile()", "inicializar_Textura()", MB_OK); } // endif // Configura a textura no dispositivo g_device->SetTexture (0, g_Textura); // Corrige visualização blocada da textura - quando textura for // menor do que a superfície ( atuante nesta aplicação ) g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); // Corrige visualização blocada da textura - quando textura for // maior do que a superfície ( não atuante nesta aplicação ) g_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); } // inicializar_Textura(void).fim void inicializar_Camera(void) { // *************************************************************************** // Inicializa todas as matrizes para elemento neutro D3DXMatrixIdentity( &g_mtxMundo ); D3DXMatrixIdentity( &g_mtxVisao ); D3DXMatrixIdentity( &g_mtxProj ); // *************************************************************************** // Configura a matriz de mundo no dispositivo renderizador g_device->SetTransform( D3DTS_WORLD, &g_mtxMundo ); // *************************************************************************** // 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 ); // Configura a matriz de visão no dispositivo renderizador g_device->SetTransform( D3DTS_VIEW, &g_mtxVisao ); // *************************************************************************** // Argumentos de configuração da matriz de projeção // aspecto dos gráficos float aspecto = (float) g_xtela / g_ytela; // campo de visão float campo_visao = 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_visao, aspecto, corte_perto, corte_longe); // Configura a matriz de projeção no dispositivo renderizador g_device->SetTransform( D3DTS_PROJECTION, &g_mtxProj ); } // inicializar_Camera().fim
//----------------------------------------------------------------------------- // Projeto: prj_Textura - arquivo: entrada.cpp // Esse projeto ilustra como renderizar um quadrado com textura // Produzido por 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; int WINAPI WinMain (HINSTANCE app_instancia, HINSTANCE app_anterior, LPSTR sComando,int nExibir) { // alça da janela HWND hJanela; // 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_Textura"; 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