Curso completo de DirectX 9 com C\C++
Gameprog - Escola de programação de jogos digitais
Contato: gameprog.br@gmail.com
Fase 01-6
01.6 Triângulo 2d
1.1 Visão geral
O triângulo é a menor célula de um objeto tridimensional. O triângulo
acima é composto por 3 vértices cada um contendo informação de
posição na forma (x, y, z). Matematicamente o vértice está completo
mas dentro do directx apenas posição é insuficiente para fazer o
melhor uso dos vértices e assim dependendo dos efeitos que se quer
obter muitas outras informações vão sendo adicionadas aos vértices.
Essa necessidade de agregação de informações aos vértices dá origem
ao formato de vértice que varia conforme a intenção da aplicação no
tocante ao uso de cor, luz, textura, animação e outros aspectos.
Na aplicação deste tópico, cada vértice recebe ainda informação de
cor e de intensidade de cor. No triângulo acima os vértices tem uma
cor básica de vermelho, verde e azul que se esparramam e se
misturam pelo triângulo com a mesma intensidade ( 1.0f ).
Ainda para ter o triângulo ou qualquer outra forma desenhada, os
vértices precisam ser posicionados seguindo uma direção regular do
relógio na linha horária ou anti-horária. No triângulo acima foram
colocados primeiro o vértice vermelho p0, depois o vértice verde p1
e por último o vértice azul p2; ou seja, os vértices seguiram uma
direção horária. Essa disposição organizada dos vértices permite a
aplicação de uma técnica pelo directx chamada culling que corta da
renderização triângulos que estão de costas para a câmera e isso
economiza processamento improdutivo da cpu ou da placa de vídeo.
Tranformações
Normalmente, um triângulo para ser exibido sofre ainda uma sequência
de operações matemáticas ou geométricas chamadas transformações. No
triângulo acima cada vértice está posicionado com relação aos outros
vértices do próprio triângulo, esse posicionamento é chamado de espaço
local. Quando o triângulo ou objeto é posicionado em um mundo virtual
ocorre a primeira transformação quando seus vértices são recalculados
para posicionar de fato o objeto neste mundo virtual.
Nessa primeira transformação, o objeto é transportado do espaço local
para o espaço mundial. Mas para ser visto o objeto precisa ser trazido
do espaço mundial para o espaço de tela ou espaço de visualização.
Geralmente estas transformações são multiplicações matemáticas que
são feitas no posicionamento dos vértices até chegar na posição (x,y)
final do vértice para compor a imagem na tela.
Falamos sobre a transformação de posicionamento chamada de translação
mas existem outras e mais outras para aplicação de escala, rotação,
correções de visualização e aplicação de efeitos especiais.
É importante destacar que as transformações são feitas internamente
pelo directx utilizando os dados numéricos dispostos geralmente
em matrizes e vetores matemáticos.
Formato de vértice
Nosso triângulo não vai sofrer nenhuma transformação uma vez que
vamos passar a coordenada 2D final do vértice acompanhada da
informação de cor. Dizemos então que o formato de vértice do nosso
triângulo é transformado e colorido, TransformedColored como se diz
em directx. Outros formatos de vértice podem incluir informações
sobre texturas ou posicionamento que vai sofrer cálculos futuros de
transformações.
1.2 Estrutura principal da aplicação
Arquivo: motor.cpp
initGfx()
Inicializa objeto Direct3d
Inicializa dispositivo renderizador
chama montar_Geometria() para configurar os vértices
montar_Geometria()
Configura posição dos vértices
renderizar_Geometria()
Declara o formato de vértice utilizado ao directx
Renderiza os vértices com g_device->DrawPrimitiveUP()
Renderizar()
Limpa a tela
Desenha a cena
chama renderizar_Geometria() para desenhar o triângulo
Apresenta a cena
Limpar()
Libera dispositivo renderizador
Libera objeto Direct3d
2.1 Aspectos globais - Arquivo: motor.h
// Projeto: prj_Triangulo01 - Arquivo: motor.h
// Esta aplicação ilustra como renderizar um triângulo
#ifndef motor_h
#define motor_h
// 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);
// Declaração da função que atende as mensagens da janela
LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem,
WPARAM wParam, LPARAM lParam);
#endif
// Essa função monta formas geométricas
void montar_Geometria (void);
Essa função configura os vértices que vão compor o triângulo que
será renderizado. O triângulo está representado por uma array de
3 vértices g_Vertices. Os vértices por sua vez estão formatados numa
estrutura chamada CustomVertex_TransformedColored com informação de
posição, cor e intensidade de cor de cada vértice utilizado. O
prefixo CustomVertex_ do nome dessa estrutura é traduzido como vértice
customizado ou personalizado ou ainda também de vértice flexível pois
o directx dá a liberdade ao programador de compor o vértice conforme
a necessidade particular da aplicação. O restante do nome da estrutura
TransformedColored indica que os vértices são coloridos e já estão
posicionados em coordenadas de tela e não necessitam de transformações
ou ainda do uso de uma câmera em cena.
// Renderiza os vértices em formas geométricas
void renderizar_Geometria (void);
Essa função desenha o triângulo na cena. Lembramos que todo processo
de desenhar ocorre entre as funções BeginScene() e EndScene() do
dispositivo renderizador. Então essa função e outras como ela que
desenham as formas geométricas são chamadas pela função Renderizar()
que contém essas funções obrigatórias de início e finalização do
processo de renderização.
A função renderizar_Geometria() antes de desenhar a cena deve
informar ou declarar ao dispositivo renderizador o formato de
vértice utilizado. De forma geral, antes de desenhar alguma coisa
é configurado vários estados internos do dispositivo renderizador que
vão impactar como a cena vai ser desenhada tais como visualização
sólida ou em wireframe (aramado) entre centenas de outros estados que
podem ser configurados.
2.1.2 Aspectos globais - Arquivo: motor.cpp
// -----------------------------------------------------------------------------
// Projeto: prj_Triangulo01 - arquivo: motor.cpp
// Esta aplicação ilustra como renderizar um triângulo
// Produzido por 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;
// Essa variável recebe informação de erro do Directx
HRESULT g_hr = 0;
extern int g_xtela;
extern int g_ytela;
// Constante para cores
const DWORD vermelho = 0xFFFF0000;
const DWORD branco = 0xFFFFFFFF;
const DWORD verde = 0xFF00FF00;
const DWORD azul = 0xFF0000FF;
// Definição do formato de vértice utilizado pela aplicação
#define CustomVertex_TransformedColored_Format(D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
// Definição da estrutura de vértice customizado
struct CustomVertex_TransformedColored
{
float x, y, z;
float rhw;
DWORD cor;
// Construtor default
CustomVertex_TransformedColored() {}
// Construtor com inicialização
CustomVertex_TransformedColored( float _x, float _y, float _z, float _rhw, DWORD _cor)
{
x = _x;
y = _y;
z = _z;
rhw = _rhw;
cor = _cor;
} // fim do construtor
}; // fim da estrutura CustomVertex_TransformedColored
// Declaração dos vértices para o triângulo
CustomVertex_TransformedColored g_Vertices[3 ];
// Constante para cores
const DWORD vermelho = 0xFFFF0000;
const DWORD branco = 0xFFFFFFFF;
const DWORD verde = 0xFF00FF00;
const DWORD azul = 0xFF0000FF;
Estas contantes de cores definidas vão facilitar a leitura de
informação de cor na configuração dos vértices.
// Definição do formato de vértice utilizado pela aplicação
#define CustomVertex_TransformedColored_Format( D3DFVF_XYZRHW | D3DFVF_DIFFUSE )
Aqui é definido a composição do formato de vértice que será utilizado
no desenho de formas geométricas nesta aplicação. O elemento
D3DFVF_XYZRHW indica que o vértice vai ter quatro floats iniciais
(x,y,z,rhw) seguido por um elemento do tipo DWORD que indica cor
D3DFVF_DIFFUSE. Estes elementos estão declarados dentro do arquivo
d3d9types.h junto com outros valores interessantes para formato de
vértice. Por fim, CustomVertex_TransformedColored_Format traz a
combinação coletiva de D3DFVF_XYZRHW e D3DFVF_DIFFUSE que
posteriormente é utilizado na declaração ao dispositivo renderizador
do formato de vértice utilizado pela aplicação.
// Definição da estrutura de vértice customizado
struct CustomVertex_TransformedColored
{
float x, y, z;
float rhw;
DWORD cor;
// Construtor default
CustomVertex_TransformedColored() {}
// Construtor com inicialização
CustomVertex_TransformedColored( float _x, float _y, float _z,
float _rhw, DWORD _cor)
{
x = _x;
y = _y;
z = _z;
rhw = _rhw;
cor = _cor;
} // fim do construtor
}; // fim da estrutura CustomVertex_TransformedColored
Com relação aos seus membros (x, y, z) representa a coordenada 2d de
tela sendo que z fica ignorado nesta aplicação. O membro cor é auto
explicativo. O float rhw é um quarto float que nesta aplicação
representa a intensidade da cor do vértice; esse quarto float pode
representar outros aspectos em outros contextos. Se configurado
como 1.0f (x, y, z) significa uma posição; se configurado como zero
(x, y, z) significa um vetor que indica direção. Reafirmando, rhw no
contexto dessa aplicação varia de 0.0f a 1.0f e representa a
intensidade com a qual a cor do vértice se esparrama pelo triângulo.
CustomVertex_TransformedColored() {}
Este construtor é para permitir a declaração desta estrutura sem uma
inicialização explícita dos valores dos membros pela aplicação.
CustomVertex_TransformedColored( float _x, float _y, float _z,
float _rhw, DWORD _cor)
Este construtor é para permitir a inicialização explícita dos membros
da estrutura pela aplicação. Esse construtor permitiu montar_Geometria()
apresentar uma linha como esta na configuração dos vértices:
g_Vertices[2] = CustomVertex_TransformedColored( 128.0f, 384.0f, zpos, 1.0f, azul);
// Declaração dos vértices para o triângulo
CustomVertex_TransformedColored g_Vertices[3];
Aqui declaramos inicialmente os 3 vértices que vão ser plenamente
configurados em montar_Geometria().
2.1 Inicializando o motor gráfico
Veja no destaque que initGfx() chama a função montar_Geometria()
para a trabalho de configuração inicial dos vértices.
// 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 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 vira 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 as formas geométricas
montar_Geometria();
return S_OK;
} // initGfx().fim
2.2 Construção das formas geométricas
void montar_Geometria(void)
{
// Posicionamento de profundidade
float zpos = 1.0f;
// p0 - primeiro vértice
g_Vertices[0] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 1.0f, vermelho);
// p1 - segundo vértice
g_Vertices[1] = CustomVertex_TransformedColored( 512.0f, 384.0f, zpos, 1.0f, verde);
// p2 - terceiro vértice
g_Vertices[2] = CustomVertex_TransformedColored( 128.0f, 384.0f, zpos, 1.0f, azul);
} // montar_Geometria().fim
// Posicionamento de profundidade
float zpos = 1.0f;
Aqui é a configuração de profundidade do triângulo mas este valor não
será utilizado efetivamente por esta aplicação. O essencial da
coordenada vai ser (x, y) que apontam direto para a tela.
// p0 - primeiro vértice
g_Vertices[0] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 1.0f, vermelho);
// p1 - segundo vértice
g_Vertices[1] = CustomVertex_TransformedColored( 512.0f, 384.0f, zpos, 1.0f, verde);
// p2 - terceiro vértice
g_Vertices[2] = CustomVertex_TransformedColored( 128.0f, 384.0f, zpos, 1.0f, azul);
Aqui é um aspecto fundamental de uma aplicação 3d: o processo de
posicionamento dos vértices que produz com isso as diversas formas
geométricas. O valor 1.0f é o rhw que nesse contexto determina a
intensidade de cor; faça variações nestes valores para ver os efeitos
de colorimento que isso provoca no triângulo. Aqui montamos um
triângulo manualmente para mostrar como o directx funciona mas
geralmente os objetos 3d são carregados de arquivos como o arquivo x
nativo do directx depois de terem sido criados em outras aplicações
de modelagem gráfica.
2.3 Renderização das formas geométricas
void renderizar_Geometria()
{
// Todo código de desenhar ocorre aqui dentro
g_device->SetFVF( CustomVertex_TransformedColored_Format);
// Quantidade de primitivas possíveis de acordo com o uso de vértices
UINT nContagem = 1;
// Tamanho do passo para achar o próximo vértice
UINT nPasso = sizeof(CustomVertex_TransformedColored);
// Desenha forma geométrica
g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, nPasso);
} // renderizar_Geometria().fim
// Todo código de desenhar ocorre aqui dentro
g_device->SetFVF( CustomVertex_TransformedColored_Format);
Aqui é informado ao dispositivo renderizador o formato de vértice
utilizado pela aplicação.
// Quantidade de primitivas possíveis de acordo com o uso de vértices
UINT nContagem = 1;
Esta variável representa a quantidade de formas primitivas que serão
renderizadas com o conjunto de (3) vértices apresentados. Aqui é a
indicação de quantos (1) triângulos serão produzidos. O mesmo
conjunto de vértices pode dar origem a quantidades diferentes de
outros tipos de formas primitivas. Por exemplo, se a forma primitiva
fosse pontos finais na tela, a variável nContagem poderia ser
configurada para três.
// Tamanho do passo para achar o próximo vértice
UINT nPasso = sizeof(CustomVertex_TransformedColored);
A função que renderiza os vértices precisa saber qual é o espaçamento
entre um vértice e outro. Esse espaçamento é obtido pela instrução
sizeof() com a estrutura do formato de vértice como seu argumento.
// Desenha forma geométrica
g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, nPasso);
A função DrawPrimitiveUP() renderiza os vértices de usuário presentes
numa array ( &g_Vertices ) na quantidade determinada ( nContagem ) da
forma primitiva escolhida D3DPT_TRIANGLELIST (lista de triângulos).
Vamos conhecer as outras formas primitivas em um outro tópico.
2.4 Renderizando a cena
A função Renderizar() prepara o contexto obrigatório de renderização
e chama a função renderizar_Geometria() para o desenho do triângulo.
// -----------------------------------------------------------------------------
// 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 as formas geométricas
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
3. Código fonte do projeto de exemplo: prj_Triangulo01
// Projeto: prj_Triangulo01 - Arquivo: motor.h
// Esta aplicação ilustra como renderizar um triângulo
#ifndef motor_h
#define motor_h
// 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);
// 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_Triangulo01 - arquivo: motor.cpp
// Esta aplicação ilustra como renderizar um triângulo
// Produzido por 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;
// Essa variável recebe informação de erro do Directx
HRESULT g_hr = 0;
extern int g_xtela;
extern int g_ytela;
// Constante para cores
const DWORD vermelho = 0xFFFF0000;
const DWORD branco = 0xFFFFFFFF;
const DWORD verde = 0xFF00FF00;
const DWORD azul = 0xFF0000FF;
// Definição do formato de vértice utilizado pela aplicação
#define CustomVertex_TransformedColored_Format(D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
// Definição da estrutura de vértice customizado
struct CustomVertex_TransformedColored
{
float x, y, z;
float rhw;
DWORD cor;
// Construtor default
CustomVertex_TransformedColored() {}
// Construtor com inicialização
CustomVertex_TransformedColored( float _x, float _y, float _z, float _rhw, DWORD _cor)
{
x = _x;
y = _y;
z = _z;
rhw = _rhw;
cor = _cor;
} // fim do construtor
}; // fim da estrutura CustomVertex_TransformedColored
// Declaração dos vértices para o triângulo
CustomVertex_TransformedColored g_Vertices[3 ];
// 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 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 vira 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 as formas geométricas
montar_Geometria();
return S_OK;
} // initGfx().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 as formas geométricas
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 montar_Geometria(void)
{
// Posicionamento de profundidade
float zpos = 1.0f;
// p0 - primeiro vértice
g_Vertices[0] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 1.0f, vermelho);
// p1 - segundo vértice
g_Vertices[1] = CustomVertex_TransformedColored( 512.0f, 384.0f, zpos, 1.0f, verde);
// p2 - terceiro vértice
g_Vertices[2] = CustomVertex_TransformedColored( 128.0f, 384.0f, zpos, 1.0f, azul);
} // montar_Geometria().fim
void renderizar_Geometria()
{
// Todo código de desenhar ocorre aqui dentro
g_device->SetFVF( CustomVertex_TransformedColored_Format);
// Quantidade de primitivas possíveis de acordo com o uso de vértices
UINT nContagem = 1;
// Tamanho do passo para achar o próximo vértice
UINT nPasso = sizeof(CustomVertex_TransformedColored);
// Desenha forma geométrica
g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, 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 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
//-----------------------------------------------------------------------------
// Projeto: prj_Triangulo01 - arquivo: entrada.cpp
// Esta aplicação ilustra como renderizar um triângulo
// 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_Triangulo01";
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