Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: (Not bug)Bug with sfmlRenderTexture or i am doing it wrong  (Read 5633 times)

0 Members and 1 Guest are viewing this topic.

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
(Not bug)Bug with sfmlRenderTexture or i am doing it wrong
« on: August 25, 2014, 11:22:00 pm »
Hello.
In short what i want to do: I want to draw sf::Text once and save it as texture, then use texture to speed up drawing.

In short what i achieve: I draw text and save it as texture, all but last texture are white. I suspect the renderTexture deconstructor releases its texture and thus i am getting all white when using it.
But i have no clue what em i doing wrong.
Magic happens in Dialog::MakeText(...);
EDIT::Also the creating renderTexture does not fail.

Code: [Select]
class Dialog
{
public:
Dialog(std::string & str, int linkedObjectVecID = -1, int posX = -1, int posY = -1);
Dialog& operator=(Dialog & d);
Dialog(const Dialog & d);
void MakeText(sf::Font & font);

sf::Text txt;
sf::Texture tex;
sf::Sprite spr;
int linkedObjectVecID;
int posX, posY;
std::string str;
};

Dialog::Dialog(std::string & Str, int LinkedObjectVecID, int PosX, int PosY)
{
linkedObjectVecID = LinkedObjectVecID;
posX = PosX;
posY = PosY;
str = Str;
}

Dialog& Dialog::operator = (Dialog & d)
{
txt = d.txt;
tex = d.tex;
spr = d.spr;
linkedObjectVecID = d.linkedObjectVecID;
posX = d.posX;
posY = d.posY;
str = d.str;
return *this;
}
Dialog::Dialog(const Dialog & d)
{
txt = d.txt;
tex = d.tex;
spr = d.spr;
linkedObjectVecID = d.linkedObjectVecID;
posX = d.posX;
posY = d.posY;
str = d.str;
}

void Dialog::MakeText(sf::Font & font)
{
txt.setCharacterSize(32);
txt.setColor(sf::Color::White);
txt.setFont(font);
txt.setString(str);
txt.setPosition(-txt.getLocalBounds().left, -txt.getLocalBounds().top);
std::cout << "MakeText str:" << str << std::endl;

sf::RenderTexture renTex;
if (renTex.create(txt.getLocalBounds().width + txt.getLocalBounds().left * 2, txt.getLocalBounds().height + txt.getLocalBounds().top * 2) == false)
std::cout << "Dialog::MakeText Creating texture failed:" << std::endl;
renTex.draw(txt);
renTex.display();
//tex.create(renTex.getSize().x, renTex.getSize().y);
tex = renTex.getTexture();

spr.setTexture(tex);
//Set position on position
spr.setPosition(posX - (txt.getLocalBounds().width / 2), posY - txt.getLocalBounds().height - (txt.getLocalBounds().top * 2));
}

int main()
{
sf::View view;
view.setViewport(sf::FloatRect(0, 0, 1, 1));

sf::RenderWindow win;
sf::VideoMode vidMod(800,600,32);
win.create(vidMod, "hello", sf::Style::Default);
win.setFramerateLimit(100);
win.setView(view);

sf::Font arial;
arial.loadFromFile("arial.ttf");

std::vector<Dialog> listDialog;
listDialog.push_back(Dialog(std::string("Greeting traveler."), -1, 300, 300));
listDialog.back().MakeText(arial);
listDialog.push_back(Dialog(std::string("Two trees."), -1, 300, 100));
listDialog.back().MakeText(arial);
listDialog.push_back(Dialog(std::string("Derp"), -1, 300, 500));
listDialog.back().MakeText(arial);

bool done = false;
while(done == false)
{
win.clear();

sf::Event event;
while(win.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
done = true;
break;
default:
break;
}
}

for (Dialog & d : listDialog)
win.draw(d.spr);

win.display();
}

return 0;
};
« Last Edit: August 27, 2014, 07:11:55 pm by BaneTrapper »
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

