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

Author Topic: Redrawing Sprites in a Multi - Threaded Program  (Read 2814 times)

0 Members and 1 Guest are viewing this topic.

justcolorado

  • Newbie
  • *
  • Posts: 16
    • View Profile
Redrawing Sprites in a Multi - Threaded Program
« on: January 14, 2012, 03:11:21 am »
I am working on my first game.  I have been stuck for the last few hours and I just cannot figure out how to redraw my sprite in a separate thread.   First I created a struct with a bunch of pointers.  Then I set up a new thread and passed the struct in.  Everything worked great until I tried to redraw the sprite.

Whenever I try to access the sf::RenderWindow.Draw Function, I don't have the right Object type to pass in.  It needs a reference to a Sprite Object, and I only have a pointer.
I tried converting it with a line like the one below but the compiler rejected it with this message: error C2440: 'initializing' : cannot convert from 'sf::Sprite *' to 'sf::Sprite &'
Code: [Select]
Sprite& rPlayer (pSprite);

I tried not using a pointer and just including a Sprite Object in the Struct.  It compiled but when the thread launched, the program froze up for a few seconds, and gave me a bunch of OpenGL error messages in the console window.  I can't figure out what to do with my Pointer so I can pass my sprite in to the sf::RenderWindow.Draw function a separate thread.

Any Help would be greatly appreciated!

My Code looks something like this.

Code: [Select]

struct UserData{
int* pMap;
RenderWindow* pApp;
Sprite* pSprite;
AnimationClass* pAnimator;
};

void ThreadFunction(void* UserData)
{

    for (int i = 0; i < 10; ++i)
{
Data->pAnimator->myAnimation(pSprite);
Data->pApp->Draw(???????What can I pass in here???????);
}
}


int main()
{

    UserData Data = { pMap, pApp, pSprite, pAnimator };
    sf::Thread myThread(&ThreadFunction, &Data);
    myThread.Launch();

    return EXIT_SUCCESS;

}

Tex Killer

  • Full Member
  • ***
  • Posts: 242
    • View Profile
Redrawing Sprites in a Multi - Threaded Program
« Reply #1 on: January 14, 2012, 07:43:40 am »
You can pass a pointer like this:
Draw(*pointer)
But I don't think you can access the RenderWindow from multiple threads. Laurent should know better than me, though.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Redrawing Sprites in a Multi - Threaded Program
« Reply #2 on: January 14, 2012, 09:42:43 am »
You can't draw from multiple threads. But it seems like a bad solution for what you want to do (animation?).
Laurent Gomila - SFML developer

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Redrawing Sprites in a Multi - Threaded Program
« Reply #3 on: January 14, 2012, 09:45:21 am »
Btw, *foo is called dereferencing (it calls the operator*() function which returns Type&, i.e. a reference).

And yep, the OpenGL context can be active in one thread at a time only. Why did you choose to render from multiple threads?

justcolorado

  • Newbie
  • *
  • Posts: 16
    • View Profile
Redrawing Sprites in a Multi - Threaded Program
« Reply #4 on: January 14, 2012, 11:34:16 pm »
Thanks for your replies.  Now I am not sure how to achieve what I want. When I broke it into two separate threads, the animation sequence I wanted was jerky and would skip frames, because the only thing redrawing the screen was in Main.  

The reason for me wanting to start another thread was:

I want to have my character freeze and do an animation of about 1 second on certain collisions, but I do not want this to stop the enemy from advancing.


So what is the best approach to achieve this?

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Redrawing Sprites in a Multi - Threaded Program
« Reply #5 on: January 15, 2012, 12:44:25 am »
Your way off if that's what you want to do. This can be done and should be done single-threaded. You don't have to play the entire animation directly in a sequence. You just have to advance the animation frame when enough time have passed. Check out the animation classes in the SFML Wiki.

You are doing a common rookie mistake here when it comes to threads. And I better stop talking here or I can give hour long lectures on how to properly use threads to achieve optimal parallelism (which is their intended usage). And why not to use threads to complete a single task in parallel like you are doing.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

justcolorado

  • Newbie
  • *
  • Posts: 16
    • View Profile
Redrawing Sprites in a Multi - Threaded Program
« Reply #6 on: January 15, 2012, 01:02:41 am »
Quote from: "Groogy"
Your way off if that's what you want to do. This can be done and should be done single-threaded. You don't have to play the entire animation directly in a sequence. You just have to advance the animation frame when enough time have passed. Check out the animation classes in the SFML Wiki.

You are doing a common rookie mistake here when it comes to threads. And I better stop talking here or I can give hour long lectures on how to properly use threads to achieve optimal parallelism (which is their intended usage). And why not to use threads to complete a single task in parallel like you are doing.


Thanks.  I will just keep it all in one thread. That should be easy enough to do.  What about playing a separate sound above the background music.  Should this also stay in the main thread?

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
Redrawing Sprites in a Multi - Threaded Program
« Reply #7 on: January 15, 2012, 01:18:45 am »
Quote from: "justcolorado"
What about playing a separate sound above the background music.  Should this also stay in the main thread?


Technically no, they need a seperate thread. But SFML already does that for you in the Audio module if I am not mistaken. There were even some heated discussion of it for some managed language binding where the bindings developer complained that SFML had threads under-the-hood that he couldn't touch. Though even if he experienced "problems" with it I never did while making rbSFML.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio