eng_graph_draw.hh

Go to the documentation of this file.
00001 /*
00008  * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
00009  *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
00010  *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
00011  *****************************************************************************/
00012 
00013 #ifndef ENG_GRAPH_DRAW_HH
00014 #define ENG_GRAPH_DRAW_HH 1
00015 
00016 // Because of how the dot product formula used for polygon culling,
00017 // normal vectors no longer should be transformed.
00018 #define COMPILE_RETRANSFORM_NORMALS 0
00019 
00020 #include "eng_node.hh"
00021 #include "eng_node_visitor.hh"
00022 #include "eng_graph.hh"
00023 
00024 namespace eng {
00025 
00029 class VisitorDraw : public Visitor
00030 {
00031 private:
00032 #define VISITOR_DRAW_SPECIAL_NODE(CLASS)                                    \
00033                 CLASS( void ) : SpecialNode() { }                           \
00034                 CLASS( const CLASS& src ) : SpecialNode(src) { }            \
00035                 ~CLASS() { }                                                \
00036     /* Cast is critical to select proper Visit() of derived class. */       \
00037     void        Accept( Visitor& visitor )                                  \
00038     {                                                                       \
00039          static_cast<VisitorDraw&>(visitor).Visit( *this );                 \
00040     }                                                                       \
00041     Node::Ptr   Clone( void ) const { return new CLASS( *this ); }
00042 
00043 private:
00049     class PopMatrixNode : public SpecialNode
00050     {
00051     public:
00052         VISITOR_DRAW_SPECIAL_NODE(PopMatrixNode)
00053     };
00054 
00055 public:
00056     VisitorDraw( Graph& graph, SharedPtr<Object> object );
00057     ~VisitorDraw( void );
00058 
00059     // Regular nodes:
00060     void    Visit( TransformNode& node );
00061     void    Visit( VertexsNode& node );
00062     void    Visit( NormalsNode& node );
00063     void    Visit( ModesNode& node );
00064     void    Visit( MaterialNode& node );
00065     void    Visit( TextureNode& node );
00066     void    Visit( ColorsNode& node );
00067     void    Visit( PolygonNode& node );
00068     void    Visit( PolygonNode_TriColor1& node );
00069     void    Visit( PolygonNode_TriColor3& node );
00070     void    Visit( PolygonNode_QuadColor1& node );
00071     void    Visit( PolygonNode_QuadColor4& node );
00072     void    Visit( PolygonNode_Tex& node );
00073     void    Visit( PolygonNode_TexTriColor1& node );
00074     void    Visit( PolygonNode_TexTriColor3& node );
00075     void    Visit( PolygonNode_TexQuadColor1& node );
00076     void    Visit( PolygonNode_TexQuadColor4& node );
00077 
00078     // Special nodes:
00079     void    Visit( SpecialNode& node ) { ASSERT(false); }
00080     void    Visit( PopMatrixNode& node );
00081 
00082     void    Begin( GraphTraversal::Ptr traversal );
00083     void    End( void );
00084 
00085 private:
00086     void        ComputeEyeMatrix( void );
00087     void        ComputeNormals( NormalsNode& normalsNode );
00088 #if COMPILE_RETRANSFORM_NORMALS
00089     void        TransformNormals( NormalsNode& normalsNode );
00090 #endif
00091 #if DEBUG
00092     void        DRAW_POLYGON_NODE_CHECKS( PolygonNode& node );
00093     void        DRAW_POLYGON_NODE_TEX_CHECKS( PolygonNode_Tex& node );
00094 #endif
00095 
00096     enum ePolygonType
00097     {
00098         ePolygonType_NONE,
00099         ePolygonType_TRIANGLES,
00100         ePolygonType_QUADS
00101     };
00102 
00103     void BeginTriangle( void )
00104     {
00105         if ( UX( mPolygonType != ePolygonType_TRIANGLES ) )
00106         {
00107             if ( EX( mPolygonType != ePolygonType_NONE ) )  // end previous primitive
00108                 GFX::End();
00109             GFX::Begin( GFX::ePrim_TRIANGLES );
00110             mPolygonType = ePolygonType_TRIANGLES;  // after the if
00111         }
00112     }
00113 
00114     void BeginQuad( void )
00115     {
00116         if ( UX( mPolygonType != ePolygonType_QUADS ) )
00117         {
00118             if ( EX( mPolygonType != ePolygonType_NONE ) )  // end previous primitive
00119                 GFX::End();
00120             GFX::Begin( GFX::ePrim_QUADS );
00121             mPolygonType = ePolygonType_QUADS;  // after the if
00122         }
00123     }
00124 
00125 
00126     // EndTriangle()/EndQuad() vs. EndDrawing():
00127     // The purpose of EndDrawing() is to unconditionally stop drawing polygons.
00128     // The purpose of EndTriangle()/EndQuad() is to logically mark the end of a primitive
00129     // (in fact, the drawing mode is left enabled for speed).
00130 
00131     void EndTriangle( void )
00132     {
00133         // NOP
00134     }
00135 
00136     void EndQuad( void )
00137     {
00138         // NOP
00139     }
00140 
00141     void EndDrawing( void )
00142     {
00143         if ( mPolygonType != ePolygonType_NONE )
00144         {
00145             mPolygonType = ePolygonType_NONE;
00146             GFX::End();
00147         }
00148     }
00149 
00150 private:
00151     SharedPtr<Object>               mObject;
00152     GraphTraversal::Ptr         mTraversal;         
00153     Matrix                      mMatrix;            
00154     Matrix                      mMatrixEye;         
00155     const Matrix                mMatrixView;        
00156     Stack<Matrix>               mMatrixStack;
00157     SharedPtr0<const LocalVertexs>  mLocalVertexs;
00158     EyeVertexs                  mEyeVertexs;        
00159     shptr0<NormalVertexs>       mPolygonNormals;    
00160     shptr0<NormalVertexs>       mVertexNormals;     
00161     ModesNode::Modes            mModes;             
00162     bool                        mLighting;          
00163     shptr<Texture>              mTexture;           
00164     bool                        mRestoreTextureMatrix;  
00165     fp                          mSavedTextureMatrix[16];
00166     ColorsNode::Colors          mColors;            
00167     ePolygonType                mPolygonType;       
00168 #if DEBUG
00169     bool                        mDone;              
00170 #endif
00171 };
00172 
00176 class VisitorComputeNormals : public Visitor
00177 {
00178 public:
00179             VisitorComputeNormals( Graph& graph, NormalsNode& normalsNode, const LocalVertexs& localVertexs );
00180             ~VisitorComputeNormals();
00181     void    Begin( void ) { }
00182     void    End( void );
00183 
00184 private:
00196     template<typename VIXS>
00197     void ComputeAndTotalNormal( const Nix nix, const VIXS& vixs )
00198     {
00199         // Compute normal vector on this polygon.
00200         const Vector3 crossProduct = CrossProduct( mLocalVertexs[vixs[0]],  // 0,2,1
00201                                                    mLocalVertexs[vixs[2]],
00202                                                    mLocalVertexs[vixs[1]] );
00203         const NormalVertex polygonNormal = NormalVertex( Normalize( crossProduct ) );
00204         Expand( mPolygonNormals, nix );        // resize, polygon cnt is unknown so it wasn't pre-resized
00205         mPolygonNormals[nix] = polygonNormal;  // ref to NormalsNode::mPolygonNormals
00206 
00207         // For the first step of averaging normal vectors, add this vector to a total.
00208         // Later, Visitor will normalize the totals.
00209         for ( uint i = 0; i < vixs.size(); ++i )  // compile should unroll since TinyArray::size() is a constant
00210         {
00211         ASSERT( vixs[i] < mVertexNormals.size() );  // should be pre-resized since vertex cnt is known
00212             mVertexNormals[vixs[i]] += polygonNormal;
00213         }
00214     }
00215 
00216 private:
00217     // One suffices since variants of Visitor::Visit(PolygonNode&) default to calling the base Visit().
00218     void    Visit( PolygonNode& node ) { ComputeAndTotalNormal( node.GetNix(), node.GetVixs() ); }
00219 
00220 private:
00221     // Normal vectors exist and remain in Normal Space.
00222     // TransformNormals(), despite its name, really rotates normals within Normal Space.
00223     const LocalVertexs&     mLocalVertexs;      // ref to VertexsNode::mLocalVertexs
00224     NormalVertexs&          mPolygonNormals;    // ref to NormalsNode::mPolygonNormals
00225     NormalVertexs&          mVertexNormals;     // ref to NormalsNode::mVertexNormals
00226 };
00227 
00228 } // namespace eng
00229 
00230 #endif // ENG_GRAPH_DRAW_HH
Palomino 3D Engine documents generated by doxygen 1.5.3 on Fri Nov 23 11:26:08 2007