Browse Source

Test that binding index buffer internally doesn't affect bound VAOs.

Fails. Problem spotted on WebGL 2 and is an unfortunate consequence of
these events:

1. Neither EXT_DSA nor ARB_DSA is available, but VAOs are available,
   which means virtually all ES 3 and WebGL 2 implementations and also
   ES 2 / WebGL 1 with OES_VAO available.
2. Index buffer gets created with TargetHint::ElementArray, bound to
   GL_ELEMENT_ARRAY_BUFFER and filled with data.
3. Mesh object with VAO inside is created and the index buffer from
   above gets bound to GL_ELEMENT_ARRAY_BUFFER again to attach it to the
   VAO.
4. Another index buffer, possibly for another mesh, gets created with
   TargetHint::ElementArray and bound to GL_ELEMENT_ARRAY_BUFFER in
   order to be filled with data. But because the VAO from above is still
   bound, the index buffer attachment is then stomped on.
5. Rendering such mesh will use a different index buffer, most probably
   causing some out-of-range GL error and nothing rendered.
pull/206/head
Vladimír Vondruš 9 years ago
parent
commit
c8b31b8468
  1. 48
      src/Magnum/Test/MeshGLTest.cpp

48
src/Magnum/Test/MeshGLTest.cpp

@ -111,6 +111,8 @@ struct MeshGLTest: OpenGLTester {
void setIndexBufferRange(); void setIndexBufferRange();
void setIndexBufferUnsignedInt(); void setIndexBufferUnsignedInt();
void unbindVAOWhenSettingIndexBufferData();
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void setBaseVertex(); void setBaseVertex();
#endif #endif
@ -202,6 +204,8 @@ MeshGLTest::MeshGLTest() {
&MeshGLTest::setIndexBufferRange, &MeshGLTest::setIndexBufferRange,
&MeshGLTest::setIndexBufferUnsignedInt, &MeshGLTest::setIndexBufferUnsignedInt,
&MeshGLTest::unbindVAOWhenSettingIndexBufferData,
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
&MeshGLTest::setBaseVertex, &MeshGLTest::setBaseVertex,
#endif #endif
@ -1454,6 +1458,50 @@ void MeshGLTest::setIndexBufferUnsignedInt() {
CORRADE_COMPARE(value, indexedResult); CORRADE_COMPARE(value, indexedResult);
} }
void MeshGLTest::unbindVAOWhenSettingIndexBufferData() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::vertex_array_object>())
CORRADE_SKIP(Extensions::GL::ARB::vertex_array_object::string() + std::string(" is not available."));
if(Context::current().isExtensionSupported<Extensions::GL::ARB::direct_state_access>())
CORRADE_SKIP(Extensions::GL::ARB::direct_state_access::string() + std::string(" is active with circumvents the issue tested here."));
if(Context::current().isExtensionSupported<Extensions::GL::EXT::direct_state_access>())
CORRADE_SKIP(Extensions::GL::EXT::direct_state_access::string() + std::string(" is active with circumvents the issue tested here."));
#elif defined(MAGNUM_TARGET_GLES2)
if(!Context::current().isExtensionSupported<Extensions::GL::OES::vertex_array_object>())
CORRADE_SKIP(Extensions::GL::OES::vertex_array_object::string() + std::string(" is not available."));
#endif
typedef Attribute<0, Float> Attribute;
const Float data[] = { -0.7f, Math::unpack<Float, UnsignedByte>(92), Math::unpack<Float, UnsignedByte>(32) };
Buffer buffer{Buffer::TargetHint::Array};
buffer.setData(data, BufferUsage::StaticDraw);
Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(std::vector<UnsignedByte>{5, 0}, BufferUsage::StaticDraw);
Mesh mesh;
mesh.addVertexBuffer(buffer, 4, Attribute{})
.setIndexBuffer(indices, 0, Mesh::IndexType::UnsignedByte);
/* This buffer should have no effect on the mesh above */
Buffer otherIndices{Buffer::TargetHint::ElementArray};
otherIndices.setData(std::vector<UnsignedByte>{100, 1}, BufferUsage::StaticDraw);
MAGNUM_VERIFY_NO_ERROR();
const auto value = Checker(FloatShader("float", "vec4(valueInterpolated, 0.0, 0.0, 0.0)"),
#ifndef MAGNUM_TARGET_GLES2
RenderbufferFormat::RGBA8,
#else
RenderbufferFormat::RGBA4,
#endif
mesh).get<UnsignedByte>(PixelFormat::RGBA, PixelType::UnsignedByte);
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(value, 92);
}
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MeshGLTest::setBaseVertex() { void MeshGLTest::setBaseVertex() {
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::draw_elements_base_vertex>()) if(!Context::current().isExtensionSupported<Extensions::GL::ARB::draw_elements_base_vertex>())

Loading…
Cancel
Save