New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Texture Unit 0 in resetGLStates #523

Closed
wants to merge 2 commits into
base: master
from

Conversation

Projects
None yet
6 participants
@ColinDuquesnoy

ColinDuquesnoy commented Jan 6, 2014

When we combine a 3D engine which uses multiple texture units (such as Horde3D) with SFML graphics API, SFML's textures won't show up. This is discussed in this topic.

The issue is that Horde3D does not reset texture unit 0 as the active texture unit when finishing rendering (see here)

The fix is simple: (re)activate texture unit 0 before rendering with SFML, i.e. when resetting GL states.

I made a complete example (based on the Horde3D chicago sample). Pre-compiled binaries for Windows are available in the release section if you want to try it out by yourself.

Here is the output without the fix:

notworking

And here is the output with the fix:

working

As you can see, SFML and Horde3D can play nicely together ;) I have tried the example on Windows 7, Windows Xp and Ubuntu 13.10 (using gcc 4.8)

I have hesitated a lot about whether to post the fix here or on the Horde3D bug-tracker but resetGLStates seems like the perfect place for this job.

ColinDuquesnoy added some commits Jan 6, 2014

Reset texture unit 0
3D Engines such as Horde3D do not reset texture unit 0 when
finishing rendering. This fix make it possible to combine Horde3D and
SFML.

@ghost ghost assigned LaurentGomila Jan 6, 2014

binary1248 added a commit that referenced this pull request Apr 28, 2014

