Curso completo de DirectX 9 com C\C++
Gameprog - Escola de programação de jogos digitais
Contato: gameprog.br@gmail.com
Fase 01-7
01.7 Estados do dispositivo renderizador
1.1 Visão geral
1.2 Estrutura principal da aplicação
Arquivo: motor.cpp
initGfx()
Inicializa objeto Direct3d
Inicializa dispositivo renderizador
chama montar_Geometria() para configurar os vértices
montar_Geometria()
Configura posição dos vértices para formar um quadrado
tratarTeclado()
Trata as teclas 'S' e 'W' para modificar estado interno do
dispositivo renderizador que controla o modo de preenchimento
renderizar_Geometria()
Declara o formato de vértice utilizado ao directx
Configura estado interno de modo de preenchimento
Renderiza os vértices com g_device->DrawPrimitiveUP()
Configura modo de preenchimento para pontos
Renderiza os vértices com g_device->DrawPrimitiveUP()
Renderizar()
Limpa a tela
Desenha a cena
chama renderizar_Geometria() para desenhar o quadrado
Apresenta a cena
Limpar()
Libera dispositivo renderizador
Libera objeto Direct3d
2.1.1 Aspectos globais - Arquivo: motor.h
// Projeto: prj_Estados - Arquivo: motor.h
// Esta aplicação ilustra como renderizar um quadrado
// em modo de preenchimento sólido ou wireframe
#ifndef motor_h
#define motor_h
// Esta função inicializa o Direct3D
HRESULT initGfx (HWND hJanela);
// Essa função libera os objetos utilizados
void Limpar();
// Essa função desenha a cena
void Renderizar();
// Verifica pressionamento de teclas S ou W
void tratarTeclado (WPARAM wParam);
// Essa função monta formas geométricas
void montar_Geometria (void);
// Renderiza os vértices em formas geométricas
void renderizar_Geometria (void);
// Declaração da função que atende as mensagens da janela
LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem,
WPARAM wParam, LPARAM lParam);
#endif
// Essa função monta formas geométricas
void montar_Geometria (void);
Essa função vai configurar o posicionamento dos vértices para formar
um quadrado.
// Verifica pressionamento de teclas S ou W
void tratarTeclado (WPARAM wParam);
Essa função vai tratar o pressionamento das teclas 'S' e 'W' que
configuram o modo de preenchimento da renderização respectivamente
para sólido ou wireframe (aramado).
// Renderiza os vértices em formas geométricas
void renderizar_Geometria (void);
Essa função desenha o quadrado na tela e vai mostrar também como
modificar os estados internos do dispositivo renderizador.
2.1.2 Aspectos globais - Arquivo: motor.cpp
// -----------------------------------------------------------------------------
// Projeto: prj_Estados - arquivo: motor.cpp
// Esta aplicação ilustra como renderizar um quadrado
// em modo de preenchimento sólido ou wireframe
// Produzido por www.gameprog.com.br
// -----------------------------------------------------------------------------
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <stdio.h>
#include "motor.h"
// Inclui as bibliotecas do Direct3D
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
// Variáveis globais
// Representa o dispositivo Direct3D
LPDIRECT3D9 g_Direct3d = NULL;
// Representa o dispositivo Renderizador
IDirect3DDevice9* g_device = NULL;
// Essa variável recebe informação de erro do Directx
HRESULT g_hr = 0;
extern int g_xtela;
extern int g_ytela;
// Controla o modo de preenchimento da forma geométrica
DWORD g_nFillMode = 0;
// Constante para cores
const DWORD vermelho = 0xFFFF0000;
const DWORD branco = 0xFFFFFFFF;
const DWORD verde = 0xFF00FF00;
const DWORD azul = 0xFF0000FF;
const DWORD cinza = 0xFF808080;
// Definição do formato de vértice utilizado por estado aplicação
#define CustomVertex_TransformedColored_Format(D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
// Estrutura do vértice customizado
struct CustomVertex_TransformedColored
{
float x, y, z;
float rhw;
DWORD cor;
// Construtor default
CustomVertex_TransformedColored() {}
CustomVertex_TransformedColored( float _x, float _y, float _z, float _rhw, DWORD _cor)
{
x = _x;
y = _y;
z = _z;
rhw = _rhw;
cor = _cor;
}
}; // fim da estrutura CustomVertex_TransformedColored
// Declara 6 vértices para produzir o quadrado
CustomVertex_TransformedColored g_Vertices[6 ];
// Controla o modo de preenchimento da forma geométrica
DWORD g_nFillMode = 0;
Essa variável vai ser modificada na função tratarTeclado() e vai
guardar o modo de preenchimento selecionado pelo usuário.
// Definição do formato de vértice utilizado por estado aplicação
#define CustomVertex_TransformedColored_Format ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE )
Como foi esclarecido no tópico anterior, aqui definimos a configuração
do formato de vértice que deve ser declarado ao dispositivo gráfico.
O que não foi dito é que esse longo nome é arbitrário e foi escolhido
com base nas práticas da versão gerenciada do directx que utiliza
nomes com esse aspecto para qualificar as estruturas de vértices e de
formato de vértice. Procedemos dessa forma para facilitar a conversão
entre programas escritos em C# para C++ e vice-versa. Assim, esse
longo nome poderia ser abreviado para, como exemplo, VerticeConfig
sem prejuízos para a aplicação.
// Declara 6 vértices para produzir o quadrado
CustomVertex_TransformedColored g_Vertices[6];
Aqui definimos seis vértices que irão compor os dois triângulos
necessários para a formação do quadrado. No próximo tópico vamos
aprender sobre buffer de índices (IndexBuffer) que permite montar
formas geométricas com menos vértices. Sobre a variável g_Vertices
podemos afirmar que ela é um buffer de vértices e mais adiante neste
curso vamos verificar que o directx apresenta uma interface própria
(VertexBuffer) para lidar com buffer de vértices de forma mais
rápida e eficiente. O comentário acima sobre a definição do formato
de vértice serve igualmente para os critérios de denominação dessa
estrutura customizada de vértices.
2.2 Inicialização do motor gráfico
Segue abaixo a listagem de initGfx() sem mudanças em relação ao tópico
anterior ( 01.09 ).
// initGfx() - Inicializa o Direct3D
HRESULT initGfx( HWND hJanela )
{
// Cria o objeto D3D que é necessário para criar o dispositivo gráfico
g_Direct3d = Direct3DCreate9( D3D_SDK_VERSION);
// Verifica se objeto Direct3D foi criado
if(g_Direct3d == NULL)
{
MessageBox (NULL,
"Falha na inialização do Direct3D", "InitGfx()", MB_OK);
return E_FAIL;
} // endif
// Declara a variável para os parâmetros de apresentação
D3DPRESENT_PARAMETERS pps;
// Limpa a estrutura
ZeroMemory( &pps, sizeof(pps) );
// Configura os parâmetros de apresentação
// A aplicação vai ter janela
pps.Windowed = TRUE;
// Esse método vira rapidamente o backbuffer para a tela imediata
pps.SwapEffect = D3DSWAPEFFECT_DISCARD;
// Esse formato vai procurar se encaixar no modo de video corrente
pps.BackBufferFormat = D3DFMT_UNKNOWN;
// Configuração do renderizador a ser criado
// Adaptador default (0)
int nAdaptador = D3DADAPTER_DEFAULT;
// Tipo de dispositivo Hardware ou emulador de referência (software)
D3DDEVTYPE dispositivo_tipo = D3DDEVTYPE_HAL;
// Flags de configuração do dispositivo
DWORD create_flags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
// Criamos aqui o dispositivo renderizador
g_hr = g_Direct3d->CreateDevice( nAdaptador, dispositivo_tipo,
hJanela, create_flags, &pps, &g_device );
// Verifica se houve falha no processo
if( FAILED( g_hr ) ) {
MessageBox (NULL, "Falha na criação: g_device", "initGfx()", MB_OK);
return E_FAIL;
} // endif
montar_Geometria();
return S_OK;
} // initGfx().fim
2.3 Montagem do quadrado
void montar_Geometria(void)
{
// Posicionamento de profundidade
float zpos = 1.0f;
// Primeiro triângulo
g_Vertices[0] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 0.7f, vermelho);
g_Vertices[1] = CustomVertex_TransformedColored( 512.0f, 384.0f, zpos, 0.8f, verde);
g_Vertices[2] = CustomVertex_TransformedColored( 128.0f, 384.0f, zpos, 1.0f, azul);
// Segundo triângulo
g_Vertices[3] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 0.7f, vermelho);
g_Vertices[4] = CustomVertex_TransformedColored( 512.0f, 50.0f, zpos, 1.0f, cinza);
g_Vertices[5] = CustomVertex_TransformedColored( 512.0f, 384.0f, zpos, 0.8f, verde);
} // montar_Geometria().fim
// Primeiro triângulo
g_Vertices[0] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 0.7f, vermelho);
g_Vertices[1] = CustomVertex_TransformedColored( 512.0f, 384.0f, zpos, 0.8f, verde);
// Segundo triângulo
g_Vertices[3] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 0.7f, vermelho);
g_Vertices[4] = CustomVertex_TransformedColored( 512.0f, 50.0f, zpos, 1.0f, cinza);
São necessários dois triângulos para compor um quadrado e cada
triângulo necessita de 3 vértices em sua composição; isto dá um total
de 6 vértices conforme foi declarado nessa função. Mas repare acima
que ocorre o fato de haver vértices com o mesmo posicionamento. No
próximo tópico vamos aprender sobre buffer de índices que permite
utilizar vértices compartilhados para compor triângulos diferentes.
2.4 Estados internos do dispositivo renderizador
void tratarTeclado (WPARAM wParam)
{
// Modo de preenchimento sólido na tecla S
if (wParam == 'S') g_nFillMode = D3DFILL_SOLID;
// Modo de preenchimento wireframe na tecla S
if (wParam == 'W') g_nFillMode = D3DFILL_WIREFRAME;
} // tratarTeclado().fim
// Modo de preenchimento sólido na tecla S
if (wParam == 'S') g_nFillMode = D3DFILL_SOLID;
// Modo de preenchimento wireframe na tecla S
if (wParam == 'W') g_nFillMode = D3DFILL_WIREFRAME;
Essa função permite ao usuário selecionar o estado interno que
controla o modo de preenchimento da renderização. D3DFILL_SOLID indica
o modo sólido e D3DFILL_WIREFRAME indica o modo em wireframe.
Na sequência da aplicação esse estado interno sendo visto aqui é
configurado efetivamente dessa forma:
g_device->SetRenderState(D3DRS_FILLMODE, g_nFillMode);
g_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
g_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
E mais adiante em renderizar_Geometria() vemos uma outra configuração
possível que estabelece que os vértices serão renderizados em forma
de pontos:
g_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT);
Estes exemplos ilustram como configurar os estados internos do
dispositivo renderizador que chegam a atingir centenas de aspectos
configuráveis e centenas de possibilidades. Ao longo do curso, outros
estados aparecerão mas a totalidade deles somente pode ser conhecida
analisando a documentação original do directx.
2.5 Desenhando o quadrado
void renderizar_Geometria()
{
// Declara o formato de vértice utilizado pela aplicação
g_device->SetFVF( CustomVertex_TransformedColored_Format);
// Configura modo de preenchimento da renderização
g_device->SetRenderState(D3DRS_FILLMODE, g_nFillMode);
// Quantidade de primitivas possíveis de acordo com o uso dos vértices
UINT nContagem = 2;
// Tamanho do passo para achar o próximo vértice
UINT nPasso = sizeof(CustomVertex_TransformedColored);
// Desenha forma geométrica
g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, nPasso);
// Configura modo de visualização em ponto
g_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT);
// Configura tamanho do ponto
float nTamanho = 30.0f;
g_device->SetRenderState(D3DRS_POINTSIZE, *(( DWORD*) &nTamanho ));
// Desenha forma geométrica
g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, nPasso);
} // renderizar_Geometria().fim
// Configura modo de preenchimento da renderização
g_device->SetRenderState(D3DRS_FILLMODE, g_nFillMode);
Aqui o modo de preenchimento ( D3DRS_FILLMODE ) da renderização é
efetivamente configurado pela função SetRenderState(). É desta
forma que os estados internos são configurados.
// Quantidade de primitivas possíveis de acordo com o uso dos vértices
UINT nContagem = 2;
Repare que a contagem (2) dos triângulos aumentou porque agora temos
6 vértices.
// Desenha forma geométrica
g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, nPasso);
Renderizamos a forma geométrica dentro do estado interno que foi
previamente configurado.
// Configura modo de visualização em ponto
g_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT);
Alteramos novamente o modo de preenchimento para produzir pontos com
cada vértice.
// Configura tamanho do ponto
float nTamanho = 30.0f;
g_device->SetRenderState(D3DRS_POINTSIZE, *(( DWORD*) &nTamanho ));
Configuramos mais um estado diferente que determina o tamanho que cada
ponto vai ter na renderização final. Veja que nTamanho é um float e
recebeu um cast para que o argumento DWORD aonde ele ocupa seja
transformado em um ponteiro referenciando nTamanho.
// Desenha forma geométrica
g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, nPasso);
Agora renderizamos o mesmo conjunto de vértices com um estado interno
diferente de renderização dos vértices. Merece destaque o fato de que
o mesmo conjunto de vértices pode ser renderizado inúmeras vezes em
estados internos diferentes e posições diferentes do mundo virtual.
3. Código fonte do projeto de exemplo: prj_Estados
// Projeto: prj_Estados - Arquivo: motor.h
// Esta aplicação ilustra como renderizar um quadrado
// em modo de preenchimento sólido ou wireframe
#ifndef motor_h
#define motor_h
// Esta função inicializa o Direct3D
HRESULT initGfx (
HWND hJanela);
// Essa função libera os objetos utilizados
void Limpar();
// Essa função desenha a cena
void Renderizar();
// Verifica pressionamento de teclas S ou W
void tratarTeclado (
WPARAM wParam);
// Essa função monta formas geométricas
void montar_Geometria (
void);
// Renderiza os vértices em formas geométricas
void renderizar_Geometria (
void);
// Declaração da função que atende as mensagens da janela
LRESULT CALLBACK processaJanela (
HWND hJanela,
UINT mensagem,
WPARAM wParam,
LPARAM lParam);
#endif
// -----------------------------------------------------------------------------
// Projeto: prj_Estados - arquivo: motor.cpp
// Esta aplicação ilustra como renderizar um quadrado
// em modo de preenchimento sólido ou wireframe
// Produzido por www.gameprog.com.br
// -----------------------------------------------------------------------------
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <stdio.h>
#include "motor.h"
// Inclui as bibliotecas do Direct3D
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
// Variáveis globais
// Representa o dispositivo Direct3D
LPDIRECT3D9 g_Direct3d = NULL;
// Representa o dispositivo Renderizador
IDirect3DDevice9* g_device = NULL;
// Essa variável recebe informação de erro do Directx
HRESULT g_hr = 0;
extern int g_xtela;
extern int g_ytela;
// Controla o modo de preenchimento da forma geométrica
DWORD g_nFillMode = 0;
// Constante para cores
const DWORD vermelho = 0xFFFF0000;
const DWORD branco = 0xFFFFFFFF;
const DWORD verde = 0xFF00FF00;
const DWORD azul = 0xFF0000FF;
const DWORD cinza = 0xFF808080;
// Definição do formato de vértice utilizado por estado aplicação
#define CustomVertex_TransformedColored_Format(D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
// Estrutura do vértice customizado
struct CustomVertex_TransformedColored
{
float x, y, z;
float rhw;
DWORD cor;
// Construtor default
CustomVertex_TransformedColored() {}
CustomVertex_TransformedColored( float _x, float _y, float _z, float _rhw, DWORD _cor)
{
x = _x;
y = _y;
z = _z;
rhw = _rhw;
cor = _cor;
}
}; // fim da estrutura CustomVertex_TransformedColored
// Declara 6 vértices para produzir o quadrado
CustomVertex_TransformedColored g_Vertices[6 ];
// initGfx() - Inicializa o Direct3D
HRESULT initGfx( HWND hJanela )
{
// Cria o objeto D3D que é necessário para criar o dispositivo gráfico
g_Direct3d = Direct3DCreate9( D3D_SDK_VERSION);
// Verifica se objeto Direct3D foi criado
if(g_Direct3d == NULL)
{
MessageBox (NULL,
"Falha na inialização do Direct3D", "InitGfx()", MB_OK);
return E_FAIL;
} // endif
// Declara a variável para os parâmetros de apresentação
D3DPRESENT_PARAMETERS pps;
// Limpa a estrutura
ZeroMemory( &pps, sizeof(pps) );
// Configura os parâmetros de apresentação
// A aplicação vai ter janela
pps.Windowed = TRUE;
// Esse método vira rapidamente o backbuffer para a tela imediata
pps.SwapEffect = D3DSWAPEFFECT_DISCARD;
// Esse formato vai procurar se encaixar no modo de video corrente
pps.BackBufferFormat = D3DFMT_UNKNOWN;
// Configuração do renderizador a ser criado
// Adaptador default (0)
int nAdaptador = D3DADAPTER_DEFAULT;
// Tipo de dispositivo Hardware ou emulador de referência (software)
D3DDEVTYPE dispositivo_tipo = D3DDEVTYPE_HAL;
// Flags de configuração do dispositivo
DWORD create_flags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
// Criamos aqui o dispositivo renderizador
g_hr = g_Direct3d->CreateDevice( nAdaptador, dispositivo_tipo,
hJanela, create_flags, &pps, &g_device );
// Verifica se houve falha no processo
if( FAILED( g_hr ) ) {
MessageBox (NULL, "Falha na criação: g_device", "initGfx()", MB_OK);
return E_FAIL;
} // endif
montar_Geometria();
return S_OK;
} // initGfx().fim
void montar_Geometria(void)
{
// Posicionamento de profundidade
float zpos = 1.0f;
// Primeiro triângulo
g_Vertices[0] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 0.7f, vermelho);
g_Vertices[1] = CustomVertex_TransformedColored( 512.0f, 384.0f, zpos, 0.8f, verde);
g_Vertices[2] = CustomVertex_TransformedColored( 128.0f, 384.0f, zpos, 1.0f, azul);
// Segundo triângulo
g_Vertices[3] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 0.7f, vermelho);
g_Vertices[4] = CustomVertex_TransformedColored( 512.0f, 50.0f, zpos, 1.0f, cinza);
g_Vertices[5] = CustomVertex_TransformedColored( 512.0f, 384.0f, zpos, 0.8f, verde);
} // montar_Geometria().fim
void tratarTeclado (WPARAM wParam)
{
// Modo de preenchimento sólido na tecla S
if (wParam == 'S') g_nFillMode = D3DFILL_SOLID;
// Modo de preenchimento wireframe na tecla S
if (wParam == 'W') g_nFillMode = D3DFILL_WIREFRAME;
} // tratarTeclado().fim
void renderizar_Geometria()
{
// Declara o formato de vértice utilizado pela aplicação
g_device->SetFVF( CustomVertex_TransformedColored_Format);
// Configura modo de preenchimento da renderização
g_device->SetRenderState(D3DRS_FILLMODE, g_nFillMode);
// Quantidade de primitivas possíveis de acordo com o uso dos vértices
UINT nContagem = 2;
// Tamanho do passo para achar o próximo vértice
UINT nPasso = sizeof(CustomVertex_TransformedColored);
// Desenha forma geométrica
g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, nPasso);
// Configura modo de visualização em ponto
g_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT);
// Configura tamanho do ponto
float nTamanho = 30.0f;
g_device->SetRenderState(D3DRS_POINTSIZE, *(( DWORD*) &nTamanho ));
// Desenha forma geométrica
g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, nPasso);
} // renderizar_Geometria().fim
// Esta função é chamada por DispatchMessage()
LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem,
WPARAM wParam, LPARAM lParam)
{
switch (mensagem)
{
case WM_DESTROY:
// Coloca uma mensagem WM_QUIT na fila de mensagem
Limpar();
PostQuitMessage (0);
break;
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
{
Limpar();
PostQuitMessage( 0);
} // endif
tratarTeclado (wParam);
break;
// Essa mensagem vai ocorrer a todo momento
case WM_PAINT:
// Renderiza a cena
Renderizar();
// Invalida a tela para chamar WM_PAINT novamente
InvalidateRect( hJanela, NULL, false);
break;
// Processamento default de mensagens não tratada pela aplicação
default:
return DefWindowProc (hJanela, mensagem, wParam, lParam);
} // endswitch
return 0;
} // processaJanela().fim
// Limpar() - Libera todos os objetos previamente inicializados
// -----------------------------------------------------------------------------
VOID Limpar()
{
// Libera o dispositivo gráfico
if( g_device != NULL) g_device->Release();
// Libera o motor do Direct3D
if( g_Direct3d != NULL) g_Direct3d->Release();
} // Limpar().fim
// -----------------------------------------------------------------------------
// Renderizar() - Desenha a cena
// -----------------------------------------------------------------------------
VOID Renderizar()
{
// Retorne se o dispositivo estiver nulo
if( g_device == NULL) return;
// Limpa o backbuffer com uma cor branca
g_device->Clear( 0, NULL, D3DCLEAR_TARGET, branco, 1.0f, 0);
// Começa a cena
if( SUCCEEDED( g_device->BeginScene() ) )
{
// Vamos renderizar a geometria
renderizar_Geometria();
// Finalizando a cena
g_device->EndScene();
} // endif
// Apresenta o conteúdo do backbuffer na tela
g_device->Present( NULL, NULL, NULL, NULL);
} // Renderizar().fim
//-----------------------------------------------------------------------------
// Projeto: prj_Estados - arquivo: entrada.cpp
// Esta aplicação ilustra como renderizar um quadrado
// em modo de preenchimento sólido ou wireframe
// Produzido por www.gameprog.com.br
//-----------------------------------------------------------------------------
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include "motor.h"
// Variável global da classe da janela
char sclasseJanela[ ] = "cls_directx";
// Dimensões da janela
int g_xtela = 640;
int g_ytela = 480;
int WINAPI WinMain (HINSTANCE app_instancia, HINSTANCE app_anterior,
LPSTR sComando,int nExibir) {
// alça da janela
HWND hJanela;
// Estrutura de recepção das mensagens
MSG mensagem;
// Estrutura de descrição da janela
WNDCLASSEX wcls;
// Estrutura que descreve a janela
wcls.hInstance = app_instancia;
wcls.lpszClassName = sclasseJanela;
wcls.lpfnWndProc = processaJanela;
wcls.style = CS_HREDRAW | CS_VREDRAW;
wcls.cbSize = sizeof (WNDCLASSEX);
// O cursor e os ícones da aplicação são default
wcls.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wcls.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wcls.hCursor = LoadCursor (NULL, IDC_ARROW);
// Aplicação sem menu
wcls.lpszMenuName = NULL;
// Nada de espaço extra atrelado a classe da janela (wcls)
wcls.cbClsExtra = 0;
// Nada de espaço extra atrelado a janela
wcls.cbWndExtra = 0;
// Cor default da janela
wcls.hbrBackground = ( HBRUSH) COLOR_BACKGROUND;
// Registra a janela e retorna se esta operação falhar
int status = RegisterClassEx (&wcls);
if(status == 0) {
MessageBox(NULL, "Registro falhou!", "WinMain()", MB_OK);
return 0;
} // endif
// Com a classe criada pode-se criar a janela
DWORD estiloExtra = 0;
const char janelaTitulo[] = "prj_Estados - Teclado: (S)ólido ou (W)ireframe";
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