Void sceneview: updateuniforms ()
{
If (! _ Localstateset)
{
_ Localstateset = new OSG: stateset;
}
If (! _ Localstateset) return;
If (_ activeuniforms & frame_number_uniform) & _ framestamp. Valid ())
{
OSG: Uniform * uniform = _ localstateset-> getorcreateuniform ("osg_framenumber", OSG: Uniform: INT );
Uniform-> set (_ framestamp-> getframenumber ());
}
If (_ activeuniforms & frame_time_uniform) & _ framestamp. Valid ())
{
OSG: Uniform * uniform = _ localstateset-> getorcreateuniform ("osg_frametime", OSG: Uniform: Float );
Uniform-> set (static_cast <float> (_ framestamp-> getreferencetime ()));
}
If (_ activeuniforms & delta_frame_time_uniform) & _ framestamp. Valid ())
{
Float delta_frame_time = (_ previusframetime! = 0.0 )? Static_cast <float> (_ framestamp-> getreferencetime ()-_ previusframetime): 0.0f;
_ Previusframetime = _ framestamp-> getreferencetime ();
OSG: Uniform * uniform = _ localstateset-> getorcreateuniform ("osg_deltaframetime", OSG: Uniform: Float );
Uniform-> set (delta_frame_time );
}
If (_ activeuniforms & simulation_time_uniform) & _ framestamp. Valid ())
{
OSG: Uniform * uniform = _ localstateset-> getorcreateuniform ("osg_simulationtime", OSG: Uniform: Float );
Uniform-> set (static_cast <float> (_ framestamp-> getsimulationtime ()));
}
If (_ activeuniforms & delta_simulation_time_uniform) & _ framestamp. Valid ())
{
Float delta_simulation_time = (_ previussimulationtime! = 0.0 )? Static_cast <float> (_ framestamp-> getsimulationtime ()-_ previoussimulationtime): 0.0f;
_ Previussimulationtime = _ framestamp-> getsimulationtime ();
OSG: Uniform * uniform = _ localstateset-> getorcreateuniform ("osg_deltasimulationtime", OSG: Uniform: Float );
Uniform-> set (delta_simulation_time );
}
If (_ activeuniforms & view_matrix_uniform) // use uniform to pass the browser matrix to the shader.
{
OSG: Uniform * uniform = _ localstateset-> getorcreateuniform ("osg_viewmatrix", OSG: Uniform: float_mat4 );
Uniform-> set (getviewmatrix ());
}
If (_ activeuniforms & view_matrix_inverse_uniform)
{
OSG: Uniform * uniform = _ localstateset-> getorcreateuniform ("osg_viewmatrixinverse", OSG: Uniform: float_mat4 );
Uniform-> set (OSG: matrix: inverse (getviewmatrix ()));
}
}
//------------------
Void cullvisitor: Apply (Transform & node )//
{
If (isculled (node) return;
// Push the culling mode.
Pushcurrentmask ();
// Push the node's state.
Stateset * node_state = node. getstateset ();
If (node_state) pushstateset (node_state );
Ref_ptr <refmatrix> matrix = createorreusematrix (* getmodelviewmatrix ());
Node. computelocaltoworldmatrix (* matrix, this); // convert matrix to world coordinates, Model View matrix, and local Matrix
Pushmodelviewmatrix (matrix. Get (), node. getreferenceframe ());
Handle_cull_callbacks_and_traverse (node );
Popmodelviewmatrix ();
// Pop the node's state off the render graph stack.
If (node_state) popstateset ();
// Pop the culling mode.
Popcurrentmask ();
}
Void cullvisitor: Apply (geode & node)
{
If (isculled (node) return;
// Push the node's state.
Stateset * node_state = node. getstateset ();
If (node_state) pushstateset (node_state );
// Traverse any call callbacks and traverse any children.
Handle_cull_callbacks_and_traverse (node );
Refmatrix & matrix = * getmodelviewmatrix (); // obtain the current local coordinate matrix and view matrix.
For (unsigned int I = 0; I <node. getnumdrawables (); ++ I)
{
Drawable * drawable = node. getdrawable (I );
Const boundingbox & BB = drawable-> getbound ();
If (drawable-> getcullcallback ()
{< br> If (drawable-> getcullcallback ()-> cull (this, drawable, & _ renderinfo) = true)
continue;
}< br>
// else
{< br> If (node. iscullingactive () & isculled (bb) continue;
}
If (_ computenearfar & BB. Valid ())
{
If (! Updatecalculatednearfar (matrix, * drawable, false) continue;
}
// Need to track how push/POPS There are, so we can unravel the stack correctly.
Unsigned int numpopstatesetrequired = 0;
// Push the geoset's state on the geostate stack.
Stateset * stateset = drawable-> getstateset ();
If (stateset)
{
++ Numpopstatesetrequired;
Pushstateset (stateset );
}
Cullingset & cs = getcurrentcullingset ();
If (! CS. getstatefrustumlist (). Empty ())
{
OSG: cullingset: statefrustumlist & SFL = cs. getstatefrustumlist ();
For (OSG: cullingset: statefrustumlist: iterator itr = SFL. Begin ();
Itr! = SFL. End ();
++ Itr)
{
If (itr-> second. Contains (bb ))
{
++ Numpopstatesetrequired;
Pushstateset (itr-> first. Get ());
}
}
}
Float depth = BB. Valid ()? Distance (BB. Center (), matrix): 0.0f;
If (OSG: isnan (depth ))
{
OSG: Notify (OSG: Notice) <"cullvisitor: Apply (geode &) detected Nan," <STD: Endl
<"Depth =" <depth <", center = (" <BB. Center () <")," <STD: Endl
<"Matrix =" <matrix <STD: Endl;
}
Else
{
Adddrawableanddepth (drawable, & matrix, depth); // input the Matrix
}
For (unsigned int I = 0; I <numpopstatesetrequired; ++ I)
{
Popstateset ();
}
}
// Pop the node's state off the geostate stack.
If (node_state) popstateset ();
}
Inline void cullvisitor: adddrawableanddepth (OSG: drawable * drawable, OSG: refmatrix * matrix, float depth)
{
If (_ currentstategraph-> leaves_empty ())
{
// This is first leaf to be added to stategraph
// And therefore shocould not already know to current render bin,
// So need to add it.
_ Currentrenderbin-> addstategraph (_ currentstategraph );
}
// _ Currentstategraph-> addleaf (New renderleaf (drawable, matrix, depth ));
_ Currentstategraph-> addleaf (createorreuserenderleaf (drawable, _ projectionstack. Back (). Get (), matrix, depth); // generate the rendering leaf
}
inline renderleaf * cullvisitor: createorreuserenderleaf (OSG: drawable * drawable, OSG: refmatrix * Projection, OSG: refmatrix * matrix, float depth)
{< br> // skips any already reused renderleaf.
while (_ currentreuserenderleafindex <_ reuserenderleaflist. size () &
_ reuserenderleaflist [_ currentreuserenderleafindex]-> referencecount ()> 1)
{< br> OSG: Policy (OSG: notice) <"Warning: createorreuserenderleaf () skipping multiply refrenced entry. " ++ _ currentreuserenderleafindex;
}
// If still within list, element must be singularly referenced then return it to be reused.
If (_ currentreuserenderleafindex <_ reuserenderleaflist. Size ())
{
Renderleaf * renderleaf = _ reuserenderleaflist [_ currentreuserenderleafindex ++]. Get ();
Renderleaf-> set (drawable, projection, matrix, depth );
Return renderleaf;
}
// Otherwise need to create new renderleaf.
Renderleaf * renderleaf = new renderleaf (drawable, projection, matrix, depth); // matrix passed to the rendering leaf
_ Reuserenderleaflist. push_back (renderleaf );
++ _ Currentreuserenderleafindex;
Return renderleaf;
}
}
Void renderleaf: render (OSG: renderinfo & renderinfo, renderleaf * Previous)
{
OSG: State & State = * renderinfo. getstate ();
// Don't draw this leaf if the abort rendering flag has been set.
If (State. getabortrendering ())
{
// Cout <"Early abort" <Endl;
Return;
}
If (previous)
{
// Apply matrices if required.
State. applyprojectionmatrix (_ projection. Get ());
State. applymodelviewmatrix (_ modelview. Get ());
// Apply state if required.
Stategraph * prev_rg = previous-> _ parent;
Stategraph * prev_rg_parent = prev_rg-> _ parent;
Stategraph * Rg = _ parent;
If (prev_rg_parent! = Rg-> _ parent)
{
Stategraph: movestategraph (State, prev_rg_parent, RG-> _ parent );
// Send state changes and matrix changes to OpenGL.
State. Apply (rg-> getstateset ());
}
Else if (RG! = Prev_rg)
{
// Send state changes and matrix changes to OpenGL.
State. Apply (rg-> getstateset ());
}
// Draw the drawable
_ Drawable-> draw (renderinfo );
}
Else
{
// Apply matrices if required.
State. applyprojectionmatrix (_ projection. Get (); // applies the Model View matrix.
State. applymodelviewmatrix (_ modelview. Get ());
// Apply state if required.
Stategraph: movestategraph (State, null, _ parent-> _ parent );
State. Apply (_ parent-> getstateset ());
// Draw the drawable
_ Drawable-> draw (renderinfo );
}
If (_ dynamic)
{
State. decrementdynamicobjectcount ();
}
// OSG: Notify (OSG: Notice) <"renderleaf" <_ drawable-> getname () <"<_ depth <STD :: endl;
}