Opengl обновит только последний объект массива вершин

Я пишу код, который генерирует некоторый VAO, а затем, когда физика обновляется, делается вызов для обновления вершин внутри VAO, а затем делается вызов для перерисовки этих объектов.

Проблема с моим кодом в том, что UpdateScene обновляет только последний VAO. Следующие две функции создают буферы.

void BuildBuffers(std::vector<demolish::Object>& objects)
{
    VAO = new UINT[objects.size()];
    glGenVertexArrays(objects.size(),VAO);
    int counter = 0;
    for(auto& o:objects)
    {
        if(o.getIsSphere())
        {
            BuildSphereBuffer(o.getRad(),o.getLocation(),counter);
            counter++;
        }
        else
        {
        }
    }
}

void BuildSphereBuffer(float radius,std::array<iREAL,3> position,int counter)
{

    GeometryGenerator::MeshData meshObj;
    geoGenObjects.push_back(meshObj);
    geoGen.CreateSphere(radius,30,30,meshObj,position);

    VAOIndexCounts.push_back(meshObj.Indices.size());
    glGenBuffers(2,BUFFERS);
    glBindVertexArray(VAO[counter]);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);


    glBindBuffer(GL_ARRAY_BUFFER,BUFFERS[0]);
    glBufferData(GL_ARRAY_BUFFER,
                                  meshObj.Vertices.size()*sizeof(GLfloat)*11,
                                  &meshObj.Vertices.front(), GL_STATIC_DRAW);


    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BUFFERS[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                                   meshObj.Indices.size() * sizeof(UINT),
                                   &meshObj.Indices.front(), GL_STATIC_DRAW);

    glVertexPointer(3, GL_FLOAT,sizeof(GLfloat)*11, 0);
    glNormalPointer(GL_FLOAT,sizeof(GLfloat)*11,(GLvoid*)(3*sizeof(GLfloat)));
}

Затем следующая функция обновляет буферы при вызове.

void UpdateScene(float dt, std::vector<demolish::Object>& objects)
{
    float x = radius*sinf(phi)*cosf(theta);
    float z = radius*sinf(phi)*sinf(theta);
    float y = radius*cosf(phi);


    AV4FLOAT position(x,y,z,1.0);

    AV4FLOAT target(0.0,0.0,0.0,0.0);
    AV4FLOAT up(0.0,1.0,0.0,0.0);

    viewModelMatrix = formViewModelMatrix(position,target,up);

    for(int i=0;i<objects.size();i++)
    {
        geoGen.CreateSphere(objects[i].getRad(),
                            30,
                            30,
                            geoGenObjects[i],
                            objects[i].getLocation());

        VAOIndexCounts[i] = geoGenObjects[i].Indices.size();

        glBindVertexArray(VAO[i]);
        glBufferSubData(GL_ARRAY_BUFFER,
                                0,
                                geoGenObjects[i].Vertices.size()*sizeof(GLfloat)*11,
                                &geoGenObjects[i].Vertices.front());
    }

    RedrawTheWindow();

}

Проблема с этим кодом в том, что он обновляет не все буферы, а только «последний». Например, если объекты имеют размер 3, то даже если расположение всех трех объектов изменится, только последний буфер обновляется новыми вершинами.

Я сузил его до OpenGL, но не уверен, что делаю неправильно.

1
0
125
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Привязка Объект массива вершин не связывает ни один объект буфера массива. Если вы хотите изменить содержимое буфера массива, вам необходимо привязать буфер массива:

GLuint VBO = .....; // VBO which corresponds to VAO[i]

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(
    GL_ARRAY_BUFFER, 0,
    geoGenObjects[i].Vertices.size()*sizeof(GLfloat)*11,
    &geoGenObjects[i].Vertices.front());

Обратите внимание, что объект массива вершин может относиться к другому объекту буфера массива для каждого атрибута. Итак, какой из них должен быть связан?

Начиная с OpenGL 4.5, вы также можете сделать это с помощью версии с прямым доступом к состоянию. См. glNamedBufferSubData:

glNamedBufferSubData (
    VBO, 0,
    geoGenObjects[i].Vertices.size()*sizeof(GLfloat)*11,
    &geoGenObjects[i].Vertices.front());

Если объект массива вершин привязан, то объект буфера именованного массива, который привязан к точке привязки, может быть запрошен glGetVertexAttribIuiv с помощью параметра GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:

например.:

glBindVertexArray(VAO[i]);
GLuint VBO;
glGetVertexAttribIuiv(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &VBO);

glBindVertexArray (VAO [i]); glBindBuffer (GL_ARRAY_BUFFER, BUFFERS [0]); glBufferSubData (GL_ARRAY_BUFFER, 0, geoGenObjects [i] .Vertices.size () * sizeof (GLfloat) * 11, & geoGenObjects [i] .Vertices.front ());

user9833551 31.10.2018 14:27

@HMPARTICLE Наверное BUFFERS[0] изношен. Вы должны использовать буферный объект, соответствующий VAO[i].

Rabbid76 31.10.2018 14:27

Аааа, так мне нужно ХРАНИТЬ пару буферов для КАЖДОГО VAO ?!

user9833551 31.10.2018 14:28

@HMPARTICLE Да, если вы хотите изменить содержимое буфера позже, вам придется это сделать.

Rabbid76 31.10.2018 14:29

Теперь я понимаю. Я думаю, что здесь виновато мое плохое понимание графического конвейера / openGL. Спасибо! это сработало.

user9833551 31.10.2018 14:36

@HMPARTICLE Пожалуйста. Обратите внимание, что можно запросить объект буфера массива, см. Последнюю часть ответа.

Rabbid76 31.10.2018 14:42

Другие вопросы по теме