SFML flickering renderwindow? - c++

I'm hoping someone can help me out, I'm using SFML 2.1 and when I draw my renderWindow it just keeps flickering, now I know SFML uses two buffers so i'm sure one is not getting drawn at all but I can't understand why.
Here is my loop
while(!quit)
{
rs.Canvas.pollEvent(gameEvent);
colour += 1;
rs.Update(colour);
if(gameEvent.type == sf::Event::Closed)
quit = true;
rs.Canvas.clear( sf::Color(colour,0,0) );
rs.Canvas.draw( sprite );
rs.Canvas.display();
if(colour >= 300)
quit = true;
}
the rs.Canvas has these set
Canvas.setVerticalSyncEnabled(true);
Canvas.setFramerateLimit(60);
Can anyone see why my renderWindow would flicker?

From the SFML 2.0 tutorial, under the section Controlling the framerate:
Never use both setVerticalSyncEnabled and setFramerateLimit at the same time! They would badly mix and make things worse.
http://www.sfml-dev.org/tutorials/2.0/window-window.php#controlling-the-framerate
In the comments of your post, you state that you were calling clear twice on the window. This would effectively treat your window as if it were single buffered. I understand that the effect of this could create some screen tearing, but on my end I am not getting a glaring flicker effect. Make sure to remove your a call to either setting the framerate or to using the vertical sync, just to be sure.

Basically I was calling
rs.Canvas.clear
twice. I removed the second call and everything then worked fine

Related

how can i draw a sprite by left clicking?

i've tried to make a project, but i can't draw a sprite as i want. I mean that everything works when i just draw a sprite, but it stop working when i am trying to draw the sprite by clicking left mouse button. There's code i tried:
if(zdarzenie.type == Event::MouseButtonPressed && zdarzenie.mouseButton.button == Mouse::Left)
{
pocisk.setPosition(10, 10);
oknoAplikacji.draw(pocisk);
}
Btw, I am writing in Polish as if it would change something.
And yes, i have everything good besides that.
(and i am using 2.4.1 version of SFML)
I don't know what you are doing now because you didn't provide enough of your code and I actually don't understand your if statement but, it can just be :
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sprite.setPosition(sf::Mouse::getPosition());
renderTarget.draw(sprite);
}
By the way I strongly suggest that you do not use the draw function here but organize your code to have a draw method called in a render loop, because depending on where your code is in your program, the sprite could be drawn for only one frame and then erased since it's not updated.
From what I understand in your code in Polish, you have the right code to do what you want, but the problem comes from the fact that you draw the sprite only once.
The draw method is called every frame and it will erase everything on screen and then redraw them. Doing it only once, like in your code, will only draw it a single time then delete it the very next frame.
At that point multiple solution can be used. If its a GameObject clicking can activate the object to then draw it or a simple bool could be used has a switch in your draw to make it appear.

Image over another image in allegro5 (C++)

I have a problem with adding a background in my game. My code looks like that:
while (true)
{
al_draw_bitmap(background, 0, 0, NULL);
al_flip_display();
some code(...);
al_draw_bitmap(snake,0,0,NULL);
/*drawing my snake's tail*/
al_clear_to_color(al_map_rgb(0,0,0));
al_draw_bitmap(apple,0,0,NULL);
al_flip_display();
}
And I have visible an apple and a black screen most of the time.
I've been changing order of some lines in code and none of these combination worked (best case was when I had visible snake and background but there was no apple).
Before adding a background, my snake's tail sometimes disappered, but it wasn't very visible, and except that, everything seemed to be okay.
Anyone knows how to add a background properly?
Or maybe it's fault of my computer?
Once per draw loop, you should:
clear the display
draw your background
draw bitmaps on top of the background
flip the display
For example:
al_clear_to_color(al_map_rgb(0,0,0));
al_draw_bitmap(background, 0, 0, NULL);
al_draw_bitmap(apple,0,0,NULL);
al_draw_bitmap(snake,0,0,NULL);
al_flip_display();
Note that you should only call al_flip_display once per draw loop, after you have drawn everything for that loop. al_clear_to_color should be called first as it will wipe out everything you have drawn. In the example you gave, you are drawing your apple and snake to the same location, so I wouldn't be suprised if one is blocking part of the other.
Also, you probably don't want to stick your draw loop in a while(true) as the framerate will be unconstrained. That is, it will run as fast as it is allowed, and the framerate won't be consistent. The typical approach is to use an event-driven draw loop.

SFML + fixed time step = lagging?

