OSG study notes - drawing of basic geometry (3-2)

3.2 Drawing of basic geometry

​ The examples in this section are mainly the drawing of basic graphics, such as line segments, triangles, circles and quadrilaterals.

​ We know that any complex thing is composed of some simple parts. The same is true for scenes and objects created by OSG. They have simple primitives (we call the components that make up 3D objects primitives) according to certain All primitives in OSG are one-dimensional or two-dimensional objects, including single points, straight lines and complex polygons.

3.2.1 Geometry class

​ osg::Geometry inherits from osg::Drawable. Its main function is to specify the number of vertices of the drawn geometry and analyze the data. It mainly provides the following three categories of methods:

(1) Specify vector data. A series of vector data such as vertex data, texture coordinates and colors can be realized through the following functions.

  • function illustrate
    void setVertexArray(Array* array) set vertex array
    void setVertexData(const ArrayData& arrayData) Set vertex array data
    void setVertexIndices(IndexArray* array) set vertex index array
    void setNormalArray(Array* array) Set the normal array
    void setNormalData(const ArrayData& arrayData) Set the normal array data
    void setNormalIndices(IndexArray* array) Set the normal index array
    void setColorArray(Array* array) Set the color array data
    void setColorData(const ArrayData& arrayData) Set the color array data
    void setColorIndices(IndexArray* array) set color index array
    void setTexCoordArray(unsigned int unit,Array*) Set texture coordinate data
    void setTexCoordData(unsigned int index,const ArrayData& arrayData) Set texture coordinate data
    void setTexCoordIndices(unsigned int unit,IndexArray*) Set texture coordinate data

(2) Set the binding method. There are two main data bindings, namely normal and color, which can be realized through the following two functions.

  • function illustrate
    void setNormalBinding(AttributeBinding ab) Set the normal binding method
    void setColorBinding(AttributeBinding ab) Set the color binding method

There are mainly the following binding methods:

  • macro name illustrate
    BIND_OFF Do not enable binding
    BIND_OVERALL Bind all top lines
    BIND_PER_PRIMITIVE_SET Single graphics primitive binding
    BIND_PER_PERMITIVE Single independent drawing primitive binding
    BIND_PER_VERTEX single vertex binding

(3) Data analysis. After specifying various vector data and binding methods, the method used to render the geometry is the most critical. In different ways, the rendered graphics are different. Even if the effect is the same, there may be differences in the number of faces or internal mechanisms. Data analysis is mainly specified by the following functions:

​ bool addPrimitiveSet(PrimitiveSet* primitiveSet);

​ // osg::PrimitiveSet is a virtual base class that cannot be initialized, so here it is mainly to call its subclasses to specify data rendering. The most commonly used is the osg::DrawArrays introduced earlier. The usage is relatively simple. Initialize an object instance. For parameter description, see the previous osg::DrawArray class

​ From the previous description, we can see that there are three main steps to draw and render geometry as follows:

(1) Create various vector data, such as vertices, texture coordinates, colors and normals, etc. It should be noted that when adding vertex data, it is mainly added in a counterclockwise order to ensure that the backface culling is correct.

(2) Instantiate a geometry object (osg::Geometry), set the vertex coordinate array, texture coordinate array, color array, normal array, binding method and data analysis.

(3) Add leaf nodes to draw and render .

3.2.2 Example of Basic Geometry Drawing

The basic geometry drawing (osg::Geometry) example demonstrates the process of creating a geometry, and the simplest quadrilateral is created in the example. Learn how to create simple geometry with this example.

#include<osgViewer/Viewer>
#include<osg/Node>
#include<osg/Group>
#include<osg/Geode>
#include<osgDB/ReadFile>
#include<osgDB/WriteFile>
#include<osgUtil/Optimizer>
// 创建一个四边形节点
osg::ref_ptr<osg::Node>createQuad()
{
    
    
	// 创建一个叶节点对象
	osg::ref_ptr<osg::Geode> geode = new osg::Geode();

    // 创建一个几何体对象
    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(1.0f,0.0f,0.0f));
    v->push_back(osg::Vec3(1.0f,0.0f,1.0f));
    v->push_back(osg::Vec3(0.0f,0.0f,1.0f));

    // 设置顶点数据
    geom->setVertexArray(v.get());

    // 创建纹理坐标
    osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array();
    vt->push_back(osg::Vec2(0.0f,0.0f));
    vt->push_back(osg::Vec2(1.0f,0.0f));
    vt->push_back(osg::Vec2(1.0f,1.0f));
    vt->push_back(osg::Vec2(0.0f,1.0f));

    // 设置纹理坐标
    geom->setTexCoordArray(vt);
    
    // 创建颜色数组
    osg::ref_ptr<osg::Vec4Array> vc = new osg::Vec4Array();
    vc->push_back(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
    vc->push_back(osg::Vec4(0.0f,1.0f,0.0f,1.0f));
    vc->push_back(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
    vc->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));

    // 设置颜色数组
    geom->setColorArray(vc.get());

    // 设置颜色的绑定方式为单个顶点
    geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

    // 创建法线数组
    osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array();
    nc->push_back(osg::Vec3(0.0f,-1.0f,0.0f));

    // 设置法线数组
    geom->setNormalArray(nc.get());
   
    // 设置法线的绑定方式为全部顶点
    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

    // 添加图元,绘制基元为四边形
    geom->addPrimitiveSet(new osg::DrawArray(osg::PrimitiveSet::QUADS,0,4));

    // 添加到叶节点
    geode->addDrawable(geom.get());

    return geode.get();
}
//----------------------------------------------------------------------------
int main()
{
    
    
    // 创建Viewer对象,场景浏览器
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
    osg::ref_ptr<osg::Group> root = new osg::Group();

    // 添加到场景
    root->addChild(CreateQuad());

    // 优化场景数据
    osgUtil::Optimizer optimizer;
    optimizer.optimize(root.get());

    viewer->setSceneData(root.get());

    viewer->realize();

    viewer->run();

    return 0;
}

