edition
edition

Reputation: 678

Drawing a rectangle on SDL_Surface pixels

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:

window screenshot

Upvotes: 5

Views: 4497

Answers (1)

edition
edition

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);
}

screenshot

Upvotes: 5

Related Questions