Reality check: running OpenTK Windows.Form / GLControl demo with mono under Ubuntu7.10

Does not work out-of-the box. I'm on an i86 dual boot computer, WinXP/Ubuntu7.10.

I attached the output from command line runs of my project:

mono Dogfight2008.exe >error.txt

The exe-file was built with Visual Studio 2005. I used the .NET binary distribution of OpenTK.dll, version 0.3.13.

I also attached the output of 'mono --version >monoversion.txt'. (apparently ubuntu7.10 comes with mono1.2.4)

Additional steps tried, making no difference:

- Tried updating all packages, no additional repositories
- Added repositories called gutsy-proposed and gutsy-backports, updated everything
- Several reboots of course :)

To me it seems the call to 'ShadeModel' simply crashes with a null-reference exception. Maybe shade model changes aren't implemented in OpenTK? (I can try and remove this actually not-so-necessary call tomorrow and report back..)

My next attempt will be to download/install mono 1.2.6 into ubuntu7.10, a project which might break my package db, since mono1.2.6 is not in any of the ordinary repositories (have to download each and every package manually). Before I do that risky business, I'll wait until you tell I haven't missed some really simple thing.

AttachmentSize
error.txt3.14 KB
monoversion.txt255 bytes
error4.txt4.89 KB
GLUtil.cs_.txt3.16 KB
GLControlUtil.cs_.txt1.26 KB
Debug.4.zip47.08 KB
error4debug.txt4.89 KB

Comments

From the stack trace this
posted by the Fiddler.

From the stack trace this looks like the main form raises the resize event before the GLControl has a chance to initialize itself (GL.Viewport is called before the context is created). This is a wild guess, but maybe you have hooked the main form's resize event instead of the GLControl's?

Thanks I'll check that out.
posted by objarni

Thanks I'll check that out. But why does it work in Windows and not Linux?

In short I've done what you
posted by objarni

In short I've done what you suggested, plus a few other things to make my MainForm even more "clean".

Since I cannot attach files in this reply message, I'll attach files to the first message above.

Windows: still works, and did so in every step I took.
Linux: still breaks, with different error from before though. (attaching error4.txt which is the latest error report, with all cleaning up done)

I've written a short story about how I do things in MainForm.cs:

How I do things in my MainForm.cs file
My GLControl is called glControl.
I assume that glControl has been initialized by the time
the main form Load event is triggered.
Since I do GL/GLControl initilization/mechanical work in two separate files called
GLUtil.cs and GLControlUtil.cs, I will attach them.

MainForm constructor
I don't touch glControl at all here. Code:

   public MainForm()
    {
      InitializeComponent();
      game = new TempGame(); // GUI/GL independent member variable
      dogfight = new DogfightStateMachine(game); // GUI/GL independent member variable
    }

MainForm_Load
Here I initialize GL (background color, material parameters, lighting etc.).
I also add the Application_Idle event handler.

   private void MainForm_Load(object sender, EventArgs e)
    {
      GLControlUtil.Init(glControl, 1000);
      GLUtil.SunLightDirection(0, 1, 0);
      stopwatch.Start();
      Application.Idle += Application_Idle;
    }

I touch the glControl by calling HandleResize from within the
GlControlUtil.Init() method:

   public static void HandleResize(GLControl glCtrl, double viewdistance)
    {
      GL.Viewport(0, 0, glCtrl.ClientSize.Width, glCtrl.ClientSize.Height);
      GL.MatrixMode(MatrixMode.Projection);
      GL.LoadIdentity();
      Glu.Perspective(45, (double)glCtrl.Width / glCtrl.Height, 0.5, viewdistance);
      glCtrl.Invalidate();
      GL.MatrixMode(MatrixMode.Modelview);
    }

Application_Idle
The idle event handler touches glControl via an Invalidate() call:

   void Application_Idle(object sender, EventArgs e)
    {
      double deltaMS = ComputeDeltaMS(); // stopwatch mechanics
      dogfight.Tick(deltaMS);
      glControl.Invalidate();
      idleCount++;
    }

glControl_Resize
I simply call the same resize method as in MainForm_Load():

   private void glControl_Resize(object sender, EventArgs e)
    {
      GLControlUtil.HandleResize(glControl, 1000);
    }

Does "mono --debug
posted by the Fiddler.

Does "mono --debug DogFight2008.exe" give anything more? Also, can you attach a binary, so I can check it here?

I've attached Debug.4.zip to
posted by objarni

I've attached Debug.4.zip to the original message. Had to remove OpenTK.dll (version 0.3.13) from the archive because of the 256kb attached file limit.

command line: "mono Dogfight2008.exe >error4.txt" (error4.txt attached also)

Oh sorry missed the --debug
posted by objarni

Oh sorry missed the --debug flag! Will try that now and attach output ..

Attached as 'error4debug.txt'.

Thanks. I just tested on
posted by the Fiddler.

Thanks. I just tested on Vista / .Net 3.5, Ubuntu 7.04 / Mono 1.2.5 and Ubuntu 7.10 / Mono 1.2.6 and it works correctly on all three (x64 versions). There was a problem with the text on Ubuntu 7.04 / Mono 1.2.6 preview 2 (x32), but no crashes.

Unfortunately, I don't have any older Mono installations to try, but it seems likely that this is a Mono problem. It is unfortunate that Ubuntu ships with an outdated Mono version by default, and offers no way to upgrade easily (politics getting in the way of usability I'm afraid), but I'll try to think of a fix.

Do you by any chance run on 16bit color? This might cause problems, although it probably isn't the case.

Thanks for your support. I
posted by objarni

Thanks for your support.

I don't specify pixel format mode anywhere, just basic GLControl dropped on a Windows.Form. I don't know how to check what pixel format I'm in under ubuntu, but I'll hazard it's 32-bit (the background image looks crisp).

I know next release of Ubuntu will include mono1.2.6, so I'll target finishing my game until then ;)

But it would be nice to be able to test in linux before that; maybe I'll have to install another distro which make it easier to install mono 1.2.6. How did you install mono 1.2.6 on ubuntu7.10?

Am I right in assuming that
posted by objarni

Am I right in assuming that the glControl is properly initialized (context created and all) when MainForm_Load() is executed? Is there an even more "orthodox" way of building a Windows.Forms/GLControl program?

[Installing Mono] Installing
posted by the Fiddler.

[Installing Mono]
Installing mono is actually quite easy. I just download the mono and gdiplus tarballs, and run:

tar -xvf [package name]
./configure --prefix=/usr/local
make
sudo make install

first on gdiplus then on mono.

The configure script will complain on some missing stuff, just sudo apt-get install each one until it no longer complains. You may want to install libjpeg-dev, libtiff-dev and libpng-dev first, to add support for these formats (I think there was a '2' somewhere, maybe libtiff2-dev).

There also is a generic x86 installer on the mono downloads page, but I haven't tried that.

[GLControl]
It should be ready by the time the OnLoad event is called.

Take a look at the source, it's quite small. It hooks the HandleCreated event and calls the CreateControl() method in the constructor to force the creation of the handle. Inside the CreateHandle event, it creates the context and initializes the GL, Glu classes. In your case, it seems that the handle isn't created in time, but I don't really know why. As far as I know, the only thing affecting handle creation is the Visible property (if set to false, child handles aren't created automatically).

Oh do I feel silly :) I
posted by objarni

Oh do I feel silly :)

I forgot to place OpenTK.dll.config besides OpenTK.dll! It works now, with some minor graphical artifacts in the font rendering, and I actually get more FPS in ubuntu than WinXP! Happy surprise.

Has anybody investigated the possibility of embedding OpenTK.dll.config into OpenTK.dll? That would avoid this mistake (for others sake -- I will not do it again ;)

more FPS in ubuntu than
posted by Inertia

more FPS in ubuntu than WinXP!
Huh? What's the difference like?

Good to hear the problem was trivial, the way you described it in IRC it sounded pretty bad ;)

what is difference between
posted by Anonymous

what is difference between Tao and OpenTK?
thanks

Your question is answered in
posted by Inertia

Your question is answered in http://www.opentk.com/node/189

Asking more than once will not give better results, actually most likely worse results.

[FPS issue] No, the FPS drop
posted by objarni

[FPS issue]
No, the FPS drop is still there in WinXP (75->37.5 drop when going from windows approx. 600x400 window to maximized approx. 1200x900).

I'll report the exact numbers tonight. I got the feeling VSync was automatically turned off in ubuntu, got frame rates above 100 and my LCD monitors does not support that. The good thing was there was no difference between "small window" and "big window".

[OpenTK.dll.config issue]
Ideally I would like OpenTK.dll to either (a) complain in Windows also or even better (b) embed it into OpenTK.dll if it is technically possible.

(a) could be implemented as an annoying MessageBox that is display only #if DEBUG, for example. :)

[FPS Drop] I built in
posted by objarni

[FPS Drop]
I built in release mode using Visual Studio 2005. Used a Windows.Form containing a single GLControl with
VSync==true. In glControl_Paint() I do GL.Clear() followed by GL.SwapBuffers(),
nothing else:

GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 glControl.SwapBuffers();

WindowsXP, GLControl sized c:a 700x400: 75 fps
WindowsXP, GLControl sized c:a 1200x950: 37.5 fps
Ubuntu7.10, GLControl sized c:a 700x400: 210 fps
Ubuntu7.10, GLControl sized c:a 1200x950: 75 fps

I think at least two things are interesting to note:

1. VSync does not seem to make any difference in mono/ubuntu. I guess it is up to the graphics driver if the VSync property of GLControl is respected..? (my lcd monitor has a maximum refresh rate of 75).

2. The big fps drops due to larger window on both platforms. Since it is so fast in ubuntu/mono it's not a real problem for my game so far, but 37 fps is not fun in Windows. I measured the Clear() and SwapBuffers() [ adding GL.Finish() after both to remove any delayed execution ], and got the following results for both window sizes:

700x400
Clear 2ms
Swapbuffers 10 ms
1200x950
Clear 9 ms
SwapBuffers 30 ms

.. so the big milliseconds thief is SwapBuffers. Question is, what happens under the hood in SwapBuffers() in GLControl on the Windows platform..? I get the feeling some really slow GDI/GDI+ blit/copy or something.

(for the record, In ubuntu the numbers were:
700x400
Clear 2ms
SwapBuffers 1.5 ms
1200x950
Clear 6 ms
SwapBuffers 6 ms)

I'm googling to see if
posted by the Fiddler

I'm googling to see if anything related shows up, but so far no good. The only thing I was able to find was the "DoubleBuffered" property (it's protected, you'll have to inherit from GLControl to use it), which seems to carry a performance penalty if set to true. I haven't been able to find anything else, but performance does seem abnormally low. The 7300 does have dedicated memory, doesn't it?

How does the bundled GLControl example work on your machine? (the one with the spinning cube - it should be obviously jerky if it falls below 75fps).

I tried the "WinForms 2:
posted by objarni

I tried the "WinForms 2: GLControl game loop" example from the list, with a spinning cube. One 360 degree turnaround took about 6 seconds in small window, and over 15 seconds in a maximized window. Assuming the rotation amount per frame is constant, that is frame-dependent rendering, it seems like a drop 75->25 or something.

IIRC the 7300 has 128 mb dedicated gfx ram, and up to 512 mb shared with primary memory.

Have you checked out the
posted by objarni

Have you checked out the GRControl.cs library..? It is a single GL-in-Windows.Forms.Control for Windows only. Just checked the source a little, GRControl is inherited directly from the Windows.Forms.Control class instead of UserControl.

I'm testing an example cube, it feels more responsive. Maybe get some ideas from that?

Link? Edit: nevermind, found
posted by the Fiddler

Link?

Edit: nevermind, found it, but as far as I can see there isn't anything that looks more efficient (to the contrary, actually).

Can you try this dll to see if it works any better? http://users.ntua.gr/el03128/projects/OpenTK/opentk-0.3.14-wip1.zip

Summary: I used the 'fraps'
posted by objarni

Summary:

I used the 'fraps' (great program!) program to check the fps of the program under Windows. I did the same check with the spinning cube example programs, both GameWindow version and GLControl version. I also benchmarked a GRControl spinning cube example program.

Result: All of the above give approx. the same FPS in a certain window size.

Conclusion: I really need to buy a better gfx card. And now I know 3d in windowed mode may be really crappy on low-end gfx cards => go for fullscreen or make 640x480 windows or something to be sure it will run smooth.

Result: All of the above
posted by Inertia

Result: All of the above give approx. the same FPS in a certain window size.
I can confirm this, wrote three little test-applications using OpenTK's GameWindow and Tao's GLFW and FreeGlut. All 3 are using the same GL State and issuing the same draw commands.
In a small window ~500*100 the framerate is in the 1000s, when the window is maximized to 1280x1024 it runs in the low 100s. The fps results are very similar in all apps (nVidia WinXP x86).

At least this confirms again that the OpenTK windowing is working properly.