osg图元绑定方式总结

osg中图元绑定方式主要有下面几种:

/*取消绑定。此时,颜色数据或者法线数据与顶点数据完全没有关系,顶点数据的颜色和法线方向完全由缺省值决
  定。
*/
BIND_OFF


/*绑定全部几何体。此时,颜色数组或者法线坐标数组中只需要保存一个数据,该数据将影响此Geometry类的所 
  有几何体顶点坐标。例如,将红色绑定到全部几何体上,则这个类绘制出的所有物体均是红色的。
 */
BIND_OVERALL


/*绑定逐个几何体。此时,颜色数组或者法线坐标数组中保存的数据数量应当与用户将要绘制的几何体数量相同。例如,用户依据8个顶点来绘制2个四边形时,可以分别为它们设置2组法线坐标,每组法线坐标对应1个四边形,并使用此参数进行绑定。
*/
BIND_PER_PRIMITIVE


/*绑定逐个点。逐点绑定,将4个颜色数据分别绑定到4个顶点坐标,顶点和顶点之间的颜色
  通过线性插值,实现过渡效果。
*/
 BIND_PER_VERTEX

如下代码:(摘自osg自带的例子,源码在osg源码目录下examples\osganimate\osganimate.cpp,读者可以运行osg的这个例子试试)

osg::Node* createBase(const osg::Vec3& center, float radius)
{
	int numTilesX = 10;
	int numTilesY = 10;

	float width = 2 * radius;
	float height = 2 * radius;

	osg::Vec3 v000(center - osg::Vec3(width*0.5f, height*0.5f, 0.0f));
	osg::Vec3 dx(osg::Vec3(width / ((float)numTilesX), 0.0, 0.0f));
	osg::Vec3 dy(osg::Vec3(0.0f, height / ((float)numTilesY), 0.0f));

	// fill in vertices for grid, note numTilesX+1 * numTilesY+1...
	osg::Vec3Array* coords = new osg::Vec3Array;
	int iy;
	for (iy = 0; iy <= numTilesY; ++iy)
	{
		for (int ix = 0; ix <= numTilesX; ++ix)
		{
			coords->push_back(v000 + dx * (float)ix + dy * (float)iy);
		}
	}

	//Just two colours - black and white.
	osg::Vec4Array* colors = new osg::Vec4Array;
	colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); // white
	colors->push_back(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); // black

	osg::ref_ptr whitePrimitives = new osg::DrawElementsUShort(GL_QUADS);
	osg::ref_ptr blackPrimitives = new osg::DrawElementsUShort(GL_QUADS);

	int numIndicesPerRow = numTilesX + 1;
	for (iy = 0; iy < numTilesY; ++iy)
	{
		for (int ix = 0; ix < numTilesX; ++ix)
		{
			osg::DrawElementsUShort* primitives = ((iy + ix) % 2 == 0) ? whitePrimitives.get() : blackPrimitives.get();
			int a = ix + (iy + 1)*numIndicesPerRow;
			int b = ix + iy * numIndicesPerRow;
			int c = (ix + 1) + iy * numIndicesPerRow;
			int d = (ix + 1) + (iy + 1)*numIndicesPerRow;
			primitives->push_back(ix + (iy + 1)*numIndicesPerRow);
			primitives->push_back(ix + iy * numIndicesPerRow);
			primitives->push_back((ix + 1) + iy * numIndicesPerRow);
			primitives->push_back((ix + 1) + (iy + 1)*numIndicesPerRow);
		}
	}

	// set up a single normal
	osg::Vec3Array* normals = new osg::Vec3Array;
	normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));

	osg::Geometry* geom = new osg::Geometry;
	geom->setVertexArray(coords);

	geom->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET);

	geom->setNormalArray(normals, osg::Array::BIND_OVERALL);

	geom->addPrimitiveSet(whitePrimitives.get());
	geom->addPrimitiveSet(blackPrimitives.get());

	osg::Geode* geode = new osg::Geode;
	geode->addDrawable(geom);

	return geode;
}

其中

geom->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET);

就是逐个绑定几何体。此时,颜色数组或者法线坐标数组中保存的数据数量应当与用户将要绘制的几何体数量相同。例如:上面绘制了黑色和白色相间的棋盘格,即白色四边形和黑色四边形,因为有两种四边形,即两种几何体,当采用osg::Array::BIND_PER_PRIMITIVE_SET时,颜色至少也要两种,例如上面的代码有下面两句就说明了要两种颜色:

    osg::Vec4Array* colors = new osg::Vec4Array;
    colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); // white
    colors->push_back(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); // black

此时运行的结果如下:

osg图元绑定方式总结_第1张图片

如果将上面的颜色绑定方式改为如下:

	geom->setColorArray(colors, osg::Array::BIND_OVERALL);

即使颜色数组有两组,但还是将所有几何体(本例指黑色和白色的棋盘格) 的颜色都绑定到颜色数组的第一组,此时效果如下:

osg图元绑定方式总结_第2张图片

在osg自带的例子examples\osganimationnode中的createAxis()函数中有 osg::Array::BIND_PER_VERTEX用法,可以运行该例子看看效果。

你可能感兴趣的:(osg技术点,osg图元绑定方式总结)