Panda3D
|
00001 // Filename: graphicsOutput.h 00002 // Created by: drose (06Feb04) 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 GRAPHICSOUTPUT_H 00016 #define GRAPHICSOUTPUT_H 00017 00018 #include "pandabase.h" 00019 00020 #include "graphicsPipe.h" 00021 #include "displayRegion.h" 00022 #include "stereoDisplayRegion.h" 00023 #include "graphicsStateGuardian.h" 00024 #include "drawableRegion.h" 00025 #include "renderBuffer.h" 00026 #include "graphicsOutputBase.h" 00027 00028 #include "typedWritableReferenceCount.h" 00029 #include "pandaNode.h" 00030 #include "pStatCollector.h" 00031 #include "pnotify.h" 00032 #include "lightMutex.h" 00033 #include "filename.h" 00034 #include "drawMask.h" 00035 #include "pvector.h" 00036 #include "weakPointerTo.h" 00037 #include "nodePath.h" 00038 00039 class PNMImage; 00040 class GraphicsEngine; 00041 00042 //////////////////////////////////////////////////////////////////// 00043 // Class : GraphicsOutput 00044 // Description : This is a base class for the various different 00045 // classes that represent the result of a frame of 00046 // rendering. The most common kind of GraphicsOutput is 00047 // a GraphicsWindow, which is a real-time window on the 00048 // desktop, but another example is GraphicsBuffer, which 00049 // is an offscreen buffer. 00050 // 00051 // The actual rendering, and anything associated with 00052 // the graphics context itself, is managed by the 00053 // associated GraphicsStateGuardian (which might output 00054 // to multiple GraphicsOutput objects). 00055 // 00056 // GraphicsOutputs are not actually writable to bam 00057 // files, of course, but they may be passed as event 00058 // parameters, so they inherit from 00059 // TypedWritableReferenceCount instead of 00060 // TypedReferenceCount for that convenience. 00061 //////////////////////////////////////////////////////////////////// 00062 class EXPCL_PANDA_DISPLAY GraphicsOutput : public GraphicsOutputBase, public DrawableRegion { 00063 protected: 00064 GraphicsOutput(GraphicsEngine *engine, 00065 GraphicsPipe *pipe, 00066 const string &name, 00067 const FrameBufferProperties &fb_prop, 00068 const WindowProperties &win_prop, int flags, 00069 GraphicsStateGuardian *gsg, 00070 GraphicsOutput *host); 00071 00072 private: 00073 GraphicsOutput(const GraphicsOutput ©); 00074 void operator = (const GraphicsOutput ©); 00075 00076 PUBLISHED: 00077 enum RenderTextureMode { 00078 RTM_none, 00079 RTM_bind_or_copy, 00080 RTM_copy_texture, 00081 RTM_copy_ram, 00082 RTM_triggered_copy_texture, 00083 RTM_triggered_copy_ram, 00084 }; 00085 00086 // There are many reasons to call begin_frame/end_frame. 00087 enum FrameMode { 00088 FM_render, // We are rendering a frame. 00089 FM_parasite, // We are rendering a frame of a parasite. 00090 FM_refresh, // We are just refreshing the display or exposing the window. 00091 }; 00092 00093 virtual ~GraphicsOutput(); 00094 00095 INLINE GraphicsStateGuardian *get_gsg() const; 00096 INLINE GraphicsPipe *get_pipe() const; 00097 INLINE GraphicsEngine *get_engine() const; 00098 INLINE const string &get_name() const; 00099 00100 INLINE int count_textures() const; 00101 INLINE bool has_texture() const; 00102 virtual INLINE Texture *get_texture(int i=0) const; 00103 INLINE RenderTexturePlane get_texture_plane(int i=0) const; 00104 INLINE RenderTextureMode get_rtm_mode(int i=0) const; 00105 void clear_render_textures(); 00106 void add_render_texture(Texture *tex, RenderTextureMode mode, 00107 RenderTexturePlane bitplane=RTP_COUNT); 00108 void setup_render_texture(Texture *tex, bool allow_bind, bool to_ram); 00109 00110 INLINE int get_x_size() const; 00111 INLINE int get_y_size() const; 00112 INLINE int get_fb_x_size() const; 00113 INLINE int get_fb_y_size() const; 00114 INLINE bool has_size() const; 00115 INLINE bool is_valid() const; 00116 00117 void set_active(bool active); 00118 virtual bool is_active() const; 00119 00120 INLINE void set_one_shot(bool one_shot); 00121 INLINE bool get_one_shot() const; 00122 00123 void set_inverted(bool inverted); 00124 INLINE bool get_inverted() const; 00125 00126 INLINE void set_red_blue_stereo(bool red_blue_stereo, 00127 unsigned int left_eye_color_mask, 00128 unsigned int right_eye_color_mask); 00129 INLINE bool get_red_blue_stereo() const; 00130 INLINE unsigned int get_left_eye_color_mask() const; 00131 INLINE unsigned int get_right_eye_color_mask() const; 00132 00133 INLINE const FrameBufferProperties &get_fb_properties() const; 00134 INLINE bool is_stereo() const; 00135 00136 INLINE void clear_delete_flag(); 00137 INLINE bool get_delete_flag() const; 00138 00139 virtual void set_sort(int sort); 00140 INLINE int get_sort() const; 00141 00142 INLINE void set_child_sort(int child_sort); 00143 INLINE void clear_child_sort(); 00144 INLINE int get_child_sort() const; 00145 00146 INLINE void trigger_copy(); 00147 00148 INLINE DisplayRegion *make_display_region(); 00149 DisplayRegion *make_display_region(float l, float r, float b, float t); 00150 INLINE DisplayRegion *make_mono_display_region(); 00151 DisplayRegion *make_mono_display_region(float l, float r, float b, float t); 00152 INLINE StereoDisplayRegion *make_stereo_display_region(); 00153 StereoDisplayRegion *make_stereo_display_region(float l, float r, float b, float t); 00154 bool remove_display_region(DisplayRegion *display_region); 00155 void remove_all_display_regions(); 00156 00157 int get_num_display_regions() const; 00158 PT(DisplayRegion) get_display_region(int n) const; 00159 MAKE_SEQ(get_display_regions, get_num_display_regions, get_display_region); 00160 00161 int get_num_active_display_regions() const; 00162 PT(DisplayRegion) get_active_display_region(int n) const; 00163 MAKE_SEQ(get_active_display_regions, get_num_active_display_regions, get_active_display_region); 00164 00165 GraphicsOutput *make_texture_buffer( 00166 const string &name, int x_size, int y_size, 00167 Texture *tex = NULL, bool to_ram = false, FrameBufferProperties *fbp = NULL); 00168 GraphicsOutput *make_cube_map(const string &name, int size, 00169 NodePath &camera_rig, 00170 DrawMask camera_mask = PandaNode::get_all_camera_mask(), 00171 bool to_ram = false, FrameBufferProperties *fbp = NULL); 00172 00173 INLINE static Filename make_screenshot_filename( 00174 const string &prefix = "screenshot"); 00175 INLINE Filename save_screenshot_default( 00176 const string &prefix = "screenshot"); 00177 INLINE bool save_screenshot( 00178 const Filename &filename, const string &image_comment = ""); 00179 INLINE bool get_screenshot(PNMImage &image); 00180 00181 NodePath get_texture_card(); 00182 00183 virtual bool share_depth_buffer(GraphicsOutput *graphics_output); 00184 virtual void unshare_depth_buffer(); 00185 00186 public: 00187 // These are not intended to be called directly by the user. 00188 INLINE bool flip_ready() const; 00189 00190 INLINE bool operator < (const GraphicsOutput &other) const; 00191 00192 virtual GraphicsOutput *get_host(); 00193 00194 virtual void request_open(); 00195 virtual void request_close(); 00196 00197 virtual void set_close_now(); 00198 virtual void reset_window(bool swapchain); 00199 virtual void clear_pipe(); 00200 00201 void set_size_and_recalc(int x, int y); 00202 00203 // It is an error to call any of the following methods from any 00204 // thread other than the draw thread. These methods are normally 00205 // called by the GraphicsEngine. 00206 void clear(Thread *current_thread); 00207 virtual bool begin_frame(FrameMode mode, Thread *current_thread); 00208 virtual void end_frame(FrameMode mode, Thread *current_thread); 00209 00210 void change_scenes(DisplayRegionPipelineReader *new_dr); 00211 virtual void select_cube_map(int cube_map_index); 00212 00213 // These methods will be called within the app (main) thread. 00214 virtual void begin_flip(); 00215 virtual void end_flip(); 00216 00217 // It is an error to call any of the following methods from any 00218 // thread other than the window thread. These methods are normally 00219 // called by the GraphicsEngine. 00220 virtual void process_events(); 00221 00222 INLINE PStatCollector &get_cull_window_pcollector(); 00223 INLINE PStatCollector &get_draw_window_pcollector(); 00224 00225 protected: 00226 virtual void pixel_factor_changed(); 00227 void prepare_for_deletion(); 00228 bool copy_to_textures(); 00229 00230 INLINE void begin_frame_spam(FrameMode mode); 00231 INLINE void end_frame_spam(FrameMode mode); 00232 INLINE void clear_cube_map_selection(); 00233 INLINE void trigger_flip(); 00234 00235 protected: 00236 00237 class RenderTexture { 00238 public: 00239 PT(Texture) _texture; 00240 RenderTexturePlane _plane; 00241 RenderTextureMode _rtm_mode; 00242 }; 00243 PT(GraphicsStateGuardian) _gsg; 00244 GraphicsEngine *_engine; 00245 PT(GraphicsPipe) _pipe; 00246 PT(GraphicsOutput) _host; 00247 FrameBufferProperties _fb_properties; 00248 bool _stereo; 00249 string _name; 00250 pvector<RenderTexture> _textures; 00251 bool _flip_ready; 00252 int _cube_map_index; 00253 DisplayRegion *_cube_map_dr; 00254 PT(Geom) _texture_card; 00255 bool _trigger_copy; 00256 00257 private: 00258 PT(GeomVertexData) create_texture_card_vdata(int x, int y); 00259 00260 DisplayRegion *add_display_region(DisplayRegion *display_region); 00261 bool do_remove_display_region(DisplayRegion *display_region); 00262 00263 INLINE void win_display_regions_changed(); 00264 00265 INLINE void determine_display_regions() const; 00266 void do_determine_display_regions(); 00267 00268 int _sort; 00269 int _child_sort; 00270 bool _got_child_sort; 00271 unsigned int _internal_sort_index; 00272 00273 protected: 00274 bool _active; 00275 bool _one_shot; 00276 bool _inverted; 00277 bool _red_blue_stereo; 00278 unsigned int _left_eye_color_mask; 00279 unsigned int _right_eye_color_mask; 00280 bool _delete_flag; 00281 00282 // These weak pointers are used to keep track of whether the 00283 // buffer's bound Texture has been deleted or not. Until they have, 00284 // we don't auto-close the buffer (since that would deallocate the 00285 // memory associated with the texture). 00286 pvector<WPT(Texture)> _hold_textures; 00287 00288 protected: 00289 LightMutex _lock; 00290 // protects _display_regions. 00291 PT(DisplayRegion) _default_display_region; 00292 typedef pvector< PT(DisplayRegion) > TotalDisplayRegions; 00293 TotalDisplayRegions _total_display_regions; 00294 typedef pvector<DisplayRegion *> ActiveDisplayRegions; 00295 ActiveDisplayRegions _active_display_regions; 00296 bool _display_regions_stale; 00297 00298 protected: 00299 int _creation_flags; 00300 int _x_size; 00301 int _y_size; 00302 bool _has_size; 00303 bool _is_valid; 00304 00305 static PStatCollector _make_current_pcollector; 00306 static PStatCollector _copy_texture_pcollector; 00307 static PStatCollector _cull_pcollector; 00308 static PStatCollector _draw_pcollector; 00309 PStatCollector _cull_window_pcollector; 00310 PStatCollector _draw_window_pcollector; 00311 00312 public: 00313 static TypeHandle get_class_type() { 00314 return _type_handle; 00315 } 00316 static void init_type() { 00317 GraphicsOutputBase::init_type(); 00318 register_type(_type_handle, "GraphicsOutput", 00319 GraphicsOutputBase::get_class_type()); 00320 } 00321 virtual TypeHandle get_type() const { 00322 return get_class_type(); 00323 } 00324 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00325 00326 private: 00327 static TypeHandle _type_handle; 00328 00329 friend class GraphicsPipe; 00330 friend class GraphicsEngine; 00331 friend class DisplayRegion; 00332 }; 00333 00334 EXPCL_PANDA_DISPLAY ostream &operator << (ostream &out, GraphicsOutput::FrameMode mode); 00335 00336 #include "graphicsOutput.I" 00337 00338 #endif /* GRAPHICSOUTPUT_H */