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

Author Topic: [SOLVED] Cannot bind a sf::Texture to a simple GL_QUADS  (Read 4404 times)

0 Members and 1 Guest are viewing this topic.

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
[SOLVED] Cannot bind a sf::Texture to a simple GL_QUADS
« on: June 26, 2013, 05:47:54 pm »
Hi everyone,

I'm trying to render shapes off-screen and then to bind the resulting texture to a simple OpenGL texture.

Unfortunately despite all my efforts (and the numerous snippets I've found on the internet) I just can't make it work properly. I assume it might be an easy slip I've made somewhere and perhaps an external look could help me to sort this out.

Expected result & Current result




        sf::RenderWindow window(sf::VideoMode (240, 240), "SFML window");

        sf::RectangleShape rectangle;
        rectangle.setSize(sf::Vector2f(100, 50));
        rectangle.setOutlineColor(sf::Color::Red);
        rectangle.setOutlineThickness(5);
        rectangle.setPosition(10, 20);
        sf::RenderTexture renderText;
        renderText.create(240, 240);
        renderText.draw(rectangle);

        // The main loop - ends as soon as the window is closed
        while (window.isOpen())
        {
                // Event processing
                sf::Event event;
                while (window.pollEvent(event))
                {
                        // Request for closing the window
                        if (event.type == sf::Event::Closed)
                                window.close();
                }
                window.clear();
                window.pushGLStates ();
                sf::Texture::bind (&renderText.getTexture ());
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, renderText.getTexture ().copyToImage ().getPixelsPtr ());
                glBegin(GL_QUADS);
                glTexCoord2f(0.f, 1.f);
                glVertex2f(0.0f, 1.0f);
                glTexCoord2f(1.f, 1.f);
                glVertex2f(1.0f, 1.0f);
                glTexCoord2f(1.f, 0.f);
                glVertex2f(1.0f, 0.0f);
                glTexCoord2f(0.f, 0.f);
                glVertex2f(0.0f, 0.0f);
                glEnd();

                window.popGLStates ();
                // End the current frame and display its contents on screen
                window.display();
        }
 

What am I doing wrong here?


Thank you!
« Last Edit: June 27, 2013, 04:22:09 pm by tbop »

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #1 on: June 26, 2013, 06:52:31 pm »
Ok I've updated my code I'm getting closer but there's a weird rescaling happening now.

G.

  • Hero Member
  • *****
  • Posts: 1593
    • View Profile
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #2 on: June 26, 2013, 07:04:29 pm »
pushGLStates and popGLStates should be around SFML graphics drawing, but you don't have any. (unless RenderTexture counts)

