IntroduçãoNo XNA, em geral, a responsabilidade de representar imagens(2D) é atribuída a classe Texture2D.A classe Texture2D representa uma grade(2D) de Texels; também denominamos isso de Sprite. Sprite é qualquer imagem atribuída a um jogo. Visao geral sobre Texel: Um Texel representa a menor parte de uma Textura. Um Texel pode ser qualquer um dos formatos disponiveis representados na enumeração SurfaceFormat. Um Texel é composto de 1 a 4 componentes.
O Formato de Texel mais utilizado é o RGBA(SurfaceFormat.Color). O formato RGBA possui 4 componentes - R(vermelho), G(verde), B(azul), Alpha(canal que determina o quão opaco é o texel) - cada componente possui 8-bit´s, ou seja, cada texel usa um valor de 32-bit´s para representar a sua cor. Formas de obtenção de uma Textura no XNANo XNA, é muito comum obter uma textura através do código a seguir: protected override void LoadContent() { ... this.myTexture = this.Content.Load<Texture2D>(“...”); ... } O código acima ler uma textura através do Contet Pipeline. O Content Pipeline provê o suporte dos tipos de imagens a seguir: .bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm e .tga Você também pode instanciar um objeto Texture2D. Fazendo assim, para obter algum resultado visual proveniente dessa instância, você precisa manipular a cor de cada texel através de “código C#”. Logo, temos 2 formas para obtenção de uma Textura: - Através do Content Pipeline;
- Instanciando(explícitamente) uma Textura.
Existe também uma outra maneira, que é através do método Texture2D.FromFile. Mais informações sobre o Método FromFile da classe Texture2D e aonde utilizá-lo, no artigo do Shinji abaixo: Instanciando um objeto Texture2D Observe o construtor da classe Texture2D: public Texture2D ( GraphicsDevice graphicsDevice, int width, int height, int numberLevels, ResourceUsage usage, SurfaceFormat format ) graphicsDevice – usado para mostrar a textura na tela. width – a largura, em pixels, da textura. height – a altura, em pixels, da textura. numberLevels – quantidade de pequenas versões da textura; utilizadas quando a textura é redimensionada para preencher uma área menor que o tamanho da textura original. Geralmente, o numero de níveis utilizado é 1. usage – indica o comportamento da textura. format – indica o formato de cada Texel. Como abordado anteriormente, a classe Texture2D representa uma grade(2D) de Texel´s. Então, saber como manipular os Texel´s, é uma tarefa relevante quando se está instanciando(explícitamente) uma textura. A classe Texture2D, provê 2 métodos importantes para manipulação de seus texel´s: - Texture2D.GetData – Copia os dados da texture para um “array”.
- Texture2D.SetDate – Copia um “array” de dados para uma textura.
Para esta demonstração, não será necessário a utilização do método GetData, pelo fato da Textura, quando instanciada, estar desprovida de qualquer tipo de cor, como mostrado na foto a seguir: Observe o local do breakpoint após o objeto ser instanciado - observação dos texel´s da texetura. Na foto, o array de cores contém 100 elementos com cada elemento composto de 4 componentes(RGBA) de valor 0. Será criado o método criaTexturaSimples, com a seguinte assinatura: void criaTexturaSimples(ref Texture2D textura); Esse método será chamado dentro do método LoadContent e terá como função: criar uma textura que tenha todos os seus Texel´s de uma única cor; uma textura unicolor(que tem só uma cor). Quando isso(a textura) for renderizada na tela, você notará uma forma geometrica de quatro lados e uma única cor. Observe o método: void criaTexturaSimples(ref Texture2D textura) { //largura e altura da Textura int width = 100; int height = 100; //quantidade Total de Texels que a textura vai conter int quantidadeTotalDeTexels = width*height; //instanciando todas as cores que //estarão contidas nos texels da textura Color[] coresDaTextura = new Color[quantidadeTotalDeTexels]; /*instanciando um objeto Texture2D. * Para esta demonstração, o formato da superficie a ser usado * será do tipo Cor */ textura = new Texture2D(this.GraphicsDevice, width, height, 0, TextureUsage.None, SurfaceFormat.Color); /*Já instanciada, agora a textura já contém todos os Texel´s no * formato informado no seu construtor. * Neste momento, para obter algum resultado visual, é necessario * atribuir uma cor a cada Texel - o código a seguir faz isso.*/ for (int i = 0; i < quantidadeTotalDeTexels; i++) { coresDaTextura[i] = Color.Blue; } //modifica os dados atuais da textura para o array de cores processados no //bloco de codigo anterior textura.SetData<Color>(coresDaTextura); //Por fim, a textura tem todos os Texel´s com cores atribuidas. //Nesta demonstração os Texel´s contêm a cor branca } Entendendo o que foi feito de maneira Gráfica: Foi criado um textura de largura e altura: 100. Fica inviável demonstrar 10.000 texel´s, portanto, imagine uma textura com altura e largura: 4. Observe a imagem: Neste caso, cada célula da “matriz” é um Texel. Logo, temos um amontoado de Texel´s dispostos de forma Bidimensional(formado por linhas e colunas); como o proprio nome sugere – Texture2D. Observe o código: for (int i = 0; i < quantidadeTotalDeTexels; i++) { coresDaTextura[i] = Color.Blue; } Do ponto de vista da textura, os Texel´s da textura são acessados semelhante a foto abaixo: A linha vermelha, juntamente com as setas preta, representa o fluxo com que o loop(for) está acessando os texels. Se olharmos do ponto de vista do array de cores, ele está sendo acessado, conforme mostrado na figura abaixo: Cada célula do vetor unidimensional, representa um Texel e este, recebe a cor azul. Com o array de cores preenchidos, agora só falta atribuir as cores ao texel´s da textura, a linha de código abaixo faz isso: textura.SetData<Color>(coresDaTextura); Observe graficamente: O método SetData, preenche a textura com as cores fornecidas no array de cores. Neste momento a textura já está pronta para ser renderizada na tela e mostrar algum tipo de resultado visual. O resultado visual obtido é uma forma geométrica com 4 lados e totalmente azul. Criando uma BandeiraPara a criação desta bandeira, o array de cores será acessado em sua forma “nativa”; o acesso se dará através de linhas e colunas tornando possível uma melhor manipulação dos Texel´s. Observe a bandeira pronta: Bandeira ao lado do quadrado azul. Da esquerda para direita, as cores da bandeira: Purple, Pink and Yellow. Observe a assinatura do método para construção da bandeira acima: void criaBandeira(ref Texture2D bandeira); Esse método é semelhante ao método mostrado anteriormente, nomeado: criaTexturaSimples. void criaBandeira(ref Texture2D bandeira) { //variavel auxiliar para acesso aos campos do array de cores int aux; //largura e altura da Textura int width = 500; int height = 250; //quantidade Total de Texels que a textura vai conter int quantidadeTotalDeTexels = width * height; //A Bandeira criada aqui(semelhante a varias existentes na vida real), //é composta por 3 retangulos iguais e com cores diferentes int tercaParte = width / 3; ... /*Já instanciada, agora a textura já contém todos os Texel´s no * formato informado no seu construtor. * Neste momento, para obter algum resultado visual, é necessario * atribuir uma cor a cada Texel - o código a seguir faz isso.*/ for (int i = 0; i < height/*linha*/; i++) { //"Prendemos" a linha, e "andamos" com as colunas for (int j = 0; j < width/*coluna*/; j++) { aux = i * width + j; if (j < tercaParte) coresDaTextura[aux] = Color.Purple; else if (j < (tercaParte * 2)) coresDaTextura[aux] = Color.Pink; else coresDaTextura[aux] = Color.Yellow; } } ... } Entendendo o Código de criação da Bandeira: A bandeira criada e mostrada acima, tem 3 faixas de “mesmo tamanho” na vertical. A variavel tercaParte é reponsavel por guardar a largura de cada faixa. Como são 3 faixas, temos: tercaParte + tercaParte + tercaParte = larguraTotalDaTextura; Obs.: Nem sempre a soma das 3 partes será exatamente igual a largura total da textura, entretanto isso não afetará a textura visualmente. Observe a linha de código do método criaBandeira: int tercaParte = width / 3; Representação gráfica da situação: for (int i = 0; i < height/*linha*/; i++) { //"Prendemos" a linha, e "andamos" com as colunas for (int j = 0; j < width/*coluna*/; j++) { aux = i * width + j; if (j < tercaParte) coresDaTextura[aux] = Color.Purple;
|