Question

I have been attempting to get a simple SDL2 program up to display an image and then exit. I have this code:

/* compile with `gcc -lSDL2 -o main main.c` */

#include <SDL2/SDL.h>
#include <SDL2/SDL_video.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_surface.h>
#include <SDL2/SDL_timer.h>

int main(void){
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window * w = SDL_CreateWindow("Hi", 0, 0, 640, 480, 0);
    SDL_Renderer * r = SDL_CreateRenderer(w, -1, 0);

    SDL_Surface * s = SDL_LoadBMP("../test.bmp");
    SDL_Texture * t = SDL_CreateTextureFromSurface(r, s);
    SDL_FreeSurface(s);

    SDL_RenderClear(r);
    SDL_RenderCopy(r, t, 0, 0);
    SDL_RenderPresent(r);

    SDL_Delay(2000);

    SDL_DestroyTexture(t);
    SDL_DestroyRenderer(r);
    SDL_DestroyWindow(w);

    SDL_Quit();
}

I am aware that I have omitted the normal checks that each function succeeds - they all do succeed, they were removed for ease of reading. I am also aware I have used 0 rather than null pointers or the correct enum values, this also is not the cause of the issue (as the same issue occurs when I correctly structure the program, this was a quick test case drawn up to test the simplest case)

The intention is that a window appear and shows the image (which is definitely at that directory), wait for a couple of seconds and exit. The result, however, is that the window appears correctly but the window is filled with black.

An extra note SDL_ShowSimpleMessageBox() appears to work correctly. I don't know how this relates to the rest of the framework though.

Was it helpful?

Solution 2

When using SDL_RENDERER_SOFTWARE for the renderer flags this worked. Also it worked on a different machine. Guess there must be something screwed up with my configuration, although I'm not sure what it is because I'm still getting no errors shown. Ah well, mark as solved.

OTHER TIPS

I'll just clear this, you wanted to make a texture, do it directly to ease control, plus this gives you better control over the image, try using this code, fully tested, and working, all you wanted was for the window to show the image and close within 2 seconds right?. If the image doesn't load then it's your image's location.

/* compile with `gcc -lSDL2 -o main main.c` */

#include <SDL.h>
#include <SDL_image.h>  
#include <iostream> //I included it since I used cout


int main(int argc, char* argv[]){
bool off = false;
int time;

SDL_Init(SDL_INIT_VIDEO);
SDL_Window * w = SDL_CreateWindow("Hi", 0, 0, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer * r = SDL_CreateRenderer(w, -1, SDL_RENDERER_ACCELERATED);

SDL_Texture * s = NULL;
s = IMG_LoadTexture(r, "../test.bmp"); // LOADS A TEXTURE DIRECTLY FROM THE IMAGE
if (s == NULL)
{
cout << "FAILED TO FIND THE IMAGE" << endl; //we did this to check if IMG_LoadTexture found the image, if it showed this message in the cmd window (the black system-like one) then it means that the image can't be found
}
SDL_Rect s_rect; // CREATES THE IMAGE'S SPECS
s_rect.x = 100;    // just like the window, the x and y values determine it's displacement from the origin which is the top left of your window
s_rect.y = 100;
s_rect.w = 640; //width of the texture
s_rect.h = 480; // height of the texture

time = SDL_GetTicks(); //Gets the current time

while (time + 2000 < SDL_GetTicks()) //adds 2 seconds to the past time you got and waits for the present time to surpass that
{
SDL_RenderClear(r);
SDL_RenderCopy(r, s, NULL, &s_rect); // THE NULL IS THE AREA YOU COULD USE TO CROP THE IMAGE
SDL_RenderPresent(r);

}

SDL_DestroyTexture(s);
SDL_DestroyRenderer(r);
SDL_DestroyWindow(w);

return 0;   //returns 0, closes the program.
}

if you wanted to see a close button on the window and want it to take effect then create an event then add it to the while area to check if it's equal to SDL_Quit();, I didn't include it since you wanted it to immediately close within 2 seconds, thus, rendering the close button useless.

HAPPY CODING :D

I believe this to be (not 100% sure, but fairly sure), due to this line of code:

SDL_Renderer * r = SDL_CreateRenderer(w, -1, 0);

According to the SDL wiki article SDL_CreateRenderer, the parameters required for the arguments that you are passing in are as follows:

  • SDL_Window* window
  • int index
  • Uint32 flags

You are passing in the pointer to the window correctly, as well as the index correctly, but the lack of a flag signifies to SDL that SDL should use the default renderer. Most systems have a default setting for applications for which renderer should be used, and this can be modified on a application by application basis. If no default setting is provided for a specific application, the render look up immediately checks the default render settings list. The SDL wiki briefly refers to this list by the following line at the bottom of the remarks section:

"Note that providing no flags gives priority to available SDL_RENDERER_ACCELERATED renderers."

What's not explained here in the wiki is that the "renderers" the wiki is referring to comes from the default renderer list.

This leads me to believe that you have either changed a setting somewhere in the course of history of your computer, or elsewhere in you visual studio settings that is resulting in no list to be found. Therefore you must explicitly inform SDL which renderer to use because of your machine settings. Otherwise using an argument of 0 should work just fine. In the end this doesn't hurt as it's better to be explicit in your code rather than implicit if at all possible.

(That said, all of my deductions are based off of the fact that I am assuming that everything you said that works, works. If this is not true, then the issue could be because of a vast variety of reasons due to the lack of error checking.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top