Actually, I got lucky and found a quick repro case.
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(900, 900), "Test");
sf::RectangleShape shOutline;
sf::Text tName;
tName.setPosition(sf::Vector2f(10,10));
tName.setCharacterSize(20);
tName.setString("Abcdefgh");
shOutline.setPosition(sf::Vector2f(10,10));
shOutline.setSize(sf::Vector2f(100,30));
shOutline.setFillColor(sf::Color(128,128,128,128));
shOutline.setOutlineColor(sf::Color(255,255,255));
shOutline.setOutlineThickness(2.0);
while (1)
{
sf::Color darkGreyGreen(10, 30, 10, 255);
window.clear(darkGreyGreen);
window.draw(shOutline);
window.draw(tName);
window.display();
}
}
The result is shown in the image attached.
And if I comment out window.draw(shOutline), the text renders normally.
[attachment deleted by admin]
I'm using a Radion HD 5750 (and version 12.10 of the drivers,) and I experience the same problem using the latest source. Well, not quite the latest -- I haven't updated for the static library fix. While playing around with the code Kylotan provided to show the issue, I found that changing either of the background or outline alpha settings to 0 (or setting the outline thickness to 0) caused the text to display properly. I also noticed that drawing the rectangle elsewhere on the screen still seems to screw up the display of the text.
When I put together some code to test multiple scenarios in one run, that behavior disappeared, so I suspect it had something do with the initial state of the graphics subsystem.
This was the code for reference:
#include <SFML/Graphics.hpp>
struct Scenario {
sf::Color background ;
sf::Color box_fill ;
sf::Color box_outline ;
sf::Vector2f box_position ;
sf::Vector2f box_size ;
float box_outline_thickness ;
sf::Text text ;
};
void doScenario(sf::RenderWindow& window, const Scenario& s) ;
int main()
{
sf::RenderWindow window(sf::VideoMode(150, 150), "Test");
sf::Font font ;
font.loadFromFile("sketchflow.ttf") ;
sf::Text text("abcdefgh", font) ;
text.setPosition(sf::Vector2f(10.0f,10.0f)) ;
text.setCharacterSize(20) ;
const sf::Color bg(10, 30, 10) ;
const sf::Vector2f offTextPos(10.0f, 100.0f) ;
const sf::Vector2f throughTextPos(10.0f, 25.0f) ;
const sf::Vector2f onTextPos ( 10.0f, 10.0f ) ;
const sf::Color fill_alphaOff(128, 128, 128, 0) ;
const sf::Color fill_alphaOn(128, 128, 128, 255) ;
const sf::Color fill_alphaMid(128, 128, 128, 128) ;
const sf::Color outline_alphaOff(255, 255, 255, 0 ) ;
const sf::Color outline_alphaOn(255, 255, 255, 255) ;
const sf::Color outline_alphaMid(255, 255, 255, 128) ;
const float thicknessOn = 2.0f ;
const float thicknessOff = 0.0f ;
const sf::Vector2f rectSize(100, 30) ;
Scenario scenarios[] =
{
// bg color, box_fill, box_outline, box_position, box_size, box_outline_thickness
{ bg, fill_alphaOn, outline_alphaOn, onTextPos, rectSize, thicknessOn, text },
{ bg, fill_alphaOn, outline_alphaOn, throughTextPos, rectSize, thicknessOn, text },
{ bg, fill_alphaOn, outline_alphaOn, offTextPos, rectSize, thicknessOn, text },
{ bg, fill_alphaOn, outline_alphaOn, offTextPos, rectSize, thicknessOff, text },
{ bg, fill_alphaOff, outline_alphaOn, offTextPos, rectSize, thicknessOn, text },
{ bg, fill_alphaOn, outline_alphaOff, offTextPos, rectSize, thicknessOn, text },
// text shows correctly only for these two cases:
{ bg, fill_alphaOff, outline_alphaOn, offTextPos, rectSize, thicknessOff, text },
{ bg, fill_alphaOff, outline_alphaOff, offTextPos, rectSize, thicknessOn, text }
};
for ( unsigned i=0 ; i<sizeof(scenarios)/sizeof(scenarios[0]); ++i )
doScenario(window, scenarios[i]) ;
}
bool processEvents( sf::RenderWindow & window )
{
bool continueProcessing = true ;
sf::Event event ;
while ( window.pollEvent(event) )
{
switch (event.type)
{
case sf::Event::Closed:
continueProcessing = false ;
window.close() ;
break ;
case sf::Event::KeyReleased:
continueProcessing = false ;
break ;
}
}
return continueProcessing ;
}
void doScenario( sf::RenderWindow& window, const Scenario& s )
{
sf::RectangleShape rect ;
rect.setPosition(s.box_position) ;
rect.setSize(s.box_size) ;
rect.setFillColor(s.box_fill) ;
rect.setOutlineColor(s.box_outline) ;
rect.setOutlineThickness(s.box_outline_thickness) ;
const sf::Text & t = s.text ;
while ( window.isOpen() && processEvents(window) )
{
window.clear(s.background);
window.draw(rect) ;
window.draw(t) ;
window.display() ;
}
}
Result:
(http://img72.imageshack.us/img72/2636/fonttesto.png)
Sure.
#include <SFML/Graphics.hpp>
const sf::Vector2f box_size(100.0f, 30.0f) ;
const sf::Vector2f box_pos(10.0f, 100.0f) ;
const sf::Vector2f text_pos(10.0f, 10.0f) ;
sf::Text text ;
void waitForEnter( sf::RenderWindow& w)
{
bool waiting = true ;
while ( waiting )
{
sf::Event event ;
if ( w.pollEvent(event) && event.type == sf::Event::KeyPressed )
if ( event.key.code == sf::Keyboard::Return )
waiting = false ;
}
}
int main()
{
sf::RenderWindow window(sf::VideoMode(150, 150), "Test");
sf::RectangleShape box(box_size) ;
box.setPosition(box_pos) ;
box.setOutlineThickness(2.0f) ; /* REQUIRED FOR RENDERING FAILURE */
sf::Font font ;
font.loadFromFile("sketchflow.ttf") ;
text.setString("abcdefgh") ;
text.setFont(font) ;
// rendered correctly.
window.clear() ;
window.draw(box) ;
window.draw(text) ;
window.display() ;
waitForEnter(window) ;
// not rendered correctly.
window.clear() ;
window.draw(box) ;
window.draw(text) ;
window.display() ;
waitForEnter(window) ;
}
If I run this as-is I see:
(http://img28.imageshack.us/img28/8628/textl.png)
If I substitue a sprite for the sf::Text object, I see:
(http://img31.imageshack.us/img31/9549/spritexp.png)
If I never set the outline thickness, everything would render correctly.
Well...
if you comment this:
//box.setOutlineThickness(2.0f) ; /* REQUIRED FOR RENDERING FAILURE */
and change the first draw order:
// window.draw(box) ;
// window.draw(text) ;
window.draw(text) ;
window.draw(box) ;
You get the error again.. in the second draw o.O.
I made this http://en.sfml-dev.org/forums/index.php?topic=9624 (http://en.sfml-dev.org/forums/index.php?topic=9624) post with the same problem, and i have found some new things to add to this very peculiar bug.
I (almost (see Case 3)) only get the bug when drawing 2 Shapes, not with 1. The 2 Shapes yields the same result as one Shape with the setOutlineThickness(2.0f);.
If you have several Sprites with the same texture, only the first of one type of texture will not work. Thus if you try to draw 3 Sprites with Texture 1 (and some RectangleShapes or whatnot to get the bug) they will not work, but after that you can draw a Sprite with another Texture and after you have drawn that one you can draw the first Texture!
It's hard to explain in text so here is the code used and some images:
#include "stdafx.h"
#include <SFML/Graphics.hpp>
using namespace sf;
int main(){
RenderWindow window(VideoMode(150, 140, 32), "SFML", Style::Default);
window.setFramerateLimit(4);
CircleShape fooShape(20.0f, 30);
CircleShape barShape(25.0f, 30);
fooShape.setPosition(10.0f, 10.0f);
barShape.setPosition(70.0f, 20.0f);
Texture aTexture1;
aTexture1.loadFromFile("texture1.png");
Texture aTexture2;
aTexture2.loadFromFile("texture2.png");
Sprite sprite1;
sprite1.setTexture(aTexture1);
sprite1.setPosition(15.0f, 100.0f);
Sprite sprite2;
sprite2.setTexture(aTexture1);
sprite2.setPosition(40.0f, 100.0f);
Sprite sprite3;
sprite3.setTexture(aTexture1);
sprite3.setPosition(65.0f, 100.0f);
Sprite sprite4;
sprite4.setTexture(aTexture2);
sprite4.setPosition(90.0f, 100.0f);
Sprite sprite5;
sprite5.setTexture(aTexture1);
sprite5.setPosition(115.0f, 100.0f);
Sprite sprite6;
sprite6.setTexture(aTexture1);
sprite6.setPosition(40.0f, 50.0f);
bool drawFoo = false;
bool drawBar = false;
bool drawOtherSprites = true;
bool drawTexture2 = true;
bool drawMiddle = false;
while(window.isOpen()){
Event Event;
while(window.pollEvent(Event)){
if(Event.type == Event.KeyPressed){
if(Event.key.code == Keyboard::U){/*Choose if drawing first shape*/
if(drawFoo) drawFoo = false;
else drawFoo = true;
}else if(Event.key.code == Keyboard::I){/*Choose if drawing second shape*/
if(drawBar) drawBar = false;
else drawBar = true;
}else if(Event.key.code == Keyboard::O){/*Choose if drawing other sprites than the first and the middle-Sprite*/
if(drawOtherSprites) drawOtherSprites = false;
else drawOtherSprites = true;
}else if(Event.key.code == Keyboard::P){/*Choose if drawing Sprite with texture2*/
if(drawTexture2) drawTexture2 = false;
else drawTexture2 = true;
}else if(Event.key.code == Keyboard::L){/*Choose if drawing texture1 Sprite between drawing of shapes*/
if(drawMiddle) drawMiddle = false;
else drawMiddle = true;
}
}
}
window.clear(Color(200, 100, 40));
if(drawFoo)
window.draw(fooShape);
if(drawMiddle)
window.draw(sprite6);
if(drawBar)
window.draw(barShape);
window.draw(sprite1);
if(drawOtherSprites){
window.draw(sprite2);
window.draw(sprite3);
if(drawTexture2)
window.draw(sprite4);
window.draw(sprite5);
}
window.display();
}
return EXIT_SUCCESS;
}
(I'm using Visual C++ 2010 Express, a XFX Radeon 5750 graphics card and i updated to the latest SFML 2.0 build today)
Case 1.
(http://img546.imageshack.us/img546/7862/sfmlbug.png)
All Sprites. Only the first few are affected. When not drawing second textured sprite, all are affected.
Case 2.
I also noticed a difference when i have transparency in my Textures:
(http://img87.imageshack.us/img87/6459/sfmlbugtransparent.png)
Exactly the same as before but with transparency instead of white background.
As seen the partially transparent Textures will not draw anything at all instead of a white box.
Case 3.
Also, when drawing only the first Sprite, it will be affected by the bug after one of the Shapes have been set to not drawing, furthermore if i then start drawing the other Sprites it will take exactly 1 frame to update and show all the Textures correctly:
(http://img689.imageshack.us/img689/9237/sfmlbug2.png)
Bug. Still Bug. This will show for exactly one frame and then revert to this.
This is the reason of window.setFramerateLimit(4); in the code, because it will not be noticeable with a framerate of 60 or even 10.
Case 4.
As you said in the posts before, after a Shape has been drawn, the Sprites after that one will not work, in my case, after 2 shapes, and if i draw one Sprite of texture1.png, between those two Shapes, everything will render normally, except if i remove the middle Sprite and then draw it again, it will produce something like in Case 3.
This is way too much info, but if any one can get something out of this I'm happy to help!
This bit of code is helping me work around the issue. Anywhere you need to render text or sprites and it sometimes renders wrongly, insert a call to this function right before it to ensure the texture will get re-bound properly. It's a hacky thing that creates a 1x1 texture and draws a sprite with it offscreen.
#include <SFML\Graphics.hpp>
void WorkaroundAMDBug(sf::RenderWindow* window)
{
static sf::Texture amdWorkaroundImage;
static sf::Sprite sprite;
if (amdWorkaroundImage.getSize() == sf::Vector2u(0,0))
{
amdWorkaroundImage.create(1, 1);
sprite.setTexture(amdWorkaroundImage);
sprite.setPosition(-20, -20); // offscreen
}
window->draw(sprite);
}