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

Author Topic: (Very) small techdemo with sources (threaded OGL rendering)  (Read 18488 times)

0 Members and 1 Guest are viewing this topic.

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
Hey, in case anyone remembers my game "Not quite pong", I had been experimenting with doing the rendering in a separate thread (from input&game logic). Here's a very basic / reduced version of what I did. This is written against the current SFML-2.0 branch (but only 1 or 2 lines have to be changed for SFML-1.5) and boost 1.35. A windows binary (requires VS2008 runtimes) is included.

http://www.carolander.net/joe/threaded_gl.zip

You may notice a few differences in behavior from the standard way of doing it. (Try resizing!)

Please tell me if you notice anything strange. Of course comments and suggestions for improvement are welcome :-)

@Laurent: Should you happen to look in this thread, blocking input would be perfect here, as it would get rid of any and all polling  :wink:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #1 on: July 30, 2009, 06:38:13 pm »
Quote
@Laurent: Should you happen to look in this thread, blocking input would be perfect here, as it would get rid of any and all polling

Yeah, I think I'll implement it soon ;)
Laurent Gomila - SFML developer

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #2 on: July 30, 2009, 06:53:37 pm »
:mrgreen:

Jaenis

  • Newbie
  • *
  • Posts: 48
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #3 on: July 31, 2009, 04:45:45 am »
Interesting app...
Have you noticed that you can drag that SMFL window around and it's contents are still being updated while dragging? (On Windows OS)

Normally Windows blocks this that your screen would freeze while you are dragging the window.
Hmm.. You seem to have actual drawing on another thread, so it gets around this. Nice trick :)

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #4 on: July 31, 2009, 08:23:25 am »
Quote from: "Jaenis"
Interesting app...
Have you noticed that you can drag that SMFL window around and it's contents are still being updated while dragging? (On Windows OS)

Normally Windows blocks this that your screen would freeze while you are dragging the window.
Hmm.. You seem to have actual drawing on another thread, so it gets around this. Nice trick :)


Yup, that's exactly what I meant by "You may notice a few differences in behavior" :-)

