From Paul Martz, example demonstating new draw instanced primitive funcitonality.
This commit is contained in:
@@ -32,6 +32,7 @@ IF(DYNAMIC_OPENSCENEGRAPH)
|
||||
ADD_SUBDIRECTORY(osgdelaunay)
|
||||
ADD_SUBDIRECTORY(osgdepthpartition)
|
||||
ADD_SUBDIRECTORY(osgdepthpeeling)
|
||||
ADD_SUBDIRECTORY(osgdrawinstanced)
|
||||
ADD_SUBDIRECTORY(osgdistortion)
|
||||
ADD_SUBDIRECTORY(osgfadetext)
|
||||
ADD_SUBDIRECTORY(osgfont)
|
||||
|
||||
4
examples/osgdrawinstanced/CMakeLists.txt
Normal file
4
examples/osgdrawinstanced/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
SET(TARGET_SRC osgdrawinstanced.cpp )
|
||||
|
||||
#### end var setup ###
|
||||
SETUP_EXAMPLE(osgdrawinstanced)
|
||||
148
examples/osgdrawinstanced/osgdrawinstanced.cpp
Normal file
148
examples/osgdrawinstanced/osgdrawinstanced.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/* OpenSceneGraph example, osgdrawinstanced.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
//
|
||||
// This code is copyright (c) 2008 Skew Matrix Software LLC. You may use
|
||||
// the code under the licensing terms described above.
|
||||
//
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Texture2D>
|
||||
|
||||
#include <osgDB/WriteFile>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void
|
||||
createDAIGeometry( osg::Geometry& geom, int nInstances=1 )
|
||||
{
|
||||
const float halfDimX( .5 );
|
||||
const float halfDimZ( .5 );
|
||||
|
||||
osg::Vec3Array* v = new osg::Vec3Array;
|
||||
v->resize( 4 );
|
||||
geom.setVertexArray( v );
|
||||
|
||||
// Geometry for a single quad.
|
||||
(*v)[ 0 ] = osg::Vec3( -halfDimX, 0., -halfDimZ );
|
||||
(*v)[ 1 ] = osg::Vec3( halfDimX, 0., -halfDimZ );
|
||||
(*v)[ 2 ] = osg::Vec3( halfDimX, 0., halfDimZ );
|
||||
(*v)[ 3 ] = osg::Vec3( -halfDimX, 0., halfDimZ );
|
||||
|
||||
// Use the DrawArraysInstanced PrimitiveSet and tell it to draw 1024 instances.
|
||||
geom.addPrimitiveSet( new osg::DrawArrays( GL_QUADS, 0, 4, nInstances ) );
|
||||
}
|
||||
|
||||
|
||||
osg::StateSet*
|
||||
createStateSet()
|
||||
{
|
||||
osg::ref_ptr< osg::StateSet > ss = new osg::StateSet;
|
||||
|
||||
// Create a vertex program that references the gl_InstanceID to
|
||||
// render each instance uniquely. gl_InstanceID will be in the range
|
||||
// 0 to numInstances-1 (1023 in our case).
|
||||
std::string vertexSource =
|
||||
"uniform sampler2D osgLogo; \n"
|
||||
"uniform float osg_SimulationTime; \n"
|
||||
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
// Using the instance ID, generate "texture coords" for this instance.
|
||||
"vec2 tC; \n"
|
||||
"const float r = 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"
|
||||
|
||||
// Use the (scaled) tex coord to translate the position of the vertices.
|
||||
"vec4 pos = vec4( tC.s * 48., 0., tC.t * 48., 1. ); \n"
|
||||
|
||||
// Compute a rotation angle from the instanceID and elapsed time.
|
||||
"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"
|
||||
// New orientation, rotate around z axis.
|
||||
"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"
|
||||
"gl_Position = ( gl_ModelViewProjectionMatrix * mV * gl_Vertex ); \n"
|
||||
"} \n";
|
||||
|
||||
osg::ref_ptr< osg::Shader > vertexShader = new osg::Shader();
|
||||
vertexShader->setType( osg::Shader::VERTEX );
|
||||
vertexShader->setShaderSource( vertexSource );
|
||||
|
||||
osg::ref_ptr< osg::Program > program = new osg::Program();
|
||||
program->addShader( vertexShader.get() );
|
||||
|
||||
ss->setAttribute( program.get(),
|
||||
osg::StateAttribute::ON | osg::StateAttribute::PROTECTED );
|
||||
|
||||
osg::ref_ptr< osg::Image> iLogo = osgDB::readImageFile( "Images/osg128.png" );
|
||||
if( !iLogo.valid() )
|
||||
{
|
||||
osg::notify( osg::ALWAYS ) << "Can't open image file osg128.png" << std::endl;
|
||||
return( NULL );
|
||||
}
|
||||
osg::Texture2D* texLogo = new osg::Texture2D( iLogo );
|
||||
texLogo->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR );
|
||||
texLogo->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR );
|
||||
|
||||
ss->setTextureAttribute( 0, texLogo );
|
||||
|
||||
osg::ref_ptr< osg::Uniform > texLogoUniform =
|
||||
new osg::Uniform( "osgLogo", 0 );
|
||||
ss->addUniform( texLogoUniform.get() );
|
||||
|
||||
return( ss.release() );
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
// Make a scene graph consisting of a single Geode, containing
|
||||
// a single Geometry, and a single PrimitiveSet.
|
||||
osg::ref_ptr< osg::Geode > geode = new osg::Geode;
|
||||
|
||||
osg::ref_ptr< osg::Geometry > geom = new osg::Geometry;
|
||||
// Configure the Geometry for use with EXT_draw_arrays:
|
||||
// DL off and buffer objects on.
|
||||
geom->setUseDisplayList( false );
|
||||
geom->setUseVertexBufferObjects( true );
|
||||
// OSG has no clue where out vertex shader will place the geometric data,
|
||||
// so specify an initial bound to allow proper culling and near/far computation.
|
||||
osg::BoundingBox bb( -1., -.1, -1., 49., 1., 49. );
|
||||
geom->setInitialBound( bb );
|
||||
// Add geometric data and the PrimitiveSet. Specify numInstances as 32*32 or 1024.
|
||||
createDAIGeometry( *geom, 32*32 );
|
||||
geode->addDrawable( geom );
|
||||
|
||||
// Create a StateSet to render the instanced Geometry.
|
||||
osg::ref_ptr< osg::StateSet > ss = createStateSet();
|
||||
geode->setStateSet( ss.get() );
|
||||
|
||||
// osgDB::writeNodeFile(*geode, "instanced.osg");
|
||||
|
||||
osgViewer::Viewer viewer;
|
||||
viewer.setSceneData( geode.get() );
|
||||
return viewer.run();
|
||||
}
|
||||
Reference in New Issue
Block a user