I'm following this tutorial that teaches how to use SDL2 with the final goal of learning C++ in a more fun and interactive way.
For this, I only need to be able to draw lines, polygons and circles.
So, after reading part 1 that explains how to create a window on the screen and part 3 that introduces event handling, I headed torward part 7 and 8 that explain, respectively, how to create a renderer and how to draw a rectangle on the screen. This is the code I've got so far (it isn't exactly the same as the code on the tutorial: I've introduced a struct to pass SDL objects around and removed all the error handling which was confusing):
#include <SDL2/SDL.h>
//screen dimensions costants
#define SCREEN_WIDTH 540
#define SCREEN_HEIGHT 960
//data structure holding the objects needed to create a window and draw on it
struct interface {
SDL_Window * window = NULL;
SDL_Surface * surface = NULL;
SDL_Renderer * renderer = NULL;
};
//function which inits the sdl and creates an interface object
interface init() {
interface screen;
SDL_Init(SDL_INIT_VIDEO);
screen.window = SDL_CreateWindow("", 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
screen.surface = SDL_GetWindowSurface(screen.window);
screen.renderer = SDL_CreateRenderer(screen.window, -1, SDL_RENDERER_ACCELERATED);
return screen;
}
//function to free the memory and close the sdl application
void close(interface screen) {
SDL_DestroyRenderer(screen.renderer);
SDL_DestroyWindow(screen.window);
screen.renderer = NULL;
screen.window = NULL;
SDL_Quit();
}
int main(int argc, char* args[]) {
//start the application
interface screen = init();
//setup for event handling
bool quit = false;
SDL_Event event;
//the shape to render
SDL_Rect fillRect = { SCREEN_WIDTH / 4, SCREEN_HEIGHT / 4, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 };
//main loop which first handles events
while (!quit) {
while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT)
quit = true;
}
//should draw a red rectangle on the screen
SDL_SetRenderDrawColor(screen.renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(screen.renderer);
SDL_SetRenderDrawColor(screen.renderer, 0xFF, 0x00, 0x00, 0xFF);
SDL_RenderFillRect(screen.renderer, &fillRect);
}
//End the application
close(screen);
return 0;
}
The problem is that, as it is, the program draws nothing to the screen (which remains black), and if I remove the line screen.surface = SDL_GetWindowSurface(screen.window);
it also begins lagging a lot in a manner I even find difficult to exit the application.
Note that I'm programming on Android using C4droid and the SDL Plugin for C4droid.
Why is that happening? What am I doing wrong?
EDIT Problem solved by renaming close
to end
and by including a call to SDL_RenderPresent(screen.renderer);
at the end of the main loop. With this setup the screen surface has to be deleted or the program won't draw anything.
Thanks to @keltar and @Wutipong Wongsakuldej for answering the question in the comments
First of all I tested the code in Windows (MSYS2) rather than on Android as I don't have AIDE installed at the moment.
Basically I added 2 lines of code into the main loop :
//main loop which first handles events
while (!quit) {
while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT)
quit = true;
}
//should draw a red rectangle on the screen
SDL_SetRenderDrawColor(screen.renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(screen.renderer);
SDL_SetRenderDrawColor(screen.renderer, 0xFF, 0x00, 0x00, 0xFF);
SDL_RenderFillRect(screen.renderer, &fillRect);
/** below lines are added **/
SDL_RenderPresent(screen.renderer);
SDL_Delay(0);
}
SDL_RenderPresent
draw whatever you've renderred so far to the screen. This make the output shows up.
SDL_Delay()
this is added to give the cpu time back to the os. Without this your app might become unresponsive and the cpu utilization will be 100% (at one core) in some operating system (especially the very old one). I don't know if this is needed in Android or not anyway. Give it a try.