Why won't my image render? - c++

So I'm learning C++ with SDL (on Visual Studio 2013). I'm following Lazy Foo's tutorials (specifically: http://lazyfoo.net/tutorials/SDL/02_getting_an_image_on_the_screen/index.php).
My image won't render. In contrast to the tutorial (which works) I do not have global surface variables. Instead I declared them in the main and passed the pointers around.
Code:
#include <SDL.h>
#include <SDL_image.h>
#include <stdio.h>
#include <string>
const int SCREEN_WIDTH = 600;
const int SCREEN_HEIGHT = 480;
//SDL init.
bool initialiseSDL(SDL_Window* gWindow, SDL_Surface* gWindowSurface)
{
bool success = true;
/*SDL_Init() initisalises SDL library. Returning 0 or less signifies an error.
SDL_INIT_VIDEO flag refers to graphics sub system.*/
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialise. SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Create the window
gWindow = SDL_CreateWindow("Asteroids", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (gWindow == NULL)
{
printf("Could not create window. SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Get the window surface.
gWindowSurface = SDL_GetWindowSurface(gWindow);
}
}
return success;
}
bool loadMedia(SDL_Surface* surface, std::string path)
{
//Success flag
bool success = true;
surface = SDL_LoadBMP(path.c_str());
if (surface == NULL)
{
printf("SDL surface failed to load. SDL Error: %s\n", SDL_GetError());
success = false;
}
return success;
}
void close()
{
}
int main(int argc, char* argv[])
{
SDL_Window* gWindow = NULL;
SDL_Surface* gWindowSurface = NULL;
SDL_Surface* gImageSurface = NULL;
if (!initialiseSDL(gWindow, gWindowSurface))
{
printf("Failed to initialise.\n");
}
else
{
if (!loadMedia(gImageSurface, "hw.bmp"))
{
printf("Failed to load inital media.");
}
else
{
//Apply the image
SDL_BlitSurface(gImageSurface, NULL, gWindowSurface, NULL);
//Update the surface
SDL_UpdateWindowSurface(gWindow);
//Wait two seconds
SDL_Delay(2000);
}
}
return 0;
}

Your program exhibits undefined behavior, because the pointers inside the main function are not initialized.
When you pass them to the initialiseSDL function you pass them by value, meaning they are copied and the function only operates on the copies and not the original pointers, which will still be uninitialized after the call.
What you need to do is to pass the pointers by reference instead:
bool initialiseSDL(SDL_Window*& gWindow, SDL_Surface*& gWindowSurface)
You of course need to do the same with the loadMedia function.

Related

SDL2 opens no window without giving any errors

I'm trying to test a simple SDL2 application. The app runs without any errors. However, no window shows up.
I'm using Ubuntu18.04 on a VMWare machine. I also tried to compile SDL from the source but got the same result. I am unsure if the cause of the problem is related to my OS or because of executing from a virtual machine.
Here is a simple application from docs (I just added SDL_GetNumDisplayModes to make sure the display mode is OK- returns 1)
// Using SDL and standard IO
#include <SDL2/SDL.h>
#include <stdio.h>
// Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
int main(int argc, char *args[])
{
// 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
{
int res = SDL_GetNumDisplayModes(0);
printf("SDL_GetNumDisplayModes: %d\r\n", res);
// 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());
}
else
{
// Get window surface
screenSurface = SDL_GetWindowSurface(window);
// Fill the surface white
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF));
// Update the surface
SDL_UpdateWindowSurface(window);
// Hack to get window to stay up
SDL_Event e;
bool quit = false;
while (quit == false)
{
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT)
{
quit = true;
}
}
}
}
}
// Destroy window
SDL_DestroyWindow(window);
// Quit SDL subsystems
SDL_Quit();
return 0;
}

How do I get SDL_image to work on Code::Blocks running on Ubuntu?

