Red Flicker down or right direction

Started by
10 comments, last by Zakwayda 5 years, 8 months ago

Hello,

I am currently reading Procedural Generation Content with C++. They start you off with a basic template using SFML, and it slowly builds off it. I have noticed a bug that is really bothering me now. I thought it might have been an error on my part. Unfortunately, it seems to be the source code in general. I did a google for the source code on github to see if someone fixed the problem. I only found some people who literally copied the final example's source code, which isn't helpful because I own it already. 

What is happening is when I am stationary and press either down or right, there is a quick red flicker. If I am already moving and press down or right, there is no problem. I've tried messing around with the texture manager and they have done in a way I have not come across yet and I'm wondering if this is the issue or if I'm wasting my time. I would like to keep the book's code, but I might just replace the whole thing.


// Gets a texture from the texture manager from an ID.
sf::Texture& TextureManager::GetTexture(const int textureID)
{
	auto it = m_textures.begin();
	auto found = false;
 
	while (it != m_textures.end())
	{			
		if (it->second.first == textureID)
		{			
			return *it->second.second;		
		}
		else
		{
			++it;
		}
	}
}

I can't recall exactly what I did. But messing around with a modern for loop and the traditional way gave me different results. With one of the for loops, I got a "white" flicker when I went left now. I changed it back and the white is now gone. So I believe it has something to do with this. The original code from the book did this


for (auto it = m_textures.begin(); it != m_textures.end(); ++it)
	{
		if (it->second.first == textureID)
		{
			return *it->second.second;
		}
	}


When I changed the for loop to the modern iteration, the white flicker appears. So I have no idea what that means since I thought it was the same thing. 

I hope this is enough information for an idea of the problem. Down below I posted a link of the source code from someone's Github that is basically the exact same from the basic template standpoint. If anyone can get me through this, I would greatly appreciate it. 

https://github.com/utilForever/ProceduralContentGeneration

Thanks, have a great day!

Advertisement

Maybe it's clear from what you posted, but are you saying the bug is present in the book's code as is? Or that it only manifested after you made changes?

It's clear what the GetTexture() function you posted is doing, but there's an unused 'found' variable, and not all code paths return a value. The return value issue seems to exist in the code you linked to as well. Not sure if that's related, but it's an issue that jumped out.

What do you mean by flicker? Do you have a graphic or something that's changing colors briefly? Or maybe a different graphic is being substituted briefly?

Hello Zakwayda,

The template provided in the book has the bug. I haven't changed anything related to the provided code for Input, TextureManager, SoundBuffer, or the Object code. Which basically makes up the very small engine example to work with. I thought it was something I did, so I ran the template from scratch and the final example. But they all produce the same bug. So I tried to find someone on Github who possibly noticed this and fixed it themselves, but I just found direct copies of the final example (which I have all the chapters).

When I say 'flicker', I mean when I press either the down or right direction from a stationary position, there is a red box, sort of outlining the sprite for a split second, that is noticeable. It reminds me of a red square placed on top of the sprite with some transparency to it, where I still can see the character.

When you are walking around, the animation runs smoothly and you don't see any of the "red box flicker". Up and left do NOT produce this. But going back to where I said "I changed the 'for loop' to a modernized one" straight from the book, it actually created the same problem, except the "left direction" produced a WHITE Flicker, replicating the RED from the right and down direction. So left was white, right and down remained red. I fixed the WHITE flicker issue though by going back to the original 'for loop' or using a while loop like my first code snippet. That was a recommendation from ReSharper to use the 'modernized loop' which caused the white flicker. 

