VGA – Tutorial 21 – Denthor

--==[ PARTE 21 ]==--

Autor: DENTHOR do ASPHYXIA
Atualizado por Snowman
Traduzido por Krull >>> tradução revisada e atualizada em 2020

Para obter os programas mencionados neste tutorial, por favor baixe o zip com a versão antiga do tutorial, neste link.

Introdução

E aí! Passou um tempão (de novo) desde o último tutorial… Aposto que alguns de vocês já desistiram de mim 😉

Hoje é meu 21º aniversário, então decidi que seria a hora perfeita para terminar esse tutorial que já deveria ter feito há semanas. É sobre mapeamento de texturas. Eu sei, eu sei, eu disse fontes de iluminação, depois gourad, e depois mapeamento de texturas, mas recebi email o suficiente um dilúvio, na verdade 😉 me dizendo para fazer sobre mapeamento de texturas…

Vou usar o código do tutorial 20 bastante aqui, então tenha certeza de
que você sabe o que está acontecendo lá… bem, vamos ao show!

Se você gostaria de me contactar, ou ao time, há muitos modos que você pode fazê-lo: 1) Escrever uma mensagem para Grant Smith/Denthor/Asphyxia em email privado na ASPHYXIA BBS.
2) Escrever para:
Grant Smith
P.O.Box 270 Kloof
3640
Natal
África do Sul
3) Ligar para mim (Grant Smith) no número (031) 73 2129 (deixe uma mensagem se você ligar quando eu estiver na faculdade) Ligue para +27-31-73-2129 se você está ligando de fora da África do Sul (A conta é sua ;-))
4) Escrever para denthor@goth.vironix.co.za
5) Escrever para asphyxia@beastie.cs.und.ac.za para falar com todos
nós de uma vez.

OBS1 : Se você é um representante de uma companhia ou BBS e quer que a ASPHYXIA faça um demo para você, mande um email pra mim; podemos discutir.
OBS2 : Se você fez/tentou fazer um demo, MANDE PARA MIM! Estamos nos sentindo muito solitários e queremos encontrar/ajudar/trocar código com outros grupos de demos. O que você tem a perder? Mande uma mensagem aqui e podemos ver como transferir. Nós realmente queremos ouvir de você.

http://goth.vironix.co.za/~denthor (WWW)
htp://ftp.eng.ufl.edu pub/msdos/demos/code/graph/tutor (FTP)

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Mapeamento de Texturas de Direção Livre

Há duas coisas que você deveria saber antes de começarmos.

Inicialmente, estou roubando. O mapeamento de texturas que vou mostrar a você não está correta na perspectiva, com divisões espertas para posição em Z, etc. Esse método parece quase bom e é bem rápido também.

Em segundo, você vai achar tudo muito fácil. A razão para isso é que é tudo muito simples. Primeiro eu fiz a rotina sentado com uns pedaços de papel e lápis, e coloquei na máquina em algumas horas. Um pouco mais tarde, quando as pessoas na rede começaram a discutir seus métodos, eles eram bem parecidos.

Deixa eu te mostrar o que quero dizer.

Vamos assumir que você tenha uma textura de 128×128 (um vetor de bytes [0..127, 0..127]) que você quer mapear em um lado do polígono. O problema é óbvio, é que o polígono pode estar em todo lugar, ter um lado ser maior que o outro, etc.

Nosso primeiro passo é ter certeza que sabemos qual ponto está por cima… deixe-me demonstrar…

                   1
                   +
                 /  \
              /       \
          4 +          + 2
              \      /
                \  /
                 +
                 3

Digamos que o polígono acima é o escolhido. Decidimos que o ponto 1 é o superior esquerdo, ponto 3 o inferior direito. Isso significa que

1 – 2 é o topo da textura
2 – 3 é a direita da textura
3 – 4 é o fundo da textura
4 – 1 é a esquerda da textura

O mesmo polígono, mas rodado:

                  3
                +
             /    \
          /         \
      2 +            +  4
          \        /
            \   /
              +
              1

Embora as posições dos pontos estejam diferentes, o ponto 1 ainda é o superior esquerdo da textura.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Como colocar na tela

OK, então agora você tem quatro pontos e sabe qual deles é topo esquerdo da textura. O que vem agora?

