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.
Related
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!
I'm trying to set the transparency of my image. This code works fine in C++, but when I try the same code in C it no longer works. On executing the code, the image displays, however the black background remains. This is the code I'm using. Can anyone help me identify the issue?
SDL_Texture* Utilities_loadImage( SDL_Renderer* r, const char* file )
{
/* load an image into memory using SDL_image library function */
SDL_Surface* surface = SDL_LoadBMP(file);
if(!surface)
{
printf("error creating surface: %s\n", SDL_GetError());
return NULL;
}
if(SDL_SetColorKey(surface, SDL_TRUE, SDL_MapRGB(surface->format, 0, 0, 0)) != 0)
{
printf("Unable to set colourkey: %s", SDL_GetError());
}
/* convert image into a texture for use by the grafx hardware */
SDL_Texture* texture = SDL_CreateTextureFromSurface(r, surface);
/* get rid of surface */
SDL_FreeSurface(surface);
if(!texture)
{
printf("error creating texture: %s\n", SDL_GetError());
return NULL;
}
return texture;
}
Well maybe in this specific line:
SDL_SetColorKey(surface, SDL_TRUE, SDL_MapRGB(surface->format, 0, 0, 0))
you are calling the same variable "surface" and maybe the you background it's in other variable for example:
SDL_SetColorKey(background, SDL_TRUE, SDL_MapRGB(surface->format, 0, 0, 0))
and the variable surface it's the principal image that what you try to move or work.
#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
typedef struct{
SDL_Texture *texture; // The image/sprite itself
int width; // Sprite width
int height; // Sprite height
} Sprite;
Sprite *createSprite(SDL_Renderer *r, char *path);
int main(int argc, char *argv[]){
// Initialise SDL and SDL_image
SDL_Init(SDL_INIT_VIDEO);
IMG_Init(IMG_INIT_PNG);
// Create window
SDL_Window *window = SDL_CreateWindow(
"VN", // Title
SDL_WINDOWPOS_CENTERED, // Initial x position
SDL_WINDOWPOS_CENTERED, // Initial y position
1280, // Width
720, // Height
0 // Flags
);
if(window == NULL){
printf("Failed to create window. %s\n", SDL_GetError());
return 1;
}
// Create renderer
SDL_Renderer *renderer = SDL_CreateRenderer(
window, // Window
-1, // Monitor index (-1 for first available)
SDL_RENDERER_ACCELERATED // Flags
);
if(renderer == NULL){
printf("Failed to create renderer. %s\n", SDL_GetError());
return 1;
}
// Set up event handling
SDL_Event event;
while(1){
// Handle events/input
while(SDL_PollEvent(&event) != 0){
// Check if user wants to quit (press window close button)
if(event.type == SDL_QUIT){
return 1;
}
}
// Set screen colour to white
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
// Render white to screen (clear screen)
SDL_RenderClear(renderer);
// Update screen
SDL_RenderPresent(renderer);
}
// Exit SDL and SDL_image
SDL_Quit();
IMG_Quit();
return 0;
}
Sprite *createSprite(SDL_Renderer *r, char *path){
printf("Entered createSprite()\n");
// Create a Sprite structure, containing an image (texture) and its dimensions
Sprite *newSprite = NULL;
SDL_Texture *spriteTexture = NULL;
// Temporary surface (for loading texture)
SDL_Surface *tempSurface = NULL;
// Load image from path
tempSurface = IMG_Load(path);
if(tempSurface == NULL){
printf("Failed to load image '%s'. %s\n", path, IMG_GetError());
} else{
spriteTexture = SDL_CreateTextureFromSurface(r, tempSurface);
if(spriteTexture == NULL){
printf("Failed to create texture from '%s'. %s\n", path, SDL_GetError());
} else{
// Store texture, image width & height in Sprite structure
newSprite->texture = spriteTexture;
newSprite->width = tempSurface->w;
newSprite->height = tempSurface->h;
}
}
// Free memory of temp surface
SDL_FreeSurface(tempSurface);
printf("Leaving createSprite()\n");
return newSprite;
}
I'm attempting to load an image using the SDL_image addon, and store its width and height in a structure (along with a texture created from the surface).
It crashes when attempting to run the newSprite->texture = spriteTexture; section on Line 93. That's as much information as I can give I'm afraid. Any ideas?
I'm attempting to load an image using the SDL_image addon, and store its width and height in a structure (along with a texture created from the surface).
The problem is you're not allocating memory for Sprite in your createSprite function. You set it to NULL and than try to access that location which of course fails.
Try this:
Sprite *createSprite(SDL_Renderer *r, char *path){
printf("Entered createSprite()\n");
// Create a Sprite structure, containing an image (texture) and its dimensions
Sprite *newSprite = new Sprite(); //<<- this is where you allocate the memory
SDL_Texture *spriteTexture = NULL;
// Temporary surface (for loading texture)
SDL_Surface *tempSurface = NULL;
// Load image from path
tempSurface = IMG_Load(path);
if(tempSurface == NULL){
printf("Failed to load image '%s'. %s\n", path, IMG_GetError());
} else{
spriteTexture = SDL_CreateTextureFromSurface(r, tempSurface);
if(spriteTexture == NULL){
printf("Failed to create texture from '%s'. %s\n", path, SDL_GetError());
} else{
// Store texture, image width & height in Sprite structure
newSprite->texture = spriteTexture;
newSprite->width = tempSurface->w;
newSprite->height = tempSurface->h;
}
}
// Free memory of temp surface
SDL_FreeSurface(tempSurface);
printf("Leaving createSprite()\n");
return newSprite;
}
When i try to run my program i get the following error message:
SDL could not initialize! SDL_Error: No available video device
I have all the necessary SDL libraries installed and I'm currently running ubuntu 15.10
Here is my simple SDL code:
#include <stdio.h>
#include "SDL2/SDL.h"
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
int main(int argc, char* argv[])
{
//The window we'll be rendering to
SDL_Window* window = NULL;
//The surface contained by the window
SDL_Surface* screenSurface = NULL;
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
}
else
{
//Create window
window = SDL_CreateWindow("SDL Tutorial",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());
}
}
return 0;
}
The SDL2 library are correctly linked to my C project.
This error message occurs when there is no available video driver built into SDL2 for your display system (X11, Mir, Wayland, RPI ...).
Have you installed SDL2 package from Ubuntu repository or compiled from source ? When compiled from source, you should check that the supported video drivers are going to be built into the binary at the end of the "configure" step. Otherwise you need to install the required development headers (for X11 and Mir).
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.