SFML community forums

Help => General => Topic started by: Users.RandomUser(); on January 07, 2014, 06:07:42 pm

Title: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 07, 2014, 06:07:42 pm
Hi,

My code is causing errors in the console window:
"Failed to activate the window's context" and sometimes something about creating the OpenGL context.
The errors are thrown repeatedly.
#include <SFML/Graphics.hpp>
#include <atomic>
#include <iostream>

struct gameClass
{
    gameClass(): cSettings(24,8,16,4,4), window(sf::VideoMode(800, 600), "OpenGL", sf::Style::Default, cSettings) {}
    sf::ContextSettings cSettings;
    sf::Window window;
    std::atomic_bool glHasControl;
};

int drawGLScene(gameClass* gameCore)                // Here's where we draw
{
    gameCore->window.setActive(true);

    while (gameCore->glHasControl.load(std::memory_order_acquire))
        gameCore->window.display();

    gameCore->window.setActive(false);
    return 1;                    // Everything went OK
}

int main()
{
    gameClass gameCore;

    sf::ContextSettings settings = gameCore.window.getSettings();
    std::cout << "depth bits:" << settings.depthBits << std::endl;
    std::cout << "stencil bits:" << settings.stencilBits << std::endl;
    std::cout << "antialiasing level:" << settings.antialiasingLevel << std::endl;
    std::cout << "version:" << settings.majorVersion << "." << settings.minorVersion << std::endl;

    gameCore.window.setVerticalSyncEnabled(true);
    gameCore.glHasControl.store(true, std::memory_order_release);
    sf::Thread displayThread(&drawGLScene, &gameCore);
    displayThread.launch();
    while (gameCore.window.isOpen())
    {
        sf::Event event;
        while (gameCore.window.pollEvent(event))
        {
            gameCore.glHasControl.store(false, std::memory_order_release);
            displayThread.wait();
            gameCore.window.setActive(true);

            if (event.type == sf::Event::Closed)
                gameCore.window.close();
        }
    }
    return 0;
}
 

-Jared
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: amir ramezani on January 07, 2014, 07:19:38 pm
read the SFML's window tutorial first and try to fix it!
I've got your code
but, I haven't time to fix that
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: amir ramezani on January 07, 2014, 08:14:34 pm
I've uploaded the modified source with the given project as the static library in code::blocks
I've compiled it, it worked fine for me ;)
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 07, 2014, 09:41:11 pm
I fixed the | and made it a ||, but project still starts with a ton of "failed to activate the window's context" errors in the black console window.

