I have been trying for hours to get a test SDL program up and running, but no matter what I try, it instantly terminates upon launching.
My code:
#include <iostream>
#include <SDL.h>
#undef main
using namespace std;
int main(int argc, char *argv[]) {
const int WIDTH = 800, HEIGHT = 600, SDLWP = SDL_WINDOWPOS_UNDEFINED;
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
cout << "SDL not working." << endl;
}
cout << "SDL working properly." << endl;
SDL_Window *window = SDL_CreateWindow("Test", SDLWP, SDLWP, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
if(window == NULL) {
SDL_Quit();
}
bool quit = false;
SDL_Event event;
while(!quit) {
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) {
quit = true;
}
}
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
I have gotten the program to actually do something by having this code:
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
cout << "SDL working properly." << endl;
}
Also, about the #undef main part, I need that because otherwise, the program will think that I am calling SDL_main.
Here is the library search path if that helps:
C:\Users\ (my username)\Desktop\SDL2-2.0.4\i686-w64-mingw32\lib
And the libraries themselves, written in order from top to bottom:
mingw32
SDL2main
SDL2
No other library path will give me no compiler errors except:
C:\Users\ (my username)\Desktop\SDL2-2.0.4\lib\x86
So it seems that the root of problem is:
#include <SDL.h>
Related
This question already has answers here:
How do I use SDL2 in my programs correctly?
(3 answers)
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 months ago.
I've got the following piece of code attempting to use SDL_image;
#include <iostream>
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <SDL_image.h>
int WIDTH = 800;
int HEIGHT = 800;
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) > 0) {
std::cout << "SDL INIT FAILED" << SDL_GetError() << std::endl;
}
SDL_Window* window = SDL_CreateWindow("Chaturanga", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (NULL == window)
{
std::cout << "Could not create window: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Texture* boardTexture = IMG_LoadTexture(renderer, "res/images/board.png");
if (boardTexture == NULL) {
std::cout << "Failed to load texture. Error: " << SDL_GetError() << std::endl;
}
SDL_Event windowEvent;
while (true)
{
if (SDL_PollEvent(&windowEvent))
{
if (SDL_QUIT == windowEvent.type)
{break;}
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, boardTexture, NULL, NULL);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
When I compile with:
g++ src/*.cpp -o main.exe -I lib/SDL2_lib/include -L lib/sdl2_lib/libr -L lib/sdl2_lib -lsdl2 -lsdl2_image
I get the following error;
My file structure is as follows, all functionality not relating to sdl image works fine.
Yes, the sdl_image.h file is in include;
Inside the libr folder:
I'm working on a small project in CLion with SDL2 on Windows.
When I compile and run (Shift+F10) my program in CLion, it does not show any console output. However, when I run it using the debugger (Shift+F9), it does show console output..
I have no idea what is causing this.
To make sure my project or CLion isn't corrupting something, I've copied the sources over to a new project and set it up using the same CMakeList.txt file, and it still does not work.
My CMakeList.txt:
CMakeList.txt
cmake_minimum_required(VERSION 3.6)
project(SDL_Project)
set(CMAKE_CXX_STANDARD 14)
# FindSDL2.cmake
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
#find_package(SDL2_ttf REQUIRED)
include_directories(${SDL2_INCLUDE_DIR})
include_directories(${SDL2_IMAGE_INCLUDE_DIR})
#include_directories(${SDL2_TTF_INCLUDE_DIR})
add_executable(SDL_Project src/main.cpp src/Game.cpp src/Game.h)
set_target_properties(SDL_Project PROPERTIES WIN32_EXECUTABLE FALSE)
target_link_libraries(SDL_Project ${SDL2_LIBRARY})
target_link_libraries(SDL_Project ${SDL2_IMAGE_LIBRARIES})
#target_link_libraries(SDL_Project ${SDL2_TTF_LIBRARIES})
I also tried compiling the following code (without SDL2, but using the same CMakeList.txt):
#include <iostream>
int main(int argv, char* args[]) {
std::cout << "Hello World!" << std::endl;
return 0;
}
This has the same issue; no console output.
Compiling the above code without the find_package, include_directories and target_link_libraries in CMakeList.txt shows console output! So it is related to SDL2, I think..?
Does anyone know what is causing this, and how to fix it?
Though I believe the problem lies in CMakeList.txt, here is the remaining code:
main.cpp
#include <SDL.h>
#include <iostream>
#include "Game.h"
int main(int argv, char* args[]) {
const int FPS = 60;
const uint32_t frameDelay = 1000 / FPS;
const WindowSettings settings = {SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720};
Game game;
Uint32 frameStart;
Uint32 frameTime;
game.init("Game", settings);
while (game.isRunning()) {
frameStart = SDL_GetTicks();
game.handleEvents();
game.tick();
game.render();
frameTime = SDL_GetTicks() - frameStart;
std::cout << "Frame time: " << frameTime << " / " << frameDelay << std::endl;
if (frameTime < frameDelay) {
std::cout << "Frame delay: " << (frameDelay - frameTime) << std::endl;
SDL_Delay(frameDelay - frameTime);
}
}
game.cleanup();
return 0;
}
Game.h
#ifndef SDL_PROJECT_GAME_H
#define SDL_PROJECT_GAME_H
#include <SDL.h>
struct WindowSettings {
int x;
int y;
int width;
int height;
};
class Game {
private:
bool running;
SDL_Window* window;
SDL_Renderer* renderer;
public:
Game();
~Game();
void init(const char* title, const WindowSettings &settings);
void tick();
void render();
void cleanup();
void handleEvents();
bool isRunning() { return running; }
};
#endif //SDL_PROJECT_GAME_H
Game.cpp
#include <iostream>
#include "Game.h"
Game::Game():
running(false),
window(nullptr),
renderer(nullptr) {
}
Game::~Game() = default;
void Game::init(const char *title, const WindowSettings &settings) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cout << "SDL initialization failed: " << SDL_GetError() << std::endl;
return;
};
window = SDL_CreateWindow(title, settings.x, settings.y, settings.width, settings.height, SDL_WINDOW_SHOWN);
if (window == nullptr) {
std::cout << "Unable to create window: " << SDL_GetError() << std::endl;
return;
}
renderer = SDL_CreateRenderer(window, -1 , 0);
if (renderer == nullptr) {
std::cout << "Unable to create renderer: " << SDL_GetError() << std::endl;
return;
}
running = true;
}
void Game::tick() {
}
void Game::render() {
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
void Game::cleanup() {
if (renderer) {
SDL_DestroyRenderer(renderer);
}
if (window) {
SDL_DestroyWindow(window);
}
SDL_Quit();
std::cout << "Game clean exit" << std::endl;
}
void Game::handleEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
}
}
}
I can think of 1 issue. Are you sure your run configuration is correct CLION? The debug build could be running a different executable than you think. CLION does a lot of stuff behind the scenes. Click the run arrow drop down and look at edit configurations or something to that effect.
Alright, I figured it out..
Apparently, compiling on Windows redirects stdout and stderr to null (?). I was unable to locate/remove the compiler flag that influences this, however, SDL provides SDL_Log, which does in fact output to the console (and presumably stdout?).
Since I'm using SDL2 anyway, I might as well use the logger. It supports printf-style formatting, which is a nice bonus. And it allows me to set up a custom logging function if I want to redirect log messages.
Here is a small code and when we press "é" key or special characters with for instance french keyboards, we get in the console weird characters such as "├®".
#include <iostream>
#include "SDL.h"
using namespace std;
int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_CreateWindow("test", 100, 100, 1920, 1080, SDL_WINDOW_RESIZABLE);
bool opened = true;
SDL_Event event;
while(opened)
{
SDL_StartTextInput();
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
{
opened = 0;
break;
}
case SDL_TEXTINPUT:
{
cout << event.text.text << endl;
break;
}
}
}
return EXIT_SUCCESS;
}
PS: I am using SDL 2
Just have to use TTF_RenderUTF8_Blended for render (output in file was fine).
I have the following sound loading function:
bool Sound::load(const char* fileName)
{
sound = Mix_LoadWAV(fileName);
if (sound == nullptr)
{
std::cout << "Failed to load sound at path: " << fileName << "SDL_mixer error: " << Mix_GetError();
return false;
}
return true;
}
In Dev-C++, this works, fine. I wanted to use another IDE, so I started using Visual Studio 2017, and configured SDL2 for it. However, when I run this code, from the moment Mix_LoadWAV is called, Visual studio gives the following:
https://imgur.com/a/STnXx
I have searched alot on the internet, but I could not find anything useful that worked for me.
EDIT: as per request, I created a minimal example that still produces the same error.
#include "SDL2\SDL_mixer.h"
#include "SDL2\SDL.h"
#include <iostream>
#undef main
class SoundTest
{
private:
Mix_Chunk* sound = nullptr;
public:
bool load(const char* fileName)
{
sound = Mix_LoadWAV(fileName);
if (sound == nullptr)
{
std::cout << "Failed to load sound at path: " << fileName << "SDL_mixer error: " << Mix_GetError();
return false;
}
return true;
}
};
SDL_Window *window = nullptr;
int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
window = SDL_CreateWindow("Sound bug? ", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 300, 300, SDL_WINDOW_SHOWN);
Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 2048);
SoundTest sound;
sound.load("audio/soundEffect.wav");
while (true)
{
//Do fun stuff with the sound
}
return 0;
}
I cant seem to load a image onto a SDL window.
Code:
#include <iostream>
#include <SDL2/SDL.h>
#include <stdio.h>
using namespace std;
SDL_Window *window;
SDL_Surface *imageSurface;
SDL_Surface *image;
void createWindow() {
SDL_INIT_EVERYTHING;
if(SDL_INIT_EVERYTHING <0) {
cout << "SDL failed to initialize!" << endl;
}
window = SDL_CreateWindow("Test Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480,0);
if (window==NULL) {
cout << "Window could not be made" << endl;
}
imageSurface = SDL_GetWindowSurface(window);
}
void close() {
SDL_FreeSurface(image);
SDL_DestroyWindow(window);
SDL_Quit();
}
void loadmedia() {
image = SDL_LoadBMP("Test.bmp");
if (image==NULL) {
cout << "Image could not be loaded" << endl;
}
}
int main() {
createWindow();
loadmedia();
SDL_BlitSurface(image, NULL, imageSurface, NULL);
SDL_UpdateWindowSurface(window);
SDL_Delay(10000);
close();
}
You are missing the message loop.
Basically, your application is receiving messages to process operations such as drawing the window and all.
What you are missing is something like that:
while (!done) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
done = true;
}
}
You can find a sample here: http://www.gamedev.net/topic/376858-a-proper-sdl-message-loop/