diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7a3498a1d..fb4db69fa 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -123,6 +123,7 @@ endmacro() add_sdl_example_executable(renderer-clear SOURCES renderer/01-clear/renderer-clear.c) add_sdl_example_executable(renderer-primitives SOURCES renderer/02-primitives/renderer-primitives.c) add_sdl_example_executable(renderer-lines SOURCES renderer/03-lines/renderer-lines.c) +add_sdl_example_executable(renderer-points SOURCES renderer/04-points/renderer-points.c) add_sdl_example_executable(audio-simple-playback SOURCES audio/01-simple-playback/simple-playback.c) add_sdl_example_executable(audio-simple-playback-callback SOURCES audio/02-simple-playback-callback/simple-playback-callback.c) add_sdl_example_executable(audio-load-wav SOURCES audio/03-load-wav/load-wav.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.wav) diff --git a/examples/renderer/02-primitives/README.txt b/examples/renderer/02-primitives/README.txt index 1e2bfce8b..82da8e52f 100644 --- a/examples/renderer/02-primitives/README.txt +++ b/examples/renderer/02-primitives/README.txt @@ -1,3 +1,7 @@ This example creates an SDL window and renderer, and then draws some lines, rectangles and points to it every frame. +This is just a quick overview of simple drawing primitives; futher examples +will explore them in more detail. + + diff --git a/examples/renderer/03-lines/renderer-lines.c b/examples/renderer/03-lines/renderer-lines.c index b2c8cf2cc..459af73d1 100644 --- a/examples/renderer/03-lines/renderer-lines.c +++ b/examples/renderer/03-lines/renderer-lines.c @@ -56,7 +56,7 @@ SDL_AppResult SDL_AppIterate(void *appstate) }; /* as you can see from this, rendering draws over whatever was drawn before it. */ - SDL_SetRenderDrawColor(renderer, 100, 100, 100, 255); /* black, full alpha */ + SDL_SetRenderDrawColor(renderer, 100, 100, 100, 255); /* grey, full alpha */ SDL_RenderClear(renderer); /* start with a blank canvas. */ /* You can draw lines, one at a time, like these brown ones... */ diff --git a/examples/renderer/04-points/README.txt b/examples/renderer/04-points/README.txt new file mode 100644 index 000000000..00e941911 --- /dev/null +++ b/examples/renderer/04-points/README.txt @@ -0,0 +1,3 @@ +This example creates an SDL window and renderer, and then draws a bunch of +single points, moving across the screen. + diff --git a/examples/renderer/04-points/renderer-points.c b/examples/renderer/04-points/renderer-points.c new file mode 100644 index 000000000..468a30abd --- /dev/null +++ b/examples/renderer/04-points/renderer-points.c @@ -0,0 +1,118 @@ +/* + * This example creates an SDL window and renderer, and then draws some points + * to it every frame. + * + * This code is public domain. Feel free to use it for any purpose! + */ + +#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ +#include +#include + +/* We will use this renderer to draw into this window every frame. */ +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static Uint64 last_time = 0; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 + +#define NUM_POINTS 500 +#define MIN_PIXELS_PER_SECOND 30 /* move at least this many pixels per second. */ +#define MAX_PIXELS_PER_SECOND 60 /* move this many pixels per second at most. */ + +/* (track everything as parallel arrays instead of a array of structs, + so we can pass the coordinates to the renderer in a single function call.) */ + +/* Points are plotted as a set of X and Y coordinates. + (0, 0) is the top left of the window, and larger numbers go down + and to the right. This isn't how geometry works, but this is pretty + standard in 2D graphics. */ +static SDL_FPoint points[NUM_POINTS]; +static float point_speeds[NUM_POINTS]; + +/* This function runs once at startup. */ +SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) +{ + int i; + + if (!SDL_Init(SDL_INIT_VIDEO)) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't initialize SDL!", SDL_GetError(), NULL); + return SDL_APP_FAILURE; + } + + if (!SDL_CreateWindowAndRenderer("examples/renderer/points", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window/renderer!", SDL_GetError(), NULL); + return SDL_APP_FAILURE; + } + + SDL_srand(0); /* seed the random number generator */ + + /* set up the data for a bunch of points. */ + for (i = 0; i < SDL_arraysize(points); i++) { + points[i].x = SDL_randf() * ((float) WINDOW_WIDTH); + points[i].y = SDL_randf() * ((float) WINDOW_HEIGHT); + point_speeds[i] = MIN_PIXELS_PER_SECOND + (SDL_randf() * (MAX_PIXELS_PER_SECOND - MIN_PIXELS_PER_SECOND)); + } + + last_time = SDL_GetTicks(); + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + if (event->type == SDL_EVENT_QUIT) { + return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ + } + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once per frame, and is the heart of the program. */ +SDL_AppResult SDL_AppIterate(void *appstate) +{ + const Uint64 now = SDL_GetTicks(); + const float elapsed = ((float) (now - last_time)) / 1000.0f; /* seconds since last iteration */ + int i; + + /* let's move all our points a little for a new frame. */ + for (i = 0; i < SDL_arraysize(points); i++) { + const float distance = elapsed * point_speeds[i]; + points[i].x += distance; + points[i].y += distance; + if ((points[i].x >= WINDOW_WIDTH) || (points[i].y >= WINDOW_HEIGHT)) { + /* off the screen; restart it elsewhere! */ + if (SDL_rand(2)) { + points[i].x = SDL_randf() * ((float) WINDOW_WIDTH); + points[i].y = 0.0f; + } else { + points[i].x = 0.0f; + points[i].y = SDL_randf() * ((float) WINDOW_HEIGHT); + } + point_speeds[i] = MIN_PIXELS_PER_SECOND + (SDL_randf() * (MAX_PIXELS_PER_SECOND - MIN_PIXELS_PER_SECOND)); + } + } + + last_time = now; + + /* as you can see from this, rendering draws over whatever was drawn before it. */ + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); /* black, full alpha */ + SDL_RenderClear(renderer); /* start with a blank canvas. */ + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); /* white, full alpha */ + SDL_RenderPoints(renderer, points, SDL_arraysize(points)); /* draw all the points! */ + + /* You can also draw single points with SDL_RenderPoint(), but it's + cheaper (sometimes significantly so) to do them all at once. */ + + SDL_RenderPresent(renderer); /* put it all on the screen! */ + + return SDL_APP_CONTINUE; /* carry on with the program! */ +} + +/* This function runs once at shutdown. */ +void SDL_AppQuit(void *appstate) +{ + /* SDL will clean up the window/renderer for us. */ +} +