victorlevasseur

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: Bug with sfmlRenderTexture or i am doing it wrong, test for me please!
« Reply #1 on: August 25, 2014, 11:51:16 pm »
Hi, the render texture is destructed at the end of Dialog::MakeText, so that is normal if the texture is all white.

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
Re: Bug with sfmlRenderTexture or i am doing it wrong, test for me please!
« Reply #2 on: August 26, 2014, 12:00:30 am »
Hi, the render texture is destructed at the end of Dialog::MakeText, so that is normal if the texture is all white.
I suspected so, thank you on confirming it.
How do i make a copy of renderTexture renText(actual texture) to sf::Texture tex?
The reason being, renderTexture is a heavy object compared to Texture.
I tried
Code: [Select]
tex = renTex.getTexture();
« Last Edit: August 26, 2014, 12:14:05 am by BaneTrapper »
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Bug with sfmlRenderTexture or i am doing it wrong, test for me please!
« Reply #3 on: August 26, 2014, 12:13:42 am »
I'm not sure about that. getTexture() returns an actual sf::Texture, and copying an sf::Texture does a very real copy (in fact, it looks like it copies it from GPU to CPU back to GPU...which you probably don't want to do too often).  After looking at the SFML source to confirm this (I was bored), I don't think there is a heavier or deeper way to perform that copy operation.

I don't think I can see what the real problem is, but as a shot in the dark, try a node-based container like a std::map instead of a std::vector.  Maybe the vector resizing is causing copies and your Dialog class doesn't like being copied.  Obviously you no longer have any non-copyables causing compiler errors, but putting a class with sf::Textures into a non-node-based container still doesn't look right to me--I once had a similar issue with sf::Font which I believe was caused by putting them in a std::vector.  Even if I'm wrong and they are being copied correctly, textures are not lightweight objects you want to be copying willy-nilly anyway.
« Last Edit: August 26, 2014, 12:27:35 am by Ixrec »

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
Re: Bug with sfmlRenderTexture or i am doing it wrong, test for me please!
« Reply #4 on: August 26, 2014, 11:15:34 pm »
I'm not sure about that. getTexture() returns an actual sf::Texture, and copying an sf::Texture does a very real copy (in fact, it looks like it copies it from GPU to CPU back to GPU...which you probably don't want to do too often).  After looking at the SFML source to confirm this (I was bored), I don't think there is a heavier or deeper way to perform that copy operation.
getTexture() return const reference to its texture. The issue is i don't know how to copy it.
Doing
Code: [Select]
sf::Texture tex;
sf::RenderTexture renTex;

tex = renTex.getTexture();
Performs assignment operation as it should.
There is this constructor for Texture tho
Code: [Select]
Texture(const Texture& copy);
When i used it with getTexture().
The texture was still null after renderTexture deconstructor got called. Beats me why... i don't know whats going on anymore, i made quite few posts, read all documentation... I hit brick wall, i will attempt to reintroduce the problem again and solve it in different way.
If i fail even then, i will probably quit sfml, it is probably not for for me.
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Bug with sfmlRenderTexture or i am doing it wrong, test for me please!
« Reply #5 on: August 27, 2014, 12:14:52 am »
sf::Texture texture = renderTexture.getTexture();
doesn't copy the texture?

If i fail even then, i will probably quit sfml, it is probably not for for me.
This is a terrible attitude to have. I have many other words to describe it but I will refrain from doing so.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
SOLVED!

sf::Texture texture = renderTexture.getTexture();
doesn't copy the texture?

If i fail even then, i will probably quit sfml, it is probably not for for me.
This is a terrible attitude to have. I have many other words to describe it but I will refrain from doing so.
I think you misunderstood me i expressed poorly, the text is important and i have more then i stated at first, drawing it with sf::Text uses too much performance to do. I was unable to achieve that, so i would have to resolve to different library or method.
The issue was quite a whacky one, i stated i do not use sprites, i was unaware the sf::Sprite member "m_texture" was a const.

Fixed the issue.

