I want to create a simple program that lets me move around a little sprite with some music.
I'm able to bring up a window, my next step is getting some music. I have everything setup properly as when I build my main.exe with make it builds perfectly. I've narrowed the issue down to the first instance when the mixer is used in the line Mix_OpenAudio(48000, AUDIO_S16SYS, 2, 1024.
I'm not sure why it's not working, but when this line is included, the program simply doesn't open the window and ends the program. On the contrary, when the line isn't included, then the window opens just fine. I've provided a screencap to further illustrate:
Here is my main.cpp code:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDl2/SDL_mixer.h>
//Define window size
const int WIDTH = 800;
const int HEIGHT = 600;
bool init();
void closeWindow();
SDL_Window *window = NULL;
bool init() {
window = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_ALLOW_HIGHDPI);
if (NULL == window) {
std::cout << "Could not create window: " << SDL_GetError() << std::endl;
return 1;
}
else {
return 0;
}
}
void closeWindow() {
SDL_DestroyWindow(window);
SDL_Quit();
return;
}
int main(int argc, char *argv[]) {
/* Initialize the SDL library */
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
exit(2);
}
/* Opens the audio device */
if (Mix_OpenAudio(48000, AUDIO_S16SYS, 2, 1024) < 0 ) {
fprintf(stderr, "Warning: Couldn't set 48000Hz 16-bit audio\n- Reason: %s\n", SDL_GetError());
}
init();
SDL_Event windowEvent;
while(true) {
if(SDL_PollEvent(&windowEvent)) {
if (SDL_QUIT == windowEvent.type) {
break;
}
}
}
closeWindow();
Mix_CloseAudio();
return EXIT_SUCCESS;
}
How do I fix this issue?
Related
I'm trying SDL2 for ios. I followed this instructions to build libsdl2.a and libsdlmain.a.
Have used the built in ios template xcode project.
But gives me error while Initialization.
SDL Error: Application didn’t initialize properly, did you include SDL_main.h in the file containing your main() function?
could anyone help me?
#include "SDL.h"
int main(int argc, char *argv[])
{
SDL_Window *window;
SDL_Renderer *renderer;
int done;
SDL_Event event;
/* initialize SDL */
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("Could not initialize SDL\n");
return 1;
}
/* seed random number generator */
srand(time(NULL));
/* create window and renderer */
window =
SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_OPENGL);
if (!window) {
printf("Could not initialize Window\n");
return 1;
}
renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer) {
printf("Could not create renderer\n");
return 1;
}
/* Enter render loop, waiting for user to quit */
done = 0;
while (!done) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
done = 1;
}
}
SDL_Delay(1);
}
/* shutdown SDL */
SDL_Quit();
return 0;
}
you have to Initialize SDL with SDL_Init() to Initialize everything you state: SDL_Init(SDL_INIT_EVERYTHING);
I've been trying to have a bitmap image displayed on screen but I can't figure out why it's not displaying it for the life of me. Here's the code:
#include <iostream>
#include <SDL.h>
bool init(SDL_Window *window, SDL_Surface *surface) {
bool success {true};
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
std::cout << "Could not initialize video: " << SDL_GetError() << "\n";
success = false;
}
window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
if (window == NULL) {
std::cout << "Could not create window: " << SDL_GetError() << "\n";
success = false;
}
surface = SDL_GetWindowSurface(window);
return success;
}
bool loadMedia(SDL_Surface *image) {
bool success {true};
image = SDL_LoadBMP("C:\\Users\\Admin\\Documents\\Files\\Programming\\C++\\game\\Untitled.bmp");
if (image == NULL) {
std::cout << "Could not load image: " << SDL_GetError() << "\n";
success = false;
}
return success;
}
void close(SDL_Window *window, SDL_Surface *surface, SDL_Surface *image) {
SDL_FreeSurface(surface);
surface = nullptr;
SDL_FreeSurface(image);
image = nullptr;
SDL_DestroyWindow(window);
window = nullptr;
SDL_Quit();
}
int main(int argc, char *argv[]) {
bool quit {false};
SDL_Event event;
SDL_Window *window {nullptr};
SDL_Surface *surface {nullptr};
SDL_Surface *image {nullptr};
if (!init(window, surface)) {
std::cout << "Initialization failed\n";
return 1;
}
if (!loadMedia(image)) {
std::cout << "Loading media failed\n";
return 1;
}
SDL_BlitSurface(image, NULL, surface, NULL);
SDL_UpdateWindowSurface(window);
while (!quit) {
SDL_WaitEvent(&event);
switch (event.type) {
case SDL_QUIT:
quit = true;
break;
default: break;
}
}
close(window, surface, image);
return 0;
}
The file structure is like so:
-game/
-image.bmp
-main.cpp
-main.exe
-Makefile
Makefile is like so:
all : main.cpp
g++ main.cpp -IC:\SDL2\include\SDL2 -LC:\SDL2\lib -w -lmingw32 -lSDL2main -lSDL2 -o main
SDL version 2.0.14 64-bit
mingw 64-bit
Windows 10 64-bit
I don't even know how much more information is necessary.
I have tried using events, not using events, using an absolute path, making the variables global, different file formats, trying to display it using a renderer and a texture, putting everything in main, making the image the same size as the screen, using ImageMagick convert as per the suggestion of an answer on some other thread on here, disabling the console window with the -Wl,-subsystem,windows compiler flag, but nothing I did has worked. Any help here?
You are passing parameters to init() - but the function receives a copy of those things. Then you change the copies passed into the function so they point somewhere else - but that doesn't change where the original pointers point. Then when you return to main() you use the original pointers which are still pointing to null.
It's the same as writing this:
void f(int x) {
x=2; // change the copy of x passed to this function
}
int main() {
int x=1;
f(x);
printf("%d\n",x); // prints the original value: 1
}
When what you should do is pass pointers to the things you want to change and then inside the function change the contents of the parameters:
void f(int *x) {
*x=2; // change the contents of the pointer: the original x
}
int main() {
int x=1;
f(&x); // pass a pointer to x
printf("%d\n",x); // prints the changed value: 2
}
So, in your case, what you need to do is pass pointers to the things you want to change (a pointer to window and a pointer to surface) and then inside init() change the contents of the parameters:
bool init(SDL_Window **window, SDL_Surface **surface) {
// ...
*window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
// ...
*surface = SDL_GetWindowSurface(window);
// ...
}
int main(int argc, char *argv[]) {
// ...
SDL_Window *window {nullptr};
SDL_Surface *surface {nullptr};
// ...
if (!init(&window, &surface)) {
std::cout << "Initialization failed\n";
return 1;
}
// ...
}
I'm using SDL 2.0.8 and SDL_image 2.0.3. I've written a small program which renders on screen 2 textures.
When I start the programme my computer is lagging so much that I can't close the programme window. I gave this programme to my friend and when he opened it, he got the same lag as me. We thought that something in my code is bad. We analyzed the code and we saw literally nothing wrong. Then I remembered that I wrote similar code last year and everything was running well. I downloaded it because I had it in the cloud and we ran it. This programme was also lagging. That was totally weird for us. Our graphics cards had 100% utilization because I didn't set framerate lock or vsync.
My computer:
AMD Ryzen 7 2700x #4.3GHz
AMD Radeon R9 390
16 GB RAM DDR4 3000MHz
My friend's computer:
AMD Ryzen 7 1700 #3.6GHz
NVidia GTX 770
16 GB RAM DDR4 3200MHz
I can add that commenting render function in loop removes lags.
EDIT:
It happens only when graphics card utilization is around 100%. Probably when the processor is too weak to run it so fast that graphics card is fully loaded, problem would not ocurr.
Here is code:
Main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "Client.h"
int main(int argc, char** argv)
{
// Redict strerr to file
freopen("ErrorFile.log", "w", stderr);
Client * c = new Client();
c->start(40);
system("pause");
return 0;
}
Client.h
#pragma once
#include "Graphics.h"
#include <time.h>
class Client
{
public:
Client()
{
gptr = new Graphics();
}
~Client()
{
delete gptr;
gptr = NULL;
}
// -Triggers needed components and starts client
void start(int tickrate)
{
gptr->init();
loop(tickrate);
}
private:
void loop(int tickrate)
{
clock_t start;
clock_t timer;
start = clock();
while (!quit)
{
timer = clock();
while (start + tickrate <= timer)
{
//TODO Mechanics update
start += tickrate;
}
while (SDL_PollEvent(&gptr->e) != 0)
{
if (gptr->e.type == SDL_QUIT)
quit = true;
}
gptr->render();
}
}
private:
Graphics * gptr;
bool quit = false;
};
Graphics.h
#pragma once
#include "Texture.h"
class Graphics
{
public:
void init()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
fprintf(stderr, "Cannot init SDL. Error: %s\n", SDL_GetError());
exit(-1);
}
//Set texture filtering to linear
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
{
printf("Warning: Linear texture filtering not enabled!");
}
window = SDL_CreateWindow("Client", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN);
if (window == NULL)
{
fprintf(stderr, "Cannot create window. Error: %s\n", SDL_GetError());
exit(-1);
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL)
{
fprintf(stderr, "Cannot create renderer. Error: %s\n", SDL_GetError());
exit(-1);
}
SDL_RenderClear(renderer);
//Init PNG loading
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
fprintf(stderr, "Cannot init PNG loading. Error: %s\n", IMG_GetError());
exit(-1);
}
loadMedia();
}
void render()
{
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(renderer);
textures[MAP].render(renderer, 0, 0);
textures[CHARACTER].render(renderer, 0, 0);
SDL_RenderPresent(renderer);
}
private:
bool loadMedia()
{
bool success = true;
if (!textures[MAP].loadTexture("res/map.png", renderer))
success = false;
if (!textures[CHARACTER].loadTexture("res/link.png", renderer))
success = false;
return success;
}
public:
SDL_Event e;
private:
SDL_Renderer * renderer;
Texture textures[TOTAL_TEXTURES];
SDL_Window * window;
};
Texture.h
#pragma once
#include <SDL.h>
#include <SDL_image.h>
#include <cstdio>
enum TextureEnum
{
MAP,
CHARACTER,
TOTAL_TEXTURES
};
class Texture
{
public:
Texture()
{
texture = NULL;
width = 0;
height = 0;
}
bool loadTexture(const char* path, SDL_Renderer * renderer)
{
bool success = true;
free();
SDL_Surface* loadedSurface = IMG_Load(path);
if (loadedSurface == NULL)
{
fprintf(stderr, "Cannot load image %s. SDL_image Error: %s\n", path, IMG_GetError());
printf("Cannot load image %s. SDL_image Error: %s\n", path, IMG_GetError());
SDL_FreeSurface(loadedSurface);
success = false;
}
else
{
SDL_SetColorKey(loadedSurface, SDL_TRUE, SDL_MapRGB(loadedSurface->format, 0, 0xFF, 0xFF));
texture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
width = loadedSurface->w;
height = loadedSurface->h;
if (texture == NULL)
{
fprintf(stderr, "Cannot create texture from %s. SDL Error: %s\n", path, SDL_GetError());
printf("Cannot create texture from %s. SDL Error: %s\n", path, SDL_GetError());
success = false;
}
}
SDL_FreeSurface(loadedSurface);
return success;
}
void free()
{
if (texture != NULL)
{
SDL_DestroyTexture(texture);
texture == NULL;
width = 0;
height = 0;
}
}
void render(SDL_Renderer * renderer, int x, int y)
{
SDL_Rect quad = { x, y, width, height };
SDL_RenderCopy(renderer, texture, NULL, &quad);
}
private:
SDL_Texture * texture;
int width;
int height;
};
After updating to the newest Windows 10 version problem did not ocurr.
I was following the SDL Game development book and I cant even get the first file to work right. Upon the application starting it renders the window and then after a few seconds Linux says the game is not responding and ask me to force quit. This repeats every few seconds if I click wait. One thing I have noticed is that SDL_PollEvent never returns true.I am not sure why things are not working. Here is my code.
Main.cpp
#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#include "Game.h"
// our Game object
Game* g_game = 0;
int main(int argc, char* argv[]) {
g_game = new Game();
g_game->init("Chapter 1", 100, 100, 640, 480, 0);
while(g_game->running()) {
g_game->handleEvents();
//g_game->update();
g_game->render();
}
g_game->clean();
return 0;
}
Game.h
#ifndef __Game__
#define __Game__
#if !WINDOWS
#include <SDL2/SDL.h>
#else
#include <SDL.h>
#endif
class Game {
public:
Game() {}
~Game() {}
// simply set the running variable to true
bool init(const char* title, int xpos, int ypos, int width, int
height, bool fullscreen);
void render();
void update();
void handleEvents();
void clean();
// a function to access the private running variable
bool running() {
return m_bRunning;
}
private:
SDL_Window* m_pWindow;
SDL_Renderer* m_pRenderer;
bool m_bRunning;
};
#endif /* defined(__Game__) */
Game.cpp
#include "Game.h"
#include <iostream>
bool Game::init(const char* title, int xpos, int ypos, int width,
int height, bool fullscreen) {
// attempt to initialize SDL
if(SDL_Init(SDL_INIT_EVERYTHING) == 0) {
std::cout << "SDL init success\n";
// init the window
int flags = 0;
if(fullscreen) {
flags = SDL_WINDOW_FULLSCREEN;
}
m_pWindow = SDL_CreateWindow(title, xpos, ypos,
width, height, flags);
if(m_pWindow != 0) { // window init success
std::cout << "window creation success\n";
m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
if(m_pRenderer != 0) { // renderer init success
std::cout << "renderer creation success\n";
SDL_SetRenderDrawColor(m_pRenderer,
255,0,255,255);
} else {
std::cout << "renderer init fail\n";
return false; // renderer init fail
}
} else {
std::cout << "window init fail\n";
return false; // window init fail
}
} else {
std::cout << "SDL init fail\n";
return false; // SDL init fail
}
std::cout << "init success\n";
m_bRunning = true; // everything inited successfully, start the main loop
return true;
}
void Game::render() {
SDL_RenderClear(m_pRenderer); // clear the renderer to the draw color
SDL_RenderPresent(m_pRenderer); // draw to the screen
}
void Game::clean() {
std::cout << "cleaning game\n";
SDL_DestroyWindow(m_pWindow);
SDL_DestroyRenderer(m_pRenderer);
SDL_Quit();
}
void Game::handleEvents() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
std::cout << "Checking Events";
switch(event.type) {
case SDL_QUIT:
std::cout << "Quiting";
m_bRunning = false;
break;
default:
break;
}
}
}
Edit:
so I made a minamal version of the code and now i get a new error. The error says "Segmentation Fault (core dumped)". Based on running it to a specific line in debug the error seems to appear at the line that says "SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);" I am not sure what the error is though
Here is the minial code:
#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#include <iostream>
#include <SDL2/SDL.h>
int main(int argc, char** argv) {
if(SDL_Init(SDL_INIT_EVERYTHING) != 0) {
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
if(win == NULL) {
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if(ren == NULL) {
SDL_DestroyWindow(win);
std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
std::string imagePath = "cb.bmp";
SDL_Surface *bmp = SDL_LoadBMP(imagePath.c_str());
if(bmp == NULL) {
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
if(tex == NULL) {
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return 1;
}
SDL_FreeSurface(bmp);
SDL_Event e;
bool quit = false;
while(!quit) {
while(SDL_PollEvent(&e)) {
//If user closes the window
if(e.type == SDL_QUIT) {
quit = true;
}
//If user presses any key
if(e.type == SDL_KEYDOWN) {
quit = true;
}
//If user clicks the mouse
if(e.type == SDL_MOUSEBUTTONDOWN) {
quit = true;
}
}
SDL_RenderClear(ren);
SDL_RenderPresent(ren);
}
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
I have compiled and run your minimal code successfully under Linux with SDL 2.0.4. I used a simple image as "cb.bmp".
Try the following :
compile like this : g++ -Wall -ggdb $(sdl2-config --cflags) -o program main.cpp -lSDL2
gdb ./program, then type 'run'
when it crashes, type 'bt' (for backtrace)
copy the output here
My guess is : either the "bmp" file format is not supported or the rendering driver is not supported. try to use :
SDL_CreateRenderer(win, -1, 0);
Why the window that created by SDL Game Library are automatically closed after specific time.
I know the reason is SDL_Delay() function, but if not used that function, the game will appear runtime error.
How can I create a window that continuously work without appear in specific period time ?
My code(Simplest code):
SDL_Window *window;
SDL_Renderer *render;
int main(int argc, char* args[]){
if(SDL_Init(SDL_INIT_EVERYTHING) >= 0){
window = SDL_CreateWindow("Simple game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
if(window != 0){
render = SDL_CreateRenderer(window, -1, 0);
}
}else{
return 1;
}
SDL_SetRenderDrawColor(render, 0, 0, 0, 255);
SDL_RenderClear(render);
SDL_RenderPresent(render);
SDL_Delay(3000);
SDL_Quit();
return 0
}
You need to loop forever and call SDL update screen functions. Read LazyFoo tutorials found here: http://lazyfoo.net/SDL_tutorials
Or here a short code to get you started:
#include <iostream>
#include "SDL/SDL.h" // basic SDL
#include <string>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BBP = 32; // bits per-pixel
SDL_Surface* screen = NULL; // display screen
SDL_Event event; // grab events
using namespace std;
bool init() {
// initialize SDL
if(SDL_Init( SDL_INIT_EVERYTHING ) == -1)
return false;
//the screen image
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT,
SCREEN_BBP, SDL_SWSURFACE );
if(!screen) {
cout << "error creating screen" << endl;
return false;
}
//Set the window caption
SDL_WM_SetCaption("Event Test", NULL );
return true;
}
int main(int argc, char* argv[])
{
try
{
// make sure the program waits for a quit
bool quit = false;
cout << "Starting SDL..." << endl;
// Start SDL
if(!init()) {
cout << "initialize error" << endl;
return false;
}
// main loop
while( quit == false )
{
if (SDL_PollEvent(&event))
{
// The x button click
if(event.type == SDL_QUIT)
{
//quit the program
quit = true;
}
}
// Fill the screen white
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB(
screen->format, 0xFF, 0xFF, 0xFF ) );
//Update screen
if(SDL_Flip(screen) == -1)
return -1;
}
}
catch (exception& e)
{
cerr << "exception caught: " << e.what() << endl;
return -1;
}
return 0;
}