RenderTexture needs a call to its own display() before being used. (usual problem is that the texture is upside down without display(), you won't see it with your rectangle, but maybe something else can happen ^^)

I'm not sure your expected result corresponds to what your code does.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #3 on: June 26, 2013, 07:16:47 pm »
Additionnally to what G. said (which is explained in the official tutorials, by the way), your glTexImage2D call makes no sense (you're uploading the texture's contents to the texture). Just remove it.
Laurent Gomila - SFML developer

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #4 on: June 27, 2013, 10:56:18 am »
Yes sorry those push and pop were ruins of a former version I had.

The expected result is correct, it's from the official tutorial and it's what I've got if I just do a regular window.draw() call.

Nevertheless I guess I got you wrong because now the result's just worse! :)
I've removed the push-pop block, added renderText.display() before the rendering loop, removed the glTexImage2D (although I'm not sure to understand why is it wrong? And since I've seen this call on many other examples).

But now here's what I've got:



        sf::RenderWindow window(sf::VideoMode (w, h), "SFML window");
        glEnable(GL_TEXTURE_2D);
        sf::RectangleShape rectangle;
        rectangle.setSize(sf::Vector2f(100, 50));
        rectangle.setOutlineColor(sf::Color::Red);
        rectangle.setOutlineThickness(5);
        rectangle.setPosition(10, 20);
        sf::RenderTexture renderText;
        renderText.create(w, h);
        renderText.draw(rectangle);
        renderText.display();

        // The main loop - ends as soon as the window is closed
        while (window.isOpen())
        {
                // Event processing
                sf::Event event;
                while (window.pollEvent(event))
                {
                        // Request for closing the window
                        if (event.type == sf::Event::Closed)
                                window.close();
                }
                window.clear();
                sf::Texture::bind (&renderText.getTexture ());
                glBegin(GL_QUADS);
                        glTexCoord2f(0.f, 1.f);
                        glVertex2f(0.0f, 1.0f);
                        glTexCoord2f(1.f, 1.f);
                        glVertex2f(1.0f, 1.0f);
                        glTexCoord2f(1.f, 0.f);
                        glVertex2f(1.0f, 0.0f);
                        glTexCoord2f(0.f, 0.f);
                        glVertex2f(0.0f, 0.0f);
                glEnd();
                // End the current frame and display its contents on screen
                window.display();
        }
 
« Last Edit: June 27, 2013, 01:34:20 pm by tbop »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #5 on: June 27, 2013, 11:17:48 am »
It would be useful to see the complete program, to make sure that you don't set other OpenGL states before drawing with SFML.

Quote
removed the glTexImage2D (although I'm not sure to understand why is it wrong? And since I've seen this call on many other examples).
It copies the texture pixels to a sf::Image in RAM, then copies this image back to the texture. So to summarize, you're copying the texture to itself. You're wasting a huge amount of resources (CPU, GPU, RAM) for nothing.

Why did you think it was necessary?
Laurent Gomila - SFML developer

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #6 on: June 27, 2013, 11:50:22 am »
Hi Laurent!


It's the entire program. The rest's just the usual main bracketing stuff.

Quote
Why did you think it was necessary?

That link mainly but now I understand how much wrong I was. Hum, sorry about that.

In sf::Texture::bind it seems that the flag texture->m_pixelsFlipped is always set to true if it could be of any help.
« Last Edit: June 27, 2013, 11:53:14 am by tbop »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #7 on: June 27, 2013, 12:08:58 pm »
Ok, I'll try to test your program.

Quote
In sf::Texture::bind it seems that the flag texture->m_pixelsFlipped is always set to true if it could be of any help.
This is expected, this flag is set for textures produced by a sf::RenderTexture.
Laurent Gomila - SFML developer

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #8 on: June 27, 2013, 12:16:22 pm »
That's great. I'm still tinkering some stuffs here anyway.

I'm sure it can't be more than an stupid easy slip somewhere due to my lack of OpenGL concepts' understanding overall (I'm a DSP dood normally so I'm no more than a fresher still...).

At least what I've learnt so far is that OpenGL can turn out to be quite ticklish; that easy things can be insanely complicated to achieve albeit it usually makes tricky stuffs quite easier.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #9 on: June 27, 2013, 12:34:26 pm »
I haven't tested it yet, but I can already see what's missing: a call to glEnable(GL_TEXTURE_2D). Not sure if it will be enough to solve your problem though.
Laurent Gomila - SFML developer

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #10 on: June 27, 2013, 01:33:32 pm »
Right, I thought this was enabled right away by default actually. My bad.
I put it right after the initializing the RenderWindow (previous post EDITED).... Close enough...
but there're still unexpected re-scaling and translation that occurs between (though different from the first result I had above).



Cheers!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #11 on: June 27, 2013, 01:58:24 pm »
Since you don't configure any OpenGL state (especially matrices), the result that you get is expected.

The screen coordinates with the default matrices range from -1 to 1, not from 0 to 1 (that's why your quad only covers a quarter of the screen).

And with the default matrices and viewport, Y axis is inverted compared to SFML.

Fix these two issues (by setting a proper projection matrix and viewport) and you'll get the desired result.
Laurent Gomila - SFML developer

tbop

  • Newbie
  • *
  • Posts: 34
    • View Profile
Re: Cannot bind a sf::Texture to a simple GL_QUADS
« Reply #12 on: June 27, 2013, 04:10:47 pm »
Hi,

Further to your advice I just added these lines before drawing the quads and it seems to be working now.

Thank you very much Laurent!

window.clear();
sf::Texture::bind (&renderText.getTexture ());
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, 1, 1, 0, -1, 1);
glBegin(GL_QUADS);
        glTexCoord2f(0.f, 1.f);
        glVertex2f(0.0f, 1.0f);
        glTexCoord2f(1.f, 1.f);
        glVertex2f(1.0f, 1.0f);
        glTexCoord2f(1.f, 0.f);
        glVertex2f(1.0f, 0.0f);
        glTexCoord2f(0.f, 0.f);
        glVertex2f(0.0f, 0.0f);
glEnd();