SFML community forums

Help => Graphics => Topic started by: CreaM on April 10, 2014, 05:11:34 pm

Title: too much text problem
Post by: CreaM on April 10, 2014, 05:11:34 pm
Hello, i know that isnt good to call window.draw(...) to many times. So when i write text can i somehow transfer it to vertex arrays? - i mean when i write lot of individuallys texts.
Title: Re: too much text problem
Post by: Jesper Juhl on April 10, 2014, 05:17:45 pm
Define "lots". If it is just a few tens of draw calls it probably doesn't matter.
Have you profiled your application? Is there an actual problem? Are draw() calls the problem?
Beware of premature optimization. Make sure there is actually a real problem first :)
Title: Re: too much text problem
Post by: Nexus on April 10, 2014, 05:20:56 pm
So when i write text can i somehow transfer it to vertex arrays?
No, you can't.
Title: Re: too much text problem
Post by: CreaM on April 10, 2014, 05:57:03 pm
Well, can i at least copy part of screen and use it like texture/shape...
Then i could copy text to sprite, display that spirit, add next text, and again copy sprite + new text.....
Title: Re: too much text problem
Post by: Jesper Juhl on April 10, 2014, 06:05:36 pm
How about just drawing the text you need to draw and not worry about it until it becomes a problem?
My guess is that it never will.
Title: AW: Re: too much text problem
Post by: eXpl0it3r on April 10, 2014, 06:10:17 pm
Well, can i at least copy part of screen and use it like texture/shape...
You could use a render texture, but it most likely won't make a difference if you just draw it. ;)
Title: Re: too much text problem
Post by: CreaM on April 10, 2014, 09:12:26 pm
well - this is why i needed render texture, unfortunately i cant still use it, because i just cant draw rectangle to render texture...
class Text_manager{
public:
        bool add_text(const std::string& text_worlds){
               
                //rectangle.setTexture(texture);
               
                renderTexture.create(800, count * (text_size + space_size) + space_size + text_size);

                renderTexture.clear();                                                         
                rectangle.setColor(sf::Color(0, 255, 0));//here im trying to draw rect. to renderTexture
                rectangle.setPosition(0,0);//here im trying to draw rect. to renderTexture
                rectangle.setColor(sf::Color(0, 255, 0));//here im trying to draw rect. to renderTexture
                renderTexture.draw(rectangle);//here im trying to draw rect. to renderTexture

                sf::Font font;
                if (!font.loadFromFile("arial.ttf"))
                        return false;
                sf::Text text;
                text.setFont(font);
                text.setString(text_worlds);
                text.setCharacterSize(text_size);
                text.setColor(sf::Color::Red);

                text.setPosition(0,count * (text_size + space_size) + space_size);
                renderTexture.draw(text);
                renderTexture.display();

                texture = renderTexture.getTexture();
               
                count ++;
                return true;
        };
        void set_text(int p_count, int p_text_size, int p_space_size){
                count = p_count;
                text_size = p_text_size;
                space_size = p_space_size;
        };
        void draw(){
                sprite.setTexture(texture);
                window.draw(sprite);
        };

private:
        int count;

        int text_size;
        int space_size;
       
        sf::RenderTexture renderTexture;
        sf::Sprite rectangle;
        sf::Sprite sprite;
        sf::Texture texture;
};
 
Why is renderTexture ignoring that rectangle?
Title: Re: too much text problem
Post by: Ixrec on April 10, 2014, 09:22:55 pm
Is the text rendering correctly, and it's only the rectangle missing?  What jumps out to me is the sf::Font and sf::Text objects going out of scope at the end of add_text, but your rendertexture and rectangle clearly shouldn't have that problem, so it'd be weird if the text was showing up and not the rectangle.

(also, a *complete* and minimal example would make it a lot easier for us to help)
Title: Re: too much text problem
Post by: Jesper Juhl on April 10, 2014, 09:43:38 pm
Is the text rendering correctly, and it's only the rectangle missing?  What jumps out to me is the sf::Font and sf::Text objects going out of scope at the end of add_text, but your rendertexture and rectangle clearly shouldn't have that problem,...
They live long enough to be drawn onto the rendertexture. That's not the problem..
Title: Re: too much text problem
Post by: Ixrec on April 10, 2014, 09:53:33 pm
Oh, I think I see the problem.