The issue was not with the sf::Texture or sf::RenderTexture. It was the sf::Sprite all the time.
The reason is, as i was adding more elements to the vector, the vector reached maximum size and had to reallocate, issue comes from sf::Sprite member (const Texture* m_texture; ).
Fixed the issue with, setting size for vector before adding any elements. Or setting sf::Sprite texture before drawing.


 :-[, unsure if i was supposed to know this.
Two lines are commented out in main which fix issue.
Code: [Select]
class Dialog
{
public:
Dialog();
Dialog(const Dialog & d);
void MakeText(sf::Font & font);

sf::Texture tex;
sf::Sprite spr;
};
Dialog::Dialog(){ std::cout << "defC" << std::endl; }
Dialog::Dialog(const Dialog & d)
{
tex = d.tex;
spr = d.spr;
std::cout << "d:" << d.spr.getTexture() << std::endl;
std::cout << "s:" << spr.getTexture() << std::endl;
}

void Dialog::MakeText(sf::Font & font)
{
std::cout << "mTXT" << std::endl;
sf::Text txt;
int posX = 0, posY = 0;

txt.setCharacterSize(32);
txt.setColor(sf::Color::White);
txt.setFont(font);
txt.setString("Hello");
txt.setPosition(0, 0);

sf::RenderTexture renTex;
renTex.create(100, 100);
renTex.draw(txt);
renTex.display();

tex = renTex.getTexture();

spr.setTexture(tex, true);
spr.setPosition(1, 1);
}

int main()
{
sf::View view;
view.setViewport(sf::FloatRect(0, 0, 1, 1));

sf::RenderWindow win;
sf::VideoMode vidMod(800,600,32);
win.create(vidMod, "hello", sf::Style::Default);
win.setFramerateLimit(100);
win.setView(view);

sf::Font arial;
arial.loadFromFile("arial.ttf");


std::vector<Dialog> listDialog;
//listDialog.reserve(4);
for (unsigned int i = 0; i < 4; i++)
{
listDialog.push_back(Dialog());
listDialog.back().MakeText(arial);
}

sf::Sprite tmpSpr1, tmpSpr2, tmpSpr3;
sf::Texture tex;
tex.loadFromFile("link.png");

tmpSpr1.setTexture(tex);
tmpSpr1.setPosition(101, 0);

tmpSpr2 = tmpSpr1;
tmpSpr2.setPosition(101, 50);

tmpSpr3 = tmpSpr2;
tmpSpr3.setPosition(101, 100);

bool done = false;
while(done == false)
{
win.clear();

sf::Event event;
while(win.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
done = true;
break;
default:
break;
}
}

for (unsigned int i = 0; i < listDialog.size(); i++)
{
//listDialog[i].spr.setTexture(listDialog[i].tex, true);
listDialog[i].spr.setPosition(0, i*101);
win.draw(listDialog[i].spr);
}
win.draw(tmpSpr1);
win.draw(tmpSpr2);
win.draw(tmpSpr3);
win.display();
}

return 0;
};
« Last Edit: August 27, 2014, 07:16:29 pm by BaneTrapper »
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: (Not bug)Bug with sfmlRenderTexture or i am doing it wrong
« Reply #7 on: August 28, 2014, 12:00:16 am »
Good to know that you fixed it  :)

I'm not sure I understand what you found as the problem. Is it because you were using pointers to elements in a vector and they were moving when allocating more size?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

BaneTrapper

  • Full Member
  • ***
  • Posts: 213
  • Do you even see this, i dont need it.
    • View Profile
    • Email
Re: (Not bug)Bug with sfmlRenderTexture or i am doing it wrong
« Reply #8 on: August 28, 2014, 06:05:24 pm »
Good to know that you fixed it  :)

I'm not sure I understand what you found as the problem. Is it because you were using pointers to elements in a vector and they were moving when allocating more size?
The issue was with the sf::Sprite::m_texture member (const Texture* m_texture;)
When using vectors push_back() function the m_texture is copied properly.
But when vector resize() occurs(Manually, or when it reaches maximum size) all m_texture go invalid, i don't know why, and currently don't care i fixed it!

I suspected issue was texture because i was only getting last texture created drawn.
BaneTrapperDev@hotmail.com Programing, Coding
Projects: Not in development(unfinished/playable):
http://en.sfml-dev.org/forums/index.php?topic=11073.msg76266#msg76266
UP and in Development: The Wanderer - Lost in time
http://en.sfml-dev.org/forums/index.php?topic=14563.0

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: (Not bug)Bug with sfmlRenderTexture or i am doing it wrong
« Reply #9 on: August 28, 2014, 06:13:41 pm »
Lets just be clear about what caused the problem.

In your Dialog class you defined a couple of copy overloads. Lets just look at one since they are basically the same.

Dialog::Dialog(const Dialog & d)
{
        txt = d.txt;
        tex = d.tex; // here is your problem
        spr = d.spr; // and here
        linkedObjectVecID = d.linkedObjectVecID;
        posX = d.posX;
        posY = d.posY;
        str = d.str;
}

You copy the sprite and the texture, that is fine, what is wrong is that the sprite doesn't know about the new texture. The sprite has an internal pointer that still points at old texture that was destroyed after being copied to the new instance. Therefore, the fix would be to update the sprite's internal texture with the newly copied texture.

(click to show/hide)
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor