Curso completo de DirectX 9 com C\C++
Gameprog - Escola de programação de jogos digitais
Contato: gameprog.br@gmail.com
Fase 03-5
03.5 Mistura de cor - Parte 2/2 (Objeto texturizado)
1.1 Visão geral
Repare que na ilustração que abre esse tópico há um efeito conjunto
de luz e sombras sobre a textura quadriculada. Isso foi obtido com a
renderização do quad duas vezes, primeiro com a textura quadriculada,
e depois com uma textura simples com um hexágono laranja desenhado e
aplicando uma configuração simples de mistura de cor.
textura do segundo quad renderizado: gp-alpha.png
Nesta textura a cor preta está definida como cor transparente.
Para a obtenção dos resultados adequados com mistura de cor com
aproveitamento do canal alpha é importante na criação do dispositivo
renderizador selecionar um formato com canal alpha para o backbuffer.
A aplicação desse tópico utiliza esse formato:
pps.BackBufferFormat = D3DFMT_A8R8G8B8;
Outras configurações importantes foram feitas na função
inicializar_Textura().
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 o quadrado texturizado.
chama inicializar_Camera() para a configuração inicial da câmera.
Configura iluminação
montar_Geometria()
Faz a montagem do quadrilátero texturizado.
desenhar_Cortina()
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 formato de vértice.
renderiza o quad com DrawIndexedPrimitiveUP()
desenharQuad()
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, textura e formato de vértice.
renderiza o quad com DrawIndexedPrimitiveUP()
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_Cortina() para renderizar o quad (quadrilátero)
liga blending
chama desenhar_Quad() para renderizar o quad na configuração
de blending selecionada
2.1.1 Aspectos globais - Arquivo: motor.h
A entrada de coordenadas de textura na estrutura de vértice
customizado sofreu um pequeno ajuste ficando restrita ao tipo float.
//-----------------------------------------------------------------------------
// Projeto: prj_Alpha02 - Arquivo: motor.h
// Esta aplicação mostra os efeitos de alpha blending
// com um objeto texturizado
// Produzido por www.gameprog.com.br
//-----------------------------------------------------------------------------
#ifndef motor_h
#define motor_h
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
// Definição do formato de vértice utilizado por esta aplicação
#define CustomVertex_PositionTextured_Format(D3DFVF_XYZ | D3DFVF_TEX1)
// Estrutura do 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,
float _tu, float _tv)
{
// Configura posição
x = _x;
y = _y;
z = _z;
// Configura textura
tu = _tu;
tv = _tv;
}
}; // fim da estrutura CustomVertex_PositionTextured
// Estrutura para guardar cor, posição e rotação do objeto 3d
struct Propriedades3d
{
D3DXVECTOR3 pos;
D3DXVECTOR3 rot;
D3DCOLORVALUE cor;
};
// 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);
// Cria um material com a cor especificada
void criarMaterial(D3DMATERIAL9 *mtl, D3DCOLORVALUE cvCor );
// Desenha o quadriângulo de fundo
void desenhar_Cortina(Propriedades3d *props );
// Desenha o quad de frente
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
void desenhar_Cortina(Propriedades3d *props );
void desenhar_Quad(Propriedades3d *props);
Estas funções têm o mesmo corpo de código e as duas desenham o quad
cada qual com sua textura diferente. A função desenhar_Cortina()
produz o quad com a textura quadriculada enquando a outra função
produz o outro quad com os efeitos de blending aplicados.
2.1.2 Aspectos globais: Arquivo: motor.cpp
IDirect3DTexture9 *texCortina = NULL;
IDirect3DTexture9 *texQuad = NULL;
// Matrizes para controlar posição e rotação do objeto 3d
D3DXMATRIX obj_rot;
D3DXMATRIX obj_pos;
D3DXMATRIX obj_esc;
// Matriz para combinar todas as transformações do objeto 3d
D3DXMATRIX mtxCombinada;
D3DXMATRIX obj_rot;
D3DXMATRIX obj_pos;
D3DXMATRIX obj_esc;
D3DXMATRIX mtxCombinada;
Estas matrizes são usadas para controlar posição, rotação e escala
dos objetos. Foram puxadas para o espaço global porque são usadas nas
duas funções que desenham o quad.
2.2 Inicialização dos estados de texturização
void inicializar_Textura(void)
{
g_hr = D3DXCreateTextureFromFile (g_device,
"\\gameprog\\gdkmedia\\bitmap\\textura2x2.bmp",
&texCortina);
g_hr = D3DXCreateTextureFromFile( g_device,
"\\gameprog\\gdkmedia\\bitmap\\gp-alpha.png",
&texQuad);
if (FAILED (g_hr))
{
MessageBox(NULL, "Falha: D3DXCreateTextureFromFile()",
"inicializar_Textura()", MB_OK);
} // endif
// Habilita o uso do canal alpha da cor difusa do material\textura
g_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
g_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
// Corrige visualização blocada da textura - quando textura for
// menor do que a superfície
g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// Corrige visualização blocada da textura - quando textura for
// maior do que a superfície
g_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
// Configura modo de endereçamento
g_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
g_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
} // inicializar_Textura(void).fim
// Habilita o uso do canal alpha da cor difusa do material\textura
g_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
g_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
Estas duas linhas fazem o trabalho de habilitar o uso do canal alpha
da cor difusa da textura e/ou material para os efeitos de mistura
de cor com conexão com a textura do estágio zero (0).
A parte TSS da sigla D3DTSS_ALPHAARG1 e outras semelhantes é
abreviação para texture stage state traduzido pela Gameprog como
'estado de estágio de textura.' Nestas configurações de estágio,
o final OP parte das siglas D3DTSS_ALPHAOP e D3DTOP_SELECTARG1 quer
dizer 'operação'. A parte TA de D3DTA_DIFFUSE quer dizer texture
argument ou argumento de textura.
D3DTSS_ALPHAARG1 e D3DTSS_ALPHAOP fazem parte da enumeração
D3DTEXTURESTAGESTATETYPE que define vários tipos de estados para
estágios de textura.
D3DTA_DIFFUSE faz parte de uma lista solta de opções para argumentos
em outros processos presente no arquivo d3d9types.h.
D3DTOP_SELECTARG1 faz parte da enumeração D3DTEXTUREOP que define
várias operações que definem como é processado a mistura de cor.
2.3 Inicialização do motor gráfico
Reforçando o que já foi citado na visão geral, é importante notar
aqui nesta função que foi selecionado um formato de backbuffer com
suporte ao canal alpha.
// 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;
// Formato com alpha para o backbuffer
pps.BackBufferFormat = D3DFMT_A8R8G8B8;
pps.BackBufferCount = 1;
// 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ção de iluminação
g_device->SetRenderState (D3DRS_LIGHTING, true);
g_device->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB( 200,200,200 ) );
return S_OK;
} // initGfx().fim
2.4 Renderização da geometria
void renderizar_Geometria()
{
// Mensagens para a barra de títulos da janela
char *mensagem[] =
{
"prj_Alpha02: By Gameprog",
"prj_Alpha02: 1. D3DBLEND_ZERO",
"prj_Alpha02: 2. D3DBLEND_ONE",
"prj_Alpha02: 3. D3DBLEND_SRCCOLOR",
"prj_Alpha02: 4. D3DBLEND_INVSRCCOLOR",
"prj_Alpha02: 5. D3DBLEND_SRCALPHA",
"prj_Alpha02: 6. D3DBLEND_INVSRCALPHA",
"prj_Alpha02: 7. D3DBLEND_DESTALPHA",
"prj_Alpha02: 8. D3DBLEND_INVDESTALPHA",
"prj_Alpha02: 9. D3DBLEND_DESTCOLOR",
"prj_Alpha02: 10. D3DBLEND_INVDESTCOLOR",
"prj_Alpha02: 11. D3DBLEND_SRCALPHASAT",
"prj_Alpha02: 12. D3DBLEND_BOTHSRCALPHA",
"prj_Alpha02: 13. D3DBLEND_BOTHINVSRCALPHA",
"prj_Alpha02: 14. D3DBLEND_BLENDFACTOR",
"prj_Alpha02: 15. D3DBLEND_INVBLENDFACTOR",
};
// Produz a cada quadro segundos um valor de 2 a 15.
temporizador = ( clock() / 4000 ) % 14;
temporizador = temporizador + 2;
// Configura o texto da janela
config_janelaTexto (mensagem[temporizador]);
// Fator de mistura para os modos 14 e 15
if (temporizador > 13)
g_device->SetRenderState(D3DRS_BLENDFACTOR, 0xFFFF0000);
// Desenha a cortina de fundo
cvBranco.a = 0.9f;
g_props.cor = cvBranco;
g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
desenhar_Cortina(&g_props);
// ********* Próximo passo: desenhar o quad na frente da cortina *********
// Posição e rotação do quad
cvBranco.a = 0.2f;
g_props.cor = cvBranco;
g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, 1.0f);
g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
// Configura as opções de blending
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
g_device->SetRenderState(D3DRS_SRCBLEND, temporizador);
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
// Desenha o quad
desenhar_Quad(&g_props);
} // renderizar_Geometria().fim
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
g_device->SetRenderState(D3DRS_SRCBLEND, temporizador);
A primeira linha habilita o uso de alpha blending e a segunda
configura o fator de mistura para o pixel fonte ou entrante.
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
Esta linha configura o fator de mistura para o pixel corrente que já
está no backbuffer assinalando que este pixel deve prevalescer na
mistura ( D3DBLEND_ONE ).
Na sequência o quad é renderizado com a textura do hexágono laranja
com as configurações acima.
2.5 Renderização do quad
void desenhar_Quad(Propriedades3d *props )
{
// Atualiza o ângulo
g_angulo += 0.01f;
// Vamos inicializar as matrizes para um valor neutro
D3DXMatrixIdentity( &obj_rot );
D3DXMatrixIdentity( &obj_pos );
D3DXMatrixIdentity( &obj_esc );
D3DXMatrixIdentity( &mtxCombinada );
// Configura rotação do objeto 3d
D3DXMatrixRotationYawPitchRoll(&obj_rot,
props->rot.y,
props->rot.x,
props->rot.z + g_angulo);
// 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
D3DXMatrixScaling (&obj_esc, 1.0f, 1.0f, 1.0f);
// Produz a matriz combina com as matrizes parciais
mtxCombinada = obj_rot * obj_pos;
// Configura matriz mundo para o dispositivo renderizador
g_device->SetTransform( D3DTS_WORLD, &mtxCombinada );
// Prepara e aplica uma material na caixa
criarMaterial( &g_material, props->cor);
g_device->SetMaterial (&g_material);
g_device->SetTexture(0, texQuad);
// Argumentos da função DrawIndexedPrimitiveUP()
UINT nPasso = sizeof(CustomVertex_PositionTextured);
// Renderiza o quad
g_device->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST,
0, 4, 2, &g_Indices, D3DFMT_INDEX16, &g_Verts, nPasso);
} // desenhar_Quad().fim
3. Código fonte do projeto de exemplo: prj_Alpha02

