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

Author Topic: RenderWindow .display() seems to do nothing  (Read 4350 times)

0 Members and 1 Guest are viewing this topic.

chitfacedagain

  • Newbie
  • *
  • Posts: 4
    • View Profile
RenderWindow .display() seems to do nothing
« on: September 01, 2015, 06:08:47 am »
I'm new to SFML and C++ in general, reading a few texts while playing around with code to keep things fun. My first goal is to get some really basic code into an object oriented shape so that I can see a gameloop, keystrokes, and some simple draws all working together.

I started with the code from the setup tutorial, and it drew my little 200x200 window & green circle just fine. So I started moving stuff around to get that .draw() and .display() into its own thread under a block that fires off every-so-often.

I got to a state where the block executes, but for some reason the window.display() doesn't seem to do anything.

My OutputDebug lines all fire off, so I can see that the program is looping and executing on separate threads. In debugging mode, I can see it execute the .display() but it just leaves the window blank white. On the next line, I added a window.setTitle to make sure that the thread could talk to my window object--and that succeeds. If I take the window.display() back into main(), it draws successfully. So is the problem from the threading? From not using SFML's window.setFramerateLimit(60) with main()? I'm quite confused.

I know this code is probably ugly in a lot of ways. I just want to see the gears turning with each other for now.
(But with that said, I always appreciate free opinions & information)

// (some includes)
extern float posX = 0;
extern float posY = 0;
int keepGoing = 0;

sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
sf::CircleShape shape(100.f);

auto gameStart = std::chrono::high_resolution_clock::now();
auto lastDraw = gameStart;
auto nextDraw = lastDraw;

void draw()
{
        if (GetKeyState('D') == true){ posX++; }
        if (GetKeyState('A') == true){ posX--; }
       
        shape.setPosition(posX, posY);
       
        window.clear();
        window.draw(shape);
        window.display(); //Here's the RenderWindow.display()

        window.setTitle("TITLE RESET");  //This succeeds, so I do have access to "window"
        OutputDebugString(L"\nDrawing!"); //I can see that this successfully executes, so I know the code is getting to here
}

//this runloop just calls my draw() every so often. My main() hands this loop the draw() function as *fp
void runloop(void (*fp)())
{
        while (keepGoing == 1)
        {
                OutputDebugString(L"\nLooping!");
               
                fp();

                lastDraw = std::chrono::high_resolution_clock::now();
                nextDraw += std::chrono::milliseconds(15);
               
                std::this_thread::sleep_until(nextDraw);
        }
}


int main()
{
        shape.setFillColor(sf::Color::Green);

        keepGoing = 1;

        void (*drawp)();
        drawp = draw;
        std::thread t1(runloop,drawp);
       
        while (window.isOpen())
        {
                sf::Event event;
                OutputDebugString(L"\nGotHere!");

               
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                window.close();
                }
// Here's where the RenderWindow.display() is in the tutorial
        }
        return 0;
}
 

Verra

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: RenderWindow .display() seems to do nothing
« Reply #1 on: September 01, 2015, 07:16:27 am »
In order to draw from a separate thread you have to activate the window context within that thread.
See this post regarding the problem you are having:
http://en.sfml-dev.org/forums/index.php?topic=853.msg5575#msg5575

It might be best to avoid threads for something like this. It will likely be more of a hassle than it's worth.
« Last Edit: September 01, 2015, 07:18:35 am by Verra »

chitfacedagain

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: RenderWindow .display() seems to do nothing
« Reply #2 on: September 01, 2015, 07:52:07 am »
Thanks Verra!

It eases my mind to know that this was a limitation of a library and not something I did.

Out of curiosity, why do you suggest that I avoid threads? I honestly know very little in the game-dev world at this point. Is it that threading isn't necessary for the simple applications built out of SFML? Does the VS compiler do anything to incorporate threading automatically? Or do you say that mostly because the application is so rudimentary at this point?

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: RenderWindow .display() seems to do nothing
« Reply #3 on: September 01, 2015, 08:18:52 am »
Out of curiosity, why do you suggest that I avoid threads?
Threads bring a huge amount of complexity and requires a fair amount of experience with C++ to use correctly.
Try searching the forum. There have been many posts explaining the problems that threads can bring.

