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 #include "luse.h" 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 #include "cycleData.h" 00039 #include "cycleDataLockedReader.h" 00040 #include "cycleDataReader.h" 00041 #include "cycleDataWriter.h" 00042 #include "pipelineCycler.h" 00043 #include "updateSeq.h" 00044 00045 class PNMImage; 00046 class GraphicsEngine; 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Class : GraphicsOutput 00050 // Description : This is a base class for the various different 00051 // classes that represent the result of a frame of 00052 // rendering. The most common kind of GraphicsOutput is 00053 // a GraphicsWindow, which is a real-time window on the 00054 // desktop, but another example is GraphicsBuffer, which 00055 // is an offscreen buffer. 00056 // 00057 // The actual rendering, and anything associated with 00058 // the graphics context itself, is managed by the 00059 // associated GraphicsStateGuardian (which might output 00060 // to multiple GraphicsOutput objects). 00061 // 00062 // GraphicsOutputs are not actually writable to bam 00063 // files, of course, but they may be passed as event 00064 // parameters, so they inherit from 00065 // TypedWritableReferenceCount instead of 00066 // TypedReferenceCount for that convenience. 00067 //////////////////////////////////////////////////////////////////// 00068 class EXPCL_PANDA_DISPLAY GraphicsOutput : public GraphicsOutputBase, public DrawableRegion { 00069 protected: 00070 GraphicsOutput(GraphicsEngine *engine, 00071 GraphicsPipe *pipe, 00072 const string &name, 00073 const FrameBufferProperties &fb_prop, 00074 const WindowProperties &win_prop, int flags, 00075 GraphicsStateGuardian *gsg, 00076 GraphicsOutput *host, 00077 bool default_stereo_flags); 00078 00079 private: 00080 GraphicsOutput(const GraphicsOutput ©); 00081 void operator = (const GraphicsOutput ©); 00082 00083 PUBLISHED: 00084 enum RenderTextureMode { 00085 RTM_none, 00086 RTM_bind_or_copy, 00087 RTM_copy_texture, 00088 RTM_copy_ram, 00089 RTM_triggered_copy_texture, 00090 RTM_triggered_copy_ram, 00091 }; 00092 00093 // There are many reasons to call begin_frame/end_frame. 00094 enum FrameMode { 00095 FM_render, // We are rendering a frame. 00096 FM_parasite, // We are rendering a frame of a parasite. 00097 FM_refresh, // We are just refreshing the display or exposing the window. 00098 }; 00099 00100 virtual ~GraphicsOutput(); 00101 00102 INLINE GraphicsStateGuardian *get_gsg() const; 00103 INLINE GraphicsPipe *get_pipe() const; 00104 INLINE GraphicsEngine *get_engine() const; 00105 INLINE const string &get_name() const; 00106 00107 INLINE int count_textures() const; 00108 INLINE bool has_texture() const; 00109 virtual INLINE Texture *get_texture(int i=0) const; 00110 INLINE RenderTexturePlane get_texture_plane(int i=0) const; 00111 INLINE RenderTextureMode get_rtm_mode(int i=0) const; 00112 void clear_render_textures(); 00113 void add_render_texture(Texture *tex, RenderTextureMode mode, 00114 RenderTexturePlane bitplane=RTP_COUNT); 00115 void setup_render_texture(Texture *tex, bool allow_bind, bool to_ram); 00116 00117 INLINE int get_x_size() const; 00118 INLINE int get_y_size() const; 00119 INLINE int get_fb_x_size() const; 00120 INLINE int get_fb_y_size() const; 00121 INLINE int get_sbs_left_x_size() const; 00122 INLINE int get_sbs_left_y_size() const; 00123 INLINE int get_sbs_right_x_size() const; 00124 INLINE int get_sbs_right_y_size() const; 00125 INLINE bool has_size() const; 00126 INLINE bool is_valid() const; 00127 INLINE bool is_nonzero_size() const; 00128 00129 void set_active(bool active); 00130 virtual bool is_active() const; 00131 00132 void set_one_shot(bool one_shot); 00133 bool get_one_shot() const; 00134 00135 void set_inverted(bool inverted); 00136 INLINE bool get_inverted() const; 00137 00138 INLINE void set_swap_eyes(bool swap_eyes); 00139 INLINE bool get_swap_eyes() const; 00140 00141 INLINE void set_red_blue_stereo(bool red_blue_stereo, 00142 unsigned int left_eye_color_mask, 00143 unsigned int right_eye_color_mask); 00144 INLINE bool get_red_blue_stereo() const; 00145 INLINE unsigned int get_left_eye_color_mask() const; 00146 INLINE unsigned int get_right_eye_color_mask() const; 00147 00148 void set_side_by_side_stereo(bool side_by_side_stereo); 00149 void set_side_by_side_stereo(bool side_by_side_stereo, 00150 const LVecBase4 &sbs_left_dimensions, 00151 const LVecBase4 &sbs_right_dimensions); 00152 INLINE bool get_side_by_side_stereo() const; 00153 INLINE const LVecBase4 &get_sbs_left_dimensions() const; 00154 INLINE const LVecBase4 &get_sbs_right_dimensions() const; 00155 00156 INLINE const FrameBufferProperties &get_fb_properties() const; 00157 INLINE bool is_stereo() const; 00158 00159 INLINE void clear_delete_flag(); 00160 bool get_delete_flag() const; 00161 00162 virtual void set_sort(int sort); 00163 INLINE int get_sort() const; 00164 00165 INLINE void set_child_sort(int child_sort); 00166 INLINE void clear_child_sort(); 00167 INLINE int get_child_sort() const; 00168 00169 INLINE void trigger_copy(); 00170 00171 INLINE DisplayRegion *make_display_region(); 00172 INLINE DisplayRegion *make_display_region(PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t); 00173 DisplayRegion *make_display_region(const LVecBase4 &dimensions); 00174 INLINE DisplayRegion *make_mono_display_region(); 00175 INLINE DisplayRegion *make_mono_display_region(PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t); 00176 DisplayRegion *make_mono_display_region(const LVecBase4 &dimensions); 00177 INLINE StereoDisplayRegion *make_stereo_display_region(); 00178 INLINE StereoDisplayRegion *make_stereo_display_region(PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t); 00179 StereoDisplayRegion *make_stereo_display_region(const LVecBase4 &dimensions); 00180 bool remove_display_region(DisplayRegion *display_region); 00181 void remove_all_display_regions(); 00182 00183 INLINE DisplayRegion *get_overlay_display_region() const; 00184 void set_overlay_display_region(DisplayRegion *display_region); 00185 00186 int get_num_display_regions() const; 00187 PT(DisplayRegion) get_display_region(int n) const; 00188 MAKE_SEQ(get_display_regions, get_num_display_regions, get_display_region); 00189 00190 int get_num_active_display_regions() const; 00191 PT(DisplayRegion) get_active_display_region(int n) const; 00192 MAKE_SEQ(get_active_display_regions, get_num_active_display_regions, get_active_display_region); 00193 00194 GraphicsOutput *make_texture_buffer( 00195 const string &name, int x_size, int y_size, 00196 Texture *tex = NULL, bool to_ram = false, FrameBufferProperties *fbp = NULL); 00197 GraphicsOutput *make_cube_map(const string &name, int size, 00198 NodePath &camera_rig, 00199 DrawMask camera_mask = PandaNode::get_all_camera_mask(), 00200 bool to_ram = false, FrameBufferProperties *fbp = NULL); 00201 00202 INLINE static Filename make_screenshot_filename( 00203 const string &prefix = "screenshot"); 00204 INLINE Filename save_screenshot_default( 00205 const string &prefix = "screenshot"); 00206 INLINE bool save_screenshot( 00207 const Filename &filename, const string &image_comment = ""); 00208 INLINE bool get_screenshot(PNMImage &image); 00209 INLINE PT(Texture) get_screenshot(); 00210 00211 NodePath get_texture_card(); 00212 00213 virtual bool share_depth_buffer(GraphicsOutput *graphics_output); 00214 virtual void unshare_depth_buffer(); 00215 00216 virtual bool get_supports_render_texture() const; 00217 00218 public: 00219 // These are not intended to be called directly by the user. 00220 virtual bool flip_ready() const; 00221 00222 INLINE bool operator < (const GraphicsOutput &other) const; 00223 00224 virtual GraphicsOutput *get_host(); 00225 00226 virtual void request_open(); 00227 virtual void request_close(); 00228 00229 virtual void set_close_now(); 00230 virtual void reset_window(bool swapchain); 00231 virtual void clear_pipe(); 00232 00233 void set_size_and_recalc(int x, int y); 00234 00235 // It is an error to call any of the following methods from any 00236 // thread other than the draw thread. These methods are normally 00237 // called by the GraphicsEngine. 00238 void clear(Thread *current_thread); 00239 virtual bool begin_frame(FrameMode mode, Thread *current_thread); 00240 virtual void end_frame(FrameMode mode, Thread *current_thread); 00241 00242 void change_scenes(DisplayRegionPipelineReader *new_dr); 00243 virtual void select_cube_map(int cube_map_index); 00244 00245 // These methods will be called within the app (main) thread. 00246 virtual void begin_flip(); 00247 virtual void ready_flip(); 00248 virtual void end_flip(); 00249 00250 // It is an error to call any of the following methods from any 00251 // thread other than the window thread. These methods are normally 00252 // called by the GraphicsEngine. 00253 virtual void process_events(); 00254 00255 INLINE PStatCollector &get_cull_window_pcollector(); 00256 INLINE PStatCollector &get_draw_window_pcollector(); 00257 00258 protected: 00259 virtual void pixel_factor_changed(); 00260 void prepare_for_deletion(); 00261 void promote_to_copy_texture(); 00262 bool copy_to_textures(); 00263 00264 INLINE void begin_frame_spam(FrameMode mode); 00265 INLINE void end_frame_spam(FrameMode mode); 00266 INLINE void clear_cube_map_selection(); 00267 INLINE void trigger_flip(); 00268 00269 class CData; 00270 00271 private: 00272 PT(GeomVertexData) create_texture_card_vdata(int x, int y); 00273 00274 DisplayRegion *add_display_region(DisplayRegion *display_region); 00275 bool do_remove_display_region(DisplayRegion *display_region); 00276 00277 INLINE void win_display_regions_changed(); 00278 00279 INLINE void determine_display_regions() const; 00280 void do_determine_display_regions(CData *cdata); 00281 00282 static unsigned int parse_color_mask(const string &word); 00283 00284 protected: 00285 PT(GraphicsStateGuardian) _gsg; 00286 GraphicsEngine *_engine; 00287 PT(GraphicsPipe) _pipe; 00288 PT(GraphicsOutput) _host; 00289 FrameBufferProperties _fb_properties; 00290 bool _stereo; 00291 string _name; 00292 bool _flip_ready; 00293 int _cube_map_index; 00294 DisplayRegion *_cube_map_dr; 00295 PT(Geom) _texture_card; 00296 bool _trigger_copy; 00297 00298 class RenderTexture { 00299 public: 00300 PT(Texture) _texture; 00301 RenderTexturePlane _plane; 00302 RenderTextureMode _rtm_mode; 00303 }; 00304 typedef pvector<RenderTexture> RenderTextures; 00305 00306 private: 00307 int _sort; 00308 int _child_sort; 00309 bool _got_child_sort; 00310 unsigned int _internal_sort_index; 00311 00312 protected: 00313 bool _inverted; 00314 bool _swap_eyes; 00315 bool _red_blue_stereo; 00316 unsigned int _left_eye_color_mask; 00317 unsigned int _right_eye_color_mask; 00318 bool _side_by_side_stereo; 00319 LVecBase4 _sbs_left_dimensions; 00320 LVecBase4 _sbs_right_dimensions; 00321 bool _delete_flag; 00322 00323 // These weak pointers are used to keep track of whether the 00324 // buffer's bound Textures have been deleted or not. Until they 00325 // have, we don't auto-close the buffer (since that would deallocate 00326 // the memory associated with the texture). 00327 pvector<WPT(Texture)> _hold_textures; 00328 00329 protected: 00330 LightMutex _lock; 00331 // protects _display_regions. 00332 PT(DisplayRegion) _overlay_display_region; 00333 typedef pvector< PT(DisplayRegion) > TotalDisplayRegions; 00334 TotalDisplayRegions _total_display_regions; 00335 typedef pvector<DisplayRegion *> ActiveDisplayRegions; 00336 00337 // This is the data that is associated with the GraphicsOutput that 00338 // needs to be cycled every frame. Mostly we don't cycle this data, 00339 // but we do cycle the textures list, and the active flag. 00340 class EXPCL_PANDA_DISPLAY CData : public CycleData { 00341 public: 00342 CData(); 00343 CData(const CData ©); 00344 00345 virtual CycleData *make_copy() const; 00346 virtual TypeHandle get_parent_type() const { 00347 return GraphicsOutput::get_class_type(); 00348 } 00349 00350 RenderTextures _textures; 00351 UpdateSeq _textures_seq; 00352 bool _active; 00353 int _one_shot_frame; 00354 ActiveDisplayRegions _active_display_regions; 00355 bool _active_display_regions_stale; 00356 }; 00357 PipelineCycler<CData> _cycler; 00358 typedef CycleDataLockedReader<CData> CDLockedReader; 00359 typedef CycleDataReader<CData> CDReader; 00360 typedef CycleDataWriter<CData> CDWriter; 00361 00362 protected: 00363 int _creation_flags; 00364 int _x_size; 00365 int _y_size; 00366 bool _has_size; 00367 bool _is_valid; 00368 bool _is_nonzero_size; 00369 00370 static PStatCollector _make_current_pcollector; 00371 static PStatCollector _copy_texture_pcollector; 00372 static PStatCollector _cull_pcollector; 00373 static PStatCollector _draw_pcollector; 00374 PStatCollector _cull_window_pcollector; 00375 PStatCollector _draw_window_pcollector; 00376 00377 public: 00378 static TypeHandle get_class_type() { 00379 return _type_handle; 00380 } 00381 static void init_type() { 00382 GraphicsOutputBase::init_type(); 00383 register_type(_type_handle, "GraphicsOutput", 00384 GraphicsOutputBase::get_class_type()); 00385 } 00386 virtual TypeHandle get_type() const { 00387 return get_class_type(); 00388 } 00389 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00390 00391 private: 00392 static TypeHandle _type_handle; 00393 00394 friend class GraphicsPipe; 00395 friend class GraphicsEngine; 00396 friend class DisplayRegion; 00397 }; 00398 00399 EXPCL_PANDA_DISPLAY ostream &operator << (ostream &out, GraphicsOutput::FrameMode mode); 00400 00401 #include "graphicsOutput.I" 00402 00403 #endif /* GRAPHICSOUTPUT_H */