//-----------------------------------------------------------------------------
// Projeto: prj_Alpha02 - Arquivo: motor.h
// Esta aplicação mostra os efeitos de alpha blending
// com um objeto texturizado
// Produzido por www.gameprog.com.br
//-----------------------------------------------------------------------------
#ifndef motor_h
#define motor_h
#pragma comment (lib,
"d3d9.lib")
#pragma comment (lib,
"d3dx9.lib")
// Definição do formato de vértice utilizado por esta aplicação
#define CustomVertex_PositionTextured_Format(
D3DFVF_XYZ |
D3DFVF_TEX1)
// Estrutura do 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,
float _tu,
float _tv)
{
// Configura posição
x = _x;
y = _y;
z = _z;
// Configura textura
tu = _tu;
tv = _tv;
}
}; // fim da estrutura CustomVertex_PositionTextured
// Estrutura para guardar cor, posição e rotação do objeto 3d
struct Propriedades3d
{
D3DXVECTOR3 pos;
D3DXVECTOR3 rot;
D3DCOLORVALUE cor;
};
// 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);
// Cria um material com a cor especificada
void criarMaterial(
D3DMATERIAL9 *mtl,
D3DCOLORVALUE cvCor );
// Desenha o quadriângulo de fundo
void desenhar_Cortina(
Propriedades3d *props );
// Desenha o quad de frente
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_Alpha02 - arquivo: motor.cpp
// Esta aplicação mostra os efeitos de alpha blending
// com um objeto texturizado
// Produzido por www.gameprog.com.br
// -----------------------------------------------------------------------------
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <time.h>
#include "motor.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
D3DXMATRIX g_mtxMundo;
D3DXMATRIX g_mtxVisao;
D3DXMATRIX g_mtxProj;
IDirect3DTexture9 *texCortina = NULL;
IDirect3DTexture9 *texQuad = NULL;
// Matrizes para controlar posição e rotação do objeto 3d
D3DXMATRIX obj_rot;
D3DXMATRIX obj_pos;
D3DXMATRIX obj_esc;
// Matriz para combinar todas as transformações do objeto 3d
D3DXMATRIX mtxCombinada;
// Material para o objeto 3d
D3DMATERIAL9 g_material;
// Recipiente de cor, rotação e posição do objeto
Propriedades3d g_props;
// Controla a rotação do quad de frente
float g_angulo = 0.0f;
float velocidade = 0.02f;
// Constante para cores com rgba expressado como float's
D3DCOLORVALUE cvBranco = { 1.0f, 1.0f, 1.0f, 1.0f };
// Constante para cores
const DWORD dwBranco = 0xFFFFFFFF;
// 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;
// Controla a mudança periódica da primitiva
UINT temporizador = 0;
// Memória pas 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.bmp",
&texCortina);
g_hr = D3DXCreateTextureFromFile( g_device,
"\\gameprog\\gdkmedia\\bitmap\\gp-alpha.png",
&texQuad);
if (FAILED (g_hr))
{
MessageBox(NULL, "Falha: D3DXCreateTextureFromFile()",
"inicializar_Textura()", MB_OK);
} // endif
// Habilita o uso do canal alpha da cor difusa do material\textura
g_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
g_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
// Corrige visualização blocada da textura - quando textura for
// menor do que a superfície
g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// Corrige visualização blocada da textura - quando textura for
// maior do que a superfície
g_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
// Configura modo de endereçamento
g_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
g_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
} // 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;
// Formato com alpha para o backbuffer
pps.BackBufferFormat = D3DFMT_A8R8G8B8;
pps.BackBufferCount = 1;
// 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ção de iluminação
g_device->SetRenderState (D3DRS_LIGHTING, true);
g_device->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB( 200,200,200 ) );
return S_OK;
} // initGfx().fim
void montar_Geometria(void)
{
// Posicionamento de profundidade
float zpos = 0.9f;
// Configuração normal dos vértices
g_Verts[0] = CustomVertex_PositionTextured( 2.20f, 1.50f, zpos, 0.0f, 0.0f);
g_Verts[1] = CustomVertex_PositionTextured( -2.20f, 1.50f, zpos, 3.0f, 0.0f);
g_Verts[2] = CustomVertex_PositionTextured( -2.20f, -1.50f, zpos, 3.0f, 3.0f);
g_Verts[3] = CustomVertex_PositionTextured( 2.20f, -1.50f, zpos, 0.0f, 3.0f);
} // montar_Geometria().fim
void renderizar_Geometria()
{
// Mensagens para a barra de títulos da janela
char *mensagem[] =
{
"prj_Alpha02: By Gameprog",
"prj_Alpha02: 1. D3DBLEND_ZERO",
"prj_Alpha02: 2. D3DBLEND_ONE",
"prj_Alpha02: 3. D3DBLEND_SRCCOLOR",
"prj_Alpha02: 4. D3DBLEND_INVSRCCOLOR",
"prj_Alpha02: 5. D3DBLEND_SRCALPHA",
"prj_Alpha02: 6. D3DBLEND_INVSRCALPHA",
"prj_Alpha02: 7. D3DBLEND_DESTALPHA",
"prj_Alpha02: 8. D3DBLEND_INVDESTALPHA",
"prj_Alpha02: 9. D3DBLEND_DESTCOLOR",
"prj_Alpha02: 10. D3DBLEND_INVDESTCOLOR",
"prj_Alpha02: 11. D3DBLEND_SRCALPHASAT",
"prj_Alpha02: 12. D3DBLEND_BOTHSRCALPHA",
"prj_Alpha02: 13. D3DBLEND_BOTHINVSRCALPHA",
"prj_Alpha02: 14. D3DBLEND_BLENDFACTOR",
"prj_Alpha02: 15. D3DBLEND_INVBLENDFACTOR",
};
// Produz a cada quadro segundos um valor de 2 a 15.
temporizador = ( clock() / 4000 ) % 14;
temporizador = temporizador + 2;
// Configura o texto da janela
config_janelaTexto (mensagem[temporizador]);
// Fator de mistura para os modos 14 e 15
if (temporizador > 13)
g_device->SetRenderState(D3DRS_BLENDFACTOR, 0xFFFF0000);
// Desenha a cortina de fundo
cvBranco.a = 0.9f;
g_props.cor = cvBranco;
g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
desenhar_Cortina(&g_props);
// ********* Próximo passo: desenhar o quad na frente da cortina *********
// Posição e rotação do quad
cvBranco.a = 0.2f;
g_props.cor = cvBranco;
g_props.pos = D3DXVECTOR3 (0.0f, 0.0f, 1.0f);
g_props.rot = D3DXVECTOR3 (0.0f, 0.0f, 0.0f);
// Configura as opções de blending
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
g_device->SetRenderState(D3DRS_SRCBLEND, temporizador);
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
// Desenha o quad
desenhar_Quad(&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 a textura
if (texCortina != NULL) texCortina->Release();
if (texQuad != NULL) texQuad->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;
texCortina = NULL;
texQuad = NULL;
} // Limpar().fim
// -----------------------------------------------------------------------------
// Renderizar() - Desenha a cena
// -----------------------------------------------------------------------------
VOID Renderizar()
{
// Retorne se o dispositivo estiver nulo
if( g_device == NULL) return;
// Declara o formato de vértice utilizado pela aplicação
g_device->SetFVF( CustomVertex_PositionTextured_Format);
// 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 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_Cortina( Propriedades3d *props )
{
// 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, props->cor);
g_device->SetMaterial (&g_material);
g_device->SetTexture (0, texCortina);
// Argumentos da função DrawIndexedPrimitiveUP()
UINT nPasso = sizeof(CustomVertex_PositionTextured);
// Renderiza o quad
g_device->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST,
0, 4, 2, &g_Indices, D3DFMT_INDEX16, &g_Verts, nPasso);
} // desenhar_Cortina()
void desenhar_Quad(Propriedades3d *props )
{
// Atualiza o ângulo
g_angulo += 0.01f;
// Vamos inicializar as matrizes para um valor neutro
D3DXMatrixIdentity( &obj_rot );
D3DXMatrixIdentity( &obj_pos );
D3DXMatrixIdentity( &obj_esc );
D3DXMatrixIdentity( &mtxCombinada );
// Configura rotação do objeto 3d
D3DXMatrixRotationYawPitchRoll(&obj_rot,
props->rot.y,
props->rot.x,
props->rot.z + g_angulo);
// 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
D3DXMatrixScaling (&obj_esc, 1.0f, 1.0f, 1.0f);
// Produz a matriz combina com as matrizes parciais
mtxCombinada = obj_rot * obj_pos;
// Configura matriz mundo para o dispositivo renderizador
g_device->SetTransform( D3DTS_WORLD, &mtxCombinada );
// Prepara e aplica uma material na caixa
criarMaterial( &g_material, props->cor);
g_device->SetMaterial (&g_material);
g_device->SetTexture(0, texQuad);
// Argumentos da função DrawIndexedPrimitiveUP()
UINT nPasso = sizeof(CustomVertex_PositionTextured);
// Renderiza o quad
g_device->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST,
0, 4, 2, &g_Indices, D3DFMT_INDEX16, &g_Verts, nPasso);
} // desenhar_Quad().fim
//-----------------------------------------------------------------------------
// Projeto: prj_Alpha02 - arquivo: entrada.cpp
// Esta aplicação mostra os efeitos de alpha blending
// com um objeto texturizado
// 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_Alpha02";
DWORD controleEstilo = WS_EX_TOPMOST | 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