仅在Nexus 4设备上出现VAO错误

时间:2014-02-01 21:54:14

标签: opengl-es nexus-4 vao

当我使用顶点数组对象时,我的nexus 4与OpenGL ES2有一个奇怪的错误。

以下是一些信息:

  • 当我不使用VAO时,一切正常。
  • 其他设备以及使用和不使用VAO的Ipad 2都可以使用
  • 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);

1 个答案:

答案 0 :(得分:0)

您确定usage是一个适当的名称,用于定义将指针与哪个属性数组相关联的字段?缓冲区对象已经有一个名为usage的属性(例如GL_DYNAMIC_DRAW)。 location可能更有意义。

但是,您的代码中存在更严重的问题:

element.type不能两者您的数据类型和组件数量。 glVertexAttribPointer (...)仅接受 1 2 3 4 组件,类似{{1}的枚举大于 4 的值

假设GL_FLOAT正确包裹glCheck( ... ),这种情况应该指示 glGetError (...)

这让我相信GL_INVALID_VALUE中的循环永远不会被触发。