2015-10-19 2 views
0

В одном кадре разрешено «обновлять» то же самое GL_ARRAY_BUFFER и продолжать звонить glDrawArrays после каждого обновления?Могу ли я вызвать `glDrawArrays` несколько раз при обновлении того же` GL_ARRAY_BUFFER`?

Я знаю, что это, вероятно, не самый лучший и не самый рекомендуемый способ сделать это, но мой вопрос: могу ли я сделать это и ожидать, чтобы обновить GL_ARRAY_BUFFER перед каждым звонком до glDrawArrays?

пример

код будет выглядеть следующим образом:

// setup a single buffer and bind it 
GLuint vbo; 
glGenBuffers(1, &vbo); 
glBindBuffer(GL_ARRAY_BUFFER, vbo); 

while (!renderStack.empty()) 
{ 
    SomeObjectClass * my_object = renderStack.back(); 
    renderStack.pop_back(); 

    // calculate the current buffer size for data to be drawn in this iteration 
    SomeDataArrays * subArrays = my_object->arrayData(); 
    unsigned int totalBufferSize = subArrays->bufferSize(); 
    unsigned int vertCount = my_object->vertexCount(); 

    // initialise the buffer to the desired size and content 
    glBufferData(GL_ARRAY_BUFFER, totalBufferSize, NULL, GL_STREAM_DRAW); 

    // actually transfer some data to the GPU through glBufferSubData 
    for (int j = 0; j < subArrays->size(); ++j) 
    { 
     unsigned int subBufferOffset = subArrays->get(j)->bufferOffset(); 
     unsigned int subBufferSize = subArrays->get(j)->bufferSize(); 
     void * subBufferData = subArrays->get(j)->bufferData(); 

     glBufferSubData(GL_ARRAY_BUFFER, subBufferOffset, subBufferSize, subBufferData); 

     unsigned int subAttributeLocation = subArrays->get(j)->attributeLocation(); 

     // set some vertex attribute pointers 
     glVertexAttribPointer(subAttributeLocation, ...); 
     glEnableVertexAttribArray(subAttributeLocation, ...); 
    } 

    glDrawArrays(GL_POINTS, 0, (GLsizei)vertCount); 
} 

Вы можете спросить - почему я хотел бы сделать это, и не только поджать все на GPU сразу ... ну, очевидный ответ, потому что я могу Не делайте этого, когда слишком много данных, которые не могут вписаться в один буфер.

Моя проблема в том, что я могу видеть только результат одного из glDrawArrays вызовов (я считаю, что первый один) или, другими словами, это выглядит как если GL_ARRAY_BUFFER не обновляется перед каждым glDrawArrays вызова, возвращает меня к моему вопросу, если это возможно.

Я использую OpenGL 3.2 CoreProfile (под OS X) и свяжусь с GLEW для установки OpenGL, а также Qt 5 для настройки создания окна.

+0

Вы пытались glBufferSubData – Mehdi

+0

Да, я фактически использую 'glBufferSubData' для копирования в отдельных частях буфера, но мне все еще нужно называть' glBufferData', чтобы изменить его размер ... в любом случае - есть ли разница, какая из них Я обращаюсь к моему вопросу? – Chris

+0

@ Крис: ваш подход действителен. GL сделает все неявные синхронизации, необходимые для этого, чтобы работать на вас. На самом деле, поскольку вызов 'glBufferData()' выделяет новое хранилище для объекта-буфера, разумная реализация может уйти без каких-либо дальнейших синхронизаций, поэтому подход должен быть даже не таким плохим, как вы могли бы подумать (но вы не можете полагаться на что либо). Я не знаю, что пойдет не так в вашем случае, но я могу окончательно подтвердить, что обновление буфера не является проблемой. – derhass

ответ

0

Да, это законный код OpenGL. Это никоим образом не означает, что кто-либо должен когда-либо делать это. Но это законно. В самом деле, это имеет еще меньшее значение в вашем случае, потому что вы вызываете glVertexAttribPointer для каждого объекта.

Если вы не можете поместить все ваши данные вершин в память или вам нужно сгенерировать их на графическом процессоре, тогда вы должны передать данные надлежащим образом buffer streaming techniques.

Смежные вопросы