I am using SDL2 for the first time, and when I try to create a window, it's not displaying. The only sight of the window is an icon spawning in my dock (Image of the icon, SDLTest.out is the name of my executable file). I found out that it spawned when SDL_INIT()was called.
I tried updating the window, changing its color and adding the flag SDL_WINDOW_SHOWN, but none of these solutions worked. I even pasted a code from the Internet, but it didn't work better.
Here is the code that I pasted:
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
int status = EXIT_FAILURE;
SDL_Color orange = {255, 127, 40, 255};
if(0 != SDL_Init(SDL_INIT_VIDEO))
{
fprintf(stderr, "Error SDL_Init : %s", SDL_GetError());
goto Quit;
}
window = SDL_CreateWindow("SDL2", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
640, 480, SDL_WINDOW_SHOWN);
if(NULL == window)
{
fprintf(stderr, "Error SDL_CreateWindow : %s", SDL_GetError());
goto Quit;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if(NULL == renderer)
{
fprintf(stderr, "Error SDL_CreateRenderer : %s", SDL_GetError());
goto Quit;
}
if(0 != SDL_SetRenderDrawColor(renderer, orange.r, orange.g, orange.b, orange.a))
{
fprintf(stderr, "Error SDL_SetRenderDrawColor : %s", SDL_GetError());
goto Quit;
}
if(0 != SDL_RenderClear(renderer))
{
fprintf(stderr, "Error SDL_SetRenderDrawColor : %s", SDL_GetError());
goto Quit;
}
SDL_Delay(500);
SDL_RenderPresent(renderer);
SDL_Delay(500);
status = EXIT_SUCCESS;
Quit:
if(NULL != renderer)
SDL_DestroyRenderer(renderer);
if(NULL != window)
SDL_DestroyWindow(window);
SDL_Quit();
return status;
}
My OS is MacOS 11.6, my compiler GCC, my computer has a graphic card Intel Iris Pro Graphics 6200, and I installed SDL2 using Homebrew.
Can someone help me?
I just needed an event loop. I added this code and it worked:
SDL_bool quit = SDL_FALSE;
while(!quit)
{
SDL_RenderPresent(renderer);
SDL_WaitEvent(&event);
if(event.type == SDL_QUIT)
quit = SDL_TRUE;
}
Thank you to HolyBlackCat for your comment!
Related
I'm having trouble getting my image to display using SDL. I've checked the file path, made sure the image dimensions are compatible with the window size, and verified that the image is not NULL, but it still won't show up. I've been trying to debug this for hours and I'm at a loss. Can someone please take a look at my code and help me figure out what I'm missing? Here's the relevant code:
game.c:
#include <stdlib.h>
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "header/game.h"
#include "header/constant.h"
SDL_Rect position, positionPlayer;
// Game.c
void game(/*SDL_Window* window, */SDL_Renderer* renderer){
SDL_Texture *bomber[4]={NULL};
SDL_Texture *bomberCurrent=NULL;
positionPlayer.x=33;
positionPlayer.y=33;
SDL_Event event;
int runningGame=1;
int i=0/*, j=0*/;
bomber[DOWN]=IMG_LoadTexture(renderer,"playerPink1.png");
if (!bomber[DOWN]) {
printf("Error loading image: %s\n", SDL_GetError());
return;
}
int w, h;
SDL_QueryTexture(bomber[DOWN], NULL, NULL, &w, &h);
if (w > 952 || h > 442) {
printf("Error: Image size is larger than window size\n");
return;
}
bomberCurrent = bomber[DOWN];
while(runningGame){
SDL_WaitEvent(&event); // Bloque l'exécution du programme jusqu
while(SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
runningGame = 0;
}
}
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
position.x=positionPlayer.x*TAILLE_BLOC;
position.y=positionPlayer.y*TAILLE_BLOC;
SDL_RenderCopy(renderer,bomberCurrent,NULL,&position);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
for(i=0;i<4;i++){
SDL_DestroyTexture(bomber[i]);
}
}
game.h:
#ifndef CONSTANT_H_INCLUDED
#define CONSTANT_H_INCLUDED
#define TAILLE_BLOC 34
enum{UP,DOWN,LEFT,RIGHT};
enum{VIDE,WALL,BOMBER};
#endif
main.c:
#include <stdlib.h>
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "header/game.h"
int main(){
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Texture *menu = NULL;
SDL_Event event;
SDL_Surface *icon;
int runningGame=1;
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("Etna Bomber", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 952, 442, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, 0);
icon = IMG_Load("src/favicon.bmp");
SDL_SetWindowIcon(window, icon);
menu = IMG_LoadTexture(renderer, "src/menu.png");
SDL_FreeSurface(icon);
while(runningGame){
SDL_WaitEvent(&event);
switch(event.type){
case SDL_QUIT:
runningGame=0;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym) {
case SDLK_ESCAPE:
runningGame=0;
break;
case SDLK_SPACE:
game(/*window,*/renderer);
default:
break;
}
break;
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, menu, NULL, NULL);
SDL_RenderPresent(renderer);
}
SDL_DestroyTexture(menu);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
constant.h:
#ifndef CONSTANT_H_INCLUDED
#define CONSTANT_H_INCLUDED
#define TAILLE_BLOC 34
enum{UP,DOWN,LEFT,RIGHT};
enum{VIDE,WALL,BOMBER};
#endif
I tried using the SDL_QueryTexture function to check if the dimensions of the image were compatible with the dimensions of the window, and also verified that the image was not NULL after loading it using IMG_LoadTexture. I was expecting the image to be displayed on the window at the specified position, but it is not showing up. I also tried various other methods such as checking the file path and making sure the image is in the correct format, but the problem persists.
when i start the code i get warning: incorrect audio format
i figured out its related to the mp3 file.
whats the problem and how can i fix it?
i already tried to convert the mp3 to a wav file but that also didnt work.
is it possible that 3mb of mp3 is to big? shouldnt be?
Edit: when i let it run without of mp3 the wav files will run just fine
with mp3 the programm will start but no sound at all
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
static const int width = 800;
static const int height = 600;
int main(int argc, char **argv)
{
// Initialize SDL video and audio systems
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
// Initialize SDL mixer
Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 3, 2048);
// Load audio files
Mix_Music *backgroundSound = Mix_LoadMUS("portfolio.mp3");
Mix_Chunk *jumpEffect = Mix_LoadWAV("JumpEffect.wav");
Mix_Chunk *laserEffect = Mix_LoadWAV("LaserEffect.wav");
//Mix_Chunk *musicEffect = Mix_LoadWAV("portfolio2.wav");
// Create a SDL window
SDL_Window *window = SDL_CreateWindow("Hello, SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL);
// Create a renderer (accelerated and in sync with the display refresh rate)
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
// Start the background music
Mix_PlayMusic(backgroundSound, -1);
bool running = true;
SDL_Event event;
while(running)
{
// Process events
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
{
running = false;
}
else if(event.type == SDL_KEYDOWN)
{
// Press "1" and play jump effect
if(event.key.keysym.sym == SDLK_1)
{
Mix_PlayChannel(-1, jumpEffect, 0);
}
// Press "2" and play laser effect
else if(event.key.keysym.sym == SDLK_2)
{
Mix_PlayChannel(-1, laserEffect, 0);
}
}
}
// Clear screen
SDL_RenderClear(renderer);
// Draw
// Show what was drawn
SDL_RenderPresent(renderer);
}
// Release resources
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
Mix_FreeMusic(backgroundSound);
Mix_FreeChunk(jumpEffect);
Mix_FreeChunk(laserEffect);
//Mix_FreeChunk(music);
Mix_CloseAudio();
SDL_Quit();
return 0;
}
I came across this error when running my SDL program. It compiled just fine, but the window opened up for a brief moment then closed.
Here's my code:
//Using SDL and standard IO
#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
#include <string.h>
// SDL Main Resources
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
SDL_Window* Window = NULL;
SDL_Texture* Canvas = NULL;
SDL_Renderer* Graphic_Renderer = NULL;
SDL_Event Event;
// Initialize SDL resources
int InitSDL_Environment(){
// Window
Window = SDL_CreateWindow("UML Prototype", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(Window == NULL){
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
SDL_Quit();
return 0;
}
// Video Engine
if(SDL_Init(SDL_INIT_VIDEO) < 0){
printf( "SDL Video Engine could not be initialized! SDL Error: %s\n", SDL_GetError() );
return 0;
}
// Image Formats
int imgFlags = IMG_INIT_PNG;
if(!(IMG_Init(imgFlags) & imgFlags)){
printf("SDL Image Formats could not be initialized! SDL_image Error: %s\n", IMG_GetError());
return 0;
}
// Graphics Renderer
Graphic_Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED);
if(Graphic_Renderer == NULL){
printf("Graphics renderer could not be created! SDL Error: %s\n", SDL_GetError());
return 0;
}
SDL_SetRenderDrawColor(Graphic_Renderer, 0xFF, 0xFF, 0xFF, 0xFF);
// Return Success
return 1;
}
// Load image from file
SDL_Texture* SDL_LoadTexture(char* src){
SDL_Texture* texture = NULL;
SDL_Surface* loadData = IMG_Load(src);
if(!loadData){
printf("Image \"%s\" could not be loaded! SDL_image ERROR: %s\n", src, IMG_GetError());
return NULL;
}
texture = SDL_CreateTextureFromSurface(Graphic_Renderer, loadData);
if(!texture){
printf("Image \"%s!\" could not be processed! SDL Error: %s\n", src, SDL_GetError());
}
SDL_FreeSurface(loadData);
return texture;
}
int main( int argc, char* args[] )
{
// Load SDL Resources
if(!InitSDL_Environment()){return 1;}
SDL_Texture* image = SDL_LoadTexture("Duck.png");
if(image == NULL){
printf("Image could not be found! SDL_Error: $s\n", SDL_GetError());
return 2;
}
SDL_Rect sign;
sign.x = 40;
sign.y = 31;
sign.w = 300;
sign.h = 300;
// Main loop
for(;;){
// Update screen
SDL_RenderClear(Graphic_Renderer);
SDL_RenderCopy(Graphic_Renderer, image, NULL, NULL);
SDL_RenderPresent(Graphic_Renderer);
// Event handling
SDL_PollEvent(&Event);
if(Event.type == SDL_QUIT){
SDL_DestroyWindow(Window);
SDL_Quit();
return 0;
}
}
}
When I adjusted the batch file to post program errors to the console window, it read Graphics renderer could not be created! SDL Error: Couldn't find matching render driver, pointing right to the Graphic_Renderer = SDL_CreateRenderer... line in my InitSDL_Environment() function.
As you can see, the first bit of that error is my own making, and the last bit was generated by SDL_GetError(), so it's an issue that SDL recognizes.
I found this forum post about the same basic issue where everyone suggested downloading OpenGL libraries. From there, I searched and found this link. No links on that page seemed to lead to anything I could download, and it became progressively ambiguous what OpenGL libraries to download, search for, or if it will even solve the issue. That forum post is four years old after all.
If it's an OpenGL problem with the SDL libraries, where exactly would I get the OpenGL libraries, and which ones should I download? Did I just do something dumb with my code?
So I did something dumb with my code! Of course <_<
I changed my InitSDL_Environment() function around, and it worked. I moved the SDL_CreateWindow function down below the SDL_Init(SDL_INIT_VIDEO) portion. So Initialize SDL Video, then create the window. Awesome!
// Initialize SDL resources
int InitSDL_Environment(){
// Video Engine
if(SDL_Init(SDL_INIT_VIDEO) < 0){
printf( "SDL Video Engine could not be initialized! SDL Error: %s\n", SDL_GetError() );
return 0;
}
// Image Formats
int imgFlags = IMG_INIT_PNG;
if(!(IMG_Init(imgFlags) & imgFlags)){
printf("SDL Image Formats could not be initialized! SDL_image Error: %s\n", IMG_GetError());
return 0;
}
// Window
Window = SDL_CreateWindow("UML Prototype", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(Window == NULL){
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
SDL_Quit();
return 0;
}
// Graphics Renderer
Graphic_Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED);
if(Graphic_Renderer == NULL){
printf("Graphics renderer could not be created! SDL Error: %s\n", SDL_GetError());
return 0;
}
SDL_SetRenderDrawColor(Graphic_Renderer, 0xFF, 0xFF, 0xFF, 0xFF);
// Return Success
return 1;
}
The comments brought up three main points:
SDL Textures require computers to have a graphics card & up-to-date drivers for them, which may need to be updated manually.
SDL Video needs to be initialized before a window can be created
The functions SDL_GetNumRenderDrivers() and SDL_GetRendererInfo() can be used to find out information about available cards and trouble-shoot this error.
Thanks commentators! This was a huge help.
I'm using the SDL2 library, in C.
I made a test program to open a white window, but I get a segmentation fault with the function SDL_FillRect even though there are no errors or warnings when I build it.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
static const int window_width = 1000;
static const int window_height = 1000;
int main(int argc, char* argv[])
{
//Window
SDL_Window *window = NULL;
//Window Surface where things will be shown
SDL_Surface *surface = NULL;
//Inicializar SDL
if(SDL_Init(SDL_INIT_VIDEO) == -1)
{
printf("Failed to initialize SDL2. SDL Error: %s", SDL_GetError());
}
else
{
window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_width, window_height, SDL_WINDOW_SHOWN );
if(window == NULL)
printf("Failed to create SDL2 window. SDL Error: %s", SDL_GetError());
else
{
//Fill window with white color
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 0xFF, 0xFF, 0xFF));
//Update surface with new changes
SDL_UpdateWindowSurface(window);
//Wait before closing (parameter in miliseconds)
SDL_Delay(4000);
}
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
You get Segmentation fault because surface is still NULL
This example code taken directly from the SDL wiki (https://wiki.libsdl.org/SDL_FillRect) shows how to create a SDL_Surface before calling SDL_FillRect()
/* Declaring the surface. */
SDL_Surface *s;
/* Creating the surface. */
s = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0);
/* Filling the surface with red color. */
SDL_FillRect(s, NULL, SDL_MapRGB(s->format, 255, 0, 0));
Does anyone know, how to create two Windows ans both should have an own YUV Overlay with the SDL 1.3 Library?
It is possible or do I try to use a wrong strategy?
If I tried the following source, i got an error message:
[!] can't create local overlay YUV display is only supported on the screen surface
#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>
static bool running = true;
static SDL_Window* win_local;
static SDL_Window* win_remote;
int main(int argc, char** argv) {
// SDL_SetVideoMode
if((SDL_Init(SDL_INIT_VIDEO) != 0))
{
printf("[!] can't initialize SDL %s\n", SDL_GetError());
exit(-1);
}
if(!(win_local = SDL_CreateWindow("Local Video", 0, 0, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS)))
{
printf("[!] can't create Window %s\n", SDL_GetError());
exit(-1);
}
if(!(win_remote = SDL_CreateWindow("Remote Video", 700, 0, 640, 480, SDL_WINDOW_SHOWN)))
{
printf("[!] can't create Window %s\n", SDL_GetError());
exit(-1);
}
SDL_Surface* surface_local;
SDL_Surface* surface_remote;
if(!(surface_local = SDL_GetWindowSurface(win_local)))
{
printf("[!] can't get local surface %s\n", SDL_GetError());
exit(-1);
}
if(!(surface_remote = SDL_GetWindowSurface(win_remote)))
{
printf("[!] can't get remote surface %s", SDL_GetError());
exit(-1);
}
SDL_Overlay* overlay_local;
SDL_Overlay* overlay_remote;
if(!(overlay_local = SDL_CreateYUVOverlay(640, 480, SDL_IYUV_OVERLAY, surface_local)))
{
printf("[!] can't create local overlay %s\n", SDL_GetError());
exit(-1);
}
//
// if(!(overlay_remote = SDL_CreateYUVOverlay(640, 480, SDL_IYUV_OVERLAY, surface_remote)))
// {
// printf("[!] can't create remote overlay %s\n", SDL_GetError());
// exit(-1);
// }
SDL_Event event;
while(running)
{
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
running = false;
break;
case SDL_QUIT:
running = false;
break;
}
}
SDL_Delay(20);
}
//SDL_FreeSurface(local);
//SDL_FreeSurface(remote);
SDL_DestroyWindow(win_local);
SDL_DestroyWindow(win_remote);
SDL_Quit();
exit(0);
return 0;
}
SDL_CreateYUVOverlay doesn't work well with multiple windows, because it's not part of 1.3 API, it was left for reverse compatibility with SDL 1.2.
I see three possible solutions:
Call SDL_CreateYUVOverlay just after SDL_CreateWindow for each surface. You will probably avoid the error but I'm not sure if it will work correctly.
See how SDL_CreateYUVOverlay is implemented using 1.3 API and do something similar.
Use OpenGL and shaders.