Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SDL2 - How to render with one buffer instead of two?

Tags:

c

sdl

sdl-2

In SDL2 I want to be able to draw changes to one buffer rather than redraw the whole image to two different buffers as my setup seems to be doing. Below is a really quick test which shows the unwanted behavior:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <SDL.h>

// Compile: gcc test.c -I/usr/local/include/SDL2 -L/usr/local/lib -lSDL2


void putPixel(SDL_Renderer *renderer, int x, int y)
{
    SDL_SetRenderDrawColor(renderer, 255,255,255,255);
    SDL_RenderDrawPoint(renderer, x, y);
}

int main(int argc, char* argv[]) {

    int width = 640;
    int height = 480;

    SDL_Window *window = SDL_CreateWindow("Test", 0,0,width,height, 0);
    if (window == NULL)
    {
        return -1;
    }
    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    if (renderer == NULL)
    {
        return -2;
    }

    SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_BLEND);

    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);

    for(int x=0;x<8;x++)
    {
        for(int y=0;y<10;y++)
        {
            putPixel(renderer,40+x*10,50+y);
        }

        SDL_RenderPresent(renderer);
        sleep(1);
    }


    SDL_Quit();
    return 0;
}

The output from this is two alternating screens. It is obviously using a double buffer which means I have to clear and redraw to get the output I want. After each cycle of the for...loop I wanted to add a line to the buffer - there should have been 8 lines at the end of the program running. In this case I got 4 on one buffer and 4 on another. I don't want to redraw the previous lines again either, hence the need for one buffer:

Screen 1

Screen 2

like image 236
Phil_12d3 Avatar asked Nov 01 '25 13:11

Phil_12d3


1 Answers

This uses a texture as a buffer and copies this to the screen when done.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <SDL.h>

// Compile: gcc test.c -I/usr/local/include/SDL2 -L/usr/local/lib -lSDL2


void putPixel(SDL_Renderer *renderer, int x, int y)
{
    SDL_SetRenderDrawColor(renderer, 255,255,255,255);
    SDL_RenderDrawPoint(renderer, x, y);
}

int main(int argc, char* argv[]) {

    int width = 640;
    int height = 480;

    SDL_Window *window = SDL_CreateWindow("Test", 0,0,width,height, 0);
    if (window == NULL)
    {
        return -1;
    }
    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
    if (renderer == NULL)
    {
        return -2;
    }

    SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_BLEND);

    /* Create texture for display */
    SDL_Texture *display = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);

    SDL_SetRenderTarget(renderer, display);

    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);

    for(int x=0;x<8;x++)
    {
        SDL_SetRenderTarget(renderer, display);

        for(int y=0;y<10;y++)
        {
            putPixel(renderer,40+x*10,50+y);
        }

        SDL_SetRenderTarget(renderer, NULL);
        SDL_RenderCopy(renderer, display, NULL, NULL);
        SDL_RenderPresent(renderer);
        sleep(1);
    }


    SDL_Quit();
    return 0;
}

The output from this is below:

enter image description here

like image 110
Phil_12d3 Avatar answered Nov 03 '25 04:11

Phil_12d3