-
Hello,
I'm using SFML 2.0 (compiled from the source files) on windows and I am trying to use the rendertexture. Which works fine as long as I do not move anything around, when I animated a sprite to move I got the following effect:
(http://tux.servegame.org/~zapfyr/temp/RenderTexture.png)
The code for this is a bit complex, however the core of it is the following:
renderTexture->clear();
/// Draw everything!
RenderingManager::RenderObjects(renderTexture);
renderTexture->display();
// Clear screen
window->clear();
window->draw(*renderSprite);
// Update the window
window->display();
RenderingManager::ClearRenderList();
Which is built around the example code for rendertexture usage:
// Create a new render-window
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
// Create a new render-texture
sf::RenderTexture texture;
if (!texture.create(500, 500))
return -1
// The main loop
while (window.isOpen())
{
// Event processing
// ...
// Clear the whole texture with red color
texture.clear(sf::Color::Red);
// Draw stuff to the texture
texture.draw(sprite); // sprite is a sf::Sprite
texture.draw(shape); // shape is a sf::Shape
texture.draw(text); // text is a sf::Text
// We're done drawing to the texture
texture.display();
// Now we start rendering to the window, clear it first
window.clear();
// Draw the texture
sf::Sprite sprite(texture.getTexture());
window.draw(sprite);
// End the current frame and display its contents on screen
window.display();
}
I am running this on a AMD HD7870 Eyefinity card on 2 monitors with the latest drivers installed.
// Zap
-
This shouldn't and actually can't happen, thus I suspect that your clear() call doesn't get executed, but without the full code it's impossible to say. But since you provide an example, does the example also not clear the RenderTexture?
-
I fairly sure that the rendertextures clear is called. Every visual object in my program have Z-value, when update is done all objects are pushed to a list in a sorted order (kinda like painters algorithm) when they shall be drawn the program iterates over the objects and draws them in order. Here is a bit more code:
void Player::Run(const sf::Time &delta)
{
isRunning = window->isOpen();
if (isRebuilding)
Rebuild();
HandleEvents(delta);
Update(delta);
Draw(delta);
UpdateLayout();
frameRate = 1.0f / delta.asSeconds();
}
void Player::CleanUp()
{
isRunning = false;
if (renderSprite != NULL)
{
delete renderSprite;
renderSprite = NULL;
}
if (renderTexture != NULL)
{
delete renderTexture;
renderTexture = NULL;
}
if (window != NULL && window->isOpen())
{
window->close();
delete window;
window = NULL;
}
LogMessage("Shuting down and cleaning up player module.", utils::LogManager::P2, utils::LogManager::PLAYER);
}
void Player::HandleEvents(const sf::Time &delta)
{
sf::Event event;
while (window->pollEvent(event))
{
// Close window : exit
if (event.type == sf::Event::Closed)
isRunning = false;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
isRunning = false;
}
}
void Player::Update(const sf::Time &delta)
{
if (root != NULL)
root->Update(delta);
}
void Player::Draw(const sf::Time &delta)
{
if (window != NULL &&
renderTexture != NULL &&
renderSprite != NULL)
{
renderTexture->clear();
/// Draw everything!
RenderingManager::RenderObjects(renderTexture);
renderTexture->display();
// Clear screen
window->clear();
//window->draw(*sprite);
renderSprite->setPosition(Utils::Vec2ToSFVec(utils::GraphicsManager::GetOrigin()));
renderSprite->setScale(Utils::Vec2ToSFVec(utils::GraphicsManager::GetAdaptedScale()));
window->draw(*renderSprite);
//RenderingManager::RenderObjects(window);
// Update the window
window->display();
RenderingManager::ClearRenderList();
}
}
void Player::Rebuild()
{
isRebuilding = false;
}
-
To whole run/cleanup/update thing doesn't really help since it's not connected to the drawing part.
What does RenderingManager::RenderObjects do?
-
void RenderingManager::RenderObjects(sf::RenderTarget *target)
{
auto itr = renderList.begin();
for (; itr != renderList.end(); ++itr)
{
Object *obj = *itr;
obj->Draw(target);
}
}
Where renderList is:
std::list<Object*> RenderingManager::renderList;
And Object is the base class for all visual objects, where Draw is a purely virtual function, e.g. ObjectImage's Draw looks like this:
void ObjectImage::Draw(sf::RenderTarget *target)
{
if (sprite != NULL)
target->draw(*sprite);
}
-
std::list<Object*> RenderingManager::renderList;
And it contains only one object of the animation or does it hold all objects of your animation?
I mean if you want to move object x you move it, push it into the list and draw it.
But if you now keep doing this for every iteration the list will contain every object at any position and it's obvious that when drawing the whole list every object is drawn. ;)
-
The list contains all object that should be drawn, and it is cleared every frame (I check that before posting ;) ). At the moment the screenshot was taken the list contained two objects (the bottle and the text).
-
Then let's get back to the simple example...
How does the following code perform?
#include <SFML/Graphics.hpp>
#include <list>
int main()
{
sf::RenderWindow window(sf::VideoMode(500, 500), "Test");
window.setFramerateLimit(60);
sf::RenderTexture rt;
rt.create(500, 500);
sf::RectangleShape rs;
rs.setSize(sf::Vector2f(20, 20));
rs.setPosition(0.f, 0.f);
rs.setFillColor(sf::Color::Red);
sf::Sprite sprite;
sprite.setTexture(rt.getTexture(), true);
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
}
rs.setPosition(static_cast<sf::Vector2f>(sf::Mouse::getPosition(window)));
rt.clear();
rt.draw(rs);
rt.display();
window.clear();
window.draw(sprite);
window.display();
}
}
If the render texture also doesn't get cleared then it's an issue with SFML and your graphics card (is the driver uptodate?).
If it gets cleared then it's something within your code and you should investigate further...
-
This is the results of running your code:
(http://tux.servegame.org/~zapfyr/temp/RenderTexture1.png)
I am running the AMD Catalyst 12.8 drivers, which is the current version.
-
Well then there's something wrong with SFML/your setup.
SFML 2.0 (compiled from the source files)
Can you give the commit ID and state what compiler you use in which setup (release/debug, static/dynamic)?
-
eXpl0it3r's code works on my system. I am also using Catalyst 12.8 so it can't be a driver bug. I hardly doubt this has anything to do with your specific hardware either. OpenGL calls not getting executed is normally a result of software malfunction. Did you try to run it in debug mode? When NDEBUG isn't defined SFML_DEBUG should get defined and any OpenGL errors that occur will be printed to stdout.
-
Can you give the commit ID and state what compiler you use in which setup (release/debug, static/dynamic)?
I built and tested on both release and debug, dynamic. I grabbed the snapshot a week ago, so I don't think I know the commit ID, sorry. :( I will rebuild SFML from the current snapshot tomorrow and test again.
When NDEBUG isn't defined SFML_DEBUG should get defined and any OpenGL errors that occur will be printed to stdout.
I tested in both release and debug didn't see any OpenGL errors, didn't know about SFML_DEBUG tho, I am kinda new to SFML. Will look more carefully for errors, tomorrow.
Thanks for the fast replies, guys!
// Zap
-
I have now built SFML from the latest snapshot, and the result is the same (running eXpl0it3r code), in both release and debug, using dynamically linking. Didn't see any OpenGL errors or similar. What should I look into next?
-
Did you get the SFML examples to work? It could be that clearing the framebuffer doesn't work and it just looks like it is the RenderTexture that is broken. Not being able to clear the framebuffer is probably known best from when a program in Windows hangs so if that really is the case it probably has to do with the operating system.
-
Everything seems to work fine, except RenderTexture, the framebuffer clears nicely. :)
-
Try downloading http://www.songho.ca/opengl/files/fbo.zip and running the executable and see if it runs "as expected". It uses FBOs and if SFML didn't screw up and is also using the FBO RenderTexture implementation as opposed to the default then this should be able to confirm whether it is a problem related to FBO clearing. Too bad SFML has no way of checking what implementation it is using... or maybe I just didn't look hard enough.
-
Too bad SFML has no way of checking what implementation it is using...
Since this would be useful only for advanced debugging in very specific cases, it probably doesn't deserve a dedicated public API. Just compile SFML from sources and put a breakpoint on the code that chooses the implementation.
-
Try downloading http://www.songho.ca/opengl/files/fbo.zip and running the executable and see if it runs "as expected"
It runs as expected.
I will try to run my project on my other computer with an Nvidia 580 GTX graphics card as soon as possible and report back the results.
-
It runs as expected.
Ok, so somehow SFML doesn't use FBOs the same way as this demo.
Here is an OpenGL-only version of what sf::RenderTexture does internally:
http://en.sfml-dev.org/forums/index.php?topic=9149.msg61891#msg61891
Maybe you can find the difference by testing and comparing these two programs.
-
This is the results of running your code:
(http://tux.servegame.org/~zapfyr/temp/RenderTexture1.png)
I am running the AMD Catalyst 12.8 drivers, which is the current version.
I get the same results using the SFML 2.0 RC.
Graphicscard is also an AMD, but its a 6950.
When it occured within my project i thought it were my fault, but it seems to be a more general problem.
-
I get the same results using the SFML 2.0 RC.
What about the latest sources?
-
Sorry to resurrect this thread from last year, but I'm having the same experience with RenderTexture not clearing.
Hardware: AMD Radeon 6950
Software Driver Version: 13.1
I'm building SFML from source in Windows 7, I forked SFML from 38da3f4338e3b2b11e3dff2726a62104cf27fa73 (https://github.com/SFML/SFML/commit/38da3f4338e3b2b11e3dff2726a62104cf27fa73) and have made no modifications to the source.
I ran the sample program that renders a red square with the same results at Zapfyr.
Any ideas? Is there anything I can do to help dig into this problem?
-
Can you explain the problem again please? I don't feel like reading the whole conversation to find out what you want ;)
-
The issue I am experiencing is that calls to RenderTexture::clear are not actually clearing the texture. Since I draw everything to a texture this causes a problem unless I draw enough to cover the entire screen.
-
Have you tried to investigate with the hints given in this thread?
-
Yes, I noticed the issue in my application first, but I also tried the sample application on page 1 with the same results as the OP.
Edit: As in the OP's experience, drawing to a RenderWindow, for example, works as expected. The screen is cleared every frame. Drawing to a RenderTexture, however, does not work as expected and I see only repaints of the things that change (almost like a dirty rectangle drawing strategy).
When I run the sample application I see the same thing as the OP sees, namely a bunch of red quads instead of only one.
Edit 2: It also seems to be hardware-specific because i tried the same application on my other machine and it is working as expected; the screen is cleared each frame. The other machine has Intel integrated graphics but I don't remember the specifics.
-
And what about this?
Try downloading http://www.songho.ca/opengl/files/fbo.zip and running the executable and see if it runs "as expected"
It runs as expected.
Ok, so somehow SFML doesn't use FBOs the same way as this demo.
Here is an OpenGL-only version of what sf::RenderTexture does internally:
http://en.sfml-dev.org/forums/index.php?topic=9149.msg61891#msg61891
Maybe you can find the difference by testing and comparing these two programs.
-
The application from http://www.songho.ca/opengl/files/fbo.zip runs as expected, switching FBO on and off shows no difference in functionality. The teapot is drawn rotating on each face of the cube and the screen is cleared each frame.
I haven't run the OpenGL-only version of the code -- what is the expected outcome? I will run it tomorrow when I have a chance and report my findings.
-
what is the expected outcome?
A white window.
-
Ok, the compiled program from the source provided at http://en.sfml-dev.org/forums/index.php?topic=9149.msg61891#msg61891 is working as expected; it exits with a return value of 0.
-
So can you now try the same kind of minimal app, but which uses sf::RenderTexture? (shouldn't be hard to do, the equivalent calls are written in the comments)
-
Here is the minimal application that uses RenderTexture that I tried:
#include <memory>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
int main()
{
sf::VideoMode videoMode(640, 480, 32);
sf::RenderWindow window(videoMode, "RenderTexture Test");
sf::RenderTexture renderTexture;
renderTexture.create(32, 32);
bool exit = false;
while(!exit) {
sf::Event e;
while(window.pollEvent(e)) {
if(e.type == sf::Event::Closed) {
exit = true;
}
}
window.clear(sf::Color::Black);
renderTexture.clear(sf::Color(255, 255, 255, 255));
renderTexture.display();
sf::Sprite s(renderTexture.getTexture());
window.draw(s);
window.display();
}
return 0;
}
It produces similar behavior as the "plain" OpenGL application -- a window is displayed with a 32x32 white square in the top left corner.
-
So it works after all ;)
Now you must find what's different in your code, that produces your problem.
-
No, I think there is an issue with SFML and my graphics card. Here is a sample program does not work correctly:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(500, 500), "Test");
window.setFramerateLimit(60);
sf::RenderTexture rt;
rt.create(500, 500);
sf::RectangleShape rs;
rs.setSize(sf::Vector2f(20, 20));
rs.setPosition(0.f, 0.f);
rs.setFillColor(sf::Color::Red);
sf::Sprite sprite;
sprite.setTexture(rt.getTexture(), true);
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
}
rs.setPosition(static_cast<sf::Vector2f>(sf::Mouse::getPosition(window)));
rt.clear();
rt.draw(rs);
rt.display();
window.clear();
window.draw(sprite);
window.display();
}
}
Here is what I see when I move my mouse across the screen with this program:
(http://zackthehuman.com/sfml/rendertexture-issue.png)
There should only be one red square located where my mouse cursor is, but instead there is a trail. Now, it seems to actually be clearing a region close to where the repaints are happening, which seems strange.
I have a simple and strange "fix" for this; draw a transparent quad over the entire screen and things are cleared properly. Here's a "fixed" version of the sample program above:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(500, 500), "Test");
window.setFramerateLimit(60);
sf::RenderTexture rt;
rt.create(500, 500);
sf::RectangleShape rs;
rs.setSize(sf::Vector2f(20, 20));
rs.setPosition(0.f, 0.f);
rs.setFillColor(sf::Color::Red);
sf::Sprite sprite(rt.getTexture());
sf::RectangleShape screenClearer;
screenClearer.setSize(sf::Vector2f(500, 500));
screenClearer.setPosition(0.f, 0.f);
screenClearer.setFillColor(sf::Color::Transparent);
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
}
rs.setPosition(static_cast<sf::Vector2f>(sf::Mouse::getPosition(window)));
rt.clear();
rt.draw(rs);
rt.draw(screenClearer);
rt.display();
window.clear();
window.draw(sprite);
window.display();
}
}
-
Are your SFML 2 and graphics drivers up-to-date?
-
Although I hadn't experienced the problem at the time I've written the example, I do now.
Then again I got a new PC with a slightly different graphics card, but the drivers are up to date and I'm obviously using SFML 2. It btw doesn't matter if I used VS or MinGW, debug or release...
Not sure what this could be, also the "fix" works.
-
I just pulled the latest revision from GitHub and my drivers are up-to-date (I double checked :P).
-
I'm sorry I can't investigate myself, so if you want this bug to be fixed you'll have to spend some time on it.
What I would do, is to translate your minimal app to OpenGL-only code (since the one that I already wrote doesn't show the problem), make sure that it still produces the error of course, and then compare it with the FBO sample that works.
-
I have a simple and strange "fix" for this; draw a transparent quad over the entire screen and things are cleared properly. Here's a "fixed" version of the sample program above:
thanks a lot for the trick.
-
RenderTexture.clear(sf::Color(255,255,255,0));
-
I've recently run in to this bug while trying to implement post-effect shaders without copying the contents of the window and I believe that I may have come across some additional information which may help quash this bug.
When running with a shader on, renderTexture.clear() appears to be working as intended but when the shader is switched off the problem appears again. While the previous work-around of drawing a transparent shape over the entire renderTexture works I've found another work-around which may help narrow down where the problem lies. If you call window.resetGLStates() at any point in the rendering loop the problem disappears. Looking at the source for RenderTarget::resetGLStates I've tried using all of the OpenGL calls there in my code after calling window.setActive() and it doesn't seem to have any effect. So it must be one of the other parts of resetGLStates() that is correcting the problem. It also seems weird that the call is to the window and not the renderTexture to fix the problem. I tried calling it on the renderTexture but it had no effect.
So far this seems to only be affecting ATI cards. I'm running Win 7 x64 with a Radeon 7970. My graphics card drivers are Catalyst 13.12 and I'm using the pre-compiled SFML 2.1 libs statically linked. My compiler is VS2012 x64 and the problem appears in both debug and release builds. There are no error messages sent to the console window and I've broken the shader program before and the error messages were sent to the console so the error output is working.
I've attached a piece of sample code below which demonstrates the problem on my machine. The shader, the original work-around, and my work around are all toggleable from within the program by using the F1, F2, and F3 keys respectively.
// Includes
#include <SFML/Graphics.hpp>
#include <vector>
#include <cmath>
#include <iostream>
int main()
{
// Constants
const int windowWidth = 800, windowHeight = 600;
const float ballWidth = 50.0f, ballHeight = 50.0f;
sf::Vector2f ballVelocity(-300.0f,-300.0f);
// Toggles
bool ShaderEnabled = false;
bool hackOneEnabled = false;
bool hackTwoEnabled = false;
// Fragment Shader Code
const std::string fragmentShader = \
"uniform sampler2D texture;" \
"void main()" \
"{" \
" gl_FragColor = texture2D(texture, gl_TexCoord[0].xy) * vec4(1.0, 0.0, 0.0, 1.0);" \
"}";
// Create Main Window
sf::RenderWindow window(sf::VideoMode(windowWidth, windowHeight), "RenderTexture Issue Demo");
window.setVerticalSyncEnabled(true);
// Load Shader
sf::Shader Shader;
if (!Shader.loadFromMemory(fragmentShader, sf::Shader::Fragment))
{
std::cout << "ERROR: Unable to load shader" << std::endl;
std::cout << "Press any key to continue..." << std::endl;
std::cin.get();
return EXIT_FAILURE;
}
// Create RenderTexture
sf::RenderTexture renderTexture;
renderTexture.create(windowWidth,windowHeight);
// Create Sprite for the RenderTexture
sf::Sprite renderSprite;
renderSprite.setTexture(renderTexture.getTexture());
// Create Ball
sf::RectangleShape ball(sf::Vector2f(ballWidth,ballHeight));
ball.setOrigin(sf::Vector2f(ballWidth * 0.5f, ballHeight * 0.5f));
ball.setPosition(sf::Vector2f(0.5f * windowWidth, 0.5f * windowHeight));
ball.setFillColor(sf::Color::White);
// Create Transparent Shape with the same size as the window
sf::RectangleShape screenClearer;
screenClearer.setSize(sf::Vector2f(windowWidth, windowHeight));
screenClearer.setFillColor(sf::Color::Transparent);
// Time and Timers Initialisation
sf::Clock frameTimer;
sf::Time lastFrameTime;
const sf::Time physicsTimeStep = sf::microseconds(10);
// Main Loop
while (window.isOpen())
{
// Simulation Timing
lastFrameTime += frameTimer.restart();
// Clamp the maximum frame time to prevent self-perpetuating slowdowns
if (lastFrameTime.asMilliseconds() > 250)
lastFrameTime = sf::milliseconds(250);
while (lastFrameTime >= physicsTimeStep)
{
// Move Ball
ball.move(ballVelocity * physicsTimeStep.asSeconds());
// Check Wall Colisions
if ((ball.getPosition().x - 0.5f * ballWidth) < 0)
{
ballVelocity.x = std::abs(ballVelocity.x);
}
if ((ball.getPosition().x + 0.5f * ballWidth) > windowWidth)
{
ballVelocity.x = -std::abs(ballVelocity.x);
}
if (((ball.getPosition().y - 0.5f * ballHeight) < 0) || ((ball.getPosition().y + 0.5f * ballHeight) > windowHeight))
ballVelocity.y = -ballVelocity.y;
// Advance Simulation Step
lastFrameTime -= physicsTimeStep;
}
// Render
renderTexture.clear();
renderTexture.draw(ball);
// Hack to fix bug where the renderTexture doesn't clear
if (hackOneEnabled)
renderTexture.draw(screenClearer);
renderTexture.display();
// Alternative hack to fix aforementioned bug.
// It doesn't seem to matter when this happens as long as it happens at least once per loop.
if (hackTwoEnabled)
window.resetGLStates();
window.clear();
if (ShaderEnabled)
window.draw(renderSprite, &Shader);
else
window.draw(renderSprite);
window.display();
// Event Handler
sf::Event event;
while (window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
{
// Toggle Shader
if (event.key.code == sf::Keyboard::F1)
ShaderEnabled = !ShaderEnabled;
// Toggle first RenderTexture clearing hack (Transparent texture over screen)
if (event.key.code ==sf::Keyboard::F2)
hackOneEnabled = !hackOneEnabled;
// Toggle second RenderTexture clearing hack (window.resetGLStates())
if (event.key.code ==sf::Keyboard::F3)
hackTwoEnabled = !hackTwoEnabled;
break;
}
}
}
}
return EXIT_SUCCESS;
}
-
This is the results of running your code:
(http://tux.servegame.org/~zapfyr/temp/RenderTexture1.png)
I am running the AMD Catalyst 12.8 drivers, which is the current version.
I get the same results using the SFML 2.0 RC.
Graphicscard is also an AMD, but its a 6950.
When it occured within my project i thought it were my fault, but it seems to be a more general problem.
Just my two cents, I still get the same issue with SFML 2.1. I get the red square ghosting, but the FBO teapot demo works fine. Happens consistently on both systems I've tried (one with an Nvidia quadro 3000m and Win7, one with ATI Firepro M3900 and Win8). Issue doesn't occur when writing direct to window, only when using RenderTexture. It seems inconsistent in a multi-monitor scenario, ie the ghosting appears much worse on the non-primary displays.
Is it fair to say this is still an ongoing issue? I don't mind digging in to work out why it's happening as long as it isn't already resolved and I've just missed the relevant post(s).
-
OK here's what I've got. It's using SFML.Net but I think it gets the point across.
Spike source code:
https://github.com/nathanchere/Spikes_SfmlRenderTexture
Compiled version if you just want to see the shiny:
https://dl.dropboxusercontent.com/u/14432582/sfmlRenderTextureSpike.7z
Main code for the really lazy:
private void RenderWorking
() { window
.Clear(Color
.Black); textureOne
.Clear(Color
.White); textureOne
.Display(); var renderSprite
= new Sprite
(textureOne
.Texture); // Note #2 // renderSprite.Position = new Vector2f(Mouse.GetPosition(window).X, Mouse.GetPosition(window).Y); renderSprite
.Draw(window, RenderStates
.Default); // Note #1 // window.Display(); } private void RenderBuggy
() { shapeTwo
.Position = new Vector2f
(Mouse
.GetPosition(window
).X, Mouse
.GetPosition(window
).Y); textureTwo
.Clear(); textureTwo
.Draw(shapeTwo
); textureTwo
.Display(); window
.Clear(); var renderSprite
= new Sprite
(textureTwo
.Texture); window
.Draw(renderSprite
); } private void RenderMoreBuggy
() { textureThree
.Clear(new Color
( (byte) (DateTime
.Now.Millisecond%128
),
(byte) (DateTime
.Now.Millisecond%64
),
(byte) (DateTime
.Now.Millisecond%255
) )); textureThree
.Display(); shapeThree
.Position = new Vector2f
(Mouse
.GetPosition(window
).X, Mouse
.GetPosition(window
).Y); shapeThree
.Rotation = 0
.36f
*DateTime
.Now.Millisecond; textureThree
.Draw(shapeThree
); window
.Clear(); var renderSprite
= new Sprite
(textureThree
.Texture); window
.Draw(renderSprite
); }
So basically RenderWorking is doing the white-square-in-corner thing, RenderBuggy is the red-square-following-mouse thing, and RenderMoreBuggy is intended to display the issue better.
Use: press 1 2 and 3 to toggle render mode, Space to toggle displaying text over the top.
Huh? What's the point of the text? Read on...
Observations:
- the white square test works fine, although it's a bad test. Gives a false positive that it's working OK because nothing is changing or moving
- Uncomment the window.Display() call at Note #1 and you reproduce the flickering someone mentioned earlier in the thread - make sure you're not calling Display on the main render target multiple times in a row?
- the red square demo replicates the expected buggy result. Main difference with this and the white square demo is that the whole drawing area is a RenderTexture, not just the white square, and there is movement
- The third demo tries to better highlight how RenderTexture regions which aren't being drawn over do not get updated, even when you use Clear()
The interesting part for me is the main loop:
while (window.IsOpen())
{
window.DispatchEvents();
Render();
if(DisplayText) window.Draw(Text); // Note #3
window.Display();
}
Render() calls whichever one of the three afore described functions is currently selected. Behaviour is as already described. When drawing text is enabled, suddenly the buggy drawing goes away.
Example:
(http://nathanchere.github.io/misc/sfmlbug.gif)
I'm now more inclined to believe yes it really is a bug and not just people "doing it wrong".
{edit} disregard; issue identified will be fixed in SFML 2.2.
-
One last thing... for anyone still looking for a workaround (C#; adapt for C++ or whatever accordingly):
// do all your drawing// etc..// right before display:Shape shittyHack
= new RectangleShape
(new Vector2f
(0,
0)){ FillColor
= new Color
(0,
0,
0,
0) };Window
.Draw(shittyHack
);// and now you may...Window
.Display();
I don't normally like playing with C++ code these days but if I can get SFML building at home I'll look into exactly why this is happening and hopefully not require a fake Draw() to make sure the entire RenderTexture is drawn.
-
Thanks a lot for your investigations. You should open a new task on the tracker, since all RenderTexture tasks were closed.
-
I tried out eXpl0it3r's test set up and it caused the same problem for me (just installed catalyst 14.4).
So having CodeXL at my disposal, I fired it up and checked the texture that was being rendered to. It was being cleared as expected... So the problem clearly wasn't that the RenderTexture wasn't clearing properly... it was something else.
I then went ahead and checked the default front- and backbuffers of the RenderWindow, and what do you know... they weren't being cleared, so it's really not the RenderTexture's fault.
Knowing that GL can get quite sensitive in certain situations, I just tried stuff out, and it seems that a resetGLStates() before clearing the RenderWindow fixed it. Then I went ahead and checked which call inside resetGLStates() would fix the problem. It seems that the RenderWindow won't clear properly if the texture that is used as the color attachment of the RenderTexture isn't unbound. A simple setTexture(NULL) inside the clear() method already fixes the problem. I don't know how the driver chose to do things, but it might be trying to access the texture in the RenderWindow's context while it was being written to in the RenderTexture's context, so unbinding it seems to have solved the problem.
I was going to fix it, but I didn't know where to and if calling setTexture(NULL) is the best solution for this problem. It has to be done somewhere, but it could decrease performance by incurring an extra bind per frame (if done while clearing) in the rare case that the user's code only uses a single texture ;). This is amortized when more textures are bound every frame. I can push a fix for this if Laurent agrees to unbind in clear.
-
This is not the cleanest fix ever, but I don't think it will ruin anyone's performances, so let's go for it. Good catch!
-
Implemented this fix and a fix for issue #523 (https://github.com/SFML/SFML/pull/523) here (https://github.com/SFML/SFML/commit/24c364ee17d7750d08ca18aac2eb6219383b7827). It just needs to be reviewed, merged and the issue closed ;).
-
Up, I need really this update!
-
Up, I need really this update!
Uhhuh.... what do you expect us to do? It is fixed so go get it yourself.......... Or did you happen to not even bother to read the thread?? :P
-
It is fixed, but not merged to project. I work in jsfml and I canno't rebuild all versions of sfml, bot windows 32/64, mac , linux, etc... So I need an official update with this merge :/
-
And what? We're going to release SFML 2.2 right now because you up'd this topic? :P
-
no no, I don't need the sfml 2.2, but i read that "needs to be reviewed, merged and the issue closed".
So I only wait a review and a merge... But if merge mean release sfml 2.2, a review is nice :D
-
It's available anyway. What difference does it make if it's in its own unmerged branch, or in master? Are you afraid it is not stable until reviewed and merged?
-
It was already merged a while ago: e6b5ce1f27d22aa0150c1376550b2e3f1baec09a (https://github.com/SFML/SFML/commit/e6b5ce1f27d22aa0150c1376550b2e3f1baec09a)
It can be considered as stable as a version bump release.
Grab the latest master, build and enjoy.
-
Thanks a lot.
yes, while this is not merged, I prefer not take it, to avoid bug due to this code.
But now it is merge, I'll take it, sure^^