[osg-users] custom vertex attribut, using BIND_OVERALL

52 views
Skip to first unread message

Daniel Schmid

unread,
Oct 24, 2012, 5:26:18 AM10/24/12
to osg-...@lists.openscenegraph.org
Hi all

I want to pass a custom vertex attribute (lets say a material code) to my vertex shader.
For the moment I use BIND_PER_VERTEX:


Code:

int l_SMC = 1027; // some material code

for (unsigned int i=0; i<a_geode.getNumDrawables(); ++i)
{
osg::Geometry* l_Geom = a_geode.getDrawable(i)->asGeometry();
if (l_Geom)
{
osg::Array* l_VertexArray = l_Geom->getVertexArray();
if (l_VertexArray)
{
unsigned int vertex_count = l_VertexArray->getNumElements();
osg::IntArray* l_Array = new osg::IntArray;
for (int v=0; v<vertex_count; v++)
{
l_Array->push_back(l_SMC);
}
l_Geom->setVertexAttribArray(6, l_Array);
l_Geom->setVertexAttribNormalize(6, false);
l_Geom->setVertexAttribBinding(6, osg::Geometry::BIND_PER_VERTEX);
}
}
}




Since the material code is unique within geometries, so actually I would need to transfer it only once per Geometry. If I change to BIND_OVERALL, the data is no longer transferred, or at least my shader cannot detect it anymore. I thought i should maybe reduce the VertexAttribArray (l_Array) to one single entry, but this doesn't work either.

What is the correct way of passing general or common data, on a per geometry (and not vertex) basis?

Regards
Daniel

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=50745#50745





_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Daniel Schmid

unread,
Oct 24, 2012, 5:28:33 AM10/24/12
to osg-...@lists.openscenegraph.org

Hi all

 

I want to pass a custom vertex attribute (lets say a material code) to my vertex shader.

For the moment I use BIND_PER_VERTEX:

 

[code]

int l_SMC = 1027; // some material code

 

for (unsigned int i=0; i<a_geode.getNumDrawables(); ++i)

{

  osg::Geometry* l_Geom = a_geode.getDrawable(i)->asGeometry();

  if (l_Geom)

  {

    osg::Array* l_VertexArray = l_Geom->getVertexArray();

    if (l_VertexArray)

    {

      unsigned int vertex_count = l_VertexArray->getNumElements();

      osg::IntArray* l_Array = new osg::IntArray;

      for (int v=0; v<vertex_count; v++)

      {

        l_Array->push_back(l_SMC);

      }

      l_Geom->setVertexAttribArray(6, l_Array);

      l_Geom->setVertexAttribNormalize(6, false);

      l_Geom->setVertexAttribBinding(6, osg::Geometry::BIND_PER_VERTEX);

    }

  }

}

[/code]

Sergey Polischuk

unread,
Oct 24, 2012, 5:34:59 AM10/24/12
to OpenSceneGraph Users
Hi
 
wouldnt it be better to use uniform in this case?
 
Cheers.
 
24.10.2012, 13:28, "Daniel Schmid" <Daniel...@swiss-simtec.ch>:
,

Daniel Schmid

unread,
Oct 24, 2012, 5:40:31 AM10/24/12
to osg-...@lists.openscenegraph.org
When I would use uniforms, I cannot set different values for different geometries. Uniforms are global for a particular stateset. So I HAVE to use vertex attributes, since in my shader I want to treat some particular surface in a special way, but without the need of separate stateset.

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=50748#50748

Tassilo Glander

unread,
Oct 24, 2012, 6:22:18 AM10/24/12
to osg-...@lists.openscenegraph.org
Hi Daniel,

you are right, with BIND_OVERALL and just one element in the array, OSG should apply the single attribute to all vertices of the geometry. You can check this behavior in Geometry.cpp searching for BIND_OVERALL. Also there is the createTexturedQuadGeometry() function which does setup a geometry like you want, so check it out if you do it the same way. If it does not work, try to put a breakpoint into Geometry.cpp and debug to see what happens.

As you say, setting Uniforms requires a state change, while with an attribute the rendering is done at the GPU completely.

Thank you!

Cheers,
Tassilo

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=50751#50751

Sergey Polischuk

unread,
Oct 24, 2012, 6:37:27 AM10/24/12
to osg-...@lists.openscenegraph.org
Hi

> As you say, setting Uniforms requires a state change, while with an attribute the rendering is done at the GPU completely.

it is kind of same both ways... here you need glUniform* call, there you need to bind vertex attrib and call glVertexAttribPointer*
and rendering is done at the GPU completely no matter what way you choose.

Cheers.

Aurelien Albert

unread,
Oct 24, 2012, 7:15:07 AM10/24/12
to osg-...@lists.openscenegraph.org
Hi,

I think OpenGL specs doesn't allow to share a vertex attribute values between multiple vertices.

Aurelien

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=50753#50753

Jason Daly

unread,
Oct 24, 2012, 11:35:19 AM10/24/12
to osg-...@lists.openscenegraph.org
On 10/24/2012 05:28 AM, Daniel Schmid wrote:

 

Since the material code is unique within geometries, so actually I would need to transfer it only once per Geometry. If I change to BIND_OVERALL, the data is no longer transferred, or at least my shader cannot detect it anymore. I thought i should maybe reduce the VertexAttribArray (l_Array) to one single entry, but this doesn't work either.

 

What is the correct way of passing general or common data, on a per geometry (and not vertex) basis?


I don't think BIND_OVERALL is valid for generic attributes.  Sergey's right, use a Uniform.

--"J"

Tassilo Glander

unread,
Oct 24, 2012, 11:50:55 AM10/24/12
to osg-...@lists.openscenegraph.org
Hi,

sorry, I was wrong. It really seems the same in terms of state changes.

A use case for a BIND_OVERALL attribute is probably that you have different types of geometry with and without individual attributes (for example color) in your scene that you want to render using the same shader.

Thank you!

Cheers,
Tassilo

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=50759#50759

Tim Moore

unread,
Oct 24, 2012, 11:57:26 AM10/24/12
to OpenSceneGraph Users
On Wed, Oct 24, 2012 at 12:37 PM, Sergey Polischuk <pol...@yandex.ru> wrote:
> Hi
>
>> As you say, setting Uniforms requires a state change, while with an attribute the rendering is done at the GPU completely.
>
> it is kind of same both ways... here you need glUniform* call, there you need to bind vertex attrib and call glVertexAttribPointer*
> and rendering is done at the GPU completely no matter what way you choose.
>
Actually, OSG could use one of the glVertexAttrib calls without
binding anything. This is reputed to be a fast way to get "per object"
data to a vertex shader.

Tim

Jason Daly

unread,
Oct 24, 2012, 1:36:30 PM10/24/12
to osg-...@lists.openscenegraph.org
Scratch that, I'm wrong...

From the man page for glVertexAttrib:
"If a generic vertex attribute bound to an attribute variable in a vertex shader is not updated while the vertex shader is executing, the vertex shader will repeatedly use the current value for the generic vertex attribute."
So it seems that BIND_OVERALL should be working just fine.

--"J"
Reply all
Reply to author
Forward
0 new messages