Summary:
I've been looking for the answer everywhere and cannot find it. Maybe someone can help. Basically I am following a tutorial series on YouTube for game dev using sdl2, and I've come to a point where I need to add and download the sdl_image libraries. I didn't have trouble linking sdl, but I am having big issues trying to link sdl_image. All the tutorials are on windows. I am desperate for a solution.
What I've tried:
adding -lSDL2_image to link settings, adding SDL_image.h to the SDL2 folder, and include it in my cpp file. I've tried adding the file path to the SDL2_image-2.0.5 folder on codeblocks and no dice. I've tried ./configure and sudo make install in the file directory, and it sent a .o and .so file to /usr/include/lib, and then I tried adding the search directory /usr/include/lib just to get a segmentation fault error.
Code:
/*This source code copyrighted by Lazy Foo' Productions (2004-2020)
and may not be redistributed without written permission.*/
//Using SDL, SDL_image, standard IO, and strings
#include <SDL2/SDL.h>
#include <SDL_image.h>
#include <stdio.h>
#include <string>
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
//Starts up SDL and creates window
bool init();
//Loads media
bool loadMedia();
//Frees media and shuts down SDL
void close();
//Loads individual image
SDL_Surface* loadSurface( std::string path );
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//Current displayed PNG image
SDL_Surface* gPNGSurface = NULL;
bool init()
{
//Initialization flag
bool success = true;
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "SDL could not initialize! SDL Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Create window
gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if( gWindow == NULL )
{
printf( "Window could not be created! SDL Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if( !( IMG_Init( imgFlags ) & imgFlags ) )
{
printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
success = false;
}
else
{
//Get window surface
gScreenSurface = SDL_GetWindowSurface( gWindow );
}
}
}
return success;
}
bool loadMedia()
{
//Loading success flag
bool success = true;
//Load PNG surface
gPNGSurface = loadSurface( "/home/zues/Desktop/Entities/Space.png" );
if( gPNGSurface == NULL )
{
printf( "Failed to load PNG image!\n" );
success = false;
}
return success;
}
void close()
{
//Free loaded image
SDL_FreeSurface( gPNGSurface );
gPNGSurface = NULL;
//Destroy window
SDL_DestroyWindow( gWindow );
gWindow = NULL;
//Quit SDL subsystems
IMG_Quit();
SDL_Quit();
}
SDL_Surface* loadSurface( std::string path )
{
//The final optimized image
SDL_Surface* optimizedSurface = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load( path.c_str() );
if( loadedSurface == NULL )
{
printf( "Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError() );
}
else
{
//Convert surface to screen format
optimizedSurface = SDL_ConvertSurface( loadedSurface, gScreenSurface->format, 0 );
if( optimizedSurface == NULL )
{
printf( "Unable to optimize image %s! SDL Error: %s\n", path.c_str(), SDL_GetError() );
}
//Get rid of old loaded surface
SDL_FreeSurface( loadedSurface );
}
return optimizedSurface;
}
int main( int argc, char* args[] )
{
//Start up SDL and create window
if( !init() )
{
printf( "Failed to initialize!\n" );
}
else
{
//Load media
if( !loadMedia() )
{
printf( "Failed to load media!\n" );
}
else
{
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//While application is running
while( !quit )
{
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
//User requests quit
if( e.type == SDL_QUIT )
{
quit = true;
}
}
//Apply the PNG image
SDL_BlitSurface( gPNGSurface, NULL, gScreenSurface, NULL );
//Update the surface
SDL_UpdateWindowSurface( gWindow );
}
}
}
//Free resources and close SDL
close();
return 0;
}
And finally I want to ask... Am I wasting my time learning sdl2? Should I be learning something else? The ultimate goal is to release a successful game and built a handsome community. Kind of hard to find 2020 resources... especially since games have gotten so big and advanced i.e fortnite, cod warzone, halo infinity... I can list hundreds more.
Thanks in advance :)

SDL_BlitSurface doesn't draw to screen

I'm trying to simply create a window and blit an image to the screen but for some reason the image is not showing up and the screen remains white. I've been using lazyfoo's tutorial for reference in order to figure this out. I posted all my code below, hopefully it's readable enough. Help would be appreciated as I've been stuck on this for an hour or two, thank you.
#include <SDL.h>
#include <SDL_audio.h>
#include <cstdio>
#include <iostream>
#include <Windows.h>
// creates Load_surface function
SDL_Surface *loadSurface(std::string path) {
SDL_Surface *loadedSurface = SDL_LoadBMP(path.c_str());
if (loadedSurface == NULL) {
printf("Unable to load image %s! SDL Error: %s\n", path.c_str(),
SDL_GetError());
}
return loadedSurface;
}
int main(int argc, char ** argv)
{
// pointer variable for window
SDL_Window *window;
SDL_Surface *surface = NULL;
SDL_Surface *media =
loadSurface("C:\\Users\\nickl\\Desktop\\buttonpressed.bmp");
// initialize and test for failure
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) == -1) {
return 1;
}
// create the window
window = SDL_CreateWindow(
"Ice Cream Boys Software",
48,
48,
640,
480,
SDL_WINDOW_OPENGL
);
// safety check, see if window was created, otherwise throw an error
if (window = NULL) {
printf("Could not create window: %s", SDL_GetError());
return 1;
}
else {
OutputDebugString(TEXT("Surface loaded.\n"));
surface = SDL_GetWindowSurface(window);
}
SDL_BlitSurface(media, NULL, surface, NULL);
SDL_UpdateWindowSurface(window);
/* ************************************** loop **************************** */
// bool to keep window open and event handler
bool quit = false;
SDL_Event e;
// loop to keep window open
while (!quit) {
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) {
quit = true;
}
else if (e.type == SDL_KEYDOWN) {
OutputDebugString(TEXT("My output string.\n"));
}
}
}
/* ************************************************************************** */
// close and destroy window
SDL_DestroyWindow(window);
// quit
SDL_Quit();
return 0;
}

Loading images with C++/SDL2 - "unhandled exception", "access violation reading location"

