IDE: Microsoft Visual Studio 2005 (.NET Framework 2.0, DirectX SDK [April 2007])
Olá amigos! Mês passado apresentei pra vocês meu primeiro artigo sobre desenvolvimento de jogos utilizando o framework do DirectX, abordamos todos os tópicos básicos e teóricos da metodologia 3D. Aprendemos também, na prática, como criar nosso dispositivo, um handle para a placa de vídeo, e limpamos nossa tela com uma cor especificada.
Hoje começo meu segundo artigo explicando a classe PresentParameters que contém diversas propriedades que definem os parâmetros de apresentação do nosso Device window. Como estou buscando mais detalhes, procurando ir o mais fundo possível no assunto, decidi mergulhar nesta classe e conhecer suas diversas propriedades para que possamos pegar todos os detalhes possíveis desta fase inicial de criação. É muito importante entender os aspectos básicos do sistema, seu funcionamento e lógica encapsulada. Por isso quanto mais você conhecer da biblioteca, mais chances terá de ter sucesso com a mesma.
Logo em seguida introduziremos um exemplo prático onde setamos diversas propriedades da classe, inicializando nosso aplicativo pela primeira vez em tela cheia. Confira a declaração da classe:
public sealed class PresentParameters : ICloneablePresentParameters é uma classe pública que define os parâmetros de apresentação de nosso dispositivo. Ela não pode ser herdada pois esta definida como sealed. Ela implementa a interface ICloneable que contém o método Clone, utilizada para clonagens do tipo shallow copy e deep copy.
Microsoft.DirectX.Direct3D.PresentParameters.
Ufa! Depois de um pouquinho de leitura, conseguimos entender os principais aspectos da classe PresentParameters. Setamos estes valores antes da criação de nosso Device para que ele possa ser inicializado corretamente de acordo com nossas necessidades. Podemos excluir alguns aspectos desnecessários para aumentarmos nosso desempenho, ou incluir diversos que nos trazem dezenas de outras possibilidades.
Agora que temos um overview básico sobre esta classe, vamos criar nossa segunda telinha preta, só que agora em tela cheia (rs). Note que também modificaremos o código da criação do Device, tratando possíveis erros de suporte a vídeo antes da criação do mesmo. Deixarei a explicação para os comentários dentro código. Confira a nova versão do método InicializaGraficos:
public bool InicializaGraficos(bool isWindowed)
{
PresentParameters presentParameters = new PresentParameters();
// Decidimos se executaremos em plano janela ou em tela cheia.
if (isWindowed)
{
presentParameters.Windowed = true;
presentParameters.SwapEffect = SwapEffect.Discard;
}
else
{
presentParameters.SwapEffect = SwapEffect.Discard;
presentParameters.BackBufferWidth = 800;
presentParameters.BackBufferHeight = 600;
presentParameters.BackBufferFormat = Format.A8R8G8B8;
}
// Estes parâmetros estão comentados pois são desnecessários no contexto atual de criação do
// Device e suas inicializações padrão são originais como as ajustadas abaixo. Para os
// perfeccionistas do desempenho, ocultamos estas configurações pois, elas já são conhecidas
// inicialmente pelo compilador.
//presentParameters.EnableAutoDepthStencil = false;
//presentParameters.AutoDepthStencilFormat = Unknow;
//presentParameters.Windowed = false;
//presentParameters.DeviceWindow = this;
//presentParameters.DeviceWindowHandle = this.Handle;
//presentParameters.BackBufferCount = 0; // 0 = 1.
//presentParameters.MultiSample = MultiSampleType.None;
//presentParameters.MultiSampleQuality = 0;
//presentParameters.FullScreenRefreshRateInHz = 0;
//presentParameters.PresentationInterval = PresentInterval.Default;
//presentParameters.ForceNoMultiThreadedFlag = false;
//presentParameters.PresentFlag = PresentFlag.None;
// Pega o número ordinal do Device padrão.
// Geralmente este número é 0.
int inteiroAdapter = Manager.Adapters.Default.Adapter;
//Obtém as capacidades da placa através da struct Caps.
Caps capacidades = Manager.GetDeviceCaps(inteiroAdapter, DeviceType.Hardware);
// Verifica as capacidades do dispositivo.
// Verifica suporte a transformações e luzes utilizadas por HardwareVertexProcessing.
CreateFlags flagCapacidadeDevice;
if (capacidades.DeviceCaps.SupportsHardwareTransformAndLight)
{
flagCapacidadeDevice = CreateFlags.HardwareVertexProcessing;
Console.WriteLine("GameEngine.cs -> HardwareVertexProcessing");
}
else // Senão utilizamos por SoftwareVertexProcessing.
{
flagCapacidadeDevice = CreateFlags.SoftwareVertexProcessing;
Console.WriteLine("GameEngine.cs -> SoftwareVertexProcessing");
}
// Se a placa de vídeo suportar HardwareVertexProcessing, checa se a mesma suporta rasterização,
// transformações de matriz, luz e etc... Essa combinação é a mais rápida.
if (capacidades.DeviceCaps.SupportsPureDevice flagCapacidadeDevice == CreateFlags.HardwareVertexProcessing)
{
flagCapacidadeDevice = CreateFlags.PureDevice;
Console.WriteLine("GameEngine.cs -> PureDevice");
}
// Cria o Device.
try
{
this.device = new Device(
inteiroAdapter,
DeviceType.Hardware,
this,
flagCapacidadeDevice,
presentParameters
);
return true;
}
catch (DirectXException)
{
this.device = new Device(
inteiroAdapter,
DeviceType.Reference,
this,
CreateFlags.SoftwareVertexProcessing,
presentParameters
);
return true;
}
} Note como agora temos um método muito mais robusto e completo para a inicialização de nosso Device. Este código ainda não trata todas as possibilidades mais é bastante útil e flexível. Não pense que em um jogo profissional teriamos uma função gigantesca para a criação do Device a toda hora. Configurações de execução são setadas antes de começarmos o negócio de nosso aplicativo. De pouco em pouco ensinarei novas técnicas e soluções para diversas situações que encontraremos no caminho.
Por hoje ficamos por aqui. Não se esqueça de continuar seus estudos pois a cada matéria, o nível técnico dos artigos tenderá a subir (assim como a dificuldade de utilização do framework). Então sem preguiça e bons estudos galera. Até a próxima!
"Vencer não é nada, se não se teve muito trabalho; fracassar não é nada se se fez o melhor possível."Nadia Boulanger

Gosto bastante dessa área, sou programador já há quase 6 anos, tenho me esforçado bastante nos tempos livres pra desenvolver meus jogos e tenho uma grande vontade de começar a desenvolver eles com c#, acredito que seja uma boa hora de iniciar.
Valeu!!
Abração!
Os textos publicados neste espaço são de responsabilidade única de seus autores (colunistas e leitores) e podem não expressar necessariamente a opinião do iMasters.
Jean Dannemann é Analista de Sistemas e desenvolvedor na Concepta Consultoria (Uberlândia). Trabalho a mais de 2 anos com Ajax e Web 2.0 e dedico meu tempo livre principalmente na linguagem C++, e criação de jogos com DirectX. Atualmente está terminando o curso de Sistemas de Informação na Universidade Presidente Antônio Carlos (UNIPAC).
2001 - iMasters FFPA Informática Ltda - Todos os direitos reservados.