Share code to draw using SDL

Programming, for all ages and all languages.
Post Reply
User avatar
~
Member
Member
Posts: 1225
Joined: Tue Mar 06, 2007 11:17 am
Freenode IRC: ArcheFire

Share code to draw using SDL

Post by ~ »

So far, I use Windows, and the MSYS 1.0 that comes with MinGW to compile.

I can compile this SDL skeleton (with SDL 1, most surely also with SDL 2):

Code: Select all

#include <SDL.h>

int main( int argc, char* args[] )
{
 //Start SDL
 ///
  SDL_Init( SDL_INIT_EVERYTHING );

 //Quit SDL
 ///
  SDL_Quit();

 return 0;
}


This video shows how to compile it:

http://lazyfoo.net/SDL_tutorials/lesson ... /index.php

Download SDL 1:
https://www.libsdl.org/download-1.2.php

Commands:
SDLCFLAGS=$(sdl-config --cflags)
SDLLIBS=$(sdl-config --libs)
gcc HelloSDL.cpp -o HelloSDL.exe $SDLCFLAGS $SDLLIBS
HelloSDL.exe

Now I want to know how I can create a window and draw generic stuff, like pixels, to the SDL window.

Can you share some clear code so I can do that, just creating the SDL window and drawing in it?
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: Share code to draw using SDL

Post by BrightLight »

~ wrote:Can you share some clear code so I can do that, just creating the SDL window and drawing in it?
The SDL documentation isn't that bad. Other SDL examples/tutorials aren't bad either and serve as a proper starting point.

Anyways...

Code: Select all

SDL_Window *window;
SDL_Surface *surface;
uint32_t *framebuffer;		// pointer to raw pixel buffer that you can read/write

int init()
{
	// initialize the video subsystem
	if(SDL_Init(SDL_INIT_VIDEO) < 0)
		return 1;

	// make a window
	SDL_Window *window;
	window = SDL_CreateWindow("Window title", x_position, y_position, width, height, SDL_WINDOW_SHOWN);

	// ensure window handle is valid
	if(!window)
		return 1;

	// a surface is a group of pixels displayed on screen
	// return the window's surface
	SDL_Surface *surface;
	surface = SDL_GetWindowSurface(window);

	// ensure compatible surface
	// here, we're looking at a 32-bit little endian RGB buffer
	// basically, the bytes should be BB GG RR 00
	if(surface->format->BitsPerPixel != 32 || surface->format->BytesPerPixel != 4 || surface->format->Rmask != 0xFF0000 || surface->format->Gmask != 0x00FF00 || surface->format->Bmask != 0x0000FF)
		return 1;

	// set up the pointer to the framebuffer
	framebuffer = surface->pixels;

	while(1)
	{
		handle_events();
	}
}

// sample put pixel, assumes 32-bit little endian RGB as we verified above^^

void put_pixel(short x, short y, uint32_t color)
{
	// calculate pixel offsets just like any other graphics programming
	uint32_t *ptr = ((y * (width << 2)) + (x << 2) + framebuffer);

	// to modify pixels yourself, you need to lock the surface to be safe
	SDL_LockSurface(surface);

	ptr[0] = color;		// write the pixel

	// redraw
	SDL_UnlockSurface(surface);
	SDL_UpdateWindowSurface(window);
}

Notice the function "handle_events" must handle the SDL events. SDL, in my experience, doesn't let the window display any changes unless its events are being handled, which makes sense, really.

Of course, you don't need to verify a 32-bit little-endian RGB surface, but I just do it this way out of laziness. Instead, you can implement support for multiple surface formats, to ensure maximum compatibility.

EDIT: I'm not sure if this works for SDL1, as I only ever used SDL2.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Post Reply