Currently I'm trying to add a Fullscreen toggle feature but I'm getting some evil, evil crash... (my window pointer is 0 after the call to create... very, very bad and I can't explain it yet)

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #5 on: July 31, 2009, 09:04:58 am »
Just in case I made any obvious errors...

Jaenis

  • Newbie
  • *
  • Posts: 48
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #6 on: July 31, 2009, 04:02:41 pm »
I got inspired of your system and made similar test.

What you are doing when you call renderTask->pause(true) ?
I do this instead:
Code: [Select]

void Renderer::DetachWindow(void)
{
// Stop the thread
Stop();              // Send async stop command
Thread.join();       // Wait thread to finish
Clear();             // Clear function queue

// We do not have window anymore
Window=NULL;
}


And where you unpause your thread I do following:
Code: [Select]

void Renderer::AttachWindow(sf::Window &NewWindow)
{
// Store pointer and set caller window inactive
Window=&NewWindow;
Window->SetActive(false);

// Launch thread
Thread=boost::thread( boost::bind(&Renderer::ThreadMain,this) );
}


So when I want to change videomode I just wait the renderer thread to exit, then I can be sure that it does not require access to SFML window. And afterwards I restart the renderer thread.
Might be overkill, but I don't care if fullscreen<->windowed change takes few more milliseconds ;)

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #7 on: July 31, 2009, 05:16:43 pm »
Maybe I should try that solution... I actually pause the thread by using a condition variable and before blocking, the render thread calls an "onPause" function which deactivates the window. (Pausing and unpausing by itself works... but recreating the window crashes with all kinds of strangeness...

Modified GameTask:
Code: [Select]

void GameTask::run()
{
running = true;
paused = false;

init();

while(running)
{
{
boost::unique_lock<boost::mutex> lock(pauseMutex);
bool first = true;
while(paused)
{
if(first)
{
first = false;
onPause(true);
}
pauseCond.notify_all();
pauseCond.wait(lock);
}

if(!first)
onPause(false);
}
loopBody();
executeCalls();
}

fini();
}

void GameTask::pause(bool pause)
{
if(pause && !paused)
{
boost::unique_lock<boost::mutex> lock(pauseMutex);
paused = true;
pauseCond.wait(lock); // wait until the task is actually paused
}
else if(!pause && paused)
{
{
boost::lock_guard<boost::mutex> lock(pauseMutex);
paused = false;
}
pauseCond.notify_all();
}
}


onPause function for Renderer:
Code: [Select]

void onPause(bool paused)
{
window->SetActive(!paused);

if(!paused)
{
// Set color and depth clear value
glClearDepth(1.f);
glClearColor(0.f, 0.f, 0.f, 0.f);

// Enable Z-buffer read and write
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);

// Setup a perspective projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, (float)window->GetWidth()/(float)window->GetHeight(), 1.f, 500.f);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
}

Astrof

  • Full Member
  • ***
  • Posts: 135
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #8 on: July 31, 2009, 06:19:42 pm »
In the code I see a
Code: [Select]
if(fullscreen= !fullscreen)
shouldn't it be
Code: [Select]
if(fullscreen==!fullscreen)
or
Code: [Select]
if(fullscreen!= fullscreen)

or wait, shouldn't it be set to something other than itself? Sorry i didnt do a thorough readthrough, this just popped up at me.

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #9 on: July 31, 2009, 06:31:22 pm »
Quote from: "Astrof"
In the code I see a
Code: [Select]
if(fullscreen= !fullscreen)
shouldn't it be
Code: [Select]
if(fullscreen==!fullscreen)
or
Code: [Select]
if(fullscreen!= fullscreen)

or wait, shouldn't it be set to something other than itself? Sorry i didnt do a thorough readthrough, this just popped up at me.


no, it's correct

if(fullscreen = !fullscreen) inverts the value of fullscreen and checks if the inverted value is true (the other variants leave fullscreen unchanged and always return false ;-) )

Daazku

  • Hero Member
  • *****
  • Posts: 896
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #10 on: July 31, 2009, 06:49:20 pm »
Nice work!
Pensez à mettre le tag [Résolu] une fois la réponse à votre question trouvée.
Remember to add the tag [Solved] when you got an answer to your question.

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #11 on: July 31, 2009, 06:59:26 pm »
Just tried stopping the render thread and starting a new one after calling window->Create ... leads to the same error. But if I destroy the window and create a new one... it works. Very strange. Does anyone have an idea what might be happening?

EDIT:

so much for "it works"... after toggling window/fullscreen a few times, my system decided to hang indefinitely...

actually something similar has been happening from time to time when just closing the window: the window stays there for 3-4 seconds and in the last 1-2 of those even the windows mouse cursor stops moving. but then the window gets closed and everything continues normally.

now the really strange thing is... it hangs after all my code has been executed, except for the destructors. and the only things that are destroyed are a mutex, and an (empty) std::vector.

EDIT 2:
Just tested all 3 variants on my Win7 machine (with much newer nvidia drivers):

V 1 (pause then re-create):
WinXP: Fails
Win7: Fails
In both cases the "window" pointer changes to an invalid value, without an actual assignment...

V 2 (stop then re-create):
WinXP: Fails
Win7: Works (so far)

V 3 (stop, destroy, create):
WinXP: Works (but has hung up windows once)
Win7: Works (so far)

Very strange stuff...

klusark

  • Newbie
  • *
  • Posts: 45
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #12 on: July 31, 2009, 09:04:45 pm »
One thing that I do in my project is in my update thread
Code: [Select]

if (lastWidth != App.GetWidth() || lastHeight != App.GetHeight()){
    lastWidth = App.GetWidth();
    lastHeight = App.GetHeight();

    float currentRatio = (float)lastWidth/(float)lastHeight;
    float correctY = 320/currentRatio;
    view.SetFromRect((sf::FloatRect(0, 0, 320, correctY)));
}

Using this I am able to get real time resizing. Something similar (and better written) would go well in your project.
I dont use the resize event in the event loop because it blocks untill the resizing is done.  

@Laurent would it be possible to use some code similar to this in sfml for better resize event prossesing?

l0calh05t

  • Full Member
  • ***
  • Posts: 200
    • View Profile
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #13 on: July 31, 2009, 09:09:42 pm »
Quote from: "klusark"

@Laurent would it be possible to use some code similar to this in sfml for better resize event prossesing?


Let's try to find a reliable solution to the fullscreen toggle error first...

PS:
Also, there isn't much to improve in that snippet, except maybe putting the actual resizing code in a separate function

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
(Very) small techdemo with sources (threaded OGL rendering)
« Reply #14 on: July 31, 2009, 09:20:56 pm »
Quote
@Laurent would it be possible to use some code similar to this in sfml for better resize event prossesing?

I don't see what SFML could do with this code.
Laurent Gomila - SFML developer