Panda3D

graphicsOutput.h

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 &copy);
00081   void operator = (const GraphicsOutput &copy);
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 &copy);
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 */
 All Classes Functions Variables Enumerations