3.2.3 Example of index bound geometry drawing

#include<osgViewer/Viewer>
#include<osg/Node>
#include<osg/Geode>
#include<osg/Group>
#include<osgDB/ReadFile>
#include<osgDB/WriteFile>
#include<osgUtil/Optimizer>
// 创建一个四边形节点
osg::ref_ptr<osg::Node> createQuad()
{
    
    
	// 创建一个叶节点对象
    osg::ref_ptr<osg::Geode> geode = new osg::Geode();
    
    // 创建一个几何体对象
    osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();
    
    // 创建顶点数组
    osg::ref_ptr<osg::Vec3Array> v = new osg:: vec3Array();
    
    // 添加数据
    v->push_back(osg::Vex3(0.0f,0.0f,0.0f));
    v->push_back(osg::Vex3(1.0f,0.0f,0.0f));
    v->push_back(osg::Vex3(1.0f,0.0f,1.0f));
    v->push_back(osg::Vex3(0.0f,0.0f,1.0f));
    v->push_back(osg::Vex3(0.0f,-1.0f,0.0f));
    
    // 设置顶点数据
    geom->setVertexArray(v.get());
    
    // 创建四边形顶点索引数组,指定绘图基元为四边形,注意添加顺序
    osg::ref_ptr<osg::DrawElementsUInt>quad = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS,0);
    
    // 添加数据
    quad->push_back(0);
    quad->push_back(1);
    quad->push_back(2);
    quad->push_back(3);
    
    // 添加到几何体
    geom->addPrimitiveSet(quad.get());
    
    // 创建三角形顶点索引数组,指定绘图基元为三角形,注意添加顺序
    osg::ref_ptr<osg::DrawElementUInt> triangle = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES,0);
    triangle->push_back(4);
    triangle->push_back(0);
    triangle->push_back(3);
    
    // 添加到几何体
    geom->addPrimitiveSet(triangle.get());
    
    // 创建颜色数组
    osg::ref_ptr<osg::Vec4Array> vc = new osg::Vec4Array();
    vc->push_back(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
    vc->push_back(osg::Vec4(0.0f,1.0f,0.0f,1.0f));
    vc->push_back(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
    vc->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
    
    // 创建颜色索引数组
    osg::TemplateIndexArray<unsigned int ,osg::Array::UIntArrayType,4,4>* colorIndex = new osg::TemplateIndexArray<unsigned int ,osg::Array::UIntArrayType,4,4>();
    // 添加数据,注意添加数组顺序与顶点一一对应
    colorIndex->push_back(0);
    colorIndex->push_back(1);
    colorIndex->push_back(2);
    colorIndex->push_back(3);
    colorIndex->push_back(2);
    
    // 设置颜色数组
    geom->setColorArray(vc.get());
   
    // 设置颜色索引数组
    geom->setColorIndices(colorIndex);
    
    // 设置颜色的绑定方式为单个顶点
    geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
    
    // 创建法线数组
    osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array();
    nc->push_back(osg::Vec3(0.0f,-1.0f,0.0f));
    
    // 设置法线数组
    geom->setNormalArray(nc.get());
    
    // 设置返现的绑定方式为全部顶点
    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
    
    // 添加到叶子节点
    geode->addDrawable(geom.get());
    
    return geode.get();
}
//--------------------------------------------------------------------------------------
int main()
{
    
    
    // 创建Viewer对象场景浏览器
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
    
    osg::ref_ptr<osg::Group> root = new osg::Group();
    root.addChild(createQuad());
    
    osgUtil::Optimizer optimizer;
    optimizer.optimize(root.get());
    
    viewer->setSceneData(root.get());
    viewer->realize();
    viewer->run();
    
    return 0;
}
    

Guess you like

Origin blog.csdn.net/liangfei868/article/details/123668974