I was studying someone else's Pong code for an earlier version of SDL, and I'm trying to get it running with SDL2. Below is an excerpt from my code, which only loads the images. When this code is run, I get a window popping up telling me this:
Unhandled exception at 0x00A065AD in The Pong.exe: 0xC0000005: Access violation reading location 0x00000004. While it's debugging, it also points to this line:
optimizedImage = SDL_ConvertSurface(loadedImage, windowSurface->format, 0);
The error list shows warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library.
I'm not sure what to make of all this. On top of that, the SDL window shows up, freezes, and sometimes won't close even after debugging has ended. (It tells me there's an access violation when I try.)
#include <string>
#include <SDL.h>
const int WINDOW_WIDTH = 640;
const int WINDOW_HEIGHT = 475;
const int SCREEN_BPP = 2;
SDL_Window *window = NULL;
SDL_Surface *windowSurface = NULL;
SDL_Surface *ball = NULL;
SDL_Surface *background = NULL;
SDL_Surface *paddleL = NULL;
SDL_Surface *paddleR = NULL;
SDL_Event event;
SDL_Surface *loadImage(std::string fileName)
{
SDL_Surface *loadedImage = NULL;
SDL_Surface *optimizedImage = NULL;
loadedImage = SDL_LoadBMP(fileName.c_str());
if (loadedImage != NULL)
{
optimizedImage = SDL_ConvertSurface(loadedImage, windowSurface->format, 0);
SDL_FreeSurface(loadedImage);
if (optimizedImage != NULL)
{
SDL_SetColorKey(optimizedImage, SDL_TRUE,
SDL_MapRGB(optimizedImage->format, 255, 255, 255));
}
}
return optimizedImage;
}
bool init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
return false;
window = SDL_CreateWindow("Pong", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH,
WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
if (window == NULL)
return false;
return true;
}
bool loadFiles()
{
ball = loadImage("ball.bmp");
background = loadImage("background.bmp");
paddleL = loadImage("paddleRed.bmp");
paddleR = loadImage("paddleBlue.bmp");
if (ball == NULL)
return false;
if (background == NULL)
return false;
if (paddleL == NULL || paddleR == NULL)
return false;
return true;
}
int main(int argc, char* args[])
{
windowSurface = SDL_GetWindowSurface(window);
if (init() == false)
return 1;
if (loadFiles() == false)
return 1;
SDL_FreeSurface(windowSurface);
SDL_FreeSurface(ball);
SDL_FreeSurface(background);
SDL_FreeSurface(paddleL);
SDL_FreeSurface(paddleR);
windowSurface = ball = background = paddleL = paddleR = nullptr;
SDL_DestroyWindow(window);
window = nullptr;
SDL_Quit();
return 0;
}
You are calling
windowSurface = SDL_GetWindowSurface(window);
before
window = SDL_CreateWindow("Pong", SDL_WINDOWPOS_CENTERED,
so window will still be NULL, causing windowSurface to be NULL, causing windowSurface->format to cause a crash.

Why Is SDL_image not working

I am new to C++ and SDL; I am trying to add a new SDL extension libary using instructions found here: http://www.lazyfoo.net/SDL_tutorials/lesson03/windows/devcpp/index.php
But I get these errors:
3 C:\Documents and Settings\Edmund\My Documents\C++\myprojects\SDL\SDLevent.cpp SDL/SDL_image.h: No such file or directory.
C:\Documents and Settings\Edmund\My Documents\C++\myprojects\SDL\SDLevent.cpp In function `SDL_Surface* load_image(std::string)':
28 C:\Documents and Settings\Edmund\My Documents\C++\myprojects\SDL\SDLevent.cpp `IMG_Load' undeclared (first use this function)
and then a bunch of unqualified ids.
This is my code:
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>
//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
//The surfaces
SDL_Surface *image = NULL;
SDL_Surface *screen = NULL;
//The event structure that will be used
SDL_Event event;
SDL_Surface *load_image( std::string filename )
{
//The image that's loaded
SDL_Surface* loadedImage = NULL;
//The optimized image that will be used
SDL_Surface* optimizedImage = NULL;
//Load the image
loadedImage = IMG_Load( filename.c_str() );
//If the image loaded
if( loadedImage != NULL )
{
//Create an optimized image
optimizedImage = SDL_DisplayFormat( loadedImage );
//Free the old image
SDL_FreeSurface( loadedImage );
}
//Return the optimized image
return optimizedImage;
}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
//Temporary rectangle to hold the offsets
SDL_Rect offset;
//Get the offsets
offset.x = x;
offset.y = y;
//Blit the surface
SDL_BlitSurface( source, NULL, destination, &offset );
}
bool init()
{
//Initialize all SDL subsystems
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}
//Set up the screen
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
//If there was an error in setting up the screen
if( screen == NULL )
{
return false;
}
//Set the window caption
SDL_WM_SetCaption( "Event test", NULL );
//If everything initialized fine
return true;
}
bool load_files()
{
//Load the image
image = load_image( "astyle.bmp" );
//If there was an error in loading the image
if( image == NULL )
{
return false;
}
//If everything loaded fine
return true;
}
void clean_up()
{
//Free the image
SDL_FreeSurface( image );
//Quit SDL
SDL_Quit();
}
//Initialize
if( init() == false )
{
return 1;
}
//Load the files
if( load_files() == false )
{
return 1;
}
//Apply the surface to the screen
apply_surface( 0, 0, image, screen );
//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
//While the user hasn't quit
while( quit == false )
{
//While there's an event to handle
while( SDL_PollEvent( &event ) )
{
//If the user has Xed out the window
if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
}
}
}
//Free the surface and quit SDL
clean_up();
return 0;
}
It is pretty much identical to what is on the tutorial so it should not be a problem with the code. I have followed the Instructions on Lazy foo to the letter, I have put all of the files in the right place and linked to them so i do not know what I am doing wrong.
Your compiler can't find the SDL/SDL_image.h header, that leads to all those 'undeclared' errors.
Maybe you skipped Step 2 in the linked instructions.
Are you sure you have the SDL_Image function at all? What IDE are you using?
If its visual studio make sure you have linked the following:
Also make sure you have downloaded the latest SDL_Image files from http://www.libsdl.org/projects/SDL_image/
Another possible issue is that you havent placed the SDL_Image DLL files in the correct place.
you should use
#include "SDL.h"
#include "SDL_image.h"
and make sure that you have put the sdl include folder in your include directory