Reputation: 678
I am trying to figure out how to draw a coloured rectangle on an unsigned char
pixel array casted from the pixels
member of a locked SDL_Surface
.
The following function is supposed to do the former:
void draw_rectangle(SDL_Surface* surface, int x, int y, int width, int height)
{
SDL_LockSurface(surface);
//Make each pixel black
std::vector<uint8_t> pixels(surface->h * surface->pitch, 0);
for (int dy = y; dy < height; dy++) {
for (int dx = x; dx < width; dx++) {
pixels[dx + dy] = 0;
pixels[dx + dy + 1] = 255;
pixels[dx + dy + 2] = 0;
}
}
memcpy(surface->pixels, pixels.data(), surface->pitch * surface->h);
SDL_UnlockSurface(surface);
}
It works, but when testing it by converting the modified surface to a texture using SDL_CreateTextureFromSurface
and copying the texture to the screen, it only displays one green pixel:
Upvotes: 5
Views: 4497
Reputation: 678
I have realized that my pointer arithmetic was wrong, I needed to consider the vertical offset, since I am mapping 2D values to single dimensional values. It helps to draft ideas on paper.
Here's the code:
void draw_rectangle(SDL_Surface* surface, int x, int y, int width, int height)
{
SDL_LockSurface(surface);
std::vector<uint8_t> pixels(surface->h * surface->pitch, 0);
int dy, dx;
int maxwidth = width * 3;
for (dy = y; dy < height; dy++) {
for (dx = x; dx < maxwidth; dx += 3) {
pixels[dx + (dy * surface->pitch)] = 0;
pixels[dx + (dy * surface->pitch) + 1] = 255;
pixels[dx + (dy * surface->pitch) + 2] = 0;
}
}
memcpy(surface->pixels, pixels.data(), surface->pitch * surface->h);
SDL_UnlockSurface(surface);
}
Upvotes: 5