Se você se lembrar do nosso tutorial sobre polígonos, você vai se lembrar que o desenhamos linha a linha. Fazemos mapeamento de texturas do mesmo jeito.

Vamos olhar aquela figura de novo:

                  1
                +
           a /    \  b
          /         \
      4 +            +  2
          \        /
            \   /
              +
              3

Sabemos que o ponto 1 está em [0,0] na nossa textura. O ponto 2 está em [127,0], o ponto 3 em [127,127], e o 4 em [0,127].

O macete, e a chave para o mapeamento de texturas, é entender que no meio do caminho entre os pontos 1 e 2 (b), estamos em [64,0] na nossa textura. (a) está, do mesmo modo, em [0,64] .

É isso. Tudo que precisamos de saber para cada scan de linha em y é:
A posição inicial no eixo x do polígono
A posição em x no mapa da textura referenciado por aquele ponto
A posição em y no mapa da textura referenciado por aquele ponto

A posição final no eixo x do polígono
A posição em x no mapa da textura referenciado por aquele ponto
A posição em y no mapa da textura referenciado por aquele ponto

Deixe-me dar um exemplo. Digamos que (a) e (b) da figura acima estão na mesma linha de scan de y. Sabemos que x dessa linha está (digamos) a 100 pixels do começo, e 200 pixels do fim, fazendo sua largura 100 pixels.

Sabemos que no lado esquerdo, a textura está em [0,64], e no lado direito, em [64,0]. Em 100 pixels, temos que cruzar nossa textura de [0,64] a [64,0].

Assuma que no começo nós calculamos os pontos de início e fim na textura

textureX = 0;
textureY = 64;
textureEndX = 64;
textureEndY = 0;

dx := (TextureEndX-TextureX)/(maxx-minx);
dy := (TextureEndY-TextureY)/(maxx-minx);
for loop1 := minx to maxx do BEGIN
  PutPixel (loop1, ypos, texture [textureX, textureY], VGA);
  textureX = textureX + dx;
  textureY = textureY + dy;
END;

Faça isso acima para todas as linhas, e você terá um polígono com textura! É simples assim.

Achamos nossas posições iniciais e finais do modo usual. Sabemos que o
ponto 1 é [0,0]. Sabemos que o ponto 2 está em [127,0]. Sabemos o
número de linhas a escanear no eixo y entre os pontos 1 e 2.

    textureDX = 127/abs (point2.y - point1.y)

Rodamos todos as scans em y, começando de [0,0] e adicionando a fórmula acima para cada X, toda vez. Quando chegarmos no último scanline, estaremos no ponto [127,0] na textura.

Repita para todos os quatro lados, e você terá as seis variáveis que você precisa, por scanline.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Fechando

Como você pode ver, mapeamento de texturas (esse tipo, pelo menos) é bem fácil, e produz um resultado muito bom. Você vai notar, porém, um pouco de distorção se trouxer o polígono pra muito perto. Isso pode ser consertado fazendo a) Subdividindo o polígono, de modo que seja formado de quatro menores. Muito maior, mas funciona; b) Usando ponto fixo com maior precisão; ou c) Calculando o mapeamento correto da perspectiva, mapeando ao longo das linhas constantes-z, etc.

Quando as pessoas me escrevem, frequentemente se referem aos meus “tutes”. Isso vem do Mark Feldman que os chama assim no PCGPE. Eu sempre achei que um “tute” fosse algo que você fazia com seu carro para ganhar atenção de alguém. Não sei, talvez seja uma coisa australiana 😉

Tenho programado quase que exclusivamente em C/C++ no último ano. Desculpa, galera, é para isso que eles me pagam 😉 De qualquer modo, os treinamentos continuam em Pascal para fácil entendimento dos principiantes, mas se alguém (ahem Snowman) não começar a convertê-los para C em breve, eu mesmo vou fazer isso. Ele também corrigiu alguns erros que fiz, enquanto convertia, então prefiro que ele faça (ele é como um revisor…)

Mandem-me presentes! É meu aniversário!

Tchauuuu…..

  • Denthor
    16-04-96

(by Krull:
Bom gente, terminou aqui a tradução da série de VGA. Espero que
tenham gostado, e que esse material seja muito útil a vocês.
Um abração)

– Krull
05/fev/2003

A Nova Krull's HomePage