天天看点

osg for android 学习之七:绘制基本的对象

1. 点

用一个球代替

osg::ShapeDrawable* sd = new osg::ShapeDrawable(new osg::Sphere( root->getBound().center(), 2));

osg::Geode* lightNode = new osg::Geode;

lightNode->addDrawable(sd);

lightNode->getOrCreateStateSet()->setTextureAttributeAndModes(0, new osg::Texture2D(osgDB::readImageFile("Images/land_shallow_topo_2048.jpg")));

root->addChild(lightNode);

纹理的使用如下:

我们使用StateSet类来控制几何基元的渲染状态。下面的代码演示了从文件中读取纹理,创建StateSet类并设置纹理,以及关联StateSet到场景节点的方法。代码的前一部分与上一章教程相同。首先我们初始化视窗并创建只有单一金字塔的场景。

int main()
{

   // 声明场景的根节点
   osg::Group* root = new osg::Group();
   osg::Geode* pyramidGeode = createPyramid();
   root->addChild(pyramidGeode);
      

现在我们添加纹理。我们定义一个纹理实例并设置其数据变更类型为“DYNAMIC”(否则的话,OSG的优化过程中可能会自动去除这个纹理)。纹理类封装了OpenGL纹理模式(GL_TEXTURE_WRAP,GL_TEXTURE_FILTER等),以及一个osg::Image对象。下面的代码将演示如何从文件读入osg::Image实例并将其关联到纹理。

osg::Texture2D* KLN89FaceTexture = new osg::Texture2D;

   //避免在优化过程中出错
   KLN89FaceTexture->setDataVariance(osg::Object::DYNAMIC); 

   // 从文件读取图片
   osg::Image* klnFace = osgDB::readImageFile("KLN89FaceB.tga");
   if (!klnFace)
   {
      std::cout << " couldn't find texture, quiting." << std::endl;
      return -1;
   }

   //  将图片关联到纹理
   KLN89FaceTexture->setImage(klnFace);
      

Texture类可以关联到渲染状态StateSet类。下一步我们将创建一个StateSet,将纹理关联到这个渲染状态实例并允许使用纹理,最后将StateSet关联到几何体节点上。

// 创建StateSet
   osg::StateSet* stateOne = new osg::StateSet();

   // 将纹理关联给StateSet的纹理单元0
   stateOne->setTextureAttributeAndModes
      (0,KLN89FaceTexture,osg::StateAttribute::ON);
   //  将渲染状态关联给金字塔节点
   pyramidGeode->setStateSet(stateOne);
      
osgViewer::Viewer viewer;

   //最后我们进入仿真循环:
   viewer.setSceneData( root );

   return viewer.run();
}      

2. 直线

画坐标轴:

osg::ref_ptr<osg::Geode> makeCoordinate()

{

//创建保存几何信息的对象

osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();

//创建四个顶点

osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array();

v->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));

v->push_back(osg::Vec3(1000.0f, 0.0f, 0.0f));

v->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));

v->push_back(osg::Vec3(0.0f, 1000.0f, 0.0f));

v->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));

v->push_back(osg::Vec3(0.0f, 0.0f, 1000.0f));

geom->setVertexArray(v.get());

//为每个顶点指定一种颜色

osg::ref_ptr<osg::Vec4Array> c = new osg::Vec4Array();

c->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); //坐标原点为红色

c->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); //x red

c->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); //坐标原点为绿色

c->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); //y green

c->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); //坐标原点为蓝色

c->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); //z blue

//如果没指定颜色则会变为黑色

geom->setColorArray(c.get());

geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX); 

//三个轴

geom->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, 2)); //X

geom->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::LINES, 2, 2)); //Y

geom->addPrimitiveSet( new osg::DrawArrays(osg::PrimitiveSet::LINES, 4, 2)); //Z

osg::ref_ptr<osg::Geode> geode = new osg::Geode();

geode->getOrCreateStateSet()->setMode(GL_LIGHTING, 

osg::StateAttribute::OFF);

geode->addDrawable(geom.get());

return geode;

}

3. 面

4. 其他

//创建精细度对象,精细度越高,细分就越多

osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;

//设置精细度为0.5f

hints->setDetailRatio(0.5f);

以下是转的

一,使用自己建立的几何形状

1,建立叶节点(Geode)

