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