OpenGL accross multiple threads in C#.NET

Hi,

I have an application (written in C#.NET with the 2.0 framework and OpenGL) that runs several display lists. It’s currently a little slow, so thought it would be a good idea to initialise the most important display lists first and display them. Then while the user is able to play with the rest of the interface (scroll and pan options etc.), initialise the rest of the display lists in a BackgroundWorker thread.

If I run the application, it runs fine, except the second set of display lists aren’t visible after they’ve created. If I close the application down and open it without about 10 mins of closing it, I get the following error:

“Attempting to read or write protected memory. This is often an indication that the other memory is corrupt”, which occurs on my call to glNewList. I’ve tried putting a lock or a mutex around the call to glNewList, but it doesn’t make a difference, I still get the error.

So I have two questions:

  1. When my application works after having had a break, why aren’t the second set of display lists visible?
  2. Why do I get the error if I run it up again too soon after closing it down?

Thanks,
Sarah

All opengl calls that target a rendering context must happen in the same thread that created that context. In this way, OpenGL is not multithreading-able.

Until two or more threads can render independently into the same context you should really keep all your rendering stuff in one thread.
(and i wish this will come soon into hardware and API support, with all the multicore stuff going on today)

With that said, you should know that you probably can speed up your rendering quite a bit by using things like VBO and advanced shaders instead of the display lists.

and if loading and building lists is still a problem you should investigate something called dynamic loading, basically it means that for each frame, just before rendering, you load a tiny bit of information or build a displaylist, or create a texture or something like that, and before you know it everything is done.

Before I read the replies, I worked out I could fix it by invoking the display list code back on the original thread, but this slows my code right down again, so I’m back to square one.

Unfortunately I don’t know anything about VBO with advanced shaders, or dynamic loading either. Can you point me in the direction of some details?

I don’t have any textures of lighting, just lots and lots of coloured and stippled lines.

Thanks

well with VBO you can put large amount’s of lines into the same object buffer(along with their colors) and then store it in the graphics memory.
Maybe this link will help you http://www.songho.ca/opengl/gl_vbo.html
You don’t have to use shaders if you don’t want to.
And for dynamic loading i can’t really help you there, it’s something you have to figure out yourself, but basically you only load a little bit at the time.

I’m trying to make a test VBO programme, but can somebody explain to me what PFNGLGENBUFFERSARBPROC (and the rest of the PFN stuff) is, and how to implement it in C#?

Thanks!

using System;
using System.Runtime.InteropServices;
using OpenGL.Delegates;
//... more usings here

namespace OpenGL
{
	namespace Delegates
	{
		public delegate void glGenBuffersARB(int n, int[] ids); // <- typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
		//... more delegates here
	}
	
	class gl
	{
		public static glGenBuffersARB GenBuffersARB; // <- PFNGLGENBUFFERSARBPROC glGenBuffersARB;
		//... more delegate statics here
	
		public static Delegate GetAddress(string name, Type t)
		{
			int addr=wgl.GetProcAddress(name);
			if(addr==0) return null;
			else return Marshal.GetDelegateForFunctionPointer(new IntPtr(addr), t);
		}
	
		public static void LoadExtensions()
		{
			GenBuffersARB=(glGenBuffersARB)GetAddress("glGenBuffersARB", typeof(glGenBuffersARB)); // <- glGenBuffersARB=(PFNGLGENBUFFERSARBPROC)GetProcAddress("glGenBuffersARB");
			//... more GetAddress-Calls here
		}
	}

	class wgl
	{
		[DllImport("OpenGL32.dll")]
		public static extern int GetProcAddress(int hwnd);
		
		//... more DllImports here
	}
}

HTH, a (almost) complete set of extension delegates is available in the OpenGL.cs file of the C# OpenGL Framework ( http://www.csharpopenglframework.com ).

Thanks! I discovered it was the GetDelegateForFunctionPointer I was missing so got that in, but I now have a protected memory exception on glDrawArrays, so I’ll try your code which is neater anyway, and see if I get any further!

Great, I’ve got it working now. I was passing an int to glGenBuffers for the buffer id rather than an array.

Thanks for everyone for their help.

Hi all,

I have a further question, or query - I don’t yet see how VBO’s are quicker than display lists? They do have the advantage that I can build up the array in a separate thread, but when I display them it takes ages. Also, I have 8 different types of lines, but if I try to display them all the onpaint function just starts over again when it gets to the end, I can only display 7 of them if I want to stop that happening.

This may be because I have multiple calls to glDrawArrays, as I’m using line strips so can’t just call it once. I have over 100,000 lines drawn on the screen at any one time, with about 4 coordinates per line.

I’m just looking into glMultiDrawArrays to see if this would suit my needs better, but in the mean time i’m interested to know if I’m doing something else wrong, or if this is just a case where display lists are quicker?

Cheers.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.