Panda3D

videoTexture.cxx

00001 // Filename: videoTexture.cxx
00002 // Created by:  drose (21Sep05)
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 #include "pandabase.h"
00016 
00017 #include "videoTexture.h"
00018 #include "clockObject.h"
00019 #include "config_gobj.h"
00020 
00021 TypeHandle VideoTexture::_type_handle;
00022 
00023 ////////////////////////////////////////////////////////////////////
00024 //     Function: VideoTexture::Constructor
00025 //       Access: Protected
00026 //  Description: 
00027 ////////////////////////////////////////////////////////////////////
00028 VideoTexture::
00029 VideoTexture(const string &name) : 
00030   Texture(name) 
00031 {
00032   // We don't want to try to compress each frame as it's loaded.
00033   Texture::CDWriter cdata(Texture::_cycler, true);
00034   cdata->_compression = CM_off;
00035 
00036   _video_width = 0;
00037   _video_height = 0;
00038 
00039   _last_frame_update = 0;
00040   _current_frame = -1;
00041 }
00042 
00043 ////////////////////////////////////////////////////////////////////
00044 //     Function: VideoTexture::Copy Constructor
00045 //       Access: Protected
00046 //  Description: 
00047 ////////////////////////////////////////////////////////////////////
00048 VideoTexture::
00049 VideoTexture(const VideoTexture &copy) : 
00050   Texture(copy),
00051   AnimInterface(copy),
00052   _video_width(copy._video_width),
00053   _video_height(copy._video_height),
00054   _last_frame_update(copy._last_frame_update),
00055   _current_frame(copy._current_frame)
00056 {
00057 }
00058 
00059 ////////////////////////////////////////////////////////////////////
00060 //     Function: VideoTexture::get_keep_ram_image
00061 //       Access: Published, Virtual
00062 //  Description: Returns the flag that indicates whether this Texture
00063 //               is eligible to have its main RAM copy of the texture
00064 //               memory dumped when the texture is prepared for
00065 //               rendering.  See set_keep_ram_image().
00066 ////////////////////////////////////////////////////////////////////
00067 bool VideoTexture::
00068 get_keep_ram_image() const {
00069   // A VideoTexture should never dump its RAM image.
00070   return true;
00071 }
00072 
00073 ////////////////////////////////////////////////////////////////////
00074 //     Function: VideoTexture::has_cull_callback
00075 //       Access: Public, Virtual
00076 //  Description: Should be overridden by derived classes to return
00077 //               true if cull_callback() has been defined.  Otherwise,
00078 //               returns false to indicate cull_callback() does not
00079 //               need to be called for this node during the cull
00080 //               traversal.
00081 ////////////////////////////////////////////////////////////////////
00082 bool VideoTexture::
00083 has_cull_callback() const {
00084   return true;
00085 }
00086 
00087 ////////////////////////////////////////////////////////////////////
00088 //     Function: VideoTexture::cull_callback
00089 //       Access: Public, Virtual
00090 //  Description: If has_cull_callback() returns true, this function
00091 //               will be called during the cull traversal to perform
00092 //               any additional operations that should be performed at
00093 //               cull time.
00094 //
00095 //               This is called each time the Texture is discovered
00096 //               applied to a Geom in the traversal.  It should return
00097 //               true if the Geom is visible, false if it should be
00098 //               omitted.
00099 ////////////////////////////////////////////////////////////////////
00100 bool VideoTexture::
00101 cull_callback(CullTraverser *, const CullTraverserData &) const {
00102   // Strictly speaking, the cull_callback() method isn't necessary for
00103   // VideoTexture, since the get_ram_image() function is already
00104   // overloaded to update itself if necessary.  However, we define it
00105   // anyway, to move the update calculation into the cull traversal
00106   // rather than the draw traversal.
00107   ((VideoTexture *)this)->reconsider_dirty();
00108   return true;
00109 }
00110 
00111 ////////////////////////////////////////////////////////////////////
00112 //     Function: VideoTexture::set_video_size
00113 //       Access: Protected
00114 //  Description: Should be called by a derived class to set the size
00115 //               of the video when it is loaded.  Assumes the lock is
00116 //               held.
00117 ////////////////////////////////////////////////////////////////////
00118 void VideoTexture::
00119 set_video_size(int video_width, int video_height) {
00120   _video_width = video_width;
00121   _video_height = video_height;
00122   set_orig_file_size(video_width, video_height);
00123 
00124   Texture::CDWriter cdata(Texture::_cycler, true);
00125   do_set_pad_size(cdata,
00126                   max(cdata->_x_size - _video_width, 0), 
00127                   max(cdata->_y_size - _video_height, 0),
00128                   0);
00129 }
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //     Function: VideoTexture::do_has_ram_image
00133 //       Access: Protected, Virtual
00134 //  Description: Returns true if the Texture has its image contents
00135 //               available in main RAM, false if it exists only in
00136 //               texture memory or in the prepared GSG context.
00137 ////////////////////////////////////////////////////////////////////
00138 bool VideoTexture::
00139 do_has_ram_image(const Texture::CData *cdata) const {
00140   int this_frame = ClockObject::get_global_clock()->get_frame_count();
00141   if (this_frame != _last_frame_update) {
00142     return false;
00143   }
00144   return !cdata->_ram_images.empty() && !cdata->_ram_images[0]._image.empty();
00145 }
00146 
00147 ////////////////////////////////////////////////////////////////////
00148 //     Function: VideoTexture::reconsider_dirty
00149 //       Access: Protected, Virtual
00150 //  Description: Called by TextureContext to give the Texture a chance
00151 //               to mark itself dirty before rendering, if necessary.
00152 ////////////////////////////////////////////////////////////////////
00153 void VideoTexture::
00154 reconsider_dirty() {
00155   consider_update();
00156 }
00157 
00158 
00159 ////////////////////////////////////////////////////////////////////
00160 //     Function: VideoTexture::unlocked_ensure_ram_image
00161 //       Access: Protected, Virtual
00162 //  Description: If the texture has a ram image already, this acquires
00163 //               the CData write lock and returns it.
00164 //
00165 //               If the texture lacks a ram image, this performs
00166 //               do_reload_ram_image(), but without holding the lock
00167 //               on this particular Texture object, to avoid holding
00168 //               the lock across what might be a slow operation.
00169 //               Instead, the reload is performed in a copy of the
00170 //               texture object, and then the lock is acquired and the
00171 //               data is copied in.
00172 //
00173 //               In any case, the return value is a locked CData
00174 //               object, which must be released with an explicit call
00175 //               to release_write().  The CData object will have a ram
00176 //               image unless for some reason do_reload_ram_image()
00177 //               fails.
00178 ////////////////////////////////////////////////////////////////////
00179 Texture::CData *VideoTexture::
00180 unlocked_ensure_ram_image(bool allow_compression) {
00181   consider_update();
00182 
00183   Thread *current_thread = Thread::get_current_thread();
00184   Texture::CData *cdata = Texture::_cycler.write_upstream(false, current_thread);
00185   return cdata;
00186 }
00187 
00188 ////////////////////////////////////////////////////////////////////
00189 //     Function: VideoTexture::do_reload_ram_image
00190 //       Access: Protected, Virtual
00191 //  Description: Called when the Texture image is required but the ram
00192 //               image is not available, this will reload it from disk
00193 //               or otherwise do whatever is required to make it
00194 //               available, if possible.
00195 ////////////////////////////////////////////////////////////////////
00196 void VideoTexture::
00197 do_reload_ram_image(Texture::CData *cdata, bool) {
00198   consider_update();
00199 }
00200 
00201 ////////////////////////////////////////////////////////////////////
00202 //     Function: VideoTexture::do_can_reload
00203 //       Access: Protected, Virtual
00204 //  Description: Returns true if we can safely call
00205 //               do_unlock_and_reload_ram_image() in order to make the
00206 //               image available, or false if we shouldn't do this
00207 //               (because we know from a priori knowledge that it
00208 //               wouldn't work anyway).
00209 ////////////////////////////////////////////////////////////////////
00210 bool VideoTexture::
00211 do_can_reload(const Texture::CData *cdata) const {
00212   return true;
00213 }
00214 
00215 ////////////////////////////////////////////////////////////////////
00216 //     Function: VideoTexture::do_adjust_this_size
00217 //       Access: Protected, Virtual
00218 //  Description: Works like adjust_size, but also considers the
00219 //               texture class.  Movie textures, for instance, always
00220 //               pad outwards, never scale down.
00221 ////////////////////////////////////////////////////////////////////
00222 bool VideoTexture::
00223 do_adjust_this_size(const Texture::CData *cdata_tex,
00224                     int &x_size, int &y_size, const string &name,
00225                     bool for_padding) const {
00226   AutoTextureScale ats = do_get_auto_texture_scale(cdata_tex);
00227   if (ats != ATS_none) {
00228     ats = ATS_pad;
00229   }
00230 
00231   return adjust_size(x_size, y_size, name, for_padding, ats);
00232 }
00233 
00234 ////////////////////////////////////////////////////////////////////
00235 //     Function: VideoTexture::consider_update
00236 //       Access: Protected, Virtual
00237 //  Description: Calls update_frame() if the current frame has
00238 //               changed.
00239 ////////////////////////////////////////////////////////////////////
00240 void VideoTexture::
00241 consider_update() {
00242   int this_frame = ClockObject::get_global_clock()->get_frame_count();
00243   if (this_frame != _last_frame_update) {
00244     int frame = get_frame();
00245     if (_current_frame != frame) {
00246       Texture::CDWriter cdata(Texture::_cycler, false);
00247       do_update_frame(cdata, frame);
00248       _current_frame = frame;
00249     }
00250     _last_frame_update = this_frame;
00251   }
00252 }
 All Classes Functions Variables Enumerations