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

index << >>


01.6 Triângulo 2d

1.1 Visão geral
O triângulo é a menor célula de um objeto tridimensional. O triângulo acima é composto por 3 vértices cada um contendo informação de posição na forma (x, y, z). Matematicamente o vértice está completo mas dentro do directx apenas posição é insuficiente para fazer o melhor uso dos vértices e assim dependendo dos efeitos que se quer obter muitas outras informações vão sendo adicionadas aos vértices. Essa necessidade de agregação de informações aos vértices dá origem ao formato de vértice que varia conforme a intenção da aplicação no tocante ao uso de cor, luz, textura, animação e outros aspectos. Na aplicação deste tópico, cada vértice recebe ainda informação de cor e de intensidade de cor. No triângulo acima os vértices tem uma cor básica de vermelho, verde e azul que se esparramam e se misturam pelo triângulo com a mesma intensidade ( 1.0f ). Ainda para ter o triângulo ou qualquer outra forma desenhada, os vértices precisam ser posicionados seguindo uma direção regular do relógio na linha horária ou anti-horária. No triângulo acima foram colocados primeiro o vértice vermelho p0, depois o vértice verde p1 e por último o vértice azul p2; ou seja, os vértices seguiram uma direção horária. Essa disposição organizada dos vértices permite a aplicação de uma técnica pelo directx chamada culling que corta da renderização triângulos que estão de costas para a câmera e isso economiza processamento improdutivo da cpu ou da placa de vídeo. Tranformações Normalmente, um triângulo para ser exibido sofre ainda uma sequência de operações matemáticas ou geométricas chamadas transformações. No triângulo acima cada vértice está posicionado com relação aos outros vértices do próprio triângulo, esse posicionamento é chamado de espaço local. Quando o triângulo ou objeto é posicionado em um mundo virtual ocorre a primeira transformação quando seus vértices são recalculados para posicionar de fato o objeto neste mundo virtual. Nessa primeira transformação, o objeto é transportado do espaço local para o espaço mundial. Mas para ser visto o objeto precisa ser trazido do espaço mundial para o espaço de tela ou espaço de visualização. Geralmente estas transformações são multiplicações matemáticas que são feitas no posicionamento dos vértices até chegar na posição (x,y) final do vértice para compor a imagem na tela. Falamos sobre a transformação de posicionamento chamada de translação mas existem outras e mais outras para aplicação de escala, rotação, correções de visualização e aplicação de efeitos especiais. É importante destacar que as transformações são feitas internamente pelo directx utilizando os dados numéricos dispostos geralmente em matrizes e vetores matemáticos. Formato de vértice Nosso triângulo não vai sofrer nenhuma transformação uma vez que vamos passar a coordenada 2D final do vértice acompanhada da informação de cor. Dizemos então que o formato de vértice do nosso triângulo é transformado e colorido, TransformedColored como se diz em directx. Outros formatos de vértice podem incluir informações sobre texturas ou posicionamento que vai sofrer cálculos futuros de transformações. 1.2 Estrutura principal da aplicação
Arquivo: motor.cpp
initGfx() Inicializa objeto Direct3d Inicializa dispositivo renderizador chama montar_Geometria() para configurar os vértices montar_Geometria() Configura posição dos vértices renderizar_Geometria() Declara o formato de vértice utilizado ao directx Renderiza os vértices com g_device->DrawPrimitiveUP() Renderizar() Limpa a tela Desenha a cena chama renderizar_Geometria() para desenhar o triângulo Apresenta a cena Limpar() Libera dispositivo renderizador Libera objeto Direct3d
2.1 Aspectos globais - Arquivo: motor.h
// Projeto: prj_Triangulo01 - Arquivo: motor.h // Esta aplicação ilustra como renderizar um triângulo #ifndef motor_h #define motor_h // Esta função inicializa o Direct3D HRESULT initGfx (HWND hJanela); // Essa função libera os objetos utilizados void Limpar(); // Essa função desenha a cena void Renderizar(); // Essa função monta formas geométricas void montar_Geometria (void); // Renderiza os vértices em formas geométricas void renderizar_Geometria (void); // Declaração da função que atende as mensagens da janela LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam); #endif
// Essa função monta formas geométricas void montar_Geometria (void); Essa função configura os vértices que vão compor o triângulo que será renderizado. O triângulo está representado por uma array de 3 vértices g_Vertices. Os vértices por sua vez estão formatados numa estrutura chamada CustomVertex_TransformedColored com informação de posição, cor e intensidade de cor de cada vértice utilizado. O prefixo CustomVertex_ do nome dessa estrutura é traduzido como vértice customizado ou personalizado ou ainda também de vértice flexível pois o directx dá a liberdade ao programador de compor o vértice conforme a necessidade particular da aplicação. O restante do nome da estrutura TransformedColored indica que os vértices são coloridos e já estão posicionados em coordenadas de tela e não necessitam de transformações ou ainda do uso de uma câmera em cena. // Renderiza os vértices em formas geométricas void renderizar_Geometria (void); Essa função desenha o triângulo na cena. Lembramos que todo processo de desenhar ocorre entre as funções BeginScene() e EndScene() do dispositivo renderizador. Então essa função e outras como ela que desenham as formas geométricas são chamadas pela função Renderizar() que contém essas funções obrigatórias de início e finalização do processo de renderização. A função renderizar_Geometria() antes de desenhar a cena deve informar ou declarar ao dispositivo renderizador o formato de vértice utilizado. De forma geral, antes de desenhar alguma coisa é configurado vários estados internos do dispositivo renderizador que vão impactar como a cena vai ser desenhada tais como visualização sólida ou em wireframe (aramado) entre centenas de outros estados que podem ser configurados. 2.1.2 Aspectos globais - Arquivo: motor.cpp
// ----------------------------------------------------------------------------- // Projeto: prj_Triangulo01 - arquivo: motor.cpp // Esta aplicação ilustra como renderizar um triângulo // Produzido por www.gameprog.com.br // ----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include <stdio.h> #include "motor.h" // Inclui as bibliotecas do Direct3D #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") // Variáveis globais // Representa o dispositivo Direct3D LPDIRECT3D9 g_Direct3d = NULL; // Representa o dispositivo Renderizador IDirect3DDevice9* g_device = NULL; // Essa variável recebe informação de erro do Directx HRESULT g_hr = 0; extern int g_xtela; extern int g_ytela; // Constante para cores const DWORD vermelho = 0xFFFF0000; const DWORD branco = 0xFFFFFFFF; const DWORD verde = 0xFF00FF00; const DWORD azul = 0xFF0000FF; // Definição do formato de vértice utilizado pela aplicação #define CustomVertex_TransformedColored_Format(D3DFVF_XYZRHW | D3DFVF_DIFFUSE) // Definição da estrutura de vértice customizado struct CustomVertex_TransformedColored { float x, y, z; float rhw; DWORD cor; // Construtor default CustomVertex_TransformedColored() {} // Construtor com inicialização CustomVertex_TransformedColored( float _x, float _y, float _z, float _rhw, DWORD _cor) { x = _x; y = _y; z = _z; rhw = _rhw; cor = _cor; } // fim do construtor }; // fim da estrutura CustomVertex_TransformedColored // Declaração dos vértices para o triângulo CustomVertex_TransformedColored g_Vertices[3 ];
// Constante para cores const DWORD vermelho = 0xFFFF0000; const DWORD branco = 0xFFFFFFFF; const DWORD verde = 0xFF00FF00; const DWORD azul = 0xFF0000FF;
Estas contantes de cores definidas vão facilitar a leitura de informação de cor na configuração dos vértices. // Definição do formato de vértice utilizado pela aplicação #define CustomVertex_TransformedColored_Format( D3DFVF_XYZRHW | D3DFVF_DIFFUSE ) Aqui é definido a composição do formato de vértice que será utilizado no desenho de formas geométricas nesta aplicação. O elemento D3DFVF_XYZRHW indica que o vértice vai ter quatro floats iniciais (x,y,z,rhw) seguido por um elemento do tipo DWORD que indica cor D3DFVF_DIFFUSE. Estes elementos estão declarados dentro do arquivo d3d9types.h junto com outros valores interessantes para formato de vértice. Por fim, CustomVertex_TransformedColored_Format traz a combinação coletiva de D3DFVF_XYZRHW e D3DFVF_DIFFUSE que posteriormente é utilizado na declaração ao dispositivo renderizador do formato de vértice utilizado pela aplicação.
// Definição da estrutura de vértice customizado struct CustomVertex_TransformedColored { float x, y, z; float rhw; DWORD cor; // Construtor default CustomVertex_TransformedColored() {} // Construtor com inicialização CustomVertex_TransformedColored( float _x, float _y, float _z, float _rhw, DWORD _cor) { x = _x; y = _y; z = _z; rhw = _rhw; cor = _cor; } // fim do construtor }; // fim da estrutura CustomVertex_TransformedColored
Com relação aos seus membros (x, y, z) representa a coordenada 2d de tela sendo que z fica ignorado nesta aplicação. O membro cor é auto explicativo. O float rhw é um quarto float que nesta aplicação representa a intensidade da cor do vértice; esse quarto float pode representar outros aspectos em outros contextos. Se configurado como 1.0f (x, y, z) significa uma posição; se configurado como zero (x, y, z) significa um vetor que indica direção. Reafirmando, rhw no contexto dessa aplicação varia de 0.0f a 1.0f e representa a intensidade com a qual a cor do vértice se esparrama pelo triângulo. CustomVertex_TransformedColored() {} Este construtor é para permitir a declaração desta estrutura sem uma inicialização explícita dos valores dos membros pela aplicação. CustomVertex_TransformedColored( float _x, float _y, float _z, float _rhw, DWORD _cor) Este construtor é para permitir a inicialização explícita dos membros da estrutura pela aplicação. Esse construtor permitiu montar_Geometria() apresentar uma linha como esta na configuração dos vértices: g_Vertices[2] = CustomVertex_TransformedColored( 128.0f, 384.0f, zpos, 1.0f, azul); // Declaração dos vértices para o triângulo CustomVertex_TransformedColored g_Vertices[3]; Aqui declaramos inicialmente os 3 vértices que vão ser plenamente configurados em montar_Geometria(). 2.1 Inicializando o motor gráfico Veja no destaque que initGfx() chama a função montar_Geometria() para a trabalho de configuração inicial dos vértices.
// initGfx() - Inicializa o Direct3D HRESULT initGfx( HWND hJanela ) { // Cria o objeto Direct3D que é necessário para criar o dispositivo gráfico g_Direct3d = Direct3DCreate9( D3D_SDK_VERSION); // Verifica se objeto Direct3D foi criado if(g_Direct3d == NULL) { MessageBox (NULL, "Falha na inialização do Direct3D", "InitGfx()", MB_OK); return E_FAIL; } // endif // Declara a variável para os parâmetros de apresentação D3DPRESENT_PARAMETERS pps; // Limpa a estrutura ZeroMemory( &pps, sizeof(pps) ); // Configura os parâmetros de apresentação // A aplicação vai ter janela pps.Windowed = TRUE; // Esse método vira rapidamente o backbuffer para a tela imediata pps.SwapEffect = D3DSWAPEFFECT_DISCARD; // Esse formato vai procurar se encaixar no modo de video corrente pps.BackBufferFormat = D3DFMT_UNKNOWN; // Configuração do renderizador a ser criado // Adaptador default (0) int nAdaptador = D3DADAPTER_DEFAULT; // Tipo de dispositivo Hardware ou emulador de referência (software) D3DDEVTYPE dispositivo_tipo = D3DDEVTYPE_HAL; // Flags de configuração do dispositivo DWORD create_flags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; // Criamos aqui o dispositivo renderizador g_hr = g_Direct3d->CreateDevice( nAdaptador, dispositivo_tipo, hJanela, create_flags, &pps, &g_device ); // Verifica se houve falha no processo if( FAILED( g_hr ) ) { MessageBox (NULL, "Falha na criação: g_device", "initGfx()", MB_OK); return E_FAIL; } // endif // Monta as formas geométricas montar_Geometria(); return S_OK; } // initGfx().fim
2.2 Construção das formas geométricas
void montar_Geometria(void) { // Posicionamento de profundidade float zpos = 1.0f; // p0 - primeiro vértice g_Vertices[0] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 1.0f, vermelho); // p1 - segundo vértice g_Vertices[1] = CustomVertex_TransformedColored( 512.0f, 384.0f, zpos, 1.0f, verde); // p2 - terceiro vértice g_Vertices[2] = CustomVertex_TransformedColored( 128.0f, 384.0f, zpos, 1.0f, azul); } // montar_Geometria().fim
// Posicionamento de profundidade float zpos = 1.0f; Aqui é a configuração de profundidade do triângulo mas este valor não será utilizado efetivamente por esta aplicação. O essencial da coordenada vai ser (x, y) que apontam direto para a tela.
// p0 - primeiro vértice g_Vertices[0] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 1.0f, vermelho); // p1 - segundo vértice g_Vertices[1] = CustomVertex_TransformedColored( 512.0f, 384.0f, zpos, 1.0f, verde); // p2 - terceiro vértice g_Vertices[2] = CustomVertex_TransformedColored( 128.0f, 384.0f, zpos, 1.0f, azul);
Aqui é um aspecto fundamental de uma aplicação 3d: o processo de posicionamento dos vértices que produz com isso as diversas formas geométricas. O valor 1.0f é o rhw que nesse contexto determina a intensidade de cor; faça variações nestes valores para ver os efeitos de colorimento que isso provoca no triângulo. Aqui montamos um triângulo manualmente para mostrar como o directx funciona mas geralmente os objetos 3d são carregados de arquivos como o arquivo x nativo do directx depois de terem sido criados em outras aplicações de modelagem gráfica. 2.3 Renderização das formas geométricas
void renderizar_Geometria() { // Todo código de desenhar ocorre aqui dentro g_device->SetFVF( CustomVertex_TransformedColored_Format); // Quantidade de primitivas possíveis de acordo com o uso de vértices UINT nContagem = 1; // Tamanho do passo para achar o próximo vértice UINT nPasso = sizeof(CustomVertex_TransformedColored); // Desenha forma geométrica g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, nPasso); } // renderizar_Geometria().fim
// Todo código de desenhar ocorre aqui dentro g_device->SetFVF( CustomVertex_TransformedColored_Format); Aqui é informado ao dispositivo renderizador o formato de vértice utilizado pela aplicação. // Quantidade de primitivas possíveis de acordo com o uso de vértices UINT nContagem = 1; Esta variável representa a quantidade de formas primitivas que serão renderizadas com o conjunto de (3) vértices apresentados. Aqui é a indicação de quantos (1) triângulos serão produzidos. O mesmo conjunto de vértices pode dar origem a quantidades diferentes de outros tipos de formas primitivas. Por exemplo, se a forma primitiva fosse pontos finais na tela, a variável nContagem poderia ser configurada para três. // Tamanho do passo para achar o próximo vértice UINT nPasso = sizeof(CustomVertex_TransformedColored); A função que renderiza os vértices precisa saber qual é o espaçamento entre um vértice e outro. Esse espaçamento é obtido pela instrução sizeof() com a estrutura do formato de vértice como seu argumento. // Desenha forma geométrica g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, nPasso); A função DrawPrimitiveUP() renderiza os vértices de usuário presentes numa array ( &g_Vertices ) na quantidade determinada ( nContagem ) da forma primitiva escolhida D3DPT_TRIANGLELIST (lista de triângulos). Vamos conhecer as outras formas primitivas em um outro tópico. 2.4 Renderizando a cena A função Renderizar() prepara o contexto obrigatório de renderização e chama a função renderizar_Geometria() para o desenho do triângulo.
// ----------------------------------------------------------------------------- // Renderizar() - Desenha a cena // ----------------------------------------------------------------------------- VOID Renderizar() { // Retorne se o dispositivo estiver nulo if( g_device == NULL) return; // Limpa o backbuffer com uma cor branca g_device->Clear( 0, NULL, D3DCLEAR_TARGET, branco, 1.0f, 0); // Começa a cena if( SUCCEEDED( g_device->BeginScene() ) ) { // Vamos renderizar as formas geométricas renderizar_Geometria(); // Finalizando a cena g_device->EndScene(); } // endif // Apresenta o conteúdo do backbuffer na tela g_device->Present( NULL, NULL, NULL, NULL); } // Renderizar().fim
3. Código fonte do projeto de exemplo: prj_Triangulo01
// Projeto: prj_Triangulo01 - Arquivo: motor.h // Esta aplicação ilustra como renderizar um triângulo #ifndef motor_h #define motor_h // Esta função inicializa o Direct3D HRESULT initGfx (HWND hJanela); // Essa função libera os objetos utilizados void Limpar(); // Essa função desenha a cena void Renderizar(); // Essa função monta formas geométricas void montar_Geometria (void); // Renderiza os vértices em formas geométricas void renderizar_Geometria (void); // Declaração da função que atende as mensagens da janela LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam); #endif
// ----------------------------------------------------------------------------- // Projeto: prj_Triangulo01 - arquivo: motor.cpp // Esta aplicação ilustra como renderizar um triângulo // Produzido por www.gameprog.com.br // ----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include <stdio.h> #include "motor.h" // Inclui as bibliotecas do Direct3D #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") // Variáveis globais // Representa o dispositivo Direct3D LPDIRECT3D9 g_Direct3d = NULL; // Representa o dispositivo Renderizador IDirect3DDevice9* g_device = NULL; // Essa variável recebe informação de erro do Directx HRESULT g_hr = 0; extern int g_xtela; extern int g_ytela; // Constante para cores const DWORD vermelho = 0xFFFF0000; const DWORD branco = 0xFFFFFFFF; const DWORD verde = 0xFF00FF00; const DWORD azul = 0xFF0000FF; // Definição do formato de vértice utilizado pela aplicação #define CustomVertex_TransformedColored_Format(D3DFVF_XYZRHW | D3DFVF_DIFFUSE) // Definição da estrutura de vértice customizado struct CustomVertex_TransformedColored { float x, y, z; float rhw; DWORD cor; // Construtor default CustomVertex_TransformedColored() {} // Construtor com inicialização CustomVertex_TransformedColored( float _x, float _y, float _z, float _rhw, DWORD _cor) { x = _x; y = _y; z = _z; rhw = _rhw; cor = _cor; } // fim do construtor }; // fim da estrutura CustomVertex_TransformedColored // Declaração dos vértices para o triângulo CustomVertex_TransformedColored g_Vertices[3 ]; // initGfx() - Inicializa o Direct3D HRESULT initGfx( HWND hJanela ) { // Cria o objeto Direct3D que é necessário para criar o dispositivo gráfico g_Direct3d = Direct3DCreate9( D3D_SDK_VERSION); // Verifica se objeto Direct3D foi criado if(g_Direct3d == NULL) { MessageBox (NULL, "Falha na inialização do Direct3D", "InitGfx()", MB_OK); return E_FAIL; } // endif // Declara a variável para os parâmetros de apresentação D3DPRESENT_PARAMETERS pps; // Limpa a estrutura ZeroMemory( &pps, sizeof(pps) ); // Configura os parâmetros de apresentação // A aplicação vai ter janela pps.Windowed = TRUE; // Esse método vira rapidamente o backbuffer para a tela imediata pps.SwapEffect = D3DSWAPEFFECT_DISCARD; // Esse formato vai procurar se encaixar no modo de video corrente pps.BackBufferFormat = D3DFMT_UNKNOWN; // Configuração do renderizador a ser criado // Adaptador default (0) int nAdaptador = D3DADAPTER_DEFAULT; // Tipo de dispositivo Hardware ou emulador de referência (software) D3DDEVTYPE dispositivo_tipo = D3DDEVTYPE_HAL; // Flags de configuração do dispositivo DWORD create_flags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; // Criamos aqui o dispositivo renderizador g_hr = g_Direct3d->CreateDevice( nAdaptador, dispositivo_tipo, hJanela, create_flags, &pps, &g_device ); // Verifica se houve falha no processo if( FAILED( g_hr ) ) { MessageBox (NULL, "Falha na criação: g_device", "initGfx()", MB_OK); return E_FAIL; } // endif // Monta as formas geométricas montar_Geometria(); return S_OK; } // initGfx().fim // ----------------------------------------------------------------------------- // Renderizar() - Desenha a cena // ----------------------------------------------------------------------------- VOID Renderizar() { // Retorne se o dispositivo estiver nulo if( g_device == NULL) return; // Limpa o backbuffer com uma cor branca g_device->Clear( 0, NULL, D3DCLEAR_TARGET, branco, 1.0f, 0); // Começa a cena if( SUCCEEDED( g_device->BeginScene() ) ) { // Vamos renderizar as formas geométricas renderizar_Geometria(); // Finalizando a cena g_device->EndScene(); } // endif // Apresenta o conteúdo do backbuffer na tela g_device->Present( NULL, NULL, NULL, NULL); } // Renderizar().fim void montar_Geometria(void) { // Posicionamento de profundidade float zpos = 1.0f; // p0 - primeiro vértice g_Vertices[0] = CustomVertex_TransformedColored( 128.0f, 50.0f, zpos, 1.0f, vermelho); // p1 - segundo vértice g_Vertices[1] = CustomVertex_TransformedColored( 512.0f, 384.0f, zpos, 1.0f, verde); // p2 - terceiro vértice g_Vertices[2] = CustomVertex_TransformedColored( 128.0f, 384.0f, zpos, 1.0f, azul); } // montar_Geometria().fim void renderizar_Geometria() { // Todo código de desenhar ocorre aqui dentro g_device->SetFVF( CustomVertex_TransformedColored_Format); // Quantidade de primitivas possíveis de acordo com o uso de vértices UINT nContagem = 1; // Tamanho do passo para achar o próximo vértice UINT nPasso = sizeof(CustomVertex_TransformedColored); // Desenha forma geométrica g_device->DrawPrimitiveUP( D3DPT_TRIANGLELIST, nContagem, &g_Vertices, nPasso); } // renderizar_Geometria().fim // Esta função é chamada por DispatchMessage() LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam) { switch (mensagem) { case WM_DESTROY: // Coloca uma mensagem WM_QUIT na fila de mensagem Limpar(); PostQuitMessage (0); break; case WM_KEYDOWN: if (wParam == VK_ESCAPE) { Limpar(); PostQuitMessage( 0); } // endif break; // Essa mensagem vai ocorrer a todo momento case WM_PAINT: // Renderiza a cena Renderizar(); // Invalida a tela para chamar WM_PAINT novamente InvalidateRect( hJanela, NULL, false); break; // Processamento default de mensagens não tratada pela aplicação default: return DefWindowProc (hJanela, mensagem, wParam, lParam); } // endswitch return 0; } // processaJanela().fim // Limpar() - Libera todos os objetos previamente inicializados // ----------------------------------------------------------------------------- VOID Limpar() { // Libera o dispositivo gráfico if( g_device != NULL) g_device->Release(); // Libera o motor do Direct3D if( g_Direct3d != NULL) g_Direct3d->Release(); } // Limpar().fim
//----------------------------------------------------------------------------- // Projeto: prj_Triangulo01 - arquivo: entrada.cpp // Esta aplicação ilustra como renderizar um triângulo // Produzido por www.gameprog.com.br //----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include "motor.h" // Variável global da classe da janela char sclasseJanela[ ] = "cls_directx"; // Dimensões da janela int g_xtela = 640; int g_ytela = 480; int WINAPI WinMain (HINSTANCE app_instancia, HINSTANCE app_anterior, LPSTR sComando,int nExibir) { // alça da janela HWND hJanela; // Estrutura de recepção das mensagens MSG mensagem; // Estrutura de descrição da janela WNDCLASSEX wcls; // Estrutura que descreve a janela wcls.hInstance = app_instancia; wcls.lpszClassName = sclasseJanela; wcls.lpfnWndProc = processaJanela; wcls.style = CS_HREDRAW | CS_VREDRAW; wcls.cbSize = sizeof (WNDCLASSEX); // O cursor e os ícones da aplicação são default wcls.hIcon = LoadIcon (NULL, IDI_APPLICATION); wcls.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wcls.hCursor = LoadCursor (NULL, IDC_ARROW); // Aplicação sem menu wcls.lpszMenuName = NULL; // Nada de espaço extra atrelado a classe da janela (wcls) wcls.cbClsExtra = 0; // Nada de espaço extra atrelado a janela wcls.cbWndExtra = 0; // Cor default da janela wcls.hbrBackground = ( HBRUSH) COLOR_BACKGROUND; // Registra a janela e retorna se esta operação falhar int status = RegisterClassEx (&wcls); if(status == 0) { MessageBox(NULL, "Registro falhou!", "WinMain()", MB_OK); return 0; } // endif // Com a classe criada pode-se criar a janela DWORD estiloExtra = 0; const char janelaTitulo[] = "prj_Triangulo01"; DWORD controleEstilo = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX; int xpos = 160; int ypos = 120; HWND hjanelaPai = HWND_DESKTOP; HMENU sem_menu = NULL; LPVOID dadoExtra = NULL; // Cria a janela hJanela = CreateWindowEx(estiloExtra, sclasseJanela, janelaTitulo, controleEstilo, xpos, xpos, g_xtela, g_ytela, hjanelaPai, sem_menu, app_instancia, dadoExtra ); // Verifica se janela foi criada if(hJanela == NULL) { MessageBox(NULL, "Falha na criação da janela!", "WinMain()", MB_OK); return 0; } // endif // Essa variável recebe informação de erro do Directx HRESULT hr; // Inicia o Direct3D hr = initGfx ( hJanela ); // Encerre a aplicação se houve falha if(FAILED (hr) ) { MessageBox (hJanela, "Direct3D: falha na inicialização", "WinMain()", MB_OK); UnregisterClass( sclasseJanela, wcls.hInstance); return E_FAIL; } // endif // Mostra a janela ShowWindow(hJanela, nExibir); UpdateWindow(hJanela ); // Rode a bombeamento de mensagens até GetMessage() retornar 0 while (GetMessage(&mensagem, NULL, 0, 0)) { // Traduz mensagem de tecla virtual em mensagem de caracteres TranslateMessage( &mensagem ); // Despacha a mensagem para a função processaJanela */ DispatchMessage( &mensagem ); } // endwhile // O valor de retorno é zero(0) passado por PostQuitMessage() UnregisterClass( sclasseJanela, wcls.hInstance); return mensagem.wParam; } // WinMain().fim

index << >>

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