0% found this document useful (0 votes)
13 views

C - SDL2 - How To Render With One Buffer Instead of Two - Stack Overflow

Some female
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views

C - SDL2 - How To Render With One Buffer Instead of Two - Stack Overflow

Some female
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

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

Asked 10 years, 5 months ago Modified 9 years, 1 month ago Viewed 5k times

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
4 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:

c sdl sdl-2
Share Improve this question Follow edited Feb 27, 2015 at 12:12 asked Nov 12, 2013 at 17:20
Martin G Phil_12d3
17.7k 10 84 100 398 7 18

You're better off creating a small compilable sample that demonstrates your issues. It's very hard for anyone to tell
what you do, how often you do it, when you do it and so on, with only a couple of lines of code and a lot of textual
explanation. – nos Nov 19, 2013 at 11:20

There are a lot of reasons why single-buffering is bad. Offscreen render target is your best shot here. – keltar Nov
19, 2013 at 11:25

@keltar out of interest, what are those reasons? Also, isn't that what i'm doing by using a texture? I'm about to
update the question with more code and better layout. – Phil_12d3 Nov 19, 2013 at 12:09

I've edited question to clarify and to show what I have found so far. Is there a better way to do this? The point of
one buffer is so that i'm only making changes to areas of the screen that need updating - I don't want to redraw the
whole screen. – Phil_12d3 Nov 19, 2013 at 12:32

@Phil_12d3 not literally the same. Your texture acts like backbuffer. However, when there is no backbuffer (by-the-
book single-buffering, drawing directly on screen), you likely to notice a lot of flickering or other visual defects.
– keltar Nov 20, 2013 at 3:09

@keltar It's not direct drawing to the screen I want. I just don't want double buffering. I still want a backbuffer as you
put it, but just one. My original approach seemed to give me two, as shown in my screenshot. – Phil_12d3 Nov
20, 2013 at 8:59

After doing more readying, this does seem the best way to do it. I'm still open to opinion, but i've moved my solution
to be the answer. – Phil_12d3 Nov 20, 2013 at 9:06

@Phil_12d3 in double buffering, you drawing to back buffer (off screen), then swapping buffers. After swap, back
buffer becomes front and vice versa, so contents swaps too. This is core idea of double buffering, falling back to
single buffer will result in drawing directly on screen. There is also a tripple buffering, but it doesn't make much
sense here. Your shadow buffer is just a copy you need; this is the most logical way to do so and it have minimal
performance impact. – keltar Nov 20, 2013 at 9:51

1 Answer Sorted by: Highest score (default)

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

8 #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:


Share Improve this answer Follow edited Nov 20, 2013 at 9:12 answered Nov 20, 2013 at 9:04
Phil_12d3
398 7 18

You might also like