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

Author Topic: pollEvents never returns true  (Read 3302 times)

0 Members and 1 Guest are viewing this topic.

The last Dodo

  • Newbie
  • *
  • Posts: 13
    • ICQ Messenger - 301020362
    • MSN Messenger - dom.dopplinger@hotmail.com
    • View Profile
    • http://dodo.bplaced.net
pollEvents never returns true
« on: July 01, 2012, 07:01:30 pm »
Hi everyone,

I recently changed my Graphics-Class to a Singleton with a thread. Since that moment window->pollEvents(event) does not send any events.  But I can still draw in the window. :o

I code with Windows 7, Code::Blocks, MinGW, SFML2, Boost 1.48

I created a minimal example, that has exactly this behavior. This code may look a bit crappy, but I removed the irrelevant parts.

First, I haven't had the "window->setActive(true/false);", but I got an error message: "Failed to active the window's context".

main.cpp
#include <SFML/Window.hpp>

#include "Graphics.h"

int main()
{
        sGraphics->start();
        sGraphics->join();
    return 0;
}
 

Graphics.h
#ifndef GRAPHICS_H_
#define GRAPHICS_H_

#include <boost/thread.hpp>
#include <sfml/Window.hpp>
#include <sfml/Graphics/RenderWindow.hpp>

using namespace sf;

class Events;
class GraphicsState;

class Graphics {
    boost::thread thread;
    bool stillRunning;
    RenderWindow *window;
    int width, height;
    static Graphics* instance;

    Graphics();
public:
    static Graphics* getInstance();
    virtual ~Graphics();
    void run();
    void start();
    void join();
    void deinit();
    bool isStillRunning();
    void quit();
};

#define sGraphics Graphics::getInstance()

#endif /* GRAPHICS_H_ */
 

Graphics.cpp
#include <cstdio>
#include <SFML/Window.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/Text.hpp>
#include <exception>

#include "Graphics.h"

using namespace sf;
using namespace std;

Graphics::Graphics() {
        char title[50] = "";
        width = 800;
        height = 600;
        sprintf(title, "%s V%d.%d", "A Geek's Warfare", 0, 0);
        VideoMode videoMode(width, height, 32);
        unsigned int params = Style::Close | Style::Titlebar;
        if(false)
                params = Style::Fullscreen;
        window = new RenderWindow(videoMode, title, params);
        window->setActive(false);

        stillRunning = true;
}

Graphics* Graphics::instance = NULL;

Graphics* Graphics::getInstance() {
        if(!instance)
                instance = new Graphics();
        return instance;
}

Graphics::~Graphics() { }

void Graphics::run() {
        try {
                window->setActive(true);
                while(isStillRunning()) {
                        Event event;
                        window->clear();
                        while(window->pollEvent(event))
                                if(event.type == sf::Event::Closed) {
                                        quit();
                                }else if(event.type == sf::Event::KeyPressed) {
                                        if(event.key.code == sf::Keyboard::Escape)
                                                quit();
                                }
                        sf::Text text("Hello World!");
                        text.setCharacterSize(30);
                        text.setStyle(sf::Text::Bold);
                        text.setColor(sf::Color::Red);
                        text.setPosition(width / 2 - text.getGlobalBounds().width / 2, height / 2 - text.getGlobalBounds().height / 2);
                        window->draw(text);
                        window->display();
                        boost::this_thread::sleep(boost::posix_time::milliseconds(50));
                }
        } catch(exception& e) {

        } catch(...) {

        }
        deinit();
}

void Graphics::start() {
        thread = boost::thread(&Graphics::run, this);
}

void Graphics::join() {
        thread.join();
}

void Graphics::deinit() {
        window->close();
}

bool Graphics::isStillRunning() {
        return stillRunning;
}

void Graphics::quit() {
        stillRunning = false;
}
 
Maze: Dodo-Labyrinth
Jump 'n' Run: DodoRun

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: pollEvents never returns true
« Reply #1 on: July 01, 2012, 08:01:07 pm »
You must poll events in the thread where you created the window. This is an OS limitation.
Laurent Gomila - SFML developer

