ravi.joshi53's picture

Using thread inside OnUpdateFrame()

Hi,

I am developing a 2D game, in which I am getting (x,y) pixel values continuously. Basically by using these (x,y) points I wanna move an object. Below is the code-

int currentX = 0;
int currentY = 0;
protected override void OnUpdateFrame(FrameEventArgs e)
{
    base.OnUpdateFrame(e);
    Point point = device.GetPoint(); // This is taking too much time to return a point
    currentX = point.X;
    currentY = point.Y;
}
protected override void OnRenderFrame(FrameEventArgs e)
{
    base.OnRenderFrame(e);
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
    GL.MatrixMode(MatrixMode.Modelview);
    GL.LoadIdentity();
    drawBallAt(currentX,currentY);
    SwapBuffers();
}

In the above code Point point = device.GetPoint(); is taking a long time to return the value. Because of this , I can see a significant amount of delay in rendering the graphics.

Can anyone here, please tell me the details of using thread with the appropriate code

-
Thanks
Ravi


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Frassle's picture

You can start a new thread running in a loop that keeps calling device.GetPoint(), start that thread in the constructor. Then in update you can just read the point that was last read. Just make sure point is accessible to both threads (probably by making it a class field) and make sure it's protected by a lock.

ravi.joshi53's picture
Frassle wrote:

You can start a new thread running in a loop that keeps calling device.GetPoint(), start that thread in the constructor. Then in update you can just read the point that was last read. Just make sure point is accessible to both threads (probably by making it a class field) and make sure it's protected by a lock.

Hi Frassle, many thanks to you however it would be great full, if you can post the required code...

Frassle's picture

You want two fields:

Point point;
object point_lock = new object();

A method to update the point:

void PointUpdate() { lock(point_lock) { point = device.GetPoint() } }

Start a new thread in your constructor to run that method:

thread = new Thread(PointUpdate);
thread.Start()

Then in update just read point:

lock(point_lock)
{
    currentX = point.X;
    currentY = point.Y;
}

That should be about right. If you want something fancier like getting every point you'll need to use a Queue (.NET has concurrent queues which won't need locking as well).

ravi.joshi53's picture

Hi Frassle ,

Thanks for the quick reply. Let me implement it in my code and let see the application behavior. I hope the rendering should be smooth this time.
Anyways I'll catch you later if I feel any need of implementing using concurrent queues.

Frassle's picture

One thing I thought about on my way home, the UpdatePoint method as I wrote won't work correctly (rendering will still not be smooth). The following should fix it, you want the GetPoint method to be called outside the lock section:

void PointUpdate() 
{
    var temp = device.GetPoint();
    lock(point_lock) { point = temp; }
}

Hope that helps.

Frassle's picture

Ugh my brain was clearly not working yesterday. Obvious really but PointUpdate needs to be a while(true) loop otherwise you'll only get the first point.

void PointUpdate() 
{
    while(true) 
    {
        var temp = device.GetPoint();
        lock(point_lock) { point = temp; }
    }
}
ravi.joshi53's picture

Hahaha...

Not a problem... I am keep on updating the code... its time for the checkout :)

Thanks a lot.

Its working very smoothly now.... just a quick question.

I can see that Visual Studio is not stopping properly even after closing the app (while debugging it). Is this newly created thread stopping by itself on closing the gamewindow? or do i need to close it?

Frassle's picture

Closing the window should be enough to end the whole process. If not you can always add thread.Abort (or something neater) when closing the window.