Curso completo de DirectX 9 com C\C++
Gameprog - Escola de programação de jogos digitais
Contato: gameprog.br@gmail.com
Fase 03-4
03.4 Mistura de cor (Blending) - Parte 1/2
1.1 Visão geral
Geralmente cada pixel da forma entrante vai encontrar um backbuffer
já preenchido por uma cor do estado anterior do backbuffer ou de
formas previamente lá desenhadas. Em resumo, a cor do pixel final
vai surgir da relação da cor do pixel entrante com a cor do pixel do
backbuffer que já está lá e nesta relação a configuração de blending
determina quem prevalesce tal como o pixel entrante ou o pixel que já
estava no frame buffer ou ainda uma mistura de ambos. Naturalmente
fazem parte desse jogo todos os participantes que influenciam na
cor dos pixels como a textura, a luz, o material e o aspecto alpha da
cor.
Uma simples equação de mistura de cor é dada dessa forma:
corPixelFinal = corPixelEntrante + corPixelCorrente
corPixelFinal é a cor final do pixel.
corPixelEntrante é a cor do pixel entrante que já sofreu colorimento
da textura com sua filtragem e impacto da luz.
corPixelCorrente é a cor que já está no backbuffer ou frame buffer.
Na equação simples a cor final foi produzida pela operação de adição
mas é comum também a utilização de outras operações como divisão ou
multiplicação.
A equação simples é só para dar uma idéia básica do processo. Na
equação final há dois fatores matemáticos que controlam o
equilíbrio da mistura de cor que pode tender para o pixel entrante
ou para o pixel corrente conforme a configuração de seus valores:
corFinal = (corEntrante * fatorFonte) + ( corCorrente * fatorDestino)
O controle dos integrantes dessa equação reside na sua aplicação.
Quando você limpa inicialmente o backbuffer com uma cor, você já
instala nesse momento uma corCorrente. Quando você pensa em
renderizar um teapot amarelo você está premeditando a corEntrante;
quando você finalizou a renderização do teapot você produziu a
corFinal que tornou-se a corCorrente do momento. Este jogo de mistura
de cor pode ficar um pouco mais complicado de se controlar na medida
em que sua aplicação vai envolvendo mais luzes, texturas e objetos
para produzir a imagem final do frame.
Para a configuração dos fatores de mistura fonte e destino o directx
oferece essas opções que foram organizadas numa array de strings na
aplicação de exemplo desse tópico:
char *mensagem[] =
{
"prj_Alpha01: 0. *** Não usado! *** ",
"prj_Alpha01: 1. D3DBLEND_ZERO ",
"prj_Alpha01: 2. D3DBLEND_ONE ",
"prj_Alpha01: 3. D3DBLEND_SRCCOLOR ",
"prj_Alpha01: 4. D3DBLEND_INVSRCCOLOR ",
"prj_Alpha01: 5. D3DBLEND_SRCALPHA ",
"prj_Alpha01: 6. D3DBLEND_INVSRCALPHA ",
"prj_Alpha01: 7. D3DBLEND_DESTALPHA ",
"prj_Alpha01: 8. D3DBLEND_INVDESTALPHA ",
"prj_Alpha01: 9. D3DBLEND_DESTCOLOR ",
"prj_Alpha01: 10. D3DBLEND_INVDESTCOLOR ",
"prj_Alpha01: 11. D3DBLEND_SRCALPHASAT ",
"prj_Alpha01: 12. D3DBLEND_BOTHSRCALPHA ",
"prj_Alpha01: 13. D3DBLEND_BOTHINVSRCALPHA",
"prj_Alpha01: 14. D3DBLEND_BLENDFACTOR ",
"prj_Alpha01: 15. D3DBLEND_INVBLENDFACTOR ",
};
Os valores alistados acima estão na enumeração D3DBLEND do directx
e são configurados dessa forma conforme esse código de exemplo:
g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
Configura o fator de mistura da cor entrante ( fatorFonte )
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
Configura o fator de mistura da cor corrente ( fatorDestino )
Nossa aplicação de exemplo testa todas as opções da lista acima
através da variável temporizador que assume um valor diferente dessa
lista a cada 4 segundos. Esse teste permite uma melhor assimilação do
impacto visual causado pelas diferentes configurações de blending.
Observando a aplicação em execução podemos visualizar várias
aplicações úteis para este recurso de blending: produção de sombras,
iluminação especial, efeitos de fantasmas e outros efeitos visuais.
Adiantamos que na produção de sombras ou espelhamentos é comum
renderizar o mesmo objeto duas vezes, com a segunda renderização
representando a sombra ou a imagem espelhada configurada adequadamente
para ter o aspecto visual de sombra ou de reflexo.
1.2 Estrutura principal da aplicação
Arquivo: motor.cpp
inicializar_Textura()
carrega a textura via D3DXCreateTextureFromFile()
initGfx()
chama inicializar_Textura() para montar o contexto de texturização.
chama montar_Geometria() para montar o quadrado texturizado.
chama inicializar_Camera() para a configuração inicial da câmera.
Configura iluminação
montar_Geometria()
Define coordenadas de texturas nomeadas.
Faz a montagem do quadrado texturizado.
desenhar_Quad()
Prepara matrizes de rotação e posicionamento.
Combina posicionamento e rotação na matriz de mundo local.
joga matriz mundo no dispositivo renderizador.
configura material, textura e endereçamento, formato de vértice.
renderiza o quad com DrawIndexedPrimitiveUP()
desenharObjeto()
prepara matrizes de rotação e posicionamento.
atualiza ângulo de rotação
combina posicionamento e rotação na matriz de mundo local.
joga matriz mundo no dispositivo renderizador.
configura material
renderiza o teapot com DrawSubset(0)
renderizar_Geometria()
Declara o formato de vértice utilizado:
CustomVertex_PositionTextured_Format.
O temporizador seleciona um modo de mistura de
cor diferente a cada quatro segundos.
desliga blending
chama desenhar_Quad() para renderizar o quad (quadrilátero)
liga blending
chama desenharObjeto() para renderizar o teapot na configuração
de blending selecionada
2.1 Aspectos globais - Arquivo: motor.h
//-----------------------------------------------------------------------------
// Projeto: prj_Alpha01 - Arquivo: motor.h
// Esta aplicação mostra os efeitos de mistura de cor (blending)
// Produzido por www.gameprog.com.br
//-----------------------------------------------------------------------------
#ifndef motor_h
#define motor_h
// Estrutura para guardar a coordenada de textura
struct TexCoord
{
// Coordenada de textura
float tu, tv;
// Construtor default
TexCoord() {}
TexCoord( float _tu, float _tv)
{
// Configura coordenada textura
tu = _tu;
tv =_tv;
}
}; // fim da estrutura TexCoord
// Estrutura para guardar cor, posição e rotação do objeto 3d
struct Propriedades3d
{
D3DXVECTOR3 pos;
D3DXVECTOR3 rot;
D3DCOLORVALUE cor;
};
// Definição do formato de vértice utilizado por esta aplicação
#define CustomVertex_PositionTextured_Format(D3DFVF_XYZ | D3DFVF_TEX1)
// Estrutura de vértice customizado
struct CustomVertex_PositionTextured
{
// Posição do vértice
float x, y, z;
// Coordenada da 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 textura
tu = texcoord.tu;
tv = texcoord.tv;
} // fim do construtor
}; // fim da estrutura CustomVertex_PositionTextured
// 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);
// Configura o texto da janela
void config_janelaTexto( char *texto);
// Desenha um objeto 3d
void desenharObjeto ( ID3DXMesh *obj3d, Propriedades3d *props);
// Cria um material com a cor especificada
void criarMaterial(D3DMATERIAL9 *mtl, D3DCOLORVALUE cvCor );
// Desenha um quadrilátero (quad)
void desenhar_Quad( 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
// Estrutura para guardar cor, posição e rotação do objeto 3d
struct Propriedades3d
{
D3DXVECTOR3 pos;
D3DXVECTOR3 rot;
D3DCOLORVALUE cor;
};
Esta estrutura vai auxiliar no posicionamento, rotação e na produção
da cor do material dos objetos 3d da cena.
void renderizar_Geometria (void);
Essa função vai coordenar a renderização dos objetos com configuração
adequada de blending para o quadrilátero (quad) e o teapot.
void desenharObjeto ( ID3DXMesh *obj3d, Propriedades3d *props);
void desenhar_Quad( Propriedades3d *props );
Estas funções têm o mesmo objetivo e são muito semelhantes no código
fonte com pequenas variações no código para acomodar as diferenças
particulares de renderização do quad e do teapot. Por exemplo, o
método DrawSubset(0) do teapot se encarrega de renderizá-lo fazendo
internamente toda a configuração necessária para isso que inclui
ajuste de formato de vértice, ajuste de vertexbuffer etc.
2.2 Aspectos globais - Arquivo: motor.cpp
IDirect3DTexture9* g_Textura = NULL;
// Material para o objeto 3d
D3DMATERIAL9 g_material;
// Interface do objeto 3d
ID3DXMesh *g_objeto3d = NULL;
// Recipiente de cor, rotação e posição do objeto
Propriedades3d g_props;
// Controla o ângulo de rotação do objeto 3d
float g_angulo = 0.0f;
// Variáveis para cores com rgba expressado em float's
D3DCOLORVALUE cvBranco = { 1.0f, 1.0f, 1.0f, 1.0f };
D3DCOLORVALUE cvAmarelo = { 1.0f, 1.0f, 0.0f, 1.0f };
// Constante para cores
const DWORD dwBranco = 0xFFFFFFFF;
// Velocidade de giro do teapot
float velocidade = 0.02f;
// Controla mudanças periódicas na configuração de blending
UINT temporizador = 0;
IDirect3DTexture9* g_Textura = NULL;
Esta é a interface para manipulação da única textura dessa aplicação.
D3DMATERIAL9 g_material;
Esta estrutura servirá para configurar o material dos objetos.
ID3DXMesh *g_objeto3d = NULL;
Este objeto é utilizado para conter o objeto 3d teapot que será
criado.
Propriedades3d g_props;
Esta estrutura vai auxiliar no posicionamento, rotação e produção do
material do quad e do teapot.
float g_angulo = 0.0f;
float velocidade = 0.02f;
Estas variáveis controlam a rotação dinâmica dada ao teapot.
D3DCOLORVALUE cvBranco = { 1.0f, 1.0f, 1.0f, 1.0f };
D3DCOLORVALUE cvAmarelo = { 1.0f, 1.0f, 0.0f, 1.0f };
Estas variáveis trazem as cores dos materiais que serão aplicados nos
objetos: amarelo para o teapot e branco para o quad. O canal alpha
da cor causa grande impacto visual na produção de efeitos de
transpararência quando aproveitado na configuração de blending.
const DWORD dwBranco = 0xFFFFFFFF;
Este é o branco que limpa inicialmente o backbuffer a cada frame.
UINT temporizador = 0;
Esta variável para o temporizador, já conhecido de aplicações
anteriores, participa do processo de trocar a configuração de
blending a cada 4 segundos.
2.3 Inicialização da texturização
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
} // inicializar_Textura(void).fim
2.4 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;
// Habilita o buffer de profundidade
pps.EnableAutoDepthStencil = true;
pps.AutoDepthStencilFormat = D3DFMT_D16;
// 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 o quad
montar_Geometria();
// Inicializa a textura
inicializar_Textura();
// Inicializa a câmera
inicializar_Camera();
// Configura luz ambiente
g_device->SetRenderState (D3DRS_LIGHTING, true);
g_device->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB(255,250,250) );
return S_OK;
} // initGfx().fim
Para a obtenção do resultado visual adequado a luz foi configurada
dessa forma:
g_device->SetRenderState (D3DRS_LIGHTING, true);
A luz foi ativada porque o teapot traz informação de normais no seu
conjunto de vértices que combinada com a configuração do material e
da luz ambiente produz uma imagem final melhor.
g_device->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB(255,250,250) );
Aqui a luz ambiente foi configurada para melhorar o visual do quad
e do teapot.
2.5 Renderização da geometria
void renderizar_Geometria()
{
// Mensagens para a barra de títulos da janela
char *mensagem[] =
{
"prj_Alpha01: By Gameprog ",
"prj_Alpha01: 1. D3DBLEND_ZERO ",
"prj_Alpha01: 2. D3DBLEND_ONE ",
"prj_Alpha01: 3. D3DBLEND_SRCCOLOR ",
"prj_Alpha01: 4. D3DBLEND_INVSRCCOLOR ",
"prj_Alpha01: 5. D3DBLEND_SRCALPHA ",
"prj_Alpha01: 6. D3DBLEND_INVSRCALPHA ",
"prj_Alpha01: 7. D3DBLEND_DESTALPHA ",
"prj_Alpha01: 8. D3DBLEND_INVDESTALPHA ",
"prj_Alpha01: 9. D3DBLEND_DESTCOLOR ",
"prj_Alpha01: 10. D3DBLEND_INVDESTCOLOR ",
"prj_Alpha01: 11. D3DBLEND_SRCALPHASAT ",
"prj_Alpha01: 12. D3DBLEND_BOTHSRCALPHA ",
"prj_Alpha01: 13. D3DBLEND_BOTHINVSRCALPHA",
"prj_Alpha01: 14. D3DBLEND_BLENDFACTOR ",
"prj_Alpha01: 15. D3DBLEND_INVBLENDFACTOR ",
};
// Produz a cada quadro segundos um valor de 0 a 14.
temporizador = ( clock() / 4000 ) % 15;
// Soma mais um para evitar o zero e produzir o 15
temporizador = temporizador + 1;
// Configura o texto da janela
config_janelaTexto (mensagem[temporizador]);
// Fator de mistura para os modos 14 e 15 (cor vermelha)
if (temporizador > 13)
g_device->SetRenderState(D3DRS_BLENDFACTOR, 0xFFFF0000);
// Desliga o uso de alpha blending para o quad
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
// Configuração de material do quad
cvBranco.a = 0.9f;
g_props.cor = cvBranco;
// Posição e rotação do teapot
g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
desenhar_Quad(&g_props);
// ********* O próximo passo consiste em desenhar o teapot *********
// Limpa a textura do dispositivo
g_device->SetTexture (0, 0);
// Cria o teapot se ele não existir
if(g_objeto3d == NULL) D3DXCreateTeapot (g_device, &g_objeto3d, NULL);
// Faz a configuração de alpha blending fonte e destino
// D3DBLEND_SRCALPHA na fonte é um boa opção para transparência
g_device->SetRenderState(D3DRS_SRCBLEND, temporizador);
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
// Habilita o uso de alpha blending para o teapot
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
// Configura a cor do material para amarelo
cvAmarelo.a = 0.2f;
g_props.cor = cvAmarelo;
// Posição e rotação do teapot
g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, 1.0f);
g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
// Desenha o teapot
desenharObjeto( g_objeto3d, &g_props);
} // renderizar_Geometria().fim
char *mensagem[] = {
"prj_Alpha01: By Gameprog ",
"prj_Alpha01: 1. D3DBLEND_ZERO ",
"prj_Alpha01: 2. D3DBLEND_ONE ",
"prj_Alpha01: 3. D3DBLEND_SRCCOLOR ",
"prj_Alpha01: 4. D3DBLEND_INVSRCCOLOR ",
"prj_Alpha01: 5. D3DBLEND_SRCALPHA ",
"prj_Alpha01: 6. D3DBLEND_INVSRCALPHA ",
"prj_Alpha01: 7. D3DBLEND_DESTALPHA ",
"prj_Alpha01: 8. D3DBLEND_INVDESTALPHA ",
"prj_Alpha01: 9. D3DBLEND_DESTCOLOR ",
"prj_Alpha01: 10. D3DBLEND_INVDESTCOLOR ",
"prj_Alpha01: 11. D3DBLEND_SRCALPHASAT ",
"prj_Alpha01: 12. D3DBLEND_BOTHSRCALPHA ",
"prj_Alpha01: 13. D3DBLEND_BOTHINVSRCALPHA",
"prj_Alpha01: 14. D3DBLEND_BLENDFACTOR ",
"prj_Alpha01: 15. D3DBLEND_INVBLENDFACTOR "};
Essa aqui é uma lista de strings das configurações possíveis de
blending que vão aparecer na barra de títulos da janela conforme
estejam configuradas pela variável temporizador.
temporizador = ( clock() / 4000 ) % 15; temporizador = temporizador + 1;
Essa linha produz um valor de 1 a 15 com intervalo de 4 segundos entre
cada mudança.
if (temporizador > 13) g_device->SetRenderState(D3DRS_BLENDFACTOR, 0xFFFF0000);
Esta linha especifica uma cor, a cor vermelha neste caso, como fator
de blending que é utilizada nos modos D3DBLEND_BLENDFACTOR e
D3DBLEND_INVBLENDFACTOR para definir a cor fonte.
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
Esta linha desliga o uso de alpha blending para o quad. Isso
simplifica a percepção inicial do funcionamento do processo de
mistura de cor pois a aplicação fica focada na mistura do teapot que
está entrando com o quad que já está no backbuffer.
cvBranco.a = 0.9f; g_props.cor = cvBranco;
Aqui é a configuração do material do quad. O impacto dessa
configuração é melhor percebido apenas se o uso de alpha blending for
habilitado com teste de alterações no aspecto alpha desse material.
g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
desenhar_Quad(&g_props);
Aqui o quad é renderizado sem rotação na posição de origem do
mundo 3d.
// ********* O próximo passo consiste em desenhar o teapot *********
Muitos efeitos especiais como sombra ou espelhamento para citar apenas
esses dois mais conhecidos são produzidos em vários passos de
renderização nos bastidores da aplicação. O complicado disso é ficar
atento ao jogo das configurações necessárias dos estados em cada
passo e visualizar parcialmente como está o backbuffer em cada
passo para dar o passo seguinte com conhecimento de causa. Pois bem,
até esse momento o quad está renderizado no backbuffer e o próximo
passo agora é habilitar o uso de alpha blending, configurar o modo
de mistura e finalmente renderizar o teapot.
g_device->SetTexture (0, 0);
O teapot não vai usar textura por isso ela é desligada.
if(g_objeto3d == NULL) D3DXCreateTeapot (g_device, &g_objeto3d, NULL);
Aqui criamos o teapot e esse código é executado apenas uma vez.
g_device->SetRenderState(D3DRS_SRCBLEND, temporizador);
Aqui nessa linha o fator de mistura do pixel entrante ou fonte
referido pelo estado D3DRS_SRCBLEND é configurado com o valor que
está na variável temporizador que assume a cada quatro segundos uma
outra configuração possível.
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
Aqui nessa linha o fator de mistura do pixel corrente que já está no
backbuffer referido pelo estado D3DRS_DESTBLEND é configurado com o
valor D3DBLEND_INVSRCALPHA que vai aproveitar o inverso da
configuração alpha do material do teapot. Por exemplo, se o canal
alpha estiver a 20%, essa configuração vai ser então 80% ou 0.8f;
o inverso é dado pela subtração (1.0f - cvAmarelo.a).
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
Aqui habilitamos o uso de alpha blending para a renderização do teapot.
cvAmarelo.a = 0.2f;
g_props.cor = cvAmarelo;
Configuramos o material do teapot com uma atenção especial no canal
alpha.
g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, 1.0f);
g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
desenharObjeto( g_objeto3d, &g_props);
Aqui renderizamos o teapot na frente do quad que vai ser afetado pela
configuração de blending.
2.6 Renderização do teapot
void desenharObjeto ( ID3DXMesh *obj3d, Propriedades3d *props)
{
// Matrizes para controlar posição e rotação do objeto 3d
D3DXMATRIX obj_rot;
D3DXMATRIX obj_pos;
// Matriz para combinar todas as transformações do objeto 3d
D3DXMATRIX mtxCombinada;
// Vamos inicializar as matrizes para um valor neutro
D3DXMatrixIdentity( &obj_rot );
D3DXMatrixIdentity( &obj_pos );
D3DXMatrixIdentity( &mtxCombinada );
// Atualiza ângulo de rotação
g_angulo += velocidade;
if (g_angulo > 6.28f) velocidade = -velocidade;
if (g_angulo < -6.28f) velocidade = -velocidade;
// 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 mundo
D3DXMatrixMultiply (&mtxCombinada, &obj_rot, &obj_pos);
// Configura matriz mundo para o dispositivo renderizador
g_device->SetTransform( D3DTS_WORLD, &mtxCombinada );
// Prepara e aplica uma material no objeto 3d
criarMaterial( &g_material, props->cor);
g_device->SetMaterial (&g_material);
// Renderiza o mesh
obj3d->DrawSubset(0);
} // desenharObjeto().fim
D3DXMATRIX obj_rot;
D3DXMATRIX obj_pos;
Estas matrizes parciais vão receber a rotação e posição do objeto 3d.
D3DXMATRIX mtxCombinada;
Esta matriz é a matriz mundo do objeto 3d; nela vão ser combinados
rotação e posicionamento do objeto 3d.
D3DXMatrixIdentity( &obj_rot );
D3DXMatrixIdentity( &obj_pos );
D3DXMatrixIdentity( &mtxCombinada );
Aqui todas as matrizes são configuradas com um fator de neutralidade
das matrizes que é a matriz identidade.
g_angulo += velocidade;
Aqui o ângulo de rotação é atualizado.
if (g_angulo > 6.28f) velocidade = -velocidade;
if (g_angulo < -6.28f) velocidade = -velocidade;
Aqui a rotação ganha um inversão para a direção oposta caso o objeto
3d tenha dado uma volta completa ( 360º ou 6.28f em radianos ).
D3DXMatrixRotationYawPitchRoll(&obj_rot,
props->rot.y + g_angulo,
props->rot.x + g_angulo,
props->rot.z);
Aqui a matriz de rotação do objeto é preparada.
D3DXMatrixTranslation(&obj_pos,
props->pos.x, props->pos.y, props->pos.z);
Aqui a matriz de posicionamento do objeto é preparada.
D3DXMatrixMultiply (&mtxCombinada, &obj_rot, &obj_pos);
Aqui a matriz final do objeto com rotação e posicionamento é preparada.
g_device->SetTransform( D3DTS_WORLD, &mtxCombinada );
Na sequência a matriz mundo do renderizador é configurada com a matriz
final do objeto 3d.
criarMaterial( &g_material, props->cor);
g_device->SetMaterial (&g_material);
Aqui ocorre a preparação e configuração do material do objeto 3d.
obj3d->DrawSubset(0);
E finalmente o método DrawSubset(0) renderiza o objeto 3d.
2.7 Renderização do quad
Segue abaixo a listagem da função desenhar_Quad() na qual o código
de uso das matrizes foi explicado na função desenharObjeto().
void desenhar_Quad( Propriedades3d *props )
{
// Matrizes para controlar posição e rotação do objeto 3d
D3DXMATRIX obj_rot;
D3DXMATRIX obj_pos;
// Matriz para combinar todas as transformações do objeto 3d
D3DXMATRIX mtxCombinada;
// Vamos inicializar as matrizes para um valor neutro
D3DXMatrixIdentity( &obj_rot );
D3DXMatrixIdentity( &obj_pos );
D3DXMatrixIdentity( &mtxCombinada );
// Configura rotação do objeto 3d
D3DXMatrixRotationYawPitchRoll(&obj_rot,
props->rot.y,
props->rot.x,
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 mundo
D3DXMatrixMultiply (&mtxCombinada, &obj_rot, &obj_pos);
// Configura matriz mundo para o dispositivo renderizador
g_device->SetTransform( D3DTS_WORLD, &mtxCombinada );
// Prepara e aplica uma material no objeto 3d
criarMaterial( &g_material, cvBranco);
g_device->SetMaterial (&g_material);
g_device->SetTexture (0, g_Textura);
// 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);
// Configura modo de textura
g_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
g_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
// Renderiza o quad
g_device->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST,
nVerticeInicial, nVerticeQtd, nContagemPrim, &g_Indices,
D3DFMT_INDEX16, &g_Verts, nPasso);
} // desenhar_Quad()
3. Código fonte do projeto de exemplo: prj_Alpha01

//-----------------------------------------------------------------------------
// Projeto: prj_Alpha01 - Arquivo: motor.h
// Esta aplicação mostra os efeitos de mistura de cor (blending)
// Produzido por www.gameprog.com.br
//-----------------------------------------------------------------------------
#ifndef motor_h
#define motor_h
// Estrutura para guardar a coordenada de textura
struct TexCoord
{
// Coordenada de textura
float tu, tv;
// Construtor default
TexCoord() {}
TexCoord(
float _tu,
float _tv)
{
// Configura coordenada textura
tu = _tu;
tv =_tv;
}
}; // fim da estrutura TexCoord
// Estrutura para guardar cor, posição e rotação do objeto 3d
struct Propriedades3d
{
D3DXVECTOR3 pos;
D3DXVECTOR3 rot;
D3DCOLORVALUE cor;
};
// Definição do formato de vértice utilizado por esta aplicação
#define CustomVertex_PositionTextured_Format(
D3DFVF_XYZ |
D3DFVF_TEX1)
// Estrutura de vértice customizado
struct CustomVertex_PositionTextured
{
// Posição do vértice
float x, y, z;
// Coordenada da 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 textura
tu =
texcoord.tu;
tv =
texcoord.tv;
} // fim do construtor
}; // fim da estrutura CustomVertex_PositionTextured
// 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);
// Configura o texto da janela
void config_janelaTexto(
char *texto);
// Desenha um objeto 3d
void desenharObjeto (
ID3DXMesh *obj3d,
Propriedades3d *props);
// Cria um material com a cor especificada
void criarMaterial(
D3DMATERIAL9 *mtl,
D3DCOLORVALUE cvCor );
// Desenha um quadrilátero (quad)
void desenhar_Quad(
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_Alpha01 - arquivo: motor.cpp
// Esta aplicação mostra os efeitos de mistura de cor (blending)
// Produzido por www.gameprog.com.br
// -----------------------------------------------------------------------------
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <time.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;
// 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;
IDirect3DTexture9* g_Textura = NULL;
// Material para o objeto 3d
D3DMATERIAL9 g_material;
// Interface do objeto 3d
ID3DXMesh *g_objeto3d = NULL;
// Recipiente de cor, rotação e posição do objeto
Propriedades3d g_props;
// Controla o ângulo de rotação do objeto 3d
float g_angulo = 0.0f;
// Variáveis para cores com rgba expressado em float's
D3DCOLORVALUE cvBranco = { 1.0f, 1.0f, 1.0f, 1.0f };
D3DCOLORVALUE cvAmarelo = { 1.0f, 1.0f, 0.0f, 1.0f };
// Constante para cores
const DWORD dwBranco = 0xFFFFFFFF;
// Velocidade de giro do teapot
float velocidade = 0.02f;
// Controla mudanças periódicas na configuração de blending
UINT temporizador = 0;
// 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;
// Memória para os vértices
CustomVertex_PositionTextured g_Verts[4 ];
// Buffer de índices - indica a ordem de conexão dos vértices
WORD g_Indices[6] = { 0, 1, 2, 2, 3, 0 };
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
} // inicializar_Textura(void).fim
// 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;
// Habilita o buffer de profundidade
pps.EnableAutoDepthStencil = true;
pps.AutoDepthStencilFormat = D3DFMT_D16;
// 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 o quad
montar_Geometria();
// Inicializa a textura
inicializar_Textura();
// Inicializa a câmera
inicializar_Camera();
// Configura luz ambiente
g_device->SetRenderState (D3DRS_LIGHTING, true);
g_device->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB(255,250,250) );
return S_OK;
} // initGfx().fim
void montar_Geometria(void)
{
// cima-esquerda
TexCoord cimaEsq( 0.0f, 0.0f);
// cima-direita
TexCoord cimaDir( 3.0f, 0.0f);
// baixo-esquerda
TexCoord baixoEsq ( 0.0f, 3.0f);
// baixo-direita
TexCoord baixoDir ( 3.0f, 3.0f);
// Posicionamento de profundidade
float zpos = 0.9f;
// Configuração normal dos vértices com coordenadas de textura
g_Verts[0] = CustomVertex_PositionTextured( 2.20f, 1.50f, zpos, cimaEsq);
g_Verts[1] = CustomVertex_PositionTextured( -2.20f, 1.50f, zpos, cimaDir);
g_Verts[2] = CustomVertex_PositionTextured( -2.20f, -1.50f, zpos, baixoDir);
g_Verts[3] = CustomVertex_PositionTextured( 2.20f, -1.50f, zpos, baixoEsq);
} // montar_Geometria().fim
void renderizar_Geometria()
{
// Mensagens para a barra de títulos da janela
char *mensagem[] =
{
"prj_Alpha01: By Gameprog ",
"prj_Alpha01: 1. D3DBLEND_ZERO ",
"prj_Alpha01: 2. D3DBLEND_ONE ",
"prj_Alpha01: 3. D3DBLEND_SRCCOLOR ",
"prj_Alpha01: 4. D3DBLEND_INVSRCCOLOR ",
"prj_Alpha01: 5. D3DBLEND_SRCALPHA ",
"prj_Alpha01: 6. D3DBLEND_INVSRCALPHA ",
"prj_Alpha01: 7. D3DBLEND_DESTALPHA ",
"prj_Alpha01: 8. D3DBLEND_INVDESTALPHA ",
"prj_Alpha01: 9. D3DBLEND_DESTCOLOR ",
"prj_Alpha01: 10. D3DBLEND_INVDESTCOLOR ",
"prj_Alpha01: 11. D3DBLEND_SRCALPHASAT ",
"prj_Alpha01: 12. D3DBLEND_BOTHSRCALPHA ",
"prj_Alpha01: 13. D3DBLEND_BOTHINVSRCALPHA",
"prj_Alpha01: 14. D3DBLEND_BLENDFACTOR ",
"prj_Alpha01: 15. D3DBLEND_INVBLENDFACTOR ",
};
// Produz a cada quadro segundos um valor de 0 a 14.
temporizador = ( clock() / 4000 ) % 15;
// Soma mais um para evitar o zero e produzir o 15
temporizador = temporizador + 1;
// Configura o texto da janela
config_janelaTexto (mensagem[temporizador]);
// Fator de mistura para os modos 14 e 15 (cor vermelha)
if (temporizador > 13)
g_device->SetRenderState(D3DRS_BLENDFACTOR, 0xFFFF0000);
// Desliga o uso de alpha blending para o quad
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
// Configuração de material do quad
cvBranco.a = 0.9f;
g_props.cor = cvBranco;
// Posição e rotação do teapot
g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
desenhar_Quad(&g_props);
// ********* O próximo passo consiste em desenhar o teapot *********
// Limpa a textura do dispositivo
g_device->SetTexture (0, 0);
// Cria o teapot se ele não existir
if(g_objeto3d == NULL) D3DXCreateTeapot (g_device, &g_objeto3d, NULL);
// Faz a configuração de alpha blending fonte e destino
// D3DBLEND_SRCALPHA na fonte é um boa opção para transparência
g_device->SetRenderState(D3DRS_SRCBLEND, temporizador);
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
// Habilita o uso de alpha blending para o teapot
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
// Configura a cor do material para amarelo
cvAmarelo.a = 0.2f;
g_props.cor = cvAmarelo;
// Posição e rotação do teapot
g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, 1.0f);
g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
// Desenha o teapot
desenharObjeto( g_objeto3d, &g_props);
} // 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 objeto 3d
if( g_objeto3d != NULL) g_objeto3d->Release();
// 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();
// Limpa os ponteiros
g_Direct3d = NULL;
g_device = NULL;
g_Textura = NULL;
g_objeto3d = 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 | D3DCLEAR_ZBUFFER, dwBranco, 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 );
// ***************************************************************************
// 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
void config_janelaTexto( char *texto)
{
// Pega o texto atual da janela
char temp_txt[80];
GetWindowText(hJanela, temp_txt, 80);
// Configura apenas se o texto de entrada for diferente
// do texto que está na janela
// Isto é para evitar um efeito visual desagradável na barra
// de título da janela.
if (strcmp (temp_txt, texto))
SetWindowText (hJanela, texto);
} // config_janelaTexto().fim
void desenharObjeto ( ID3DXMesh *obj3d, Propriedades3d *props)
{
// Matrizes para controlar posição e rotação do objeto 3d
D3DXMATRIX obj_rot;
D3DXMATRIX obj_pos;
// Matriz para combinar todas as transformações do objeto 3d
D3DXMATRIX mtxCombinada;
// Vamos inicializar as matrizes para um valor neutro
D3DXMatrixIdentity( &obj_rot );
D3DXMatrixIdentity( &obj_pos );
D3DXMatrixIdentity( &mtxCombinada );
// Atualiza ângulo de rotação
g_angulo += velocidade;
if (g_angulo > 6.28f) velocidade = -velocidade;
if (g_angulo < -6.28f) velocidade = -velocidade;
// 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 mundo
D3DXMatrixMultiply (&mtxCombinada, &obj_rot, &obj_pos);
// Configura matriz mundo para o dispositivo renderizador
g_device->SetTransform( D3DTS_WORLD, &mtxCombinada );
// Prepara e aplica uma material no objeto 3d
criarMaterial( &g_material, props->cor);
g_device->SetMaterial (&g_material);
// Renderiza o mesh
obj3d->DrawSubset(0);
} // desenharObjeto().fim
void criarMaterial(D3DMATERIAL9 *mtl, D3DCOLORVALUE cvCor )
{
// Limpa a estrutura
ZeroMemory( mtl, sizeof(D3DMATERIAL9) );
// Configura cor ambiente e difusa
mtl->Ambient = cvCor;
mtl->Diffuse = cvCor;
} // criarMaterial().fim
void desenhar_Quad( Propriedades3d *props )
{
// Matrizes para controlar posição e rotação do objeto 3d
D3DXMATRIX obj_rot;
D3DXMATRIX obj_pos;
// Matriz para combinar todas as transformações do objeto 3d
D3DXMATRIX mtxCombinada;
// Vamos inicializar as matrizes para um valor neutro
D3DXMatrixIdentity( &obj_rot );
D3DXMatrixIdentity( &obj_pos );
D3DXMatrixIdentity( &mtxCombinada );
// Configura rotação do objeto 3d
D3DXMatrixRotationYawPitchRoll(&obj_rot,
props->rot.y,
props->rot.x,
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 mundo
D3DXMatrixMultiply (&mtxCombinada, &obj_rot, &obj_pos);
// Configura matriz mundo para o dispositivo renderizador
g_device->SetTransform( D3DTS_WORLD, &mtxCombinada );
// Prepara e aplica uma material no objeto 3d
criarMaterial( &g_material, cvBranco);
g_device->SetMaterial (&g_material);
g_device->SetTexture (0, g_Textura);
// 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);
// Configura modo de textura
g_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
g_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
// Renderiza o quad
g_device->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST,
nVerticeInicial, nVerticeQtd, nContagemPrim, &g_Indices,
D3DFMT_INDEX16, &g_Verts, nPasso);
} // desenhar_Quad()
//-----------------------------------------------------------------------------
// Projeto: prj_Alpha01 - arquivo: entrada.cpp
// Esta aplicação mostra os efeitos de mistura de cor (blending)
// 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;
// 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_Alpha01";
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