coder123's picture

Vertex Arrays without VBO

Hi.

I posted in another thread about a problem with vertex arrays, and since then, I did some more research on the subject.

In short:
I'm using vertex arrays without VBO so I retain support for older systems. The OpenTK docs say I need a GL.Finish before closing the fixed{} block since otherwise I risk to have GC move my array before GL.DrawArrays gets around to reading it.

However, here's a quote from the OpenGL 2.0 spec:

Quote:

The effect of DrawArrays (mode, first, count); is the same as the effect of the command sequence

if (mode or count is invalid )
    generate appropriate error
else {
    Begin(mode);
    for (int i = 0; i < count ; i++)
    ArrayElement(first+ i);
    End();
}

with one exception: <irrelevant here>

This implies that GL.DrawArrays internally copies the array before returning (or does something equivalent like copy-on-write). This is because the Begin...End code from the spec does not access our array elements after the End().

And if that's true, then it's safe to let the GC move away our array after GL.DrawArrays returns, without calling GL.Finish().

Am I missing something?


Comments

Comment viewing options

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

The spec describes what the effect of glDrawArrays is, not what it does. The function might as well do nothing (apart from storing a pointer to the *coughs 2x* managed heap) until glFinish is called.

The OpenTK docs say I need a GL.Finish before closing the fixed{} block since otherwise I risk to have GC move my array before GL.DrawArrays gets around to reading it.
True. So, where's the problem?

By the way, VBOs are part of OpenGL core since prehistory (1.5) or maybe longer. What exactly is the point of using vertex arrays if you're following the 2.0 specification?

the Fiddler's picture

The problem isn't glDrawArrays. The problem is glVertexPointer.

What happens is this:

  • you call glVertexPointer
  • the GC moves your array data in the managed heap
  • you call glDrawArrays - boom AccessViolationException

Whether glDrawArrays copies data is irrelevant. What you need to do is ensure it receives valid data in the first place - and to do that, you need to place both glVertexPointer and glDrawArrays in the same fixed block.

glFinish is an extra precaution that may not actually be needed - I don't exactly recall what the specs have to say on the matter. However, I did encounter crashes without it, which is why I used it (disclaimer: this stuff happened half a decade ago using a different toolkit; the crashes might have been caused by something else entirely, like the toolkit not pinning the data during the glDrawArrays call).

nythrix's picture
Quote:

The problem isn't glDrawArrays. The problem is glVertexPointer.

Yeah, that's the one (and other gl*Pointer functions) I actually had in mind. I probably shouldn't post this late in the night, lol.

I had a quick look into the 1.5 spec: "Vertex data may also be placed into arrays that are stored in the client’s address space" (section 2.8). This doesn't say much so I wouldn't rely on an implementation specific behavior in any case.

There might be more info somewhere else but the document is quite large for bedtime reading.