2建立几何体对象(Geometry)

3.顶点,颜色,法线并关联到Geometry

4.设置addPrimitiveSet也就是如何画这些点(想要的图形)

5.在叶节点中addDrawable(Geometry)

//几何体对象

osg::ref_ptr <osg::Geometry> geom( new osg::Geometry);

// Create an array of four vertices.

osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;

//顶点是三维陈列,顺序是逆时针方向

geom->setVertexArray( v.get() );

v->push_back( osg::Vec3( -1.f, 0.f, -1.f ) );//左下

v->push_back( osg::Vec3( 1.f, 0.f, -1.f ) );//右下

v->push_back( osg::Vec3( 1.f, 0.f, 1.f ) );//右上

v->push_back( osg::Vec3( -1.f, 0.f, 1.f ) );//左上

// Create an array of four colors.

osg::ref_ptr<osg::Vec4Array> c = new osg::Vec4Array;

geom->setColorArray( c.get() );

//颜色关联方式

//BIND_OFF     

//BIND_OVERALL     

//BIND_PER_PRIMITIVE_SET     

//BIND_PER_PRIMITIVE     

//BIND_PER_VERTEX 

geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX );

c->push_back( osg::Vec4( 1.f, 0.f, 0.f, 1.f ) );

c->push_back( osg::Vec4( 0.f, 1.f, 0.f, 1.f ) );

c->push_back( osg::Vec4( 0.f, 0.f, 1.f, 1.f ) );

c->push_back( osg::Vec4( 1.f, 1.f, 1.f, 1.f ) );

// Create an array for the single normal.

osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array;

geom->setNormalArray( n.get() );

geom->setNormalBinding( osg::Geometry::BIND_OVERALL );

//osg的坐标系为X向右,Y向里,Z向上

n->push_back( osg::Vec3( 0.f, -1.f, 0.f ) );

// Draw a four-vertex quad from the stored data.

//bool osg::Geometry::addPrimitiveSet  (  PrimitiveSet *  primitiveset )   

//PrimitiveSet (Type primType=PrimitiveType, GLenum mode=0)

enum  Type {

PrimitiveType, DrawArraysPrimitiveType, DrawArrayLengthsPrimitiveType, DrawElementsUBytePrimitiveType,

DrawElementsUShortPrimitiveType, DrawElementsUIntPrimitiveType

}

enum mode{

POINTS     //点

LINES     //两点两点一组

LINE_STRIP     //逐个点相联,不闭合

LINE_LOOP     //首尾闭合

TRIANGLES     //3个点一组,

TRIANGLE_STRIP     //每三个点一画,不闭合4个点画两个三角形

TRIANGLE_FAN     //同一平面上的图形闭合,不同平面上的只画一个?

QUADS     

QUAD_STRIP     

POLYGON //全包在一起

}

//DrawArrays (GLenum mode, GLint first, GLsizei count) 

画的模式,所用点的数量

geom->addPrimitiveSet(

new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) );

如果想要画一个四边形的框,

geom->addPrimitiveSet(

new osg::DrawArrays( osg::PrimitiveSet::LINES, 0, 2 ) );

new osg::DrawArrays( osg::PrimitiveSet::LINES, 1, 2 ) );

new osg::DrawArrays( osg::PrimitiveSet::LINES, 2, 2 ) );

//下面的命令会有错误,因为一共有4个点,但是现在要联接0和3, GL不支持的循环,

需要加上第5个点,也就是起始点。 

new osg::DrawArrays( osg::PrimitiveSet::LINES, 3, 2 ) );

// Add the Geometry (Drawable) to a Geode and

// return the Geode.返回叶节点

osg::ref_ptr geode = new osg::Geode;

geode->addDrawable( geom.get() );

return geode.get();

二. 使用osg中定义的一些图形

osg::ShapeDrawable* shape = new osg::ShapeDrawable(new osg::Capsule(osg::Vec3(0.f,0.f,0.f),radius, height), hints);

geode->addDrawable(shape);

ShapeDrawable (Shape *shape, TessellationHints *hints=0)

osg::Shape 包括的图形有:box, sphere, capsule, cylinder......

Box ()
Box (const osg::Vec3 &center, float width)
Box (const osg::Vec3 &center, float lengthX, float lengthY, float lengthZ)