Make sure texture unit 0 is active when reseting RenderTarget states (#…
…523), fix RenderTarget not clearing when a texture used as a RenderTexture color attachment is left bound in a different context (http://en.sfml-dev.org/forums/index.php?topic=9350.0).

binary1248 added a commit that referenced this pull request Apr 28, 2014

Make sure texture unit 0 is active when reseting RenderTarget states (#…
…523), fix RenderTarget not clearing when a texture used as a RenderTexture color attachment is left bound in a different context (http://en.sfml-dev.org/forums/index.php?topic=9350.0).

binary1248 added a commit that referenced this pull request May 6, 2014

Make sure texture unit 0 is active when reseting RenderTarget states (#…
…523), fix RenderTarget not clearing when a texture used as a RenderTexture color attachment is left bound in a different context (http://en.sfml-dev.org/forums/index.php?topic=9350.0).

binary1248 added a commit that referenced this pull request May 26, 2014

Make sure texture unit 0 is active when reseting RenderTarget states (#…
…523), fix RenderTarget not clearing when a texture used as a RenderTexture color attachment is left bound in a different context (http://en.sfml-dev.org/forums/index.php?topic=9350.0).

@eXpl0it3r eXpl0it3r modified the milestones: 2.2, 2.x May 26, 2014

@eXpl0it3r

This comment has been minimized.

Show comment
Hide comment
@eXpl0it3r

eXpl0it3r May 26, 2014

Member

Fixed through @binary1248's implementation in #591 and merged in e6b5ce1.

Member

eXpl0it3r commented May 26, 2014

Fixed through @binary1248's implementation in #591 and merged in e6b5ce1.

@eXpl0it3r eXpl0it3r closed this May 26, 2014

@eXpl0it3r eXpl0it3r added resolved and removed confirmed labels May 26, 2014

@ColinDuquesnoy

This comment has been minimized.

Show comment
Hide comment
@ColinDuquesnoy

ColinDuquesnoy May 27, 2014

Unfortunately it is not fixed for me. To make the above example work, I had to move the call glClientActiveTexture and glActiveTexture before the call to glEnable(GL_TEXTURE_2D); in RenderTarget::resetGLStates, like this:

void RenderTarget::resetGLStates()
{
    // Check here to make sure a context change does not happen after activate(true)
    bool shaderAvailable = Shader::isAvailable();

    if (activate(true))
    {
        // Make sure that extensions are initialized
        priv::ensureExtensionsInit();

        // Make sure that the texture unit which is active is the number 0
        if (GLEXT_multitexture)
        {
            glCheck(GLEXT_glClientActiveTexture(GLEXT_GL_TEXTURE0));
            glCheck(GLEXT_glActiveTexture(GLEXT_GL_TEXTURE0));
        }

        // Define the default OpenGL states
        glCheck(glDisable(GL_CULL_FACE));
        glCheck(glDisable(GL_LIGHTING));
        glCheck(glDisable(GL_DEPTH_TEST));
        glCheck(glDisable(GL_ALPHA_TEST));
        glCheck(glEnable(GL_TEXTURE_2D));
        glCheck(glEnable(GL_BLEND));
        glCheck(glMatrixMode(GL_MODELVIEW));
        glCheck(glEnableClientState(GL_VERTEX_ARRAY));
        glCheck(glEnableClientState(GL_COLOR_ARRAY));
        glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
        m_cache.glStatesSet = true;

        // Apply the default SFML states
        applyBlendMode(BlendAlpha);
        applyTransform(Transform::Identity);
        applyTexture(NULL);
        if (shaderAvailable)
            applyShader(NULL);

        m_cache.useVertexCache = false;

        // Set the default view
        setView(getView());
    }
}

ColinDuquesnoy commented May 27, 2014

Unfortunately it is not fixed for me. To make the above example work, I had to move the call glClientActiveTexture and glActiveTexture before the call to glEnable(GL_TEXTURE_2D); in RenderTarget::resetGLStates, like this:

void RenderTarget::resetGLStates()
{
    // Check here to make sure a context change does not happen after activate(true)
    bool shaderAvailable = Shader::isAvailable();

    if (activate(true))
    {
        // Make sure that extensions are initialized
        priv::ensureExtensionsInit();

        // Make sure that the texture unit which is active is the number 0
        if (GLEXT_multitexture)
        {
            glCheck(GLEXT_glClientActiveTexture(GLEXT_GL_TEXTURE0));
            glCheck(GLEXT_glActiveTexture(GLEXT_GL_TEXTURE0));
        }

        // Define the default OpenGL states
        glCheck(glDisable(GL_CULL_FACE));
        glCheck(glDisable(GL_LIGHTING));
        glCheck(glDisable(GL_DEPTH_TEST));
        glCheck(glDisable(GL_ALPHA_TEST));
        glCheck(glEnable(GL_TEXTURE_2D));
        glCheck(glEnable(GL_BLEND));
        glCheck(glMatrixMode(GL_MODELVIEW));
        glCheck(glEnableClientState(GL_VERTEX_ARRAY));
        glCheck(glEnableClientState(GL_COLOR_ARRAY));
        glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
        m_cache.glStatesSet = true;

        // Apply the default SFML states
        applyBlendMode(BlendAlpha);
        applyTransform(Transform::Identity);
        applyTexture(NULL);
        if (shaderAvailable)
            applyShader(NULL);

        m_cache.useVertexCache = false;

        // Set the default view
        setView(getView());
    }
}

@eXpl0it3r eXpl0it3r removed the resolved label May 27, 2014

@eXpl0it3r

This comment has been minimized.

Show comment
Hide comment
@eXpl0it3r

eXpl0it3r May 27, 2014

Member

I guess, I'll reopen this again then, even if it's essentially more of an issue than a PR at this point and let's summon @binary1248

Member

eXpl0it3r commented May 27, 2014

I guess, I'll reopen this again then, even if it's essentially more of an issue than a PR at this point and let's summon @binary1248

@eXpl0it3r eXpl0it3r reopened this May 27, 2014

@binary1248

This comment has been minimized.

Show comment
Hide comment
@binary1248

binary1248 May 27, 2014

Member

Hmm... It seems like the enable only affects the currently active texture unit. How annoying. I am slowly starting to hate the legacy state machine and sympathize with the ARB for removing all this functionality 😉.

Member

binary1248 commented May 27, 2014

Hmm... It seems like the enable only affects the currently active texture unit. How annoying. I am slowly starting to hate the legacy state machine and sympathize with the ARB for removing all this functionality 😉.

binary1248 added a commit that referenced this pull request May 27, 2014

Moved glClientActiveTexture and glActiveTexture calls before glEnable…
…(GL_TEXTURE_2D) to make sure texture unit 0 gets affected. (#523)
@binary1248

This comment has been minimized.

Show comment
Hide comment
@binary1248

binary1248 May 27, 2014

Member

Should be fixed with 5fe5d39. The change was as simple as @ColinDuquesnoy described.

Member

binary1248 commented May 27, 2014

Should be fixed with 5fe5d39. The change was as simple as @ColinDuquesnoy described.

@ColinDuquesnoy

This comment has been minimized.

Show comment
Hide comment
@ColinDuquesnoy

ColinDuquesnoy May 27, 2014

Works great, thanks!

ColinDuquesnoy commented May 27, 2014

Works great, thanks!

@TankOs

This comment has been minimized.

Show comment
Hide comment
@TankOs

TankOs May 27, 2014

Member

Going to merge this, thanks.

Member

TankOs commented May 27, 2014

Going to merge this, thanks.

binary1248 added a commit that referenced this pull request May 27, 2014

Moved glClientActiveTexture and glActiveTexture calls before glEnable…
…(GL_TEXTURE_2D) to make sure texture unit 0 gets affected. (#523)
@eXpl0it3r

This comment has been minimized.

Show comment
Hide comment
@eXpl0it3r

eXpl0it3r May 27, 2014

Member

Merged in 1dae89a.

Member

eXpl0it3r commented May 27, 2014

Merged in 1dae89a.

@eXpl0it3r eXpl0it3r closed this May 27, 2014

@eXpl0it3r eXpl0it3r added the resolved label May 27, 2014

MarioLiebisch added a commit to MarioLiebisch/SFML that referenced this pull request Jun 13, 2014

Make sure texture unit 0 is active when reseting RenderTarget states (S…
…FML#523), fix RenderTarget not clearing when a texture used as a RenderTexture color attachment is left bound in a different context (http://en.sfml-dev.org/forums/index.php?topic=9350.0).

MarioLiebisch added a commit to MarioLiebisch/SFML that referenced this pull request Jun 13, 2014

Moved glClientActiveTexture and glActiveTexture calls before glEnable…
…(GL_TEXTURE_2D) to make sure texture unit 0 gets affected. (SFML#523)

jcowgill added a commit to jcowgill/SFML that referenced this pull request Sep 22, 2014

Make sure texture unit 0 is active when reseting RenderTarget states (S…
…FML#523)

Combination of two commits:
* Make sure texture unit 0 is active when reseting RenderTarget states (SFML#523), fix RenderTarget not clearing when a texture used as a RenderTexture color attachment is left bound in a different context (http://en.sfml-dev.org/forums/index.php?topic=9350.0).
* Moved glClientActiveTexture and glActiveTexture calls before glEnable(GL_TEXTURE_2D) to make sure texture unit 0 gets affected. (SFML#523)

(cherry picked from commit e6b5ce1 and 1dae89a)

James Cowgill: hardcode GLEXT_ stuff since GlExtensions.hpp is not in SFML 2.1

Conflicts:
	src/SFML/Graphics/GLExtensions.hpp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment