Como Desenhar Retângulos
O primeiro passo para começar a desenhar o player é através de posições min e max de pixels, que no futuro, virará sprites.
Vamos criar a função que permita receber valores minimos, máximos e checar as bordas para não desenhar fora do buffer.
internal void
draw_rect(Game_Back_Buffer *buffer,
f32 min_x, f32 min_y, f32 max_x, f32 max_y,
f32 r, f32 g, f32 b)
{
s32 x_min = (s32) roundFloat(min_x);
s32 y_min = (s32) roundFloat(min_y);
s32 x_max = (s32) roundFloat(max_x);
s32 y_max = (s32) roundFloat(max_y);
if (x_min < 0) x_min = 0;
if (y_min < 0) y_min = 0;
if (x_max > buffer->width) x_max = buffer->width;
if (y_max > buffer->height) y_max = buffer->height;
u32 color =
((u32) roundFloat(r * 255.0f) << 16) |
((u32) roundFloat(g * 255.0f) << 8) |
((u32) roundFloat(b * 255.0f) << 0);
u8 *row = buffer->memory
+ x_min * buffer->bytes_per_pixel
+ y_min * buffer->pitch;
for (s32 y = y_min; y < y_max; y++) {
u32 *pixel = (u32 *) row;
for (s32 x = x_min; x < x_max; x++) {
*pixel++ = color;
}
row += buffer->pitch;
}
}
Note o roundFloat e os valores definidos em float.
Cada coordenada de pixel, é um número inteiro não divisível.
No entanto, a maioria dos renderizadores trabalha com elas usando números decimais. Geralmente, isso permite um movimento mais fluido dos sprites na tela.
Cada pixel aceita apenas uma cor. Seria útil ter uma convenção forte sobre como este sprite influencia os pixels da borda com suas cores.
Se quiséssemos preencher de (2, 1) a (5, 4), desenharíamos apenas uma parte dessas cores para uma transição suave. Visto que subdividimos os pixels e arrendondamos quando for acima 0.5.
Segue o código para arrendodamento de maneira simples e eficaz.
inline f32 roundFloat(f32 value)
{
return (value + 0.5f);
}