SDL Renderer Issue

Started by
11 comments, last by Aldacron 8 years, 1 month ago

I cannot get my player object of the sprite class to display on the screen. I am pretty sure it is a composition issue having to do with SDL* Renderer, but I cannot figure out exactly what the problem is. I have been banging my head on the keyboard for five days now and I cannot get the sprite object to display.

Really appreciate the help.

If you see any other bugs, let me know.

- learnedseeker

Also, the texture does display fine, and since I couldn't get the sprite to display, I actually created it as a texture and then slowly converted it over to being a sprite (and that was after a few days of just fiddling with the sprite itself) - so the screen and the texture display just fine. It's just getting the sprite class rendered.

Advertisement

I am pretty sure it is a composition issue having to do with SDL* Renderer


What facts are you basing that on? If you have a guess, but nothing to prove it, and that guess happens to be false, aren't you pre-poisoning our examination of your code with the same potentially false guess? wink.png

But you haven't given us many symptoms. Is the screen getting cleared to the expected color? Is the grass texture showing up fine? Those are important clues.

Walking into a doctor's office and saying, "Doctor, I think I have cancer." isn't actually helping the doctor (he has to then ask "Why do you think you have cancer?" to get actually helpful-information). But you give actual valuable information if you inform him of the symptoms: "Doctor, for the past twenty days I've been having terrible pains in my forehead.". Doctor: "Okay, after taking those symptoms and running tests, I've concluded it's likely just migraines caused by you using the wrong prescription of glasses." smile.png

This is important to realize even when you are debugging things on your own. Often times, it's my false assumptions that keep me from seeing the problem in the code, but by re-establishing the facts and separating out the assumptions, I can occasionally save myself a few keyboards worth of head-trauma. biggrin.png

It looks like you are loading the image, and then freeing it, without actually converting it to a texture (you have that line commented out).


surface = IMG_Load("C:\\Users\\Devlin\\Documents\\Visual Studio 2015\\Projects\\Project Flesh\\Dependencies\\bob.png");
//texture2 = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);

More importantly, you're not checking for errors. ohmy.png
Error checking is super important. Maybe IMG_Load() is just failing because SDL_image hasn't been initialized correctly, or because the PNG file is invalid, or because the file isn't located at the location you think it is located at, or something to that affect. Proper error checking can tell you the cause of the problem, the moment it occurs, instead of you "banging my head on the keyboard for five days now". I like it when my code says, "Yo, homeboi, your problem is X.", because it tells me in 2 seconds what may take me two hours or two days to find out on my own - error checking does that for you (and learning to use debugging tools is the next time-saver after error-checking).

(Btw, you can use '/' as path separators on Windows instead of escaping '\\')

You're reusing the same variable ('surface') twice for different purposes. Usually that's a bad sign.
Your texture names ("texture" and "texture2") aren't good variable names. The name of a variable should inform the reader what it's for, not what it is. We already know it's a texture - the variable name doesn't need to inform us of that. But we don't know what it's for, and the variable name is failing to tell us.

Also, if you have almost-duplicate code in your project somewhere, it's an indicator that the duplicated code should be broken into their own function.

This code is almost duplicate, because it does the same three things: Loads an image into a surface, converts it to a texture, and then frees the surface.


surface = SDL_LoadBMP("C:\\Users\\Devlin\\Documents\\Visual Studio 2015\\Projects\\Project Flesh\\Dependencies\\grass.bmp");
texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
surface = IMG_Load("C:\\Users\\Devlin\\Documents\\Visual Studio 2015\\Projects\\Project Flesh\\Dependencies\\bob.png");
//texture2 = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);

It should look like:


grass  = LoadImageIntoTexture("C:/Users/Devlin/Documents/Visual Studio 2015/Projects/Project Flesh/Dependencies/Grass.bmp");
player = LoadImageIntoTexture("C:/Users/Devlin/Documents/Visual Studio 2015/Projects/Project Flesh/Dependencies/Bob.png");

