SFML community forums

Help => Graphics => Topic started by: BaneTrapper on August 24, 2014, 09:04:54 pm

Title: How to make sf::RenderTexture i can manipulate
Post by: BaneTrapper on August 24, 2014, 09:04:54 pm
Hello.
I have idea: I want to draw text on screen but keep it efficient, so draw text onto renderTexture then use VertexArray to draw it on screen so save performance is the general idea.

But i am facing one thing, i cannot manipulate render texture, for example i want to delete part of it(making it transparent so i can put another text there).
Any ideas how to clear part of renderTexture.

This is how i drawn the text via vertexArray using renderTextures
Code: [Select]
int main()
{
sf::View view;
//view.setCenter(sf::Vector2f(400, 300));
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::RenderTexture renTex;
sf::Text txt;
sf::Font font;
sf::RectangleShape rec;
sf::VertexArray verArr;

font.loadFromFile("arial.ttf");

txt.setCharacterSize(24);
txt.setColor(sf::Color::Black);
txt.setFont(font);
txt.setString("Greeting young traveler!\nMay i be of any assistence?");
txt.setPosition(-txt.getLocalBounds().left, -txt.getLocalBounds().top);
sf::FloatRect tfr = txt.getLocalBounds();

rec.setPosition(-tfr.left, -tfr.top);
rec.setSize(sf::Vector2f(tfr.width + tfr.left, tfr.height + tfr.top*2));

renTex.create(tfr.width + tfr.left, tfr.height + tfr.top);
renTex.draw(txt);
renTex.display();

verArr.setPrimitiveType(sf::Quads);
for (int i = 0; i < 1; i++)
{
std::cout << " x:" << renTex.getSize().x << " y:" << renTex.getSize().y << std::endl;
verArr.append(sf::Vertex(sf::Vector2f(i, 0), sf::Color(255, 255, 255, 255), sf::Vector2f(0, 0)));
verArr.append(sf::Vertex(sf::Vector2f(i + renTex.getSize().x, 0), sf::Color(255, 255, 255, 255), sf::Vector2f(renTex.getSize().x, 0)));
verArr.append(sf::Vertex(sf::Vector2f(i + renTex.getSize().x, renTex.getSize().y), sf::Color(255, 255, 255, 255), sf::Vector2f(renTex.getSize().x, renTex.getSize().y)));
verArr.append(sf::Vertex(sf::Vector2f(i, +renTex.getSize().y), sf::Color(255, 255, 255, 255), sf::Vector2f(0, renTex.getSize().y)));
}
sf::RenderStates renSta;
renSta.texture = &renTex.getTexture();

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;
case sf::Event::KeyPressed:
switch(event.key.code)
{
case sf::Keyboard::K:
break;
default:
break;
}
break;
default:
break;
}
}
win.draw(rec);
//win.draw(spr);

win.draw(verArr, renSta);
win.display();
}

return 0;
};
Title: Re: How to make sf::RenderTexture i can manipulate
Post by: Hapax on August 24, 2014, 09:23:26 pm
I think that the only way to "manipulate" (the way that you seem to be describing) a RenderTexture is to make a copy of its texture into a Texture object as the texture returned from a RenderTexture's getTexture() method is const. This process, however, can be extremely slow.
Title: Re: How to make sf::RenderTexture i can manipulate
Post by: BaneTrapper on August 24, 2014, 09:28:00 pm
Is there replacement for renderTexture that is stored in RAM and i can manipulate? instead of using renderTexture.
Title: Re: How to make sf::RenderTexture i can manipulate
Post by: Stauricus on August 24, 2014, 09:33:22 pm
i don't think it would be really efficient - unless you have lots of sf::Text drawed at the same time, without moving or changing.

as far as i know, there is no renderTexture in RAM. but you could extract the texture from a renderTexture, turn it into a sf::Image, manipulate it, then convert again to a sf::Texture. but i seriously think you are going to lose a lot of performance by doing that...
Title: Re: How to make sf::RenderTexture i can manipulate
Post by: BaneTrapper on August 24, 2014, 09:50:38 pm
Yeah it would cost allot of process, in that case just making texture per text.
Also there should be 5-6 dialogs with 10-30characters and 1-2 with 50-100. At certain times when game cannot lag.

So the general purpose is to have it is for dialog in rpg. While walking trough town to see dialog people are talking. shop keepers screaming "Fish, buy free fish!". Also it is supposed to work in battle when there process is tight.
Well im still open for suggestion if you got good idea, if not. I will probably keep it low with text :)
Title: Re: How to make sf::RenderTexture i can manipulate
Post by: FRex on August 24, 2014, 10:06:51 pm
That is nothing, just use sf::Text directly.
Title: Re: How to make sf::RenderTexture i can manipulate
Post by: Laurent on August 24, 2014, 10:38:28 pm
A general rule in graphics programming is to avoid GPU -> CPU transfers. The optimized flow is CPU -> GPU -> monitor, don't go against that unless you have very good reasons.

So if you want to modify your render-texture, do it on the GPU. For example, to make a part of it transparent, draw a transparent quad with alpha-blending disabled (sf::BlendNone).

Also, is there any reason why you're using a vertex array to draw a single quad, instead of a sprite?

And of course...
Quote
That is nothing, just use sf::Text directly.
Yes, don't optimize and make your code complicated, unless your profiling results show that you need to.
Title: Re: How to make sf::RenderTexture i can manipulate
Post by: Stauricus on August 24, 2014, 11:32:53 pm
i always forget about BlendModes.
but yeah, i also think in this case a few sf::Texts are the best option.

also,
"Fish, buy free fish!"
don't make your shopkeepers sell fish for free, or they'll profit nothing :P
Title: Re: How to make sf::RenderTexture i can manipulate
Post by: BaneTrapper on August 25, 2014, 12:00:44 am
also,
"Fish, buy free fish!"
don't make your shopkeepers sell fish for free, or they'll profit nothing :P
Rad hint  ;D
That is so stupid, i cannot believe i wrote that.