(http://imgur.com/Z2ENPwr.png)

Thanks for the quick response, I enjoy SFML and it's community now.  BEST MULTIMEDIA LIBRARY EVERRRRRRRRR!

-Jared
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: amir ramezani on January 08, 2014, 05:12:06 am
add -mwindows to linker flags
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 08, 2014, 05:51:11 pm
That only removes the command line, but it's throwing errors!!!  Wouldn't fixing the errors be a better solution?

-Jared
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: amir ramezani on January 08, 2014, 06:16:08 pm
I think that fixe's your error
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 08, 2014, 08:37:45 pm
Why, though?  How does it work?  What does it do?
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Nexus on January 08, 2014, 08:53:50 pm
Do not keep any OpenGL context related objects as global variables. There are known issues with render windows and other SFML types when used globally. In your case, this concerns the gameCore variable.

In general, it's a good idea to avoid global/static variables wherever possible (see also here (http://en.sfml-dev.org/forums/index.php?topic=13977.msg97950#msg97950)).

By the way, try to keep your code minimal, so that you can also insert it directly in the post with code tags. A lot of people are scared off when they have to download files just to answer the question.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 08, 2014, 09:47:09 pm
Thanks for the response!  I tried pointing the window to the thread's function at first, but it didn't work.  However, I was just pointing to the address of the variables; they themselves weren't initially pointers.  How should I go about passing the window context, and should I go back to pointers instead of storing data in gameCore?  I knew to avoid globals, but I didn't know to what extent.  I'll try to remember not to post files as the only source of code, too.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Nexus on January 08, 2014, 09:54:50 pm
However, I was just pointing to the address of the variables
What do you mean? The sf::Window in your class is not a pointer, so it will be created with the global variable.

Why don't you declare the gameCore in main() and pass it as an argument to the constructors and functions that need it?
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 09, 2014, 12:41:33 am
I was declaring window in main, and I passed &window through the thread arguments.  In the function, I typed something like bool* glRunning.

I will try passing a gameCore pointer to the function.  I may not have time until tomorrow.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Nexus on January 09, 2014, 01:37:18 am
Can you show the current code here? Try to keep it as minimal as possible (but still complete).

By the way, if you use bool* glRunning as a thread flag, that's not threadsafe. You might want to use atomic bools instead.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 11, 2014, 05:33:42 pm
Sadly, the error persists.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: zsbzsb on January 11, 2014, 05:58:58 pm
Can you show the current code here? Try to keep it as minimal as possible (but still complete).
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 11, 2014, 06:11:36 pm
Explain what is wrong with the code I posted, zsbzsb.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Nexus on January 11, 2014, 06:33:33 pm
Explain what is wrong with the code I posted, zsbzsb.
It contradicts your explanations. You said:
Quote
I was declaring window in main, and I passed &window through the thread arguments. I typed something like bool* glRunning.
Neither applies to the code you have shown us. We don't like to guess, please show the most recent code and explain what's wrong with it (not another code you once used).

Furthermore, keep the code minimal, remove everything that's not needed (initGL() which does nothing, lots of member variables and initialization settings). Read also this post (http://en.sfml-dev.org/forums/index.php?topic=5559.msg36368#msg36368).
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 11, 2014, 06:37:13 pm
I at one time, but not currrently used bool* glRunning. I will clean up the code right now.
EDIT: How is it now?
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: zsbzsb on January 11, 2014, 07:26:08 pm
Explain what is wrong with the code I posted, zsbzsb.

Sorry  :-\

Didn't see you had edited your first post  ;)
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 12, 2014, 07:18:40 pm
Does everyone get this error?
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Gobbles on January 13, 2014, 12:15:16 am
With your currently posted code I am getting

error C2864: 'gameClass::cSettings' : only static const integral data members can be initialized within a class

for this line:
Code: [Select]
sf::ContextSettings cSettings = sf::ContextSettings(24,8,16,4,3);
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 13, 2014, 02:39:24 am
I use Code::Blocks.  I used to use Visual Studio, and that looks similar to its errors with the "C2864".  Anyway, if it is unsupported by something, I'll fix that by setting the values outside the class, as I may want to change those settings during runtime in the future.

EDIT:  Interesting, it calls the struct a class.  Must be used for both.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 14, 2014, 10:11:56 pm
Gobbles, see if the code works now.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Gobbles on January 14, 2014, 10:28:02 pm
Yes it compiles, although I still see the context issue. I took the liberty to move it all into a class design ( within my own game ) and I am not seeing this issue at all.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 14, 2014, 11:16:18 pm
What does your class design look like?  It would be nice to know what I could change to fix this.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Gobbles on January 14, 2014, 11:50:31 pm
mostly just messing around with it but in my Game.h I have:
Code: [Select]
std::unique_ptr<sf::Thread> CharLoadThread;
Then in the .cpp constructor I have
Code: [Select]
CharLoadThread = std::unique_ptr<sf::Thread>(new sf::Thread(&Game::LoadCharacter, this));
CharLoadThread->launch();
and Load Character is pretty standard, but I had to add a sf::Context context;
Code: [Select]
void Game::LoadCharacter()
{
/* Stuff I'm Loading */
sf::Context context;
}
That's it that's all.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 15, 2014, 10:33:45 pm
None of that seems to make a difference.  Is it possible for you to post all of your code in a file?  I really want to see a working version of this.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Gobbles on January 15, 2014, 11:42:12 pm
I removed all non-essential code, but try these 3 files

main:
[
#include "Game.h"
#include <stdlib.h>
#include <time.h>
//DEBUG CODE
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#define DEBUG_NEW new(_CLIENT_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif

int main()
{
        _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
        std::unique_ptr<Game> game(new Game());
        srand(time(NULL));
        game->Run();

    return EXIT_SUCCESS;
}
 

Game.h
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <sstream>
#include <cmath>
#include <iostream>

class Game
{
public:
        Game();
        ~Game();
        void Run();

private:
        std::unique_ptr<sf::RenderWindow> window;

        //Loading Thread
        std::unique_ptr<sf::Thread> CharLoadThread;
};
 

and Game.cpp

#include "Game.h"

Game::Game()
{
screenSize = sf::Vector2f(1024,768);
        window = std::unique_ptr<sf::RenderWindow>(new sf::RenderWindow(sf::VideoMode(static_cast<int>(screenSize.x), static_cast<int>(screenSize.y)), "Re:Volved ver 0.0.04a", sf::Style::Close));

        window->setKeyRepeatEnabled(false);
        //LoadCharacter();
        CharLoadThread = std::unique_ptr<sf::Thread>(new sf::Thread(&Game::LoadCharacter, this));
        CharLoadThread->launch();
}

Game::~Game()
{
}

void Game::LoadCharacter()
{
        std::cout << "Start Loading\n";
        //groundMap = std::make_shared<Map>(MainCamera);
        //groundMap->Read();
    std::cout << "Map Read\n";
        //charDef = std::unique_ptr<CharDef>(new CharDef("skeleton"));
        std::cout << "CharDef Loaded\n";
        //character = std::unique_ptr<Character>(new Character(sf::Vector2f(500.f, 100.f), *charDef, 0));
        std::cout << "Character Loaded\n";
        //character->BodypartsInit();
        std::cout << "Character Bodyparts Loaded\n";
    //enemy = std::unique_ptr<Enemy>(new Enemy(sf::Vector2f(800.f, 100.f), *charDef, 1));
        std::cout << "Enemy Loaded\n";
    //enemy->BodypartsInit();
        std::cout << "Enemy BodyParts Loaded\n";
        //sf::Context context;
        Loaded = true;
}

void Game::Run()
{
        sf::Clock clock;
        sf::Time timeSinceLastUpdate = sf::Time::Zero;
        static const sf::Time timePerFrame = sf::seconds(1.f / 60.f);

        fpsText.setFont(fpsFont);

        while (window->isOpen())
    {
                timeSinceLastUpdate += clock.restart();

               
                while(timeSinceLastUpdate > timePerFrame)
                {
                        timeSinceLastUpdate -= timePerFrame;
                        std::cout << "Updating\n";
                }
        }
}
 

Let me know if this causes any problems for you, I think I have everything in there.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: eXpl0it3r on January 16, 2014, 09:16:56 am
Although it's not really necessary to put the window or the thread into unique_ptr, it shouldn't have anything to do with the described problem.

Let's do some checking before moving on: What GPU do you have and is your driver up-to-date?
What OpenGL version does SFML return? (Get the ContextSettings from the window and check the major and minor property.)
Are you now using Code::Blocks or Visual Studio? What version are you using? Which OS are you using?

Since the error is a bit non descriptive, you'll need to debug further. Make sure you're in debug mode and obviously use the debug libraries of SFML. Next make sure the debugger can find SFML's source code. Then set a break point (or step into the application until you get) to the line linked here (https://github.com/SFML/SFML/blob/6c1899d0f70e4dc845d7f482b22c9d79f7cd4f2f/src/SFML/Window/Win32/WglContext.cpp#L126). When you're there with the debugger check each of the three parts of the boolean equation. Post here which ever is interpreted as false.

Alternatively you can just pick one and google a bit, to see what issues exist. For example "wglMakeCurrent fails" gives you around 16k results.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 16, 2014, 05:33:54 pm
OS: Windows 7 Home Premium 64-bit
GPU: GeForce 650 with frequently updated driver
IDE: Code::Blocks

I will debug once I get home.

EDIT: m_context->setActive(active) in Window.cpp returns false (that outputs the error in console)
EDIT2: The m_context returns true, however, as that is the only way the error could be displayed
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Gobbles on January 16, 2014, 07:06:44 pm
OS: Windows 7 Home Premium 64-bit
GPU: GeForce 650 with frequently updated driver
IDE: Code::Blocks

Interesting, we are basically running the same specs.
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 16, 2014, 10:22:48 pm
Only suspicious thing is wglMakeCurrent = {<text variable, no debug info>} 0x6c8a955b <wglMakeCurrent>
EDIT: OpenGL Version 4.4 successfully loads
Title: Re: Multithreading Results in Window Context Activation Fail
Post by: Users.RandomUser(); on January 17, 2014, 11:13:21 pm
I've confirmed that the following code:
gameCore->window.display();
causes most errors, and this:
gameCore->window.setActive(true);
only causes 1 to 5 at the beginning.  Must have to do with the way I'm accessing gameCore.  Is there another way I could access it?