Ошибка с VAO только на устройстве Nexus 4

У меня есть странная ошибка на моем nexus 4 с OpenGL ES2, когда я использую объекты массива вершин.

Вот некоторые сведения:

  • Все работает, когда я не использую VAO
  • Все работает на других устройствах и на Ipad 2 с VAO и без него.
  • glGetError() не возвращал ошибку
  • Из-за ошибки в игре появляются глюки (некоторые элементы принимают другой вид)
  • Мои VBO - это динамика (я обновляю их с помощью glBufferData)

Вот ошибка:

Adreno-ES20 (16818): : validate_vertex_attrib_state: в вызове отрисовки не включен атрибут вершины!

И вот мой код:

void Renderer::setVertexBuffer( Uint32 stream, const Base* vertexBuffer, std::size_t stride, Uint32 startVertex, Uint32 endVertex )
{
    static const bool VAOSupported = this->isExtensionPresent(VertexArrayObject);
    if( VAOSupported )
    {
        if( vertexBuffer->vao.isReady() == false )
        {
            // Bind VAO.
            glBindVertexArrayOES( vertexBuffer->vao.getId() );

            // Bind filled VBO.
            glCheck( glBindBuffer( GL_ARRAY_BUFFER, vertexBuffer->getId() ) );

            // Set attributs with vertex format.
            this->applyVertexFormat( startVertex, endVertex );

            // Unbind buffer and VAO.
            glBindVertexArrayOES(0);

            vertexBuffer->vao.isReady(true);
        }

        glBindVertexArrayOES( vertexBuffer->vao.getId() );
    }
    else
    {
        glBindVertexArrayOES(0);
        glCheck( glBindBuffer( GL_ARRAY_BUFFER, vertexBuffer->getId() ) );
        this->applyVertexFormat( startVertex, endVertex );
    }
}

////////////////////////////////////////////////////////////
void Renderer::setIndexBuffer( const Buffer* indexBuffer, std::size_t stride )
{
    glCheck( glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBuffer->getId() ) );
    this->usedIndexBufferStride = stride;
}

////////////////////////////////////////////////////////////
void Renderer::applyVertexFormat( Uint32 startVertex, Uint32 endVertex )
{
    const Uint32 stride = this->vertexFormat->getStride();
    for( Uint32 i = 0; i < this->vertexFormat->getAttributCount(); i++ )
    {
        const VertexElement& element = this->vertexFormat->getAttribut(i);

        glCheck( glEnableVertexAttribArray( element.usage ) );
        glCheck( glVertexAttribPointer( element.usage,
                                       element.type,
                                       element.type,
                                       element.normalize,
                                       stride,
                                       BUFFER_OFFSET(element.offset + startVertex * stride ) ) );
    }
}

И вот как я его использую:

renderer->setFormat(geometry->getFormat()); // Only save a pointer to the format to use in apply method.
renderer->setVertexBuffer(geometry->getVertexBuffer());
renderer->setIndexBuffer(geometry->getIndexBuffer());
renderer->draw(GL_TRIANGLES, geometry->indiceCount);

person user30088    schedule 01.02.2014    source источник


Ответы (1)


Вы уверены, что usage является подходящим именем для поля, определяющего, с каким массивом атрибутов связать указатель? Объекты буфера уже имеют свойство под названием использование (например, GL_DYNAMIC_DRAW). location может иметь больше смысла.

Однако у вас есть гораздо более серьезная проблема в вашем коде:

element.type не может быть одновременно типом ваших данных и количеством компонентов. glVertexAttribPointer (...) принимает только компоненты 1, 2, 3 или 4, перечислитель типа GL_FLOAT имеет значение намного больше, чем 4.

Предполагая, что glCheck( ... ) правильно оборачивает glGetError (...), эта ситуация должна указывать на GL_INVALID_VALUE.

Это наводит меня на мысль, что ваш цикл в void Renderer::applyVertexFormat( Uint32 startVertex, Uint32 endVertex ) никогда не запускается.

person Andon M. Coleman    schedule 02.02.2014
comment
Упс, это ошибка во время копирования/вставки из моего кода, этой ошибки нет (с glVertexAttribPointer). Это наводит меня на мысль, что ваш цикл -> я добавил printf для проверки и запуска программы в этой части кода, очень странная проблема. Я попытаюсь отладить OpenGL с помощью инструментов eclipse, чтобы увидеть порядок команд и посмотреть, правильно ли команда вызывается. Спасибо! - person user30088; 09.02.2014