osgdrawinstanced例子

来源:互联网 发布:js系统方法描述错误 编辑:程序博客网 时间:2024/05/16 00:26
该例子属于效果方面的,用的了shader,接下来我们仔细的研究一下。
如果要变换geometry一定要 geom->setUseDisplayList( false );
    geom-
>setUseVertexBufferObjects( true );用定点缓冲对象。
 osg::BoundingBox bb( -1., -.1, -1., 49., 1., 49. );
    geom->setInitialBound( bb );
为计算远近平面指定一个包围体。
最主要的工作都在createStateSet这个函数中。
在这个函数中定义了一个二维纹理,
ss->setAttribute( program.get(),
        osg::StateAttribute::ON | 
osg::StateAttribute::PROTECTED );
设置状态集中有一个osg::StateAttribute::PROTECTED,把当前节点的状态保护起来,不受父节
点的影响。接下来我们详细的看看这个定点着色器。
首先先了解一下opengl的实例化绘制,看看
http://www.cnblogs.com/jamesclarke/archive/2009/07/08/1519462.html
http://book.51cto.com/art/201002/185467.htm链接。
我们接着看看例子,createDAIGeometry( *geom, 32*32 );这里指定了实例个数32*32个,这就意
味着DrawArrays这个函数会调用32*32次,接下来看shader程序。
"uniform sampler2D osgLogo; \n"
定义了一个二维纹理采样器
"uniform float osg_SimulationTime; \n"
osg中定义的属性,仿真时间
gl_InstanceID这个就是实例的次数值,同一个图元这个值在0-32*32-1次循环。
因此,这个定点着色器是这样的,每一帧绘制32*32次,也就是把这一个四边形分成了32*32块,
每一帧绘制32*32个快,
 "vec2 tC; \n"
            "float r = float(gl_InstanceID) / 32.; \n"
           
"tC.s = fract( r ); tC.t = floor( r ) / 32.; \n"
            // Get the color from 
the OSG logo.
            "gl_FrontColor = texture2D( osgLogo, tC ); \n"
以上代码计算了在这个纹理中所取的纹理坐标。
"vec4 pos = vec4( tC.s * 48., 0., tC.t * 48., 1. ); \n"
重新的计算了这点的位置绘制32*32块,每一块就在各自的位置绘制
"float timeOffset = gl_InstanceID / (32. * 32.); \n"
            "float angle = ( 
osg_SimulationTime - timeOffset ) * 6.283; \n"
            "float sa = sin( angle ); 
\n"
            "float ca = cos( angle ); \n"
根据osg的仿真时间计算了每一块的旋转
 "vec4 newX = vec4( ca, sa, 0., 0. ); \n"
            "vec4 newY = vec4( sa, ca, 0., 


0. ); \n"
            "vec4 newZ = vec4( 0., 0., 1., 0. ); \n"
            "mat4 mV = 
mat4( newX, newY, newZ, pos ); \n"
定义了一个矩阵,我们来分析一下这个矩阵,看前三个向量,很明显是一个绕着z轴旋转,最后
一个向量很明显是位移,这个矩阵就定义了这次绘制点的位置,
这样绘制32*32次,就出现了例子中的效果。