That's much clearer and neater.
It also helps highlight that you are loading both images from the same folder. Which indicates that that folder path shouldn't just be copy+pasted, but should be seperated into its own variable:


//Stored elsewhere:
const std::string TextureDirectory = "C:/Users/Devlin/Documents/Visual Studio 2015/Projects/Project Flesh/Dependencies/";
 
grass  = LoadImageIntoTexture(TextureDirectory + "Grass.bmp");
player = LoadImageIntoTexture(TextureDirectory + "Bob.png");

This is important because if you change or rename the folder where the textures are kept (say, to "..../Dependencies/Textures/"), you only have to change your code in one location (the variable), instead of hundreds of locations. Also, your project may eventually need "TextureDirectory" to change at runtime. If I installed your game, the filepath may need to change to: "Q:/System/Windows27/Program Files (x128)/Devlin Games/Project Flesh/Dependencies/Grass.bmp", so it's important to keep the changing-per-user (but relative between textures) part of the filepath in its own variable.

Inside LoadImageIntoTexture() is also where you'll want to do your error-checking, so you're not duplicating your error-checking code either.

Note also: IMG_Load() can load BMP files just fine. You don't need both SDL_LoadBMP() and IMG_Load(). Just use IMG_Load() everywhere, including for BMP files.

Finally, you are supposed to load an texture and keep on using it, frame-after-frame. But in your current code, you are reloading the exact same textures, over and over, every frame (because you are loading the textures in your GraphicsCore::update() function).

Hopefully that helps. If not, you're going to have to post the Sprite.h and Sprite.cpp files.

Hopefully that helps. If not, you're going to have to post the Sprite.h and Sprite.cpp files.

Player is a texture, HANDLED IN THE SPRITE CLASS. It is not texture 2, that is leftover from the "conversion". Ignore anything commented out.

Here is a link to the sprite files (I'm 99.9% certain the sprite class is fine, not sure why I decided to not post them before...):
http://pastebin.com/7Jnq6DEd

Which I didn't include in the other files, which I am posting here for convenience (same as above):
http://pastebin.com/NsfmYC0J

Thanks for your help!

- learnedseeker

To run through the program - I launch, it compiles fine (as long as sprite is commented out). The window boots up, music plays (didn't include those files for obvious reasons). The grass texture shows up as planned, and it runs until I x out of the window.

But player doesn't show. =\ =\ =\

Everything works except the player.


player->draw();
SDL_RenderCopy(renderer, texture, NULL, NULL);

Doesn't that mean you draw the player texture first and then fill the screen with grass texture? Try swapping those lines.

Derp


player->draw();
SDL_RenderCopy(renderer, texture, NULL, NULL);

Doesn't that mean you draw the player texture first and then fill the screen with grass texture? Try swapping those lines.

Thanks for the idea, but no, I've already tried that. (I gave it another go, just to be sure).

You don't seem to initialize Sprite's renderer anywhere?

Derp

You don't seem to initialize Sprite's renderer anywhere?

it's initialized in sprite.cpp

You've changed the code? The codes you gave don't initialize it.

Derp

You've changed the code? The codes you gave don't initialize it.

Yeah that was the problem.

Why uhhhh did I have to add this line:

renderer = passed_renderer;

into the cpp for sprite?

Now I have to ask so that it sinks in...:

How come the compiler cannot "figure it out"?

I was trying to assign that renderer to the renderer in GraphicsCore?

THANK YOU FOR YOUR HELP. GAHHH. <3

How come the compiler cannot "figure it out"?

Because that's not how C++ works. It expects you to be explicit about things like assignment, and does not attempt to "magically" assign constructor parameters to member variables based on the parameter names and/or types.

C++ as a language generally assumes you know it and know what you are doing.

This topic is closed to new replies.

Advertisement