I have a short question. I am learning SFML and I made few apps by using it. Someday I learned about using fixed time step while coding games and it would be great if it worked. BUT. Even though I am making simple project like square moving from left to right side of the window - it is lagging! What could be a cause of this problem? This is my code:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "Window");
window.setVerticalSyncEnabled(true);
sf::Event event;
sf::Clock clock;
sf::Time accumulator = sf::Time::Zero;
const sf::Time timePerFrame = sf::seconds(1.f / 60.f);
sf::RectangleShape square;
square.setSize(sf::Vector2f(32, 32));
square.setOrigin(16, 16);
square.setPosition(400, 300);
square.setFillColor(sf::Color::Red);
int direction = 1;
int speed = 300;
while(window.isOpen())
{
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
{
window.close();
}
}
while(accumulator >= timePerFrame)
{
if(square.getPosition().x <= 16 || square.getPosition().x >= 784) direction *= (-1);
square.move(sf::Vector2f(speed * direction * timePerFrame.asSeconds(), 0));
accumulator -= timePerFrame;
}
accumulator += clock.restart();
window.clear(sf::Color::Black);
window.draw(square);
window.display();
}
return 0;
}
As you can see I know about vertical synchronization, but it doesnt help so much. Is my fixed time step loop wrong? Any help is appreciated!
Have you tried not enabling vertical sync? Both vertical sync and the timestep you have implemented may interfere with each other by both trying to control the framerate at the same time. On the SFML tutorial page for windows they state:
"Never use both setVerticalSyncEnabled and setFramerateLimit at the same time! They would badly mix and make things worse."
As you can see here from the source code for SFML:
void Window::setFramerateLimit(unsigned int limit)
{
if (limit > 0)
m_frameTimeLimit = seconds(1.f / limit);
else
m_frameTimeLimit = Time::Zero;
}
void Window::display()
{
// Display the backbuffer on screen
if (setActive())
m_context->display();
// Limit the framerate if needed
if (m_frameTimeLimit != Time::Zero)
{
sleep(m_frameTimeLimit - m_clock.getElapsedTime());
m_clock.restart();
}
}
SFML's setFramerateLimit function is implemented in much the same way as your timestep, and thus I don't believe the situation would be any different here.
Upon testing your code on my machine I did see a slight lag on the square, however, disabling vertical sync fixed the issue.
Edit: It turns out this issue is more complex than I originally thought (and I also overlooked the obvious need for vsync if there's tearing). After days of research and messing around with the code, I've learned of a few things that fix the issue:
Disabling vsync (though of course we already know this)
Recording the program with Fraps
Calling glFinish() after window.display()
Creating a window in either fullscreen, or borderless (with sf::Style::None) at the same size as the desktop
Disabling Windows Aero theme (though of course this only applies to Windows)
All of those except the first will fix it even when vsync is enabled. The main problem here seems to be that vsync doesn't work correctly in windowed mode, apparently it's a limitation due to how the program has to share screen space with other programs that don't necessarily have vsync enabled.
So my suggestion:
Use glFinish() after every display() call if using windowed mode, although this has a penalty, it halts the CPU and synchronizes it with the GPU and monitor when it could be processing asynchronously and uninterrupted, but if your program isn't particularly CPU intensive then this shouldn't be much of an issue. In SFML you can include "SFML/OpenGL.hpp" to get access to this function. Although if you are using Windows (Vista and 7 I believe, I don't know how 8 or 10 handles things though) then while using an Aero theme vsync is apparently automatically enabled and you may not have tearing to begin with. What operating system are you using?
Use fullscreen and just accept that there will be stuttering in windowed mode. It may not even be noticeable in an actual game or other graphical application, as opposed to a rigid high contrast square moving continuously back and forth on a blank background. I know that in the game I am working on right now I have the same problem, but I hardly ever noticed it.
Read up on the issue and see if you can find a true fix. Admittedly using glFinish is somewhat of a kludge, and dealing with stuttering or tearing in windowed mode may not be acceptable. I'm not entirely sure how glFinish manages to eliminate the stutter, and it's usually never recommended to call that function anyway.
Some further reading:
https://superuser.com/questions/558007/how-does-windows-aero-prevent-screen-tearing
http://www.cplusplus.com/forum/general/108295/
http://forums.nesdev.com/viewtopic.php?f=3&t=9262#p98808 (especially
this post by rainwarrior)
https://www.opengl.org/wiki/Swap_Interval (what SFML calls internally
to enable vsync)
http://www.gamedev.net/topic/381574-sdl-no-vsync-in-windowed-mode/
http://larian.com/forums/ubbthreads.php?ubb=showflat&Number=482323
http://dev.dota2.com/archive/index.php/t-11450.html

C++ SFML mouse movement

I'm trying to detect mouse movement event and move it back to the middle of the screen using sf::RenderWindow pollEvent method and detect the event type sf::Event::MousePressed. The problem is when I'm detecing the mouse movment I need to move the mouse back to the middle of the screen and for that im using sf::Mouse::setPosition but I think (maybe I'm wrong) that function itself calling sf::Event::MouseMoved when it used, and im afraid it creates an infinite loop.
Exmaple of the way im doing that: (I know 0, 0 it's not the middle it is just and exmaple)
while (app.pollEvent(Event))
{
if(Event.type == sf::Event::MouseMoved)
{
sf::Mouse::setPosition(0 , 0));
}
}
Sorry for my bad english!
Thanks in advance!
Try using app.SetCursorPosition(x, y); instead.
Also, i would skip the check for events, since you will want the cursor to end in the middle at the end of each frame anyway.

SDL_Delay doesn't delay before each action

I have written program which has a delay between each drawn circle, but when i put for example SDL_Delay(2) everything is black for like 5 seconds and then i see everything already drawn, but i need to see everything from begining so that it would seem like an animation.
Here is my code:
while (t<tk){
l.a = l.a + (l.b - l.a) * t;
a=l.a;
Circle cir1(a,o);
draw_circle(cir1, canvas);
SDL_Delay(2);
t=t+0.001;
}
The thing is after each draw_circle you actually have to update the screen. Draw functions in almost all graphical engines write to a buffer and don't update the screen until you tell them to!
I don't know how this works with SDL that doesn't use OpenGL, but with double buffer OpenGL windows you should write SDL_GL_SwapBuffers() and then after it, start clearing the screen etc as if you are drawing the screen anew!
If it is a single buffer window, you should flush the buffer to update the screen. I never used SDL by itself (without OpenGL) so I don't know the function names, but with this hint you know why your code doesn't work and you should be able to find the functions you need from SDL documentation.