Rob Sutherland's picture

Newbie question on SwapBuffers and rewdrawing scenes

I am new to OpenTK and OpenGL programming as a whole so bear with me.

I have a C# application (windows forms, .net 3.5, visual studio 2010) which polls a device for data every 50ms. I then process this data and display a series of rings and traces (similar to a radar graph in excel). All works fine but it looks choppy. I really only draw 1`2 rings which are made up of 192 lines so the draw is not that intensive. Below is the flow

//clear the back buffer
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

//my function to grab data from a tool
ProbeDataXXX(sec1, sec2);
//the previous function loops and calls the following lines 12 times building the rings (depricated of course)
GL.Color3(gColor);
GL.LineWidth(2);
GL.Begin(BeginMode.Lines);
GL.Vertex2(pt1.X, pt1.Y);
GL.Vertex2(pt2.X, pt2.Y);
GL.End();

//bring the back buffer to the front
glWindow.SwapBuffers();

//give us time to show to user
Application.DoEvents();

//i then pause the thread for 50ms
//wait 50ms, this gives us @20fps
Thread.Sleep(50);

It seems strange to redraw every time and not just replace the lines that have not changed. Am i missing something? Thanks for any help!!

Cheers


Comments

Comment viewing options

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

The hardware is optimized for clearing and redrawing every frame, so that's not a problem (as long as you are using hardware acceleration, at least).

12*192 = 2304 calls to GL.Begin/GL.End. That's not good for performance. What you want to do is accumulate the data into a list of vertices, call GL.Begin once and loop over the data with GL.Vertex2.

On another note, OpenTK trunk allows you to specify a SwapInterval value to reduce rendering rate (e.g. SwapInterval = 3 would translate into 20fps on a 60Hz monitor). This tends to be much smoother than Thread.Sleep(50) (Sleep(50) means sleep at least 50ms, but it's up to the OS to determine how much your process will really sleep. The exact value may change from frame to frame, causing choppiness).

Rob Sutherland's picture

Thanks for the reply!! I kind of thought that would be an issue so i was looking into DrawArrays etc but can't find any real examples for filling a vertex array and then calling it. Would you have a link or code example?

Also, how do I expose SwapInterval? GL.Ext does not contain it, although i am not using a gamewindow, it is in a windows form. Is that an issue?

Cheers and thanks for any help!!

the Fiddler's picture

You can access SwapInterval through GLControl.Context.SwapInterval (WinForms) or GameWindow.Context.SwapInterval (GameWindow). It's a platform-specific (i.e. WGL/GLX/AGL/EGL) extension, not a GL one, so OpenTK wraps the various APIs with a common interface.

DrawArrays can improve performance greatly (two orders of magnitude are not uncommon) - check the VBO documentation and the "VBO Static" and "VBO Dynamic" examples in the OpenTK Example Browser (it should be available in your start menu).

Rob Sutherland's picture

I did the first try of optimizing by using LineLoops instead of lines and drawing my rings at once, seems a much better solution. I am still trying to figure out how to do the 'list of vertices' that you mentioned but will eventually.

I place the OpenTK control on my windows form, is this why i cannot call GLControl.Context.SwapInterval? I also cannot set a graphics mode after it has been created (want to set anti-aliasing). Am i correct in assuming i need to create a custom control to do this?

Sorry for the multitude of questions, thanks for all the help!!

Cheers