In this section, we will examine the program that resizes and moves the main window with window operations, detects whether the mouse is inside the main window, and switches the main window between full screen and normal view with key operations for two different windows.
When the program runs, the following operations are performed in addition to the basic operations:
The content of the main.c file will be as follows:
#include <stdio.h>
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
// Global variables
int is_running = false; // Variable that controls the execution of the main loop of the program
SDL_Window *window = NULL, *window2 = NULL; // Main window variables
SDL_Texture *texture = NULL, *texture2 = NULL; // Texture variables
SDL_Renderer *renderer = NULL, *renderer2 = NULL; // Renderer variables
int window_id, window_id2; // Windows ID
int window_width = 640, window_width2 = 640; // Window width
int window_height = 480, window_height2 = 480; // Window height
int window_x, window_x2; // Window x coordinate
int window_y, window_y2; // Window y coordinate
bool mouse_in, mouse_in2; // Mouse position
bool full_screen, full_screen2; // Full screen control
bool window_show, window_show2; // Show window control
// Function prototypes
int init_window(void);
void init_vars(void);
void load_img(void);
void process_event(void);
void update_screen(void);
void draw_screen(void);
void destroy_window(void);
int main(int argc, char* argv[])
{
// Create window and renderer
is_running = init_window();
// Initialize variables
init_vars();
// Load image
load_img();
// Main loop
while (is_running) {
process_event(); // Processing SDL events (Here keyboard inputs)
update_screen(); // Updating variables
draw_screen(); // Drawing objects on the window (Rendering)
// Application closed all windows
if(window_show==false && window_show2==false) {
is_running = false;
}
}
// Destroy renderer and SDL window
destroy_window();
return 0;
}
// Create window and renderer
int init_window(void)
{
// Initialize the SDL library.
if(SDL_Init(SDL_INIT_VIDEO) == false) {
SDL_Log("SDL init error: %s\n", SDL_GetError());
return false;
}
// Create a window and a 2D rendering context for the window.
if(!SDL_CreateWindowAndRenderer("SDL3 window - 1", window_width, window_height, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
return false;
}
window_id = SDL_GetWindowID(window);
window_show = true;
if(!SDL_CreateWindowAndRenderer("SDL3 window - 2", window_width2, window_height2, SDL_WINDOW_RESIZABLE, &window2, &renderer2)) {
return false;
}
window_id2 = SDL_GetWindowID(window2);
window_show2 = true;
return true;
}
// Initialization function that runs only once at the beginning of the program
void init_vars(void)
{
window_id = -1;
window_id2 = -1;
window_x = 0;
window_x2 = 0;
window_y = 0;
window_y2 = 0;
mouse_in = false;
mouse_in2 = false;
full_screen = false;
full_screen2 = false;
SDL_GetWindowPosition(window, &window_x, &window_y);
SDL_GetWindowPosition(window2, &window_x2, &window_y2);
SDL_SetWindowPosition(window2, window_x2+100, window_y2+100);
}
// Load image
void load_img(void)
{
// Load image to texture
texture = IMG_LoadTexture(renderer, "window_bg.png");
if(texture == NULL) {
SDL_Log("IMG_LoadTexture error: %s\n", SDL_GetError());
}
// Load image to texture
texture2 = IMG_LoadTexture(renderer2, "window_bg2.png");
if(texture2 == NULL) {
SDL_Log("IMG_LoadTexture error: %s\n", SDL_GetError());
}
}
// Function to control SDL events and process keyboard inputs
void process_event(void)
{
SDL_Event event;
// Creating a loop to process user inputs
while (SDL_PollEvent(&event)) {
switch (event.type) {
// Window appeared
case SDL_EVENT_WINDOW_SHOWN:
if(event.window.windowID == window_id) {
window_show = true;
}
else if(event.window.windowID == window_id2) {
window_show2 = true;
}
break;
// Window disappeared
case SDL_EVENT_WINDOW_HIDDEN:
if(event.window.windowID == window_id) {
window_show = false;
}
else if(event.window.windowID == window_id2) {
window_show2 = false;
}
break;
// Get new dimensions and repaint on window size change
case SDL_EVENT_WINDOW_RESIZED:
if(event.window.windowID == window_id) {
window_width = event.window.data1;
window_height = event.window.data2;
SDL_RenderPresent(renderer);
}
else if(event.window.windowID == window_id2) {
window_width2 = event.window.data1;
window_height2 = event.window.data2;
SDL_RenderPresent(renderer2);
}
break;
// Repaint on exposure
case SDL_EVENT_WINDOW_EXPOSED:
if(event.window.windowID == window_id) {
SDL_RenderPresent(renderer);
}
else if(event.window.windowID == window_id2) {
SDL_RenderPresent(renderer2);
}
break;
case SDL_EVENT_WINDOW_MOVED:
if(event.window.windowID == window_id) {
window_x = event.window.data1;
window_y = event.window.data2;
}
else if(event.window.windowID == window_id2) {
window_x2 = event.window.data1;
window_y2 = event.window.data2;
}
break;
case SDL_EVENT_WINDOW_MOUSE_ENTER:
if(event.window.windowID == window_id) {
mouse_in = true;
}
else if(event.window.windowID == window_id2) {
mouse_in2 = true;
}
break;
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
if(event.window.windowID == window_id) {
mouse_in = false;
}
else if(event.window.windowID == window_id2) {
mouse_in2 = false;
}
break;
// Hide on close
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
if(event.window.windowID == window_id) {
SDL_HideWindow(window);
}
else if(event.window.windowID == window_id2) {
SDL_HideWindow(window2);
}
break;
case SDL_EVENT_KEY_DOWN: // Key pressed
switch (event.key.key) {
case SDLK_F:
if(event.window.windowID == window_id) {
if(full_screen) {
SDL_SetWindowFullscreen(window, false);
full_screen = false;
}
else {
SDL_SetWindowFullscreen(window, true);
full_screen = true;
}
}
else if(event.window.windowID == window_id2) {
if(full_screen2) {
SDL_SetWindowFullscreen(window2, false);
full_screen2 = false;
}
else {
SDL_SetWindowFullscreen(window2, true);
full_screen2 = true;
}
}
break;
case SDLK_1:
if(!window_show) {
SDL_ShowWindow(window);
}
SDL_RaiseWindow(window);
break;
case SDLK_2:
if(!window_show2) {
SDL_ShowWindow(window2);
}
SDL_RaiseWindow(window2);
break;
case SDLK_ESCAPE: is_running = false; break;
}
break;
}
}
}
void update_screen(void)
{
char cdizi[100];
sprintf(cdizi, "Window x: %d y: %d width: %d height: %d mouse: %s",
window_x, window_y, window_width, window_height, mouse_in ? "in" : "out");
SDL_SetWindowTitle(window, cdizi);
sprintf(cdizi, "Window2 x: %d y: %d width: %d height: %d mouse: %s",
window_x2, window_y2, window_width2, window_height2, mouse_in2 ? "in" : "out");
SDL_SetWindowTitle(window2, cdizi);
}
// Render function used to draw game objects in the main window
void draw_screen(void)
{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // Set the color used for drawing operations.
SDL_RenderClear(renderer); // Clear the current rendering target with the drawing color.
SDL_FRect rect_dst = { 0, 0, window_width, window_height };
SDL_RenderTexture(renderer, texture, NULL, &rect_dst);
SDL_RenderPresent(renderer); // Update on screen all operations performed since the previous call
SDL_SetRenderDrawColor(renderer2, 0, 0, 0, 255); // Set the color used for drawing operations.
SDL_RenderClear(renderer2); // Clear the current rendering target with the drawing color.
SDL_FRect rect_dst2 = { 0, 0, window_width2, window_height2 };
SDL_RenderTexture(renderer2, texture2, NULL, &rect_dst2);
SDL_RenderPresent(renderer2); // Update on screen all operations performed since the previous call
}
// Destroy Renderer and SDL window, exit from SDL3
void destroy_window(void)
{
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_DestroyTexture(texture2);
SDL_DestroyRenderer(renderer2);
SDL_DestroyWindow(window2);
SDL_Quit();
}