[Performance] Update dynamic vertices in drawable by external incoming data

36 views
Skip to first unread message

Yuan Cheng

unread,
Feb 19, 2020, 6:11:23 AM2/19/20
to OpenSceneGraph Users
Hello everyone,

I am not experienced at osg and want to post my question here (please bear me if my question is stupid). 

Here is the backround of my question:
I get 400 ~ 800 incoming points of simulated road marks by one programm every 20 ~ 30 ms. My Programm is fed by these points continuously on the main thread. My goal is to visualise them by connecting them into lines:

After reading many releated posts on this forum, I got some ideas and implemented them:

this is basic setup:
    osg::ref_ptr<osg::Geode> road_mark_geode; // hold the vertices inside my program
    ...
    osg::ref_ptr<osg::Geometry> geom(new osg::Geometry());

    geom->setUseVertexBufferObjects(true);
    geom->setUseDisplayList(false);
    geom->setUpdateCallback(new DynamicRoadMarkCallback); //  I customized a osg::Drawable::UpdateCallback to run vertices->dirty(), to update inside road mark vertices 
    osg::Vec3Array* vertices(new osg::Vec3Array());
    geom->setVertexArray(vertices);
    geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, DEFAULT_VERTEX_SIZE));
    road_mark_geode->addDrawable(geom.get());
    ...

Given that data reception is on main thread, i did this (points_in is incoming data from another program):

Loop on main thread:
    receive points and store them -> call function "update_pos_of_vertices " to set the pos (x, y, z) for vertices by new points.
   
    Blow is the interested code snippet:
   
    getdata(points_in, points_save); // save incoming data into "points_save" of my own data type
 
    update_pos_of_vertices (points_save) {
        osg::Geometry* geo_drawable = static_cast<osg::Geometry*>(road_mark_geode->getDrawable(0));
geo_drawable->setDataVariance(osg::Object::DYNAMIC);
osg::DrawArrays* drawArrays = static_cast<osg::DrawArrays*>(geo_drawable->getPrimitiveSet(0));
osg::Vec3Array* vertices = static_cast<osg::Vec3Array*>(geo_drawable->getVertexArray());
int num_vertices = points_save.size();
drawArrays->setCount(num_vertices);
vertices->resize(num_vertices);
for (... ) { 
vertices->at(i).set(points_save[i]); // set new pos of each vertex
}
    }

My program ran and i got visualized lines which are linked by points (see pic in attachment). But my program becomes very slow: average time for one single loop is 50ms. So my question is:
How can I improve the performance?
Did I do anything wrong regarding the my implementation above?

Look  forward to any help, tips and remarks!
Thank you

Yuan

   



    

    







 



visualized_lines.png

Robert Osfield

unread,
Feb 19, 2020, 8:34:05 AM2/19/20
to OpenSceneGraph Users
HI Yuan,

There a number of ways to go about this type of task, which route to take will depend on your needs/hardware available.

In principle pass 400-800 points each frame is not a large and should work easily at 60fps without any issues.  One most efficient way to do this is to create an array which is large enough for the maximum number of points you'll need and allocate this at the start, then just fill in the parts of the array that you need, and set the DrawArrays to just reference the portion you need.  For instance you could allocate an osg::Vec3Array of 1000 vertices at setup, then never resize it.  Each time you update the data you'll need to call array->dirty() to force the VBO to be updated.

Also when doing bechmarking mark sure you are using a release build of the OSG and your application as this can make a huge difference.

Cheers,
Robert.

Yuan Cheng

unread,
Feb 19, 2020, 9:19:10 AM2/19/20
to OpenSceneGraph Users
Hi Robert,

thank you for your advice about initial setup of a big array. That is a big help.

As you said:    "There a number of ways to go about this type of task, which route to take will depend on your needs/hardware available."

My hardware is a window10 PC with intel i7 8550U CPU and intel Graphics 620.   

Later I will add more objects(e.g bounding box, point cloud maybe) to render in my program and I am not aware of how much computation it will demand. Could you please point out one link or reference of "a number of ways"?  I would really appreciate that.

Regards,
Yuan

OpenSceneGraph Users

unread,
Feb 20, 2020, 9:09:48 AM2/20/20
to OpenSceneGraph Users
On Wed, 19 Feb 2020 at 14:26, OpenSceneGraph Users <osg-...@lists.openscenegraph.org> wrote:
thank you for your advice about initial setup of a big array. That is a big help.

As you said:    "There a number of ways to go about this type of task, which route to take will depend on your needs/hardware available."

My hardware is a window10 PC with intel i7 8550U CPU and intel Graphics 620.   

Later I will add more objects(e.g bounding box, point cloud maybe) to render in my program and I am not aware of how much computation it will demand. Could you please point out one link or reference of "a number of ways"?  I would really appreciate that.

The different ways are in my head rather than a reference I can provide :-)  This type of topic has been discussed in various ways on osg-users over the years so you might find more info via a search.

If the fixed size array gives you the performance you want then our job is done.  If not then we had start looking at other ways, or why you aren't getting the performance you want.

 
Reply all
Reply to author
Forward
0 new messages