root/OpenSceneGraph/trunk/examples/osgdrawinstanced/osgdrawinstanced.cpp @ 12529

Revision 12529, 5.7 kB (checked in by robert, 3 years ago)

Replaced .osg with .osgt file usage

  • Property svn:eol-style set to native
Line 
1/* OpenSceneGraph example, osgdrawinstanced.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18//
19// This code is copyright (c) 2008 Skew Matrix Software LLC. You may use
20// the code under the licensing terms described above.
21//
22
23#include <osgDB/ReadFile>
24#include <osgViewer/Viewer>
25#include <osg/Geometry>
26#include <osg/Texture2D>
27
28#include <osgDB/WriteFile>
29
30#include <iostream>
31
32void
33createDAIGeometry( osg::Geometry& geom, int nInstances=1 )
34{
35    const float halfDimX( .5 );
36    const float halfDimZ( .5 );
37
38    osg::Vec3Array* v = new osg::Vec3Array;
39    v->resize( 4 );
40    geom.setVertexArray( v );
41
42    // Geometry for a single quad.
43    (*v)[ 0 ] = osg::Vec3( -halfDimX, 0., -halfDimZ );
44    (*v)[ 1 ] = osg::Vec3( halfDimX, 0., -halfDimZ );
45    (*v)[ 2 ] = osg::Vec3( halfDimX, 0., halfDimZ );
46    (*v)[ 3 ] = osg::Vec3( -halfDimX, 0., halfDimZ );
47
48    // Use the DrawArraysInstanced PrimitiveSet and tell it to draw 1024 instances.
49    geom.addPrimitiveSet( new osg::DrawArrays( GL_QUADS, 0, 4, nInstances ) );
50}
51
52
53osg::StateSet*
54createStateSet()
55{
56    osg::ref_ptr< osg::StateSet > ss = new osg::StateSet;
57
58    // Create a vertex program that references the gl_InstanceID to
59    // render each instance uniquely. gl_InstanceID will be in the range
60    // 0 to numInstances-1 (1023 in our case).
61    std::string vertexSource =
62        "uniform sampler2D osgLogo; \n"
63        "uniform float osg_SimulationTime; \n"
64
65        "void main() \n"
66        "{ \n"
67            // Using the instance ID, generate "texture coords" for this instance.
68            "vec2 tC; \n"
69            "float r = float(gl_InstanceID) / 32.; \n"
70            "tC.s = fract( r ); tC.t = floor( r ) / 32.; \n"
71            // Get the color from the OSG logo.
72            "gl_FrontColor = texture2D( osgLogo, tC ); \n"
73
74            // Use the (scaled) tex coord to translate the position of the vertices.
75            "vec4 pos = vec4( tC.s * 48., 0., tC.t * 48., 1. ); \n"
76
77            // Compute a rotation angle from the instanceID and elapsed time.
78            "float timeOffset = gl_InstanceID / (32. * 32.); \n"
79            "float angle = ( osg_SimulationTime - timeOffset ) * 6.283; \n"
80            "float sa = sin( angle ); \n"
81            "float ca = cos( angle ); \n"
82            // New orientation, rotate around z axis.
83            "vec4 newX = vec4( ca, sa, 0., 0. ); \n"
84            "vec4 newY = vec4( sa, ca, 0., 0. ); \n"
85            "vec4 newZ = vec4( 0., 0., 1., 0. ); \n"
86            "mat4 mV = mat4( newX, newY, newZ, pos ); \n"
87            "gl_Position = ( gl_ModelViewProjectionMatrix * mV * gl_Vertex ); \n"
88        "} \n";
89
90    osg::ref_ptr< osg::Shader > vertexShader = new osg::Shader();
91    vertexShader->setType( osg::Shader::VERTEX );
92    vertexShader->setShaderSource( vertexSource );
93
94    osg::ref_ptr< osg::Program > program = new osg::Program();
95    program->addShader( vertexShader.get() );
96
97    ss->setAttribute( program.get(),
98        osg::StateAttribute::ON | osg::StateAttribute::PROTECTED );
99
100    osg::ref_ptr< osg::Image> iLogo = osgDB::readImageFile( "Images/osg128.png" );
101    if( !iLogo.valid() )
102    {
103        osg::notify( osg::ALWAYS ) << "Can't open image file osg128.png" << std::endl;
104        return( NULL );
105    }
106    osg::Texture2D* texLogo = new osg::Texture2D( iLogo.get() );
107    texLogo->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR );
108    texLogo->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR );
109
110    ss->setTextureAttribute( 0, texLogo );
111
112    osg::ref_ptr< osg::Uniform > texLogoUniform =
113        new osg::Uniform( "osgLogo", 0 );
114    ss->addUniform( texLogoUniform.get() );
115
116    return( ss.release() );
117}
118
119
120int main( int argc, char **argv )
121{
122    osg::ArgumentParser arguments(&argc, argv);
123
124   // Make a scene graph consisting of a single Geode, containing
125    // a single Geometry, and a single PrimitiveSet.
126    osg::ref_ptr< osg::Geode > geode = new osg::Geode;
127
128    osg::ref_ptr< osg::Geometry > geom = new osg::Geometry;
129    // Configure the Geometry for use with EXT_draw_arrays:
130    // DL off and buffer objects on.
131    geom->setUseDisplayList( false );
132    geom->setUseVertexBufferObjects( true );
133    // OSG has no clue where out vertex shader will place the geometric data,
134    // so specify an initial bound to allow proper culling and near/far computation.
135    osg::BoundingBox bb( -1., -.1, -1., 49., 1., 49. );
136    geom->setInitialBound( bb );
137    // Add geometric data and the PrimitiveSet. Specify numInstances as 32*32 or 1024.
138    createDAIGeometry( *geom, 32*32 );
139    geode->addDrawable( geom.get() );
140
141    // Create a StateSet to render the instanced Geometry.
142    osg::ref_ptr< osg::StateSet > ss = createStateSet();
143    geode->setStateSet( ss.get() );
144
145    // osgDB::writeNodeFile(*geode, "instanced.osgt");
146
147    osgViewer::Viewer viewer(arguments);
148    viewer.setSceneData( geode.get() );
149    return viewer.run();
150}
Note: See TracBrowser for help on using the browser.