--------------------------------------------------------------------------------------------------------------------------------------------------------
(The warning 'not all control paths have a return Warning)

I'm glad you mentioned the unused 'found' variable. I did some googling on 'not all control paths have a return'. I could not really find anything that helped me solve it. I thought changing the code with the while loop and adding the else would help. ReSharper suggest's an extra return (for the warning obviously). But I'm not sure how to get rid of the warning correctly and this could be related to the problem.

This is what the 'for loop' is iterating.


static std::map<std::string, std::pair<int, std::unique_ptr<sf::Texture>>> m_textures;

At one point, I had found a quick solution to get rid of the warning. Long story short, I had to copy the original template code again after replacing the code and forgot about how I fixed that warning. I believe I did something very odd and created an empty texture. I doubt it was the correct way and just got rid of the warning. I also get this same warning with the SoundBuffer class.

What my problem is, I'm not sure what to return as a 'sf::Texture' that will correct the warning and possibly the issue. The previous books I've read, typically do this differently.

Thanks, sorry the long post. I thought I'd provide 2 separate parts in one post.

 

I can only guess as to the cause of the flicker effect, but I'll offer some suggestions as to how to go about debugging it.

I see some things in the code that might be worth a second look, like returning a reference to a non-constant Texture acquired by dereferencing a unique_ptr. Unless the returned references are outliving the texture objects themselves though, that's probably not an immediate issue.

I believe how the compiler responds to a missing return in a non-void function depends on the development environment. If I recall correctly though, failing to return is undefined behavior (except for main(), which is an exception).

Regardless, it's a conceptual error, so fixing that is a good place to start. If it's expected that the requested texture will always be present, you could throw an exception at the end of the function indicating that the requested texture wasn't found. (Others might have different advice though.)

From there, there are lots of things you could do to try to narrow down the problem. For example, disable rendering of the main graphic. If you still see the flicker, that suggests it's not the main graphic rendering incorrectly, but rather something else rendering along with the main graphic. Or, if there's code that selects a different graphic based on the direction of movement, temporarily change it so that the same graphic is always used. If you then always get the flicker, or never get the flicker, that will suggest that the problem is related to specific graphics. There are probably plenty of other diagnostics you could do along those lines as well.

I don't have time to look through all that code in your link, but the only time I've ever heard of the "flicker" problem is when you're doing one of the following:

1. Passing by value and not reference, then once out of scope that copy is destroyed. (Make sure you're not dealing with copies!)

2. Using something like std::vector and referencing a spot in memory, but then changing the size of the container leaving the prior spot for (x) texture moved in memory so your reference is no longer valid.

I would suggest doing the following. Create your texture manager and use a unique_ptr for the container. Once all your textures are set you can pass by reference going forward. Do not pass anything until all textures are all loaded in. Double check to make sure you're passing by reference and not by value.

I've seen this "problem" happen time and time again with new people to SFML, but it's not an SFML issue, it's a user error using C++ correctly. If by chance this is an mistake in SFML which I doubt, if you compile to the latest version it would go away.

I also made a texture manager for a SFML project months back and did not experience any flickering issues doing it this way. I would suggest you take the concept behind how a texture manager works, and make your own code.

Programmer and 3D Artist

Maybe it's not that piece of code at all (the original code looked correct to me). Perhaps it's how you're using the code. Are you running an example from the book or did you create your own example? Could you show us the code sample either way?

Hello guys,

This wasn't my code, it was provided as a template project to continue off. The only changes I have made are to the gameplay itself. So I have not touched their code for creating the level, animation, texture loading.

Rutin, I've made a texture manager before and I've never had this problem. But I would have assumed the author of the book knew what he was doing. I was just trying to see if I can fix it the way he provided. I might just have to do this my way, which is what I was trying to avoid since I rather focus my attention on gameplay. I will definitely give those debugging tips a shot. Also, I don't expect you to take a look at all that code and appreciate your thoughts on it.

So it is from the original piece of code. Since you can compile it straight out of the box, with no alterations, and get the same bug. I have found various people on Github who must have been using the book as well, and you see right away the bug is present. I believe the link I provided required some work to get it to run. But it's essentially the same deal.

I appreciate all the tips! Unfortunately, I might just do the animation and texture manager over. For now, I'm just going to finish off the book and come back to it.

Zakwayda: I'll be sure to try that and I appreciate all the help.

AtomicWinter, I posted the github link to someone who has, what looks like the final example source code (I'm not sure if it was even changed). You could click that and just view the source for the TextureManager, Input, Object, Level, SoundBuffer. Because like I said, that part was never changed so it will be the same.

Once again the link was https://github.com/utilForever/ProceduralContentGeneration . The only thing that's different from my version and the final example is gameplay elements. Everything else was fresh from the book and never changed. 

 

Thanks, everyone!

PS: Lots of stuff provided to try and solve the problem and I'll be sure to report back if I figure it out! 

 

I built the project and ran it, and while I haven't really gone through the code yet, my initial test runs indicate that the problem is most likely with your animation state switching logic, rather than with the texture cache. What led me to believe this is that when you walk upward, if you repeatedly start walking then stop, you can sometimes see flashes of the downward-facing idle sprite, as just a flash of eyes that quickly disappears. This makes me think that the state switching is glitchy, which could be causing issues with sprite frame selection.

 

I managed to fix 95% of the problem. In the Game constructor, the book code has 

 


//m_window.setVerticalSyncEnabled(true);

I commented that out and it went away. But I can still occasionally see it appear, but it no longer happens every single time. If I press down and right enough times, I'll see it appear. 

For the MOST part, it has been solved. I was wondering if anyone has some additional input on that and if it's possible to totally remove it from here?

Thanks for all the help and advice, I really appreciate it.

JTippetts, I greatly appreciate you taking the time to run the code yourself as well. Perhaps you are on to something mixed with this vertical sync feature. 

Thanks everyone!

I doubt vsync is the culprit. Turning it off is probably just partially hiding the issue. 

This topic is closed to new replies.

Advertisement