2

I have some Haskell / OpenGLRaw code that does something like this:

verticesPtr <- newArray ...
glVertexPointer 3 gl_DOUBLE 0 verticesPtr

buffersPtr <- malloc
glGenBuffers 1 buffersPtr
buffer <- peek buffersPtr

glBindBuffer gl_ARRAY_BUFFER buffer
glBufferData gl_ARRAY_BUFFER 4 verticesPtr gl_STREAM_DRAW

glDrawArrays gl_LINE_STRIP 0 4
glDeleteBuffers 1 buffersPtr

I have two questions concerning this code:

  1. I am calling this from within the draw callback. Does this entirely negate the usefulness of storing my vertex data in the server?
  2. If I should place this code outside draw, should I change the gl_STREAM_DRAW command to something more static?
sdasdadas
  • 23,917
  • 20
  • 63
  • 148
  • 3
    Storing your vertex positions using double-precision will not benefit you at all. The driver is going to convert them to single-precision, so you are basically just wasting memory. As for storing the vertex data in the server, considering you are deleting the data store immediately after drawing, I would hardly call it "storing" :) At the very least, keep the buffer somewhere persistently and use `glBufferSubData (...)` to update it rather than allocating and destroying it every time you call this function. – Andon M. Coleman Nov 21 '13 at 02:17
  • @AndonM.Coleman: He's using Haskell, and keeping a buffer around to modify acts a bit against the idioms of that language. Yes, there are mutable types, but having a mutable buffer, which then is used for updating with glBufferSubData. Clearly in Haskell you'd want the VBO itself being represented as a higher level type. Either with mutable internal state or in a copy-on-write fashion, where a new VBO is derived from an old one upon change (which would be always a GL_STATIC_DRAW access). – datenwolf Nov 21 '13 at 13:14
  • 1
    The Haskell OpenGL binding developers also work on a set of higher level functions and types that present OpenGL in a clean, functional way following Haskell idioms. I suggest at looking how they do it. – datenwolf Nov 21 '13 at 13:15

1 Answers1

2
  1. Yes, you are throwing away most of the benefits of buffer objects by using them in this manner. In all likelihood, it will still be faster than glBegin/glEnd since the driver becomes aware of all of the data simultaneously, rather than incrementally, but there's no guarantee it will be faster, and may even be slower for small buffer sizes due to the overhead of creating and destroying the buffer object.

  2. Yes, as described in the glBufferData API docs you should avoid STREAM_DRAW unless the buffer is changing every or close to every frame. My personal rule of thumb is:

    • Changes only once in a while --> STATIC
    • Changes often, but less often than it stays the same --> DYNAMIC
    • Changes more often than it stays the same --> STREAM
bcrist
  • 1,520
  • 13
  • 25
  • You don't need rules of thumb for the access mode. It's exactly specified for which scenario to use which mode. – datenwolf Nov 21 '13 at 13:09
  • @datenwolf True, but its specified in terms of how many times the buffer is accessed before it's modified. IMHO its more intuitive to think of it in the reverse fashion; as the ratio between the number of frames where the buffer is updated to the total number of frames. – bcrist Nov 22 '13 at 03:13