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

index << >>


01.4 Texto simples

1.1 Visão geral
Para mostrar texto utilizando o directx é necessário inicializar um objeto fonte do directx retornado pela função D3DXCreateFont(). A inicialização desse objeto tem muitos parâmetros para ser configurado. Para suavizar o caminho de assimilação desse objeto mostramos uma imagem de seleção de fonte do aplicativo notepad com o aspecto visual de alguns itens que devem ser configurados na criação do objeto fonte. Um dos primeiros itens notáveis é o nome da fonte que pode ser 'Arial' ou 'Verdana' entre outras centenas de opções. O nome da fonte também é chamado de facename. Outro item interessante de configuração é o tamanho da fonte que pode ser melhor assimilado experimentando diversos valores para definir qual se encaixa melhor no contexto do momento. A fonte tem uma configuração de peso que expressa se a fonte está em negrito ou regular ou ainda em diversos níveis de espessura. No mundo existem diversos idiomas, entre eles o japonês, grego e o hebraico, então deve haver uma opção que garanta apoio aos caracteres dos diversos idiomas que existem; essa opção é chamada de charset que é uma abreviação para a expressão 'conjunto de caracteres'. A fonte pode ter estilo, isto é, pode estar normal ou em itálico. Agora vamos tecer breve considerações sobre configurações mais incomuns de fonte sem adentrar em maiores detalhes ou termos técnicos. A fonte pode ter configuração de precisão e qualidade visto que é possível melhorar a visualização de texto conforme se usa monitor de led, lcd ou o antigo crt. Há configurações que tratam do espaçamento irregular entre os caracteres e o espaço irregular que os caracteres ocupam, por exemplo, a letra 'i' ocupa menos espaço que a letra 'O'. Há fontes que são desenhadas através de comandos vetoriais enquanto há outras que são rasterizadas trazendo ponto a ponto a sua descrição, isso dá origem a família de fontes. Não vamos dar muita atenção a estas configurações mais incomuns e utilizaremos valores padrões sem discussão de outras opções. 1.2 Estrutura principal da aplicação
Arquivo: entrada.cpp
WinMain() criação da classe da janela registro da classe da janela criação da janela de acordo com a classe definida chama initGfx() para inicializar o motor gráfico mostra a janela estabelecimento do laço de mensagens finaliza a aplicação processaJanela() tratamento das mensagens Verifica teclado - finaliza aplicação na tecla Escape chama Limpar() na finalização da aplicação chama Renderizar() para desenhar os gráficos
Arquivo: motor.cpp
initGfx() Inicializa objeto Direct3d Inicializa dispositivo renderizador Inicializa objeto para mostrar texto Renderizar() Limpa a tela Desenha a cena mostra texto Apresenta a cena Limpar() Libera objeto de mostrar texto Libera dispositivo renderizador Libera objeto Direct3d
2.1.1 Aspectos globais - Arquivo: motor.h
// Projeto: prj_MostrarTexto - Arquivo: motor.h #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(); // Esta função inicializa o objeto para mostrar texto void inicializarTexto(); // Esta função mostra um texto na coordenada (x, y) da janela void mostrarTexto( int x, int y, char* texto); #endif
void inicializarTexto(); Esta função inicializa um objeto gerado pela função D3DXCreateFont() para mostrar texto. void mostrarTexto( int x, int y, char* texto); Esta função mostra um texto na coordenada (x, y) da janela na cor azul. 2.1.2 Aspectos globais - Arquivo: motor.cpp
// ----------------------------------------------------------------------------- // Projeto: prj_MostrarTexto - arquivo: motor.cpp // Esta aplicação ilustra como mostrar texto // Produzido por www.gameprog.com.br // ----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.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 D3D LPDIRECT3D9 g_Direct3d = NULL; // Representa o dispositivo Renderizador IDirect3DDevice9* g_device = NULL; // Ponteiro para uma fonte do directx ID3DXFont* gdxFonte = NULL; // Essa variável recebe informação de erro do Directx HRESULT g_hr = 0; extern int g_xtela; extern int g_ytela;
// Representa o dispositivo Renderizador IDirect3DDevice9* g_device = NULL; Esta é uma maneira alternativa de se criar um ponteiro para o dispositivo renderizador ao invés de utilizar LPDIRECT3DDEVICE9. // Ponteiro para uma fonte do directx ID3DXFont* gdxFonte = NULL; Declaramos aqui o ponteiro para o objeto da interface ID3DXFont que vai mostrar texto na tela. extern int g_xtela; extern int g_ytela; Estas variáveis globais estão declaradas em entrada.cpp e precisam ser pré-fixadas com extern para serem utilizadas em motor.cpp. O extern é uma necessidade no ambiente de desenvolvimento da Microsoft mas nossos testes indicam que ele é dispensável no ambiente devcpp ou devc++ da Bloodshed visto que esse ambiente parece tratar todos os arquivos cpp como se fosse um único arquivo. 2.2 Inicializando o motor gráfico A única novidade da função initGfx() é a função inicializarTexto() que faz a configuração do objeto gdxFonte que vai mostrar texto na tela.
// 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 inicializarTexto(); return S_OK; } // initGfx().fim
2.3 Inicializando o objeto da interface ID3DXFont
void inicializarTexto() { // Altura int nAltura = 24; // Largura UINT nLargura = 0; // Peso ( weight ) UINT nPeso = FW_BOLD; // Nível de mipmap - 0: mipmap automático UINT nMipmap = 0; // Efeito itálico bool bItalico = false; // Conjunto de caracteres (charset) DWORD nCharset = DEFAULT_CHARSET; // Precisão (OutputPrecision) DWORD nPrecisao = OUT_DEFAULT_PRECIS; // Qualidade DWORD nQualidade = DEFAULT_QUALITY; // Pitch e família DWORD nFamilia = DEFAULT_PITCH | FF_DONTCARE; // Nome da fonte char* sFonte = "Arial"; g_hr = D3DXCreateFont( g_device, nAltura, nLargura, nPeso, nMipmap, bItalico, nCharset, nPrecisao, nQualidade, nFamilia, sFonte, &gdxFonte ); if(FAILED (g_hr) ) MessageBox(NULL, "Texto: falha na inicialização", "inicializarTexto()", MB_OK); } // inicializarTexto()
Abaixo descrevemos os argumentos que vão na função de criação do objeto fonte do directx. Colocamos os argumentos em variáveis para facilitar a leitura e compreensão da assinatura da função que cria esse objeto para mostrar texto. // Altura int nAltura = 24; Aqui é a configuração de altura da fonte. Parece simples mas não é. O valor está expressado em unidades lógicas ao invés de ser expressado em pixels que é mais compreensível. A razão disso é que o sistema Windows consegue garantir a mesma consistência visual da aplicação em diferentes resoluções de vídeo escalando o tamanho conforme a necessidade da resolução. // Largura UINT nLargura = 0; A largura da fonte configurada como zero (0) deixa o directx calcular a largura ideal baseado na altura dada. // Peso ( weight ) UINT nPeso = FW_BOLD; Este argumento configura o peso da fonte que está em negrito na configuração acima; utilize FW_NORMAL ou FW_REGULAR para texto normal. // Nível de mipmap - 0: mipmap automático UINT nMipmap = 0; Esta configuração mexe com a qualidade da fonte conforme as dimensões da fonte estejam muito grandes ou muito pequenas. Deixe como zero (0) para este argumento ser ajustado automaticamente. // Efeito itálico bool bItalico = false; Este argumento aplica o estilo itálico (true) ao texto ou normal (false). // Conjunto de caracteres (charset) DWORD nCharset = DEFAULT_CHARSET; Este argumento define o conjunto de caracteres configurado como o padrão default acima. Outros valores interessantes são ANSI_CHARSET (padrão ANSI ), OEM_CHARSET ( padrão local do computador ) e SHIFTJIS_CHARSET ( para uso de caracteres do idioma japonês ). // Nome da fonte char* sFonte = "Arial"; Este argumento aqui, o nome da fonte ou o facename, é um dos mais interessantes pois define a aparência decisiva da fonte. Um nome legal para testar é Wingdings que é uma fonte constituída de desenhos. // Precisão (OutputPrecision) DWORD nPrecisao = OUT_DEFAULT_PRECIS; // Qualidade DWORD nQualidade = DEFAULT_QUALITY; Os dois argumentos acima estão relacionados a qualidade do traço final da fonte sobre a tela e foi configurado com valores padrões. // Pitch e família DWORD nFamilia = DEFAULT_PITCH | FF_DONTCARE; O argumento acima configura pitch e família da fonte. O pitch refere-se ao jogo de espaçamento dos caracteres e a família refere-se ao aspecto visual da fonte como prolongamento do traço, estilo de fôrma ou cursiva imitando uma escrita manual. Os valores configurados são padrões deixando o sistema definir estes aspectos. g_hr = D3DXCreateFont( g_device, nAltura, nLargura, nPeso, nMipmap, bItalico, nCharset, nPrecisao, nQualidade, nFamilia, sFonte, &gdxFonte); Aqui a função D3DXCreateFont() faz o seu trabalho de criar o objeto fonte do directx responsável por desenhar o texto na tela. Veja que g_hr recebe o status da operação e o objeto fonte mesmo é retornado pela referência &gdxfonte. Abaixo ocorre a verificação regular se houve falha na criação desse objeto. if(FAILED (g_hr) ) MessageBox(NULL, "Texto: falha na inicialização", "inicializarTexto()", MB_OK); 2.4 Mostrando texto na tela
void mostrarTexto(int x, int y, char* texto) { // Retorne se não houver fonte inicializada if(gdxFonte == NULL) return; // Cor de fundo da janela D3DCOLOR azul = D3DCOLOR_XRGB(0, 0, 255); RECT area_limite; SetRect( &area_limite, x, y, g_xtela, g_ytela ); gdxFonte->DrawText( NULL, texto, -1, &area_limite, 0, azul ); } // mostrarTexto();
// Cor de fundo da janela D3DCOLOR azul = D3DCOLOR_XRGB(0, 0, 255); Este argumento define a cor do texto. RECT area_limite; SetRect( &area_limite, x, y, g_xtela, g_ytela ); O texto é desenhado dentro de um retângulo que restringe os limites do texto. Neste caso o retângulo de restrição foi relaxado para assumir a tela toda. A coordenada (x, y) define a posição do texto. A função SetRect() configurou os valores pré-definidos dentro do retângulo criado. gdxFonte->DrawText( NULL, texto, -1, &area_limite, 0, azul ); Esta linha de código é a forma mais simples de mostrar texto na tela. Mas esta função é mais poderosa que isso. O NULL refere-se a um objeto sprite que é montado automaticamente pelo directx neste caso. O -1 refere-se ao tamanho do texto que pode ser omitido no caso de uma string do tipo string zero ser utilizada como é o caso das strings produzidas com char*. O zero (0) refere-se a efeitos de formatação (alinhamentos, centralização...) que não serão cobertos aqui. Nossa intenção nesse momento é permitir uma exibição simples de texto para os futuros status e informações sobre a aplicação. 2.5 Dispensando o objeto fonte do directx Dispense o objeto criado no final da aplicação conforme foi destacado em negrito na listagem abaixo da função Limpar().
// Limpar() - Libera todos os objetos previamente inicializados // ----------------------------------------------------------------------------- VOID Limpar() { // Libera objeto de mostrar texto if( gdxFonte != NULL) gdxFonte->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(); } // Limpar().fim
2.6 Renderizando o texto Agora para mostrar efetivamente o texto basta utilizar a função mostrarTexto() entre BeginScene() e EndScene() conforme destacado abaixo na listagem da função Renderizar().
// ----------------------------------------------------------------------------- // Renderizar() - Desenha a cena // ----------------------------------------------------------------------------- VOID Renderizar() { // Retorne se o dispositivo estiver nulo if( g_device == NULL) return; // Cor de fundo da janela const D3DCOLOR branco = D3DCOLOR_XRGB( 255, 255, 255 ); const D3DCOLOR cor_fundo = branco; // Superfícies que serão limpas DWORD superficies = D3DCLEAR_TARGET; // Configuração padrão do buffer de profundidade float zBuffer = 1.0f; // Configuração padrão do stencil DWORD sBuffer = 0; // Quantidade de retângulos a serem limpos DWORD nPartes = 0; // Array de retângulos que serão limpos const D3DRECT* pPartes = NULL; // Limpa o backbuffer com uma cor branca g_device->Clear( nPartes, pPartes, superficies, cor_fundo, zBuffer, sBuffer); // Começa a cena if( SUCCEEDED( g_device->BeginScene() ) ) { // Todo código de desenhar ocorre aqui dentro mostrarTexto (120, 160, "Produzido na escola Gameprog"); mostrarTexto (200, 200, "Programar é legal!"); // Finalizando a cena g_device->EndScene(); } // endif // Apresenta o conteúdo do backbuffer na tela // Retangulo fonte e destino const RECT* rFonte = NULL; const RECT* rDestino = NULL; // Janela alternativa para apresentar os dados visuais HWND hOutraJanela = NULL; g_device->Present( rFonte, rDestino, hOutraJanela, NULL); } // Renderizar().fim
2.7 Aspectos globais - Arquivo: entrada.cpp (Listagem)
//----------------------------------------------------------------------------- // Projeto: prj_MostrarTexto - arquivo: entrada.cpp // Esta aplicação ilustra como mostrar texto // Produzido por www.gameprog.com.br //----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include "motor.h" // Declaração da função que atende as mensagens da janela LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam); // Variável global da classe da janela char sclasseJanela[ ] = "cls_directx"; // Dimensões da janela int g_xtela = 640; int g_ytela = 480;
2.8 WinMain() - Arquivo: entrada.cpp (Listagem)
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_MostrarTexto"; 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
2.9 processaJanela() - Arquivo: entrada.cpp (Listagem)
// 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
3. Código fonte do projeto de exemplo:prj_MostrarTexto
// Projeto: prj_MostrarTexto - Arquivo: motor.h #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(); // Esta função inicializa o objeto para mostrar texto void inicializarTexto(); // Esta função mostra um texto na coordenada (x, y) da janela void mostrarTexto( int x, int y, char* texto); #endif
// ----------------------------------------------------------------------------- // Projeto: prj_MostrarTexto - arquivo: motor.cpp // Esta aplicação ilustra como mostrar texto // Produzido por www.gameprog.com.br // ----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.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 D3D LPDIRECT3D9 g_Direct3d = NULL; // Representa o dispositivo Renderizador IDirect3DDevice9* g_device = NULL; // Ponteiro para uma fonte do directx ID3DXFont* gdxFonte = NULL; // Essa variável recebe informação de erro do Directx HRESULT g_hr = 0; extern int g_xtela; extern int g_ytela; // 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 inicializarTexto(); return S_OK; } // initGfx().fim void inicializarTexto() { // Altura int nAltura = 24; // Largura UINT nLargura = 0; // Peso ( weight ) UINT nPeso = FW_BOLD; // Nível de mipmap - 0: mipmap automático UINT nMipmap = 0; // Efeito itálico bool bItalico = false; // Conjunto de caracteres (charset) DWORD nCharset = DEFAULT_CHARSET; // Precisão (OutputPrecision) DWORD nPrecisao = OUT_DEFAULT_PRECIS; // Qualidade DWORD nQualidade = DEFAULT_QUALITY; // Pitch e família DWORD nFamilia = DEFAULT_PITCH | FF_DONTCARE; // Nome da fonte char* sFonte = "Arial"; g_hr = D3DXCreateFont( g_device, nAltura, nLargura, nPeso, nMipmap, bItalico, nCharset, nPrecisao, nQualidade, nFamilia, sFonte, &gdxFonte ); if(FAILED (g_hr) ) MessageBox(NULL, "Texto: falha na inicialização", "inicializarTexto()", MB_OK); } // inicializarTexto() void mostrarTexto(int x, int y, char* texto) { // Retorne se não houver fonte inicializada if(gdxFonte == NULL) return; // Cor de fundo da janela D3DCOLOR azul = D3DCOLOR_XRGB(0, 0, 255); RECT area_limite; SetRect( &area_limite, x, y, g_xtela, g_ytela ); gdxFonte->DrawText( NULL, texto, -1, &area_limite, 0, azul ); } // mostrarTexto(); // Limpar() - Libera todos os objetos previamente inicializados // ----------------------------------------------------------------------------- VOID Limpar() { // Libera objeto de mostrar texto if( gdxFonte != NULL) gdxFonte->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(); } // Limpar().fim // ----------------------------------------------------------------------------- // Renderizar() - Desenha a cena // ----------------------------------------------------------------------------- VOID Renderizar() { // Retorne se o dispositivo estiver nulo if( g_device == NULL) return; // Cor de fundo da janela const D3DCOLOR branco = D3DCOLOR_XRGB( 255, 255, 255 ); const D3DCOLOR cor_fundo = branco; // Superfícies que serão limpas DWORD superficies = D3DCLEAR_TARGET; // Configuração padrão do buffer de profundidade float zBuffer = 1.0f; // Configuração padrão do stencil DWORD sBuffer = 0; // Quantidade de retângulos a serem limpos DWORD nPartes = 0; // Array de retângulos que serão limpos const D3DRECT* pPartes = NULL; // Limpa o backbuffer com uma cor branca g_device->Clear( nPartes, pPartes, superficies, cor_fundo, zBuffer, sBuffer); // Começa a cena if( SUCCEEDED( g_device->BeginScene() ) ) { // Todo código de desenhar ocorre aqui dentro mostrarTexto (120, 160, "Produzido na escola Gameprog"); mostrarTexto (200, 200, "Programar é legal!"); // Finalizando a cena g_device->EndScene(); } // endif // Apresenta o conteúdo do backbuffer na tela // Retangulo fonte e destino const RECT* rFonte = NULL; const RECT* rDestino = NULL; // Janela alternativa para apresentar os dados visuais HWND hOutraJanela = NULL; g_device->Present( rFonte, rDestino, hOutraJanela, NULL); } // Renderizar().fim
//----------------------------------------------------------------------------- // Projeto: prj_MostrarTexto - arquivo: entrada.cpp // Esta aplicação ilustra como mostrar texto // Produzido por www.gameprog.com.br //----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include "motor.h" // Declaração da função que atende as mensagens da janela LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam); // 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_MostrarTexto"; 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 // 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

index << >>

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