Panda3D
|
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 ©); 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