jmanson's picture

Cube draws with hiccups

I wanted to switch to using Opengl 3, to learn modern graphics programming, in C#. Since the otherwise fine Tao library seems not to be supported any more and has no new bindings, I attempted using OpenTK. Unfortunately, the example code provided with the library does not run smoothly on my Windows XP machine with a Radeon 4800 series card. In fact, this happens for all of the demos that have an animation.

I have two questions.

1. How do you make the rendering hiccups disappear. It can't be from GC, and should really just work. In fact, it should draw at 10000 FPS.

2. Is there a well maintained direct binding to OpenGL in the spirit of Tao that I could use instead?


Comments

Comment viewing options

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

1. I cannot reproduce this issue on any of my systems (Ati 4850 + Win7/Ubuntu 9.10, Nvidia NVS135M + Win7/Ubuntu 9.10, Nvidia 9500GS + Ubuntu 9.10).

  • Are you running the examples in release mode, using a release version of OpenTK.dll?
  • Which cube example are you testing? (There is one for GameWindow and one for GLControl. Only the first can provide hiccup-less rendering.)
  • Have you tried toggling vsync (VSync = VSyncMode.Off/On)? Does behavior change then?
  • Are such hiccups reflected in the OnRenderFrame event args (i.e. does e.Time become abnormaly large whenever you see a hiccup)?

2. You can treat OpenTK as a plain OpenGL binding and avoid using facilities you don't like. In particular, you can create an OpenGL context through some other means (e.g. Tao.Glfw, Tao.Glut, Tao.SDL) and use only OpenTK.Graphics.OpenGL. OpenTK.Graphics.OpenGL is very similar to Tao.OpenGl internally and performance should be identical in the general case.

If you opt for this approach:

// (a) create your OpenGL window through Tao
// (b) afterwards create and store a reference to a 'dummy' GraphicsContext
GraphicsContext context = GraphicsContext.CreateDummyContext();
// (c) now you can use OpenTK.Graphics.OpenGL (and/or Tao.OpenGl at the same time)

(Documentation for GraphicsContext.CreateDummyContext).

I am not aware of any other .Net libraries providing access to OpenGL 3.x.

jmanson's picture

* Are you running the examples in release mode, using a release version of OpenTK.dll?

I am using Visual Studio 2010 Beta. The hiccups occur both in release mode and in debug mode. In both cases, I have linked to the release version of OpenTK.dll.

* Which cube example are you testing? (There is one for GameWindow and one for GLControl. Only the first can provide hiccup-less rendering.)

This happens for all of the provided example programs as provided in the precompiled Examples.exe binary. Specifically the tests titled "Immediate mode", "OpenGL 3.0", and "Advanced Geometry Shader" draw with inconsistent framerates.

* Have you tried toggling vsync (VSync = VSyncMode.Off/On)? Does behavior change then?

No I hadn't. I had figured that my computer could easily draw fast enough to keep up with the refresh rate of the screen. However, it appears that with VSync disabled, the cube draws correctly. Somehow, VSync is messing everything up.

Playing around, I also found that changing the line example.Run(30) to example.Run(30,30) seemed to fix framerate problems when VSync was on, but setting example.Run(200,200) had problems still, as did example.Run(). Both of these work perfectly without VSync.

* Are such hiccups reflected in the OnRenderFrame event args (i.e. does e.Time become abnormaly large whenever you see a hiccup)?

So, without VSync, the average reported time is steadily about 0.0002677.

