I am 100% sure I have set the SDL library to work properly
#include <iostream>
#include <SDL.h>
using namespace std;
int main(int argc, char* argv\[\]) {
// Initializing SDL
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *window = 0;
// Creating the window
window = SDL_CreateWindow("Hello World", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 640, 480,SDL_WINDOW_SHOWN);
// Just so I can see the window because it goes away immediately.
SDL_Delay(5000);
SDL_Quit();
return 0;
}
After you create the window, you need to handle events using SDL_PollEvent. Instead of SDL_Delay(5000), do something like this:
// ... setup (SDL_Init, SDL_CreateWindow, etc.)
SDL_Event event;
for(;;) {
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT:
goto done;
}
}
}
done:
SDL_Quit();
return 0;
Related
From this Lazy Foo tutorial (https://lazyfoo.net/tutorials/SDL/21_sound_effects_and_music/index.php) I wrote the following lines of code:
#include <SDL.h>
#include <SDL_mixer.h>
bool running = true;
int main(int argc, char** argv) {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
SDL_Window* window = SDL_CreateWindow("testing musique", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, 0);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_Event quit;
Mix_Music* music;
while (running) {
while(SDL_PollEvent(&quit)){
switch(quit.type) {
case SDL_QUIT:
running = false;
break;
}
}
Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);
music = Mix_LoadMUS("../pikachu/keypress_BMP/beat.wav");
Mix_PlayMusic(music, -1);
SDL_SetRenderDrawColor(renderer, 20, 20, 255, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
Mix_FreeMusic(music);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
I even used the same audio file (beat.wav) as Lazy Foo did in his tutorial, but while his program runs without a hitch, mine plays the wav too fast (despite the fact that I checked every parameters to make sure mine matched with his). I tried decreasing the frequency parameter in Mix_OpenAudio, but while the wav did slow down, so did the pitch, and it should not have made sense to do this in the first place. What should I do?
The audio subsystem should only be opened once, before the main loop, meanwhile you open it in each iteration of the loop. The same goes for loading the file into memory — again on each iteration of the loop, instead of once. So the correct code structure should look like this:
#include <SDL.h>
#include <SDL_mixer.h>
int main(int argc, char** argv) {
bool running = true;
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
SDL_Window* window = SDL_CreateWindow("testing musique", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, 0);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
// open audio and load music file before main loop
Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);
Mix_Music* music = Mix_LoadMUS("../pikachu/keypress_BMP/beat.wav");
SDL_Event event;
while (running) {
while(SDL_PollEvent(&event)){
switch(event.type) {
case SDL_KEYDOWN:
switch(event.key.keysym.sym) {
case SDLK_P:
Mix_PlayMusic(music, -1);
break;
case SDLK_S:
Mix_HaltMusic();
break;
}
case SDL_QUIT:
running = false;
break;
}
}
SDL_SetRenderDrawColor(renderer, 20, 20, 255, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
// close audio and free the music after main loop
Mix_CloseAudio();
Mix_FreeMusic(music);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
Don't forget about Mix_CloseAudio and about error checking.
I know this question has been asked before but most of the time answer was just to add delay or an event loop. However I have added an event loop and the window ist not showing. Only the console. I am running this program in Visual Studio 2019.
#include <iostream>
#include "GL/glew.h"
#define SDL_MAIN_HANDLED
#include "SDL.h"
int main() {
SDL_Window* window;
SDL_Init(SDL_INIT_EVERYTHING);
//fenster erstellen
window = SDL_CreateWindow("C++ OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_OPENGL);
//opengl context setzen
SDL_GLContext glContext = SDL_GL_CreateContext(window);
bool close = false;
while (!close) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
close = true;
}
}
if (close) {
break;
}
}
return 0;
}
You need to include SDL_MainReady as you are not using SDL_main.
See here
So you code would be adjusted like
int main() {
SDL_Window* window;
SDL_SetMainReady();
SDL_Init(SDL_INIT_EVERYTHING);
...
return 0;
}
I'm doing Lazy Foo's tutorial on SDL (I'm using SDL2-2.0.9), and at the texture rendering part I encountered the following problem: the program compiles and runs as expected, no issue here, but when I close the window, the console doesn't close and the process continues running, so I have to close the console separately.
When I tried to debug it, I found out that the program indeed leaves the main cycle and reaches the "return 0" line in the main function successfully, but then it just hangs like that until I close the console.
The issue is only present when I use the SDL renderer with any option other than SDL_RENDERER_SOFTWARE. If I use SDL_RENDERER_SOFTWARE - the program closes as expected. With other options it stays at "return 0" running other threads (crypt32.dll, ntdll.dll and nvd3dum, in this order in the thread view, meaning that the process is stuck in crypt32).
I'm aware that my main function is not the "real main" as it has been hijacked by SDL, so exit(0) works fine as an ad-hoc solution. But I want to know, why exactly does that happen and is there any other way to fix this, so that I don't have to use exit(0) ?
Here is an example (simplified) code, which demonstrates this issue for me:
#include "SDL.h"
#include <stdio.h>
int main(int argc, char *argv[]) {
SDL_Window *win = NULL;
SDL_Renderer *renderer = NULL;
SDL_Texture *bitmapTex = NULL;
SDL_Surface *bitmapSurface = NULL;
int width = 640, height = 480;
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("Could not initialize SDL");
return 1;
}
win = SDL_CreateWindow("Hello World", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, 0);
renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
bitmapSurface = SDL_LoadBMP("res/x.bmp");
bitmapTex = SDL_CreateTextureFromSurface(renderer, bitmapSurface);
SDL_FreeSurface(bitmapSurface);
bool quit = false;
while (!quit) {
SDL_Event e;
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) {
quit = true;
}
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, bitmapTex, NULL, NULL);
SDL_RenderPresent(renderer);
}
SDL_DestroyTexture(bitmapTex);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(win);
SDL_Quit();
printf("REACHED RETURN 0");
return 0;
}
Works as intended, but after closing the window I see "REACHED RETURN 0" printed in console and that's it, the console stays there. The code can be simplified further, the issue will be present as long as there is an instance of SDL_Renderer created.
UPD: The callstack during the hanging:
> ntdll.dll!_NtWaitForMultipleObjects#20()
KernelBase.dll!_WaitForMultipleObjectsEx#20()
crypt32.dll!ILS_WaitForThreadProc()
kernel32.dll!#BaseThreadInitThunk#12()
ntdll.dll!__RtlUserThreadStart()
ntdll.dll!__RtlUserThreadStart#8()
UPD2: The problem is not with the loop at all, I created the simplest application where I just create a window and a renderer and then return 0, it still gives me a hanging console. Like this:
#include <SDL.h>
int main(int argc, char* args[])
{
if (SDL_Init(SDL_INIT_VIDEO) < 0) return 1;
SDL_Window* window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
return 0;
}
Same thing when I destroy them properly. The problem is in the renderer.
UPD3: Here is the Parallel Stack window during the "hanging". There is no "main" thread since I close it successfully, these are the threads which stop the program from closing properly. Other than that, it doesn't give me any understanding of the problem.
I wanted to start working on SDL. I got a sample code to see if it worked fine. When compiling I get no errors, but when I run it the window shows up but the program freezes until the delay time is over.
I'm new to this so I would really appreciate some help.
int main(int argc, char* argv[]) {
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *window = 0;
window = SDL_CreateWindow("Hello World!",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
640, 480,
SDL_WINDOW_SHOWN);
SDL_Delay(10000);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
As mentioned by #HolyBlackCat, you need an event loop :
https://wiki.libsdl.org/SDL_PollEvent
It should look something like this :
while (true) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
/* handle your event here */
}
/* do some other stuff here -- draw your app, etc. */
}
Edit
You will need to replace your delay with the event loop.
Instead, you can close the application on an event. The least you can/should do, is handle the SDL_QUIT event, which is sent when the user try to close the window:
while (!quit) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
/* handle your event here */
//User requests quit
if( event.type == SDL_QUIT )
quit = true;
}
/* do some other stuff here -- draw your app, etc. */
}
I am just now learning SDL and have downloaded the libraries and added them to my linker, etc with MinGW and I am trying to run a simple demo program to display a window and it will not show up at all. I get no errors at all, the window just doesn't show up.
#include "SDL.h"
#include <stdio.h>
int main(int argc, char* argv[]) {
SDL_Window *window; // Declare a pointer
SDL_Init(SDL_INIT_VIDEO); // Initialize SDL2
// Create an application window with the following settings:
window = SDL_CreateWindow(
"An SDL2 window", // window title
SDL_WINDOWPOS_UNDEFINED, // initial x position
SDL_WINDOWPOS_UNDEFINED, // initial y position
640, // width, in pixels
480, // height, in pixels
SDL_WINDOW_OPENGL // flags - see below
);
// Check that the window was successfully created
if (window == NULL) {
// In the case that the window could not be made...
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
// The window is open: could enter program loop here (see SDL_PollEvent())
SDL_Delay(3000); // Pause execution for 3000 milliseconds, for example
// Close and destroy the window
SDL_DestroyWindow(window);
// Clean up
SDL_Quit();
return 0;
}
I just tested this on Linux and MinGW. It may be a problem with SDL_Delay blocking before the window gets a chance to show. Try adding a basic main loop to see if it works. This will create an empty window.
#include "SDL.h"
#include <stdio.h>
int main(int argc, char* argv[]) {
SDL_Window *window; // Declare a pointer
SDL_Init(SDL_INIT_VIDEO); // Initialize SDL2
// Create an application window with the following settings:
window = SDL_CreateWindow(
"An SDL2 window", // window title
SDL_WINDOWPOS_UNDEFINED, // initial x position
SDL_WINDOWPOS_UNDEFINED, // initial y position
640, // width, in pixels
480, // height, in pixels
SDL_WINDOW_OPENGL // flags - see below
);
// Check that the window was successfully created
if (window == NULL) {
// In the case that the window could not be made...
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
// A basic main loop to prevent blocking
bool is_running = true;
SDL_Event event;
while (is_running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
is_running = false;
}
}
SDL_Delay(16);
}
// Close and destroy the window
SDL_DestroyWindow(window);
// Clean up
SDL_Quit();
return 0;
}