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

Author Topic: Textures missing in Ubuntu  (Read 9664 times)

0 Members and 1 Guest are viewing this topic.

Jaenis

  • Newbie
  • *
  • Posts: 48
    • View Profile
Textures missing in Ubuntu
« Reply #15 on: October 18, 2009, 08:38:39 am »
I found one (possibly) illogical bit on window creation.
In src/SFML/Window/Window.cpp, line 133:
Code: [Select]
   // Make sure another context is bound, so that:
    // - the context creation can request OpenGL extensions if necessary
    // - myContext can safely be destroyed (it's no longer bound)
    Context context;

    // Recreate the context
    delete myContext;
    myContext = priv::ContextGL::New(myWindow, mode.BitsPerPixel, settings);

    // Perform common initializations
    Initialize();
}

Here you create another context so you can get OpenGL extensions data, as said in comments. But isn't it so that this temporary context will get destroyed - and thereby marked not active - when it goes out of scope. And after this there is no active context? Or is there?

I made a test to modify this code in following way:
Code: [Select]
   // Initialize window in it's own scope
    {
        // Make sure another context is bound, so that:
        // - the context creation can request OpenGL extensions if necessary
        // - myContext can safely be destroyed (it's no longer bound)
        Context context;

        // Recreate the context
        delete myContext;
        myContext = priv::ContextGL::New(myWindow, mode.BitsPerPixel, settings);

        // Perform common initializations
        Initialize();
    }

    // Activate context
    SetActive(true);
}


Now there is some context active when window initialization is done.
This modification fixes this problem what I am facing here in Ubuntu.

So, could it be that in Linux implementation when you call SetActive(false) to some context, all contexes will get deactivated?


Edit:
Actually it seems that "threadContext" (sfml/Window/ContextGL.cpp, line 131) will get activated when this happens.
So, there is an active context, but it is not the window that was created. That's why the SetActive(true) call on the end of the function was required.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Textures missing in Ubuntu
« Reply #16 on: October 18, 2009, 09:40:38 am »
Like you said, when a context is deactivated another one is activated, so that there's always an active context at any time.

It's not the window's one, but it shouldn't matter because all contexts are shared. Thus if you load an image with the "global" context activated, it will be available on the window's one as well. And when something must be drawn on the window, of course its context is activated ;)

However your "fix" is interesting, it will probably help me to spot the error. Actually I did like that before I implemented the batching feature, but since then something has changed: a window is no longer active all the time (so you don't have to deactivate it before using it in another thread, for example), that's why I no longer activate it by default after creation.
Laurent Gomila - SFML developer

Jaenis

  • Newbie
  • *
  • Posts: 48
    • View Profile
Textures missing in Ubuntu
« Reply #17 on: October 18, 2009, 10:33:58 am »
Actually it seems that you have bug in context activation/deactivation logic:
Every time when you deactivate an inactive context, the "threadContext" will get activated.

Way to test:
Code: [Select]
int main()
{
    // Create main window
    sf::RenderWindow Window(sf::VideoMode(500, 200), "SFML window");

    // Main window is now active
    {
        // Create context, which gets activated
        sf::Context context;

        // Activate the main window, this disables "context"
        Window.SetActive();

    }    // Context will get destroyed and deactivated

    // Main window is not active anymore
}


This is illogical, since user just activated main window.

Let's follow what happens when inactive context will get deactivated... First it cals Context::SetActive(false), which calls ContextGL::SetActive(false), which looks like this:
Code: [Select]

bool ContextGL::SetActive(bool active)
{
    if (MakeCurrent(active))
    {


MakeCurrent will get called with false:
Code: [Select]

bool ContextGLX::MakeCurrent(bool active)
{
    if (active)
    {
    ...
    }
    else
    {
        if (glXGetCurrentContext() == myContext)
            ...
        else
            return true;
    }
}

So MakeCurrent returns true, because current context was not "myContext"

This returns to SetActive function:
Code: [Select]

    if (MakeCurrent(active))   // <-- Just returned true
    {
        if (active && (threadContext == 0))
        {
            ...
        }
        else if (!active && (threadContext != NULL) && (threadContext != this))
        {
            // Activate the reference context for this thread to ensure
            // that there is always an active context for subsequent graphics operations
            threadContext->SetActive(true);
        }

The else-if branch is run, since active is false and thread context exists and it is not this.
So, now we just activated threadContext when we were deactivating an context that was not active. This sounds like a bug to me :)

Shouldn't that MakeCurrent return false when we are deactivating an inactive context? Then nothing would happen and the previously active context would stay active.

Edit: Just changing MakeCurrent to return false was not enough, also this had to be changed:
Code: [Select]
ContextGL::~ContextGL()
{
    if (threadContext == this)
    {
        threadContext = NULL;
    }
    /*else if (threadContext != NULL)
    {
        threadContext->SetActive(true);
    }*/
}