[osg-users] VBO Bug with 3.6.1 and Normal Arrays

Robert Osfield robert.osfield at gmail.com
Fri Jun 1 08:51:22 PDT 2018

Hi Dan,

Thanks for the explanation and example to reproduce the bug... Guess
it looks like we'll need to make 3.6.2 rather sooner than I was
hoping, it'll be one a month at this rate...


On 1 June 2018 at 16:01, Daniel Emminizer, Code 5773
<dan.emminizer at nrl.navy.mil> wrote:
> Hi Robert,
> Oops -- I sent this earlier today but apparently to the bounces list; that explains the confusion on GitHub -- my mistake.  This was supposedly sent right before I posted the PR.  Here's the original text:
> I think I found a bug in 3.6.1.  I am loading a FLT model and it's causing a crash in my application to draw it.  The same model does not crash in OSG 3.4.  I think I've finally tracked down the cause and have a candidate solution too.
> A few weeks back I saw a similar crash in my own code, and figured it was due to incorrect usage of the binding flags on osg::Array.  Much of our code was using osg::Geometry::setNormalBinding() (and related methods).  During debugging, I was able to determine my normals were crashing in 3.6, and the problem went away when I used the osg::Array(osg::Array::Binding) signature -- i.e. assigning a binding on construction.  At the time I thought it was something I was doing wrong and moved on.
> The problem showed up again earlier this week but not in my code, and not manifesting in exactly the same way.  Here's the run-down of what's going on:
> - Loading FLT model
> - FLT model loads a face, which has vertices, textures, and normals
> - FLT uses getOrCreateNormalArray(), which allocates an array (BIND_UNDEFINED) and sets it on the geometry
> - Geometry::addVertexBufferObjectIfRequired() is called on the normals, but nothing done due to BIND_UNDEFINED
> - FLT later sets normals to BIND_PER_VERTEX appropriately, which is a direct set and does not do anything to the Geometry's VBOs
> - First frame starts to render
> - Geometry::drawVAImpl calls vas->setNormalArray()
> - VertexArrayState::setArray() calls new_array->getOrCreateGLBufferObject(), which returns 0.  This is the first major problem.
> - Because vbo is NULL, unbindindVertexBufferObject() is called, leading to GL_ARRAY_BUFFER to go to 0
> - vad->enable_and_dispatch() gets called and does glVertexAttribPointer() with a non-NULL data ptr, which is a GL error because array buffer is 0
> Unwinding the error:
> - enable_and_dispatch() shouldn't be called if ptr is non-NULL and no GL_ARRAY_BUFFER is 0
> - GL_ARRAY_BUFFER is set to 0 because there is no VBO set up for the normal array
> - There is no normal array because the only place it seems to be created is in setNormalArray(), which fails because at that time, it is BIND_UNDEFINED
> - Binding gets swapped from BIND_UNDEFINED to BIND_PER_VERTEX after setNormalArray(), leading to the error
> There are several possible solutions I can see.  You can probably see more:
> 1) Change FLT plugin to assign array binding per vertex on construction of array.  Seems poor because invariably this bug is crashing other code -- maybe it's the cause of the DXF that Brian Hutchison reported earlier this week?
> 2) Update Array::setBinding() to create the VBO if needed.  I do not know if this is possible nor how to do it.
> 3) "Lazily" detect this issue somewhere in the rendering calls and create VBO there if necessary
> PR 554 was an attempt at approach #3 but I agree with your assessment on GitHub.  It does not solve the problem in all cases.
> Attached is a demo of the problem that generates a console warning.  More complex scenes can cause crashes.  The red triangle has the problem, but the green one does not.
>  - Dan
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

More information about the osg-users mailing list