Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing a rectangle with SDL2

Tags:

I just started using SDL2 and I already have a problem. I want to create a window and paint it in red. But it remains white, and I don't understand why.

Here is the code :

int main (int argc, char** argv) {
    SDL_Window* pWindow = NULL;
    pWindow = SDL_CreateWindow("Jeu de la vie", SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        640,
        480,
        SDL_WINDOW_SHOWN);

    SDL_Surface* pSurface = NULL;
    pSurface = SDL_GetWindowSurface(pWindow);
    SDL_FillRect(pSurface, NULL, SDL_MapRGB(pSurface->format, 255, 0, 0));

    while(1);

    SDL_FreeSurface(pSurface);
    SDL_DestroyWindow(pWindow);
    SDL_Quit();
    return EXIT_SUCCESS;
}
like image 476
Utundu Avatar asked Feb 19 '14 19:02

Utundu


People also ask

How do you draw a line in SDL?

SDL_RenderDrawLine() draws the line to include both end points. If you want to draw multiple, connecting lines use SDL_RenderDrawLines() instead.

What does SDL2 use to render?

Yes, SDL uses the GPU for 2D rendering if it can. Ok awesome.

How do I render text in SDL?

One way to render text with SDL is with the extension library SDL_ttf. SDL_ttf allows you to create images from TrueType fonts which we'll use here to create textures from font text. To use SDL_ttf, you have to set up the SDL_ttf extension library just like you would set up SDL_image.


1 Answers

There are several issues with your code, I'll try to address most of them.

Initialize SDL

SDL and SDL2 needs to be initialized before you can use it. The way to initialize SDL is the following function.

int SDL_Init(Uint32 flags)

Where flags can be a different value for different subsystems. Use SDL_INIT_EVERYTHING, to initialize everything.

int SDL_Init(SDL_INIT_EVERYTHING)

Read more about it here..


Initialize SDL_Window and SDL_Renderer

SDL_Renderer and SDL_Window needs to be set up before you can use them. You already create your window properly, so I won't cover that. Here's how to set up an SDL_Renderer

SDL_Renderer* SDL_CreateRenderer(SDL_Window* window,
                                 int         index,
                                 Uint32      flags)

index defines what driver to use. Set it to -1 to use the first driver that supports the other arguments.
flags are used to make the rendering optimized, software rendiring, prevent vsync, etc.. Set it to SDL_RENDERER_ACCELERATED.

Read more about SDL_CreateRenderer here.

Mixing SDL and SDL2

SDL_Surface is primarily something used in SDL, not SDL2. SDL2_image, SDL2_ttf etc still used SDL_Surface, but they are converted into an SDL_Texture before they can be used.

SDL_FillRect(...); is also mostly a SDL thing. But as stated above, the SDL_Surface can be used, but you need to convert it to an SDL_Texture first :

SDL_Texture* SDL_CreateTextureFromSurface(SDL_Renderer* renderer,
                                          SDL_Surface*  surface)

Read more here.

And use

int SDL_RenderCopy(SDL_Renderer*   renderer,
                   SDL_Texture*    texture,
                   const SDL_Rect* srcrect,
                   const SDL_Rect* dstrect)

To render it, read more here.

Infinite loop ( while(1); )

You REALLY shouldn't do this, it'll just loop forever. Use SDL_Delay( 5000 ); to pause for 5000msec or 5 seconds.

A simpler way

You can use

int SDL_RenderDrawRect(SDL_Renderer*   renderer,
                       const SDL_Rect* rect)

To draw a rect.

You should use

int SDL_SetRenderDrawColor(SDL_Renderer* renderer,
                           Uint8         r,
                           Uint8         g,
                           Uint8         b,
                           Uint8         a)

To set the color of what you are drawing, use

int SDL_RenderClear(SDL_Renderer* renderer)

After which you call your SDL_RenderDrawRect()

Up until this point, everything has been drawn "behind the scenes." To render it to the screen, use

void SDL_RenderPresent(SDL_Renderer* renderer)

Example

#include <SDL2/SDL.h>

int main (int argc, char** argv)
{
    SDL_Window* window = NULL;
    window = SDL_CreateWindow
    (
        "Jeu de la vie", SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        640,
        480,
        SDL_WINDOW_SHOWN
    );

    // Setup renderer
    SDL_Renderer* renderer = NULL;
    renderer =  SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED);

    // Set render color to red ( background will be rendered in this color )
    SDL_SetRenderDrawColor( renderer, 255, 0, 0, 255 );

    // Clear winow
    SDL_RenderClear( renderer );

    // Creat a rect at pos ( 50, 50 ) that's 50 pixels wide and 50 pixels high.
    SDL_Rect r;
    r.x = 50;
    r.y = 50;
    r.w = 50;
    r.h = 50;

    // Set render color to blue ( rect will be rendered in this color )
    SDL_SetRenderDrawColor( renderer, 0, 0, 255, 255 );

    // Render rect
    SDL_RenderFillRect( renderer, &r );

    // Render the rect to the screen
    SDL_RenderPresent(renderer);

    // Wait for 5 sec
    SDL_Delay( 5000 );

    SDL_DestroyWindow(window);
    SDL_Quit();

    return EXIT_SUCCESS;
}

Result

Rendered result


You can read more about SDL2 on my blog.

like image 86
olevegard Avatar answered Oct 10 '22 05:10

olevegard