The last Dodo

  • Newbie
  • *
  • Posts: 13
    • ICQ Messenger - 301020362
    • MSN Messenger - dom.dopplinger@hotmail.com
    • View Profile
    • http://dodo.bplaced.net
Re: pollEvents never returns true
« Reply #2 on: July 02, 2012, 12:53:48 am »
Thank you :) Now it works :)
Maze: Dodo-Labyrinth
Jump 'n' Run: DodoRun

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: pollEvents never returns true
« Reply #3 on: July 04, 2012, 02:34:13 am »
You should also draw in the thread you created the window. This is a very specific OpenGL Windows limitation that causes it to sporadically fail on random PCs after drawing a few frames. Major headache.

Source: http://fabiensanglard.net/doom3/interviews.php
Quote
Interestingly, we only just found out last year why it was problematic (the same thing applied to Rage’s r_useSMP option, which we had to disable on the PC) – on windows, OpenGL can only safely draw to a window that was created by the same thread. We created the window on the launch thread, but then did all the rendering on a separate render thread. It would be nice if doing this just failed with a clear error, but instead it works on some systems and randomly fails on others for no apparent reason.
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: pollEvents never returns true
« Reply #4 on: July 04, 2012, 08:04:03 am »
Quote
You should also draw in the thread you created the window. This is a very specific OpenGL Windows limitation that causes it to sporadically fail on random PCs after drawing a few frames. Major headache.
I never noticed that before, many users do it and never reported a failure.
I don't think that you should warn everyone, just because of this interview.
Laurent Gomila - SFML developer

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: pollEvents never returns true
« Reply #5 on: July 04, 2012, 09:05:46 am »
I can confirm it's an issue on my PC (Graphics card is an nVidia GeForce 555M with Optimus technology). If I render in a different thread to the one which creates the window, the program simply crashes after a few frames. Render in the main thread, runs without a hitch.
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: pollEvents never returns true
« Reply #6 on: July 04, 2012, 11:59:55 am »
Quote
I can confirm it's an issue on my PC (Graphics card is an nVidia GeForce 555M with Optimus technology). If I render in a different thread to the one which creates the window, the program simply crashes after a few frames. Render in the main thread, runs without a hitch.
Oh. Can you show how you do exactly (maybe with some pseudo-code), just to be sure that you didn't do anything wrong?
Laurent Gomila - SFML developer

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: pollEvents never returns true
« Reply #7 on: July 04, 2012, 02:59:02 pm »
Sure, I'll do that when I get back from work (on my lunch break atm xD). If you read the interview I quoted, you'll see id Software encountered it again when working on RAGE so it's still a relevant problem.

What is interesting about my machine is it has an integrated intel video card, and the nvidia graphics card. Everything runs as expected, perfectly fine using the integrated video card (which it does by default) but if I explicitly tell it to use the nVidia graphics card, it'll crash.

My suspicion is that most machines will work without complaint, but the only way to do it reliably over multiple systems is to force it all into one thread. Fortunately the way my system was set-up let me make that change easily, and I actually made it a compile-time decision based on a constexpr boolean (no need to deliberately make the Linux builds run through hoops).
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: pollEvents never returns true
« Reply #8 on: July 05, 2012, 08:32:36 pm »
Okay, I'm having trouble getting it to trigger again. However the drivers have updated since I last tested this so it may have since been fixed.

Some further tests have shown OpenGL appears to perform very poorly if the context for the same window has to switch rapidly over a large amount of threads, with nvidia simply doing it veeerrry sloooowwwly and integrated running it quickly but eventually giving and just reporting "cannot change context".

This could appear if you try to implement rendering system inside a job system. This is what I was doing when I found the original CTD. My fix was to add a separate job queue which used only 1 thread, and push any "same-thread-needed" operations onto that queue, which stopped all rendering-related crashes but added overheads.

So there are a few things I guess I could of hit that'd make the system just give up...So don't tie push your rendering straight into a job system is what I learnt here I guess.
« Last Edit: July 05, 2012, 08:35:44 pm by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.