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

index << >>


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

index << >>

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