Your "rectangle" is an sf::Sprite, not an sf::RectangleShape.  Sprites need textures; shapes don't.
Title: Re: too much text problem
Post by: CreaM on April 12, 2014, 07:24:49 pm
Thanks for your answers, i finally completed my class, but still there is one problem...
The class should classify the entered text into lines.
This is how i want bool add_text(...) works:
It draws rectangle into renderTexture, - rectangle is filled with TEXTURE. Than is written new text under rectangle. All this stuf is copied in renderTexture and renderTexture is copied to TEXTURE, to be used in next call of add_text(...) and void draw(){.
The problem is that the rectangle is just white - not filed with TEXTURE - not just for first call of add_text(...), but every call.

class Text_manager{
public:
        bool add_text(const std::string& text_worlds){
               
                renderTexture.create(800, count * (text_size + space_size) + space_size + text_size);
                renderTexture.clear(); 
               
                rectangle.setTexture(&texture);
                rectangle.setPosition(0,0);
                rectangle.setSize(sf::Vector2f(800, count * (text_size + space_size)));

                renderTexture.draw(rectangle);
                renderTexture.display();

                sf::Font font;
                if (!font.loadFromFile("arial.ttf"))
                        return false;
                sf::Text text;
                text.setFont(font);
                text.setString(text_worlds);
                text.setCharacterSize(text_size);
                text.setColor(sf::Color::Red);

                text.setPosition(0,count * (text_size + space_size) + space_size);
                renderTexture.draw(text);
                renderTexture.display();

                texture = renderTexture.getTexture();
                count ++;
                return true;
        };
        void set_text(int p_count, int p_text_size, int p_space_size){
                count = p_count;
                text_size = p_text_size;
                space_size = p_space_size;
        };
        void draw(){
                sprite.setTexture(texture);
                window.draw(sprite);
               
        };

private:
        int count;

        int text_size;
        int space_size;
       
        sf::RenderTexture renderTexture;
        sf::RectangleShape rectangle;  

        sf::Sprite sprite;
        sf::Texture texture;
};
 

thanks for help.
Title: Re: too much text problem
Post by: Ixrec on April 12, 2014, 07:54:34 pm
The typical solution to the "white square problem" doesn't seem to apply here since your texture's scope isn't limited to add_text.

However, I notice you call display() twice.  This is definitely not how it should work: every frame you clear() once, then draw() all your stuff, then display() once, that's it.  I believe what display() actually does is switch frame buffers, which would explain your bug.

It might be a good idea to put the clear/draw/display calls all at the bottom of your function so you don't lose track of them and make mistakes like this.  There's nothing wrong with leaving the rectangle undrawn while you set up your text object.
Title: Re: too much text problem
Post by: CreaM on April 12, 2014, 08:10:31 pm
Still doesnt work.
And i have to display() before
texture = renderTexture.getTexture();
 
, havent i?
Title: Re: too much text problem
Post by: Ixrec on April 13, 2014, 04:19:06 pm
Correction: It might be a good idea to put the clear/draw/display/getTexture calls all at the bottom of your function.  You're right that display() has to come before getTexture().

And once again, a complete and minimal example would be a big help.  There's not a lot we can do without real code to work on.
Title: Re: too much text problem
Post by: CreaM on April 13, 2014, 06:21:27 pm
- the problem is definitely in class. - the main(){...} really wont help you, its just creating object of Text_manager, than .set_text(0,24,10);and .add_text(...) twicely, and of course .draw() in main loop...
Something is wrong with class, the description of the problem is above.
Anyway the complete code is here:
#include <SFML/Graphics.hpp>
#include <windows.h>
#include <iostream>

sf::RenderWindow window(sf::VideoMode(800, 650), "screen");

class Text_manager{
public:
    bool add_text(const std::string& text_worlds){
       
                rectangle.setTexture(&texture);
        rectangle.setPosition(0,0);
        rectangle.setSize(sf::Vector2f(800, count * (text_size + space_size)));

                sf::Font font;
        if (!font.loadFromFile("arial.ttf"))
            return false;
        sf::Text text;
        text.setFont(font);
        text.setString(text_worlds);
        text.setCharacterSize(text_size);
        text.setColor(sf::Color::Red);
                text.setPosition(0,count * (text_size + space_size) + space_size);

                renderTexture.create(800, (count + 1) * (text_size + space_size));
        renderTexture.clear();
       
        renderTexture.draw(rectangle);
        renderTexture.draw(text);

        renderTexture.display();

        texture = renderTexture.getTexture();
        count ++;
        return true;
    };
    void set_text(int p_count, int p_text_size, int p_space_size){
        count = p_count;
        text_size = p_text_size;
        space_size = p_space_size;
    };
    void draw(){
        sprite.setTexture(texture);
        window.draw(sprite);
    };

private:
    int count;
        int text_size;
    int space_size;
   
    sf::RenderTexture renderTexture;
    sf::RectangleShape rectangle;  
        sf::Sprite sprite;
    sf::Texture texture;
};


int main()
{
    Text_manager try1;
        try1.set_text(0,24,10);
       
        try1.add_text("text");
        try1.add_text("newText");
        //---------------------------
    while (window.isOpen())
                {
                        sf::Event event;
                        while (window.pollEvent(event)){
                        if (event.type == sf::Event::Closed)window.close();
                        }
                        //------------------------------------------------
                window.clear(sf::Color::Black);
               
                try1.draw();
                //--------------------------
        window.display();
    }

    return 0;
}
 

      
Title: Re: too much text problem
Post by: Ixrec on April 13, 2014, 06:51:01 pm
I hadn't fully realized before that you're texturing the rectangle with the rendertexture's texture.  That seems like a dubious/fragile design choice (maintaining a std::string and just drawing an sf::Text would be a LOT easier, and probably safer/faster/etc than this rendertexture stuff) but I guess it should still work.

I don't remember if the texture produced by getTexture() is truly separate from the rendertexture, so drawing it to the same rendertexture it came from might not be safe.  I can't see anything in the docs or tutorials that seems to cover this case; another sign this isn't normal usage.

Someone in here is bound to know for sure, but if you want to test that theory right away, maybe use an sf::Image member instead to force the texture to get copied to main memory?
Title: Re: too much text problem
Post by: Laurent on April 13, 2014, 09:00:18 pm
Quote
I don't remember if the texture produced by getTexture() is truly separate from the rendertexture, so drawing it to the same rendertexture it came from might not be safe.
Rendering a texture to itself is not allowed. But from what I've seen, that's not what he does: he makes a copy of the render-target's texture, so the source and target textures are two separate objects.