Anonymous's picture

Vertex Array example

The Vertex array example (T02_Vertex_Arrays.cs) is missing the "Main" method in the example class file. I added it based one of the other examples, but the example does not display things.

Is this example in flux due to 0.9.1 development?

The reason I was looking at the Vertex array example is that while researching the share context issues I came accross several message boards indicating that OpenGL 3 will drop display lists from the spec and further indicated thet VA and VBO were both described as mechanisms to use in place of display lists.

djk


Comments

Comment viewing options

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

This example was disabled on purpose because it suffers from a serious flaw: the vertex arrays are stored in managed memory and may be moved by the Garbage Collector. While this can be worked around (either by allocating unmanaged memory, or by pinning the objects in question), doing this will cause a performance hit.

Vertex Buffer Objects do not suffer from this problem, as they are stored in server memory. OpenGL 3 will not use client memory anyway, so VBO's are a safer bet.

Anonymous's picture

The vertex array shows up in the example launcher under debug. I have been looking at the VBO example this morning.

the Fiddler's picture

Just a small note that the examples have grown a little stale (some major restructuring is underway for 0.9.2). Better check the VBO functionality in the GLSL example, as this is a little more up-to-date.

darxus's picture

Is it better to avoid arrays in sake of speed? I think that opengl superbible talks about this issue.

the Fiddler's picture

Speedwise, from slowest to fastest:

  • Immediate mode
  • Vertex Arrays
  • Vertex Buffer Objects
  • Display Lists

While Display Lists can be faster than VBO's, they are only suitable for static geometry, which means VBO's are the best all-around solution. Both are (or can be) stored in video memory, so they are *very* fast to draw.

VA's on the other hand are stored in client memory, and have to travel through the AGP/PCI-E bus every time before rendering. Not only does this make them quite slow, but it also places the burden of memory management to the user (hence the problem with Garbage Collectors).

For general usage VBO's are the best solution.

haymo's picture

Since I am rendering large mathematical objects and do not want to rely on large enough video memory, I'm still using vertex arrays. I came across the problem with index lists, which produce problems while switching to unmanaged context. However, by carefully designing the vertex array in stripes, one can most the time get around this issue. The way I figured out by now, does actually seems to be relatively ok. Thats why I'd like to share it here.

 fixed (VertexC4N3V3* pVertices = m_vertices) {
             // populate vertex array to GL
             GL.InterleavedArrays(OpenTK.OpenGL.Enums.InterleavedArrayFormat.C4fN3fV3f
                                  ,0,(IntPtr)pVertices); 
             // do some other stuff here, than
             // DrawElements will be called in a loop.
             // We give a pointer to the only index array existing, 
             // what will prevent from using index list array. 
             fixed (UInt32* pGridIndWalk = m_indices)
             for ([number of stripes]) {
                  GL.DrawElements(OpenTK.OpenGL.Enums.BeginMode.Lines,
                                  m_gridStripsLen,
                                  OpenTK.OpenGL.Enums.DrawElementsType.UnsignedInt,
                                  (IntPtr)(pGridIndWalk));
                  // increase the pointer to the next stripe
                  pGridIndWalk += m_gridStripsLen; 
             }
}

This will still be slower then using VBO, but may be useful for people needing to use indexed vertex arrays anyway.

the Fiddler's picture

Thanks, this should solve the problem (unless the driver decides to read the VA contents asynchronously).

One more thing to keep in mind is that the .Net GC will not move objects which are bigger than 80-90KB. Obviously this is not something to be relied on, as different versions of the runtime may have different limits, but it can affect behavior.

Inertia's picture

.Net GC will not move objects which are bigger than 80-90KB.
Good to know! I couldn't find a variable to access this limit, is there any?

the Fiddler's picture

This is called the "large object heap".

I would be surprised if such a variable existed. This is an implementation detail (the specs don't dictate how to implement the GC), and I guess they want to be free to change it in the future. If they did provide this information, some programs would start depending on the exact limit and such a compatibility nightmare is the last they want :)

Inertia's picture

From the link: ...implementation detail that could be changed in the future.
You are right, it would be nice though if this could be controlled. The ~83kb limit could also explain the VA related problems I had with PQ Torusknots in it's early stages (the Vertex[] had far less then 80kb back then), and why haymo's application does not require GL.Finish to run without random crashes at GL.Draw*