When VSync is enabled, my results are very strange. When I print the time to the console, the framerate is rock steady 60 FPS. It is only when I do not print anything that the framerate drops to about a fifth to a tenth of a second (my estimate, since I can't print the results and reproduce this). All I can say is WHAT?

So, it seems like my problem is sort of solved. Avoid VSync, because it doesn't work consistently.

jmanson's picture

I was thinking about this problem a bit more. Do you use a real VSync signal produced by the monitor/card or try to emulate VSync with timers? Although I'm not sure, I thought that VSync was only possible to use in full screen mode, because Windows prevents you from knowing "such unimportant details" normally.

the Fiddler's picture

Enabling vsync just calls wglSwapIntervalSGI(1) on Windows. The rest is up to the driver.

However, this behavior is very strange (printing information fixes the issue?) All I can think is to try adding a call to System.Threading.Thread.Sleep(1) just after the SwapBuffers() call and see what happens then. Also, it might be worth testing what happens in fullscreen mode (set WindowState = WindowState.Fullscreen).

Finally, are you using a 48x0 X2 card or is this a normal single GPU? I have heard reports of "micro-stuttering" on X2 cards, which seems to behave similar to this (their suggested solution is to run at higher fps than the monitor's framerate).

jmanson's picture

Using Sleep(1) does not fix the problem. Also, full screen hiccups regardless of whether text is printed or not. In fact, with further experimentation, I discovered that the benefit of printing text disappears in windowed mode if I cover the output printed to the console with the graphics window.

I use a single Radeon 4800 GPU with the most recent drivers that fully support opengl 3.2. This is not the micro-stuttering described in that post, because it will run fine for a couple of seconds at a time before it will stutter. Also, I am using the OpenTk 1.0-beta2 distribution on the front page.

P.S.

Can you please describe more clearly how to use the dummy graphics context with SDL. I am attempting to port my program to OpenTK, but it is large enough that I need to do so in stages. In the following setup code, the program crashes on the line that calls ClearColor.

            Sdl.SDL_Init(Sdl.SDL_INIT_VIDEO);
            screen = Sdl.SDL_SetVideoMode(settings.screen_width, settings.screen_height, 32, Sdl.SDL_OPENGL | Sdl.SDL_HWACCEL | Sdl.SDL_HWSURFACE);
            Sdl.SDL_EnableUNICODE(1);
            Sdl.SDL_EnableKeyRepeat(Sdl.SDL_DEFAULT_REPEAT_DELAY, Sdl.SDL_DEFAULT_REPEAT_INTERVAL);
 
            GraphicsContext.CreateDummyContext();
 
            GL.ClearColor(0.0f, 0.0f, 0.0f, 0.5f);
the Fiddler's picture

You need to store the dummy context somewhere so that it's not reclaimed by the GC, but otherwise this code should work. What exception does GL.ClearColor throw?

horatiohaf's picture

You may be inerested to know I've experienced a similar issue running a simple GameWindow app on a WinXP SP3 32 system with a Radeon HD4870.

When run in windowed mode, the animation doesn't look smooth because little hiccups happen on a regular basis. Not only: if I try to move the game window, all desktop objects and windows that were behind redraw themselves very slowly. But if I run the same app in fullscreen mode, the hiccups disappear.

After fiddling with the app code and ATI Tray Tool, I discovered the problems show only when vsync is turned on. No matter if I force it through ATT or I enable it by code, the results are always the same: VSynch ON = stutters, VSync OFF = smooth as silk. Enabling or disabling triple buffering with ATT doesn't make any difference.

Since the problems show up only in windowed mode, I solved them adding this line to the GameWindow constructor:

VSync = WindowState == WindowState.Fullscreen ? VSyncMode.On : VSyncMode.Off;

The most interesting thing is that running Google Earth in OpenGL mode, I noticed exactly the same issues with vsynch turned on. When I switched to DirectX rendering, on the other hand, all problems disappeared.

If Google Earth is not made with OpenTk, then the reported issues could be related to ATI's OpenGL drivers. Right now, I'm still using the 8.12 version, but issues could still be present on more recent releases, perhaps presenting slightly different symptoms.

As jmanson wrote, vsync could be unreliable in windowed mode, and therefore should be disabled. But users that keep it forced through ATT o CCC are likely to step in this annoying issue until the real cause gets fixed.

I hope you find my post useful and my english passable.

Regards,
Horatio Hafnaugels.