Panda3D
 All Classes Functions Variables Enumerations
pipeOcclusionCullTraverser.h
00001 // Filename: pipeOcclusionCullTraverser.h
00002 // Created by:  drose (29May07)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef PIPEOCCLUSIONCULLTRAVERSER_H
00016 #define PIPEOCCLUSIONCULLTRAVERSER_H
00017 
00018 #include "pandabase.h"
00019 #include "cullTraverser.h"
00020 #include "graphicsOutput.h"
00021 #include "displayRegion.h"
00022 #include "cullHandler.h"
00023 #include "texture.h"
00024 
00025 class GraphicsEngine;
00026 class GraphicsPipe;
00027 class GraphicsStateGuardian;
00028 
00029 ////////////////////////////////////////////////////////////////////
00030 //       Class : PipeOcclusionCullTraverser
00031 // Description : This specialization of CullTraverser uses the
00032 //               graphics pipe itself to perform occlusion culling.
00033 //               As such, it's likely to be inefficient (since it
00034 //               interferes with the pipe's normal mode of rendering),
00035 //               and is mainly useful to test other, CPU-based
00036 //               occlusion algorithms.
00037 //
00038 //               This cannot be used in a multithreaded pipeline
00039 //               environment where cull and draw are operating
00040 //               simultaneously.
00041 //
00042 //               It can't be defined in the cull subdirectory, because
00043 //               it needs access to GraphicsPipe and DisplayRegion and
00044 //               other classes in display.  So we put it in grutil
00045 //               instead, for lack of any better ideas.
00046 ////////////////////////////////////////////////////////////////////
00047 class EXPCL_PANDA_GRUTIL PipeOcclusionCullTraverser : public CullTraverser,
00048                                                public CullHandler {
00049 PUBLISHED:
00050   PipeOcclusionCullTraverser(GraphicsOutput *host);
00051   PipeOcclusionCullTraverser(const PipeOcclusionCullTraverser &copy);
00052 
00053   virtual void set_scene(SceneSetup *scene_setup,
00054                          GraphicsStateGuardianBase *gsg,
00055                          bool dr_incomplete_render);
00056   virtual void end_traverse();
00057 
00058   INLINE GraphicsOutput *get_buffer() const;
00059   Texture *get_texture();
00060 
00061   INLINE void set_occlusion_mask(const DrawMask &occlusion_mask);
00062   INLINE const DrawMask &get_occlusion_mask() const;
00063 
00064 protected:
00065   virtual bool is_in_view(CullTraverserData &data);
00066   virtual void traverse_below(CullTraverserData &data);
00067 
00068   virtual void record_object(CullableObject *object,
00069                              const CullTraverser *traverser);
00070 
00071 private:
00072   void make_sphere();
00073   static LVertex compute_sphere_point(PN_stdfloat latitude, PN_stdfloat longitude);
00074   void make_box();
00075 
00076   void make_solid_test_state();
00077 
00078   bool get_volume_viz(const BoundingVolume *vol, 
00079                       CPT(Geom) &geom,  // OUT
00080                       CPT(TransformState) &net_transform, // IN-OUT
00081                       CPT(TransformState) &modelview_transform  // OUT
00082                       );
00083   PT(OcclusionQueryContext) 
00084     perform_occlusion_test(const Geom *geom, 
00085                            const TransformState *net_transform,
00086                            const TransformState *modelview_transform);
00087 
00088   void show_results(int num_fragments, const Geom *geom, 
00089                     const TransformState *net_transform, 
00090                     const TransformState *modelview_transform);
00091 private:
00092   bool _live;
00093 
00094   PT(GraphicsOutput) _buffer;
00095   PT(Texture) _texture;
00096   PT(DisplayRegion) _display_region;
00097   DrawMask _occlusion_mask;
00098 
00099   PT(SceneSetup) _scene;
00100   PT(CullTraverser) _internal_trav;
00101 
00102   CullHandler *_internal_cull_handler;
00103   CullHandler *_true_cull_handler;
00104 
00105   // This is the query that has already been performed on the current
00106   // node or a parent.
00107   PT(OcclusionQueryContext) _current_query;
00108 
00109   // This is the query that has been performed for any children.
00110   PT(OcclusionQueryContext) _next_query;
00111 
00112   PT(Geom) _sphere_geom;
00113   PT(Geom) _box_geom;
00114   CPT(RenderState) _solid_test_state;
00115 
00116   class PendingObject {
00117   public:
00118     INLINE PendingObject(CullableObject *object);
00119     INLINE ~PendingObject();
00120 
00121     CullableObject *_object;
00122     PT(OcclusionQueryContext) _query;
00123   };
00124   typedef pvector<PendingObject> PendingObjects;
00125   PendingObjects _pending_objects;
00126 
00127   static PStatCollector _setup_occlusion_pcollector;
00128   static PStatCollector _draw_occlusion_pcollector;
00129   static PStatCollector _test_occlusion_pcollector;
00130   static PStatCollector _finish_occlusion_pcollector;
00131 
00132   static PStatCollector _occlusion_untested_pcollector;
00133   static PStatCollector _occlusion_passed_pcollector;
00134   static PStatCollector _occlusion_failed_pcollector;
00135   static PStatCollector _occlusion_tests_pcollector;
00136 
00137 public:
00138   static TypeHandle get_class_type() {
00139     return _type_handle;
00140   }
00141   static void init_type() {
00142     CullTraverser::init_type();
00143     register_type(_type_handle, "PipeOcclusionCullTraverser",
00144                   CullTraverser::get_class_type());
00145   }
00146   virtual TypeHandle get_type() const {
00147     return get_class_type();
00148   }
00149   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00150 
00151 private:
00152   static TypeHandle _type_handle;
00153 };
00154 
00155 #include "pipeOcclusionCullTraverser.I"
00156 
00157 #endif
00158 
00159 
00160   
 All Classes Functions Variables Enumerations