Para colocarmos um pixel de determinada cor na tela precisamos implementar uma função que receba a posição do pixel em coordenadas x,y e sua cor em RGBA. Vamos falar um pouco sobre esse sistema de cores.
O sistema RGBA contém quatro canais: R(red), G(green), B(blue), A(alpha), que são valores numéricos que, para o projeto, variam de 0 a 255. Cada um dos três primeiros canais define a intensidade luminosa das três cores primárias que temos em um pixel na tela do computador. Por exemplo, se tivermos o canal R com um valor de 255 e os outros dois canais de cores primárias com 0, o pixel ficará vermelho. Se todas os três canais receberem 255, teremos o branco, e se todos receberem 0, teremos o preto. Assim, a mistura de diferentes intensidades de cada cor primária gera as diferentes cores que podemos enxergar! O último canal, Alpha, determina a "transparência" da cor do pixel, mas não vamos utilizar ele neste projeto.
Então, precisamos de quatro variáveis para representar a cor de um pixel. Vamos definir um novo tipo de variável para facilitar testes no futuro, o tipo cor:
struct cor{ float r; float g; float b; float a = 255; };
Definimos as cores como float pois vamos modificá-las quando estivermos fazendo a interpolação linear. Como não vamos utilizar o canal Alpha, podemos definir ele como sendo sempre 255, ou seja, a cor do pixel é completamente opaca.
Agora, por conveniência, vamos inicializar algumas variáveis do tipo cor para fazermos testes no futuro:
cor white = (white = cor(), white.r = 255, white.g = 255, white.b = 255, white); cor red = (red = cor(), red.r = 255, red.g = 0, red.b = 0, red); cor green = (green = cor(), green.r = 0, green.g = 255, green.b = 0, green); cor blue = (blue = cor(), blue.r = 0, blue.g = 0, blue.b = 255, blue);
Um dos problemas que eu encontrei foi como definir e inicializar variáveis desse struct, já que o código é em C++. Assim é feio, mas funciona.
Pronto, temos cores, agora vamos ver como escrever esses valores na "memória de vídeo" fake do framework. Sabendo que cada canal pode varias entre 0 e 255, temos 256 estados possíveis para cada canal, ou seja, podemos utilizar 1 byte para cada um dos quatro canais de cor, totalizando 4 bytes por pixel.
Para calcular em que posição de memória devemos escrever os valores de cada, utilizamos a equação
4*(Posição x do pixel) + 4*(Posição y do pixel)*(Largura da tela) + 0, 1, 2 ou 3, dependendo de qual canal queremos escrever na memória.
Assim, podemos finalmente implementar a função PutPixel em toda sua glória:
void PutPixel(int x, int y, cor color){ FBptr[4*x + 4*y*IMAGE_WIDTH + 0] = color.r; // componente R FBptr[4*x + 4*y*IMAGE_WIDTH + 1] = color.g; // componente G FBptr[4*x + 4*y*IMAGE_WIDTH + 2] = color.b; // componente B FBptr[4*x + 4*y*IMAGE_WIDTH + 3] = color.a; // componente A }
A função recebe a coordenada x,y do pixel e uma variável tipo cor, escrevendo na memórias os valores de cada canal de color. O comando FBptr faz parte da framework do professor. IMAGE_WIDTH é definido em definitions.h como o número de colunas na tela, ou largura da tela, com valor 512.
Referências: Material do professor Christian.
Referências: Material do professor Christian.
Álbum da vez:

Nenhum comentário:
Postar um comentário