Here are a few:
 http://en.sfml-dev.org/forums/index.php?topic=17491.msg125858#msg125858
 
 http://en.sfml-dev.org/forums/index.php?topic=18539.msg133315#msg133315

 http://en.sfml-dev.org/forums/index.php?topic=15430.msg109640#msg109640

 http://en.sfml-dev.org/forums/index.php?topic=9949.msg68291#msg68291

 http://en.sfml-dev.org/forums/index.php?topic=17619.msg126675#msg126675

chitfacedagain

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: RenderWindow .display() seems to do nothing
« Reply #4 on: September 01, 2015, 10:10:06 pm »
Out of curiosity, why do you suggest that I avoid threads?
Threads bring a huge amount of complexity and requires a fair amount of experience with C++ to use correctly.
Try searching the forum. There have been many posts explaining the problems that threads can bring.

Here are a few:
 http://en.sfml-dev.org/forums/index.php?topic=17491.msg125858#msg125858
 
 http://en.sfml-dev.org/forums/index.php?topic=18539.msg133315#msg133315

 http://en.sfml-dev.org/forums/index.php?topic=15430.msg109640#msg109640

 http://en.sfml-dev.org/forums/index.php?topic=9949.msg68291#msg68291

 http://en.sfml-dev.org/forums/index.php?topic=17619.msg126675#msg126675

Thanks Jesper!

I just took some time to go through these posts. Very interesting. So far, the comments and warnings in them compare with those in the texts I'm reading.

One thing that's still a little obscure -- Without explicitly creating threads, the program will run entirely synchronously, right? There is no automatic or virtual threading that the VS compiler does?

I made a few simple programs in ObjectiveC a couple years ago, and for some reason I vaguely recall some automatic threading that XCode did. But maybe that was just a dream I had. Or maybe I misunderstood something I saw. Maybe I was drunk.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: RenderWindow .display() seems to do nothing
« Reply #5 on: September 01, 2015, 10:27:50 pm »
One thing that's still a little obscure -- Without explicitly creating threads, the program will run entirely synchronously, right? There is no automatic or virtual threading that the VS compiler does?
The standard/runtime library, the debugger and other C++ libraries may run in multiple threads, which you usually don't notice.

For example, sf::Sound and sf::Music in SFML use threads. But as long as you follow the documentation, you should be safe.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: RenderWindow .display() seems to do nothing
« Reply #6 on: September 01, 2015, 10:33:41 pm »
If you don't create threads yourself (or use stuff like std::future) the program will run entirely synchronously (at least you can reason about is as such).
The compiler may optimize things behind your back like vectorizing code and (in theory) it could run parts of your code in multiple threads, but only if it does not change the observable operation of the program. While many compilers will parallelize code by vectorizing loops and other constructs, I am not personally aware of any compilers that will (currently) auto thread parts of your code.

Edit: what Nexus said about libraries (potentially) running code in threads behind your back is, of course, also entirely correct.
« Last Edit: September 01, 2015, 10:42:42 pm by Jesper Juhl »

chitfacedagain

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: RenderWindow .display() seems to do nothing
« Reply #7 on: September 01, 2015, 11:01:55 pm »
Very interesting. Awesome, thanks guys!

Since my goal is not actually to publish an application, but instead to have a small playground to complement the texts I'm reading, I might tentatively go forward with this one extra thread. The resulting issues, challenges, and solutions are what I aim for. I'll ditch the threading if they become too much to bear.

Thanks again!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: RenderWindow .display() seems to do nothing
« Reply #8 on: September 01, 2015, 11:39:42 pm »
Of course you can do whatever you want, but I recommend learning threads after you understand the programming language and the libraries you're using really well. A lot of somewhat advanced C++ topics like memory model, RAII or function objects are prerequesites to the understanding of multithreaded programming and common threading techniques. Since the behavior is non-deterministic, there's no way around theory, you can't learn multithreaded programming by doing alone.

By the way, global variables will definitely not make anything easier.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything