1

In my draw method (executes every frame), I need to pass arrays of vertices coordinates to openGl.

glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices);

Every frame, all the vertices are recalculated even though only a few of them change. Effectively, all the vertices are shifted a few array positions to the left (the vertices in the smallest array indices are removed, and new values are added at the end of the array).

For example, the array values can change between iterations as follows.:

Iteration 1 : {0,1,2,3,4,5,6,7,8}
Iteration 2 : {4,5,6,7,8,9,10,11,12}

Instead of recomputing all the values again (even the unchanging ones), I would like to instead just compute the new values, and add them to the "end" of a circular array. (I know how to do this part).

I was wondering if there is someway I can pass a circular buffer / array to openGl instead of a regular array? Is there some way I can effectively do the same thing so I don't have to recompute all the values every frame ?

5
  • You can only pass a pointer to OpenGL. How you fill the corresponding buffer is completely up to you, though. So do you want to avoid the computation on the CPU side, or avoid uploading all the data to the GPU? Commented May 13, 2014 at 8:47
  • @John you can't describe a circular array in the CPU memory model. what you can do to minimize the memory movement is to make the array larger and manage the content with multiple draw calls. With this you can avoid moving memory on every frame , but at one point you will have to move around otherwise it will get too fragmented resulting in too many draw calls. Commented May 13, 2014 at 8:48
  • @lethal-guitar if you see the two iterations above, I effectively need to remove from the left and add to the right. But I can't do that in a regular array. It would be easy to just add to the right in a circular array, but I don't think I can pass that to OpenGL. Commented May 13, 2014 at 8:53
  • @Raxvan Can you explain what you mean ? I don't know very much about OpenGL. Commented May 13, 2014 at 8:53
  • 1
    @John if you are new to opengl it would be too much of a talk for me to explain this (sorry but i don't have time for that). I would suggest to stick to moving memory around and when you will gain some experience using this you will probably find the solution by yourself Commented May 13, 2014 at 8:55

1 Answer 1

2

you can use an element array and then use indexed rendering (using the glDrawElement* methods)

if you don't want to do that then you can upload the array in 2 parts (buffer is then name of the buffer, array is the pointer to the client side array, diff is the offset where the turnover in the circular array is and length is the size of the buffer)

glBindBuffer(GL_ARRAY_BUFFER, buffer);
//copies the second part of the array to the first section of the buffer
glBufferSubData(GL_ARRAY_BUFFER, 0, length-diff, array+diff); 
//copies the first part of the array to the second section of the buffer
glBufferSubData(GL_ARRAY_BUFFER, length-diff, diff, array);
glBindBuffer(GL_ARRAY_BUFFER,0);

or map the buffer and do a memmove (as they may overlap): this may stall the pipeline on glMapBuffer

glBindBuffer(GL_ARRAY_BUFFER, buffer);
do{
    void* buff = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
    memmove(buff+diff, buff, length-diff);
    //add new data
}while(glUnmapbuffer(GL_ARRAY_BUFFER)==GL_FALSE);
glBindBuffer(GL_ARRAY_BUFFER,0);

with a second buffer you can do a glCopyBufferSubData to do the move server-side:

glBindBuffer(GL_COPY_READ_BUFFER​, frontbuffer);
glBindBuffer(GL_COPY_WRITE_BUFFER​, backbuffer);
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, diff, 0, length-diff);
glBindBuffer(GL_COPY_READ_BUFFER,0​);
glBindBuffer(GL_COPY_WRITE_BUFFER​,0);
swap(frontbuffer, backbuffer);

this last one is also possible with one buffer if you allocate your buffer twice as large as you need to.

so the first iteration the buffer has (* are values that you don't render)

1,2,3,4,5,6,7,8,*,*,*,*,*,*,*,*

the second iteration:

*,*,*,*,5,6,7,8,9,10,11,12,*,*,*,*

the thirst iteration:

*,*,*,*,*,*,*,*,9,10,11,12,13,14,15,16

so you can do the glCopyBufferSubData(GL_ARRAY_BUFFER, GL_ARRAY_BUFFER, 8,0,8); and make it

9,10,11,12,13,14,15,16,*,*,*,*,*,*,*,*
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.