Browse Source

fix reload-texture bug

David Rose 19 years ago
parent
commit
9cd582faca

+ 13 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -6489,12 +6489,21 @@ apply_texture(TextureContext *tc) {
   }
   }
   GLP(BindTexture)(target, gtc->_index);
   GLP(BindTexture)(target, gtc->_index);
 
 
-  if (gtc->was_modified()) {
+  if (gtc->was_image_modified()) {
+    // If the texture image was modified, reload the texture.  This
+    // means we also re-specify the properties for good measure.
     specify_texture(gtc->get_texture());
     specify_texture(gtc->get_texture());
     upload_texture(gtc);
     upload_texture(gtc);
     gtc->mark_loaded();
     gtc->mark_loaded();
+
+  } else if (gtc->was_properties_modified()) {
+    // If only the properties have been modified, we don't necessarily
+    // need to reload the texture.
+    specify_texture(gtc->get_texture());
+    gtc->mark_loaded();
   }
   }
 
 
+
   report_my_gl_errors();
   report_my_gl_errors();
 }
 }
 
 
@@ -6728,6 +6737,9 @@ upload_texture_image(CLP(TextureContext) *gtc,
     } else if (is_compressed_format(internal_format)) {
     } else if (is_compressed_format(internal_format)) {
       GLCAT.debug()
       GLCAT.debug()
         << "compressing texture " << tex->get_name() << "\n";
         << "compressing texture " << tex->get_name() << "\n";
+    } else {
+      GLCAT.debug()
+        << "loading uncompressed texture " << tex->get_name() << "\n";
     }
     }
   }
   }
 
 

+ 29 - 14
panda/src/gobj/texture.I

@@ -169,7 +169,8 @@ read(const Filename &fullpath, const Filename &alpha_fullpath,
 INLINE bool Texture::
 INLINE bool Texture::
 read(const Filename &fullpath, int z, int n, 
 read(const Filename &fullpath, int z, int n, 
      bool read_pages, bool read_mipmaps) {
      bool read_pages, bool read_mipmaps) {
-  ++_modified;
+  ++_properties_modified;
+  ++_image_modified;
   return do_read(fullpath, Filename(), 0, 0, z, n, read_pages, read_mipmaps,
   return do_read(fullpath, Filename(), 0, 0, z, n, read_pages, read_mipmaps,
                  NULL);
                  NULL);
 }
 }
@@ -248,7 +249,8 @@ read(const Filename &fullpath, const Filename &alpha_fullpath,
      int primary_file_num_channels, int alpha_file_channel,
      int primary_file_num_channels, int alpha_file_channel,
      int z, int n, bool read_pages, bool read_mipmaps,
      int z, int n, bool read_pages, bool read_mipmaps,
      BamCacheRecord *record) {
      BamCacheRecord *record) {
-  ++_modified;
+  ++_properties_modified;
+  ++_image_modified;
   return do_read(fullpath, alpha_fullpath, primary_file_num_channels,
   return do_read(fullpath, alpha_fullpath, primary_file_num_channels,
 		 alpha_file_channel, z, n, read_pages, read_mipmaps,
 		 alpha_file_channel, z, n, read_pages, read_mipmaps,
                  record);
                  record);
@@ -343,7 +345,8 @@ load(const PNMImage &pnmimage) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 load(const PNMImage &pnmimage, int z, int n) {
 load(const PNMImage &pnmimage, int z, int n) {
-  ++_modified;
+  ++_properties_modified;
+  ++_image_modified;
   return do_load_one(pnmimage, get_name(), z, n);
   return do_load_one(pnmimage, get_name(), z, n);
 }
 }
 
 
@@ -785,7 +788,7 @@ get_ram_image_compression() const {
 INLINE PTA_uchar Texture::
 INLINE PTA_uchar Texture::
 modify_ram_image() {
 modify_ram_image() {
   do_modify_ram_image();
   do_modify_ram_image();
-  ++_modified;
+  ++_image_modified;
   return _ram_images[0]._image;
   return _ram_images[0]._image;
 }
 }
 
 
@@ -800,7 +803,7 @@ modify_ram_image() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE PTA_uchar Texture::
 INLINE PTA_uchar Texture::
 make_ram_image() {
 make_ram_image() {
-  ++_modified;
+  ++_image_modified;
   do_make_ram_image();
   do_make_ram_image();
   return _ram_images[0]._image;
   return _ram_images[0]._image;
 }
 }
@@ -931,20 +934,32 @@ get_expected_ram_mipmap_page_size(int n) const {
 INLINE PTA_uchar Texture::
 INLINE PTA_uchar Texture::
 modify_ram_mipmap_image(int n) {
 modify_ram_mipmap_image(int n) {
   do_modify_ram_mipmap_image(n);
   do_modify_ram_mipmap_image(n);
-  ++_modified;
+  ++_image_modified;
   return _ram_images[n]._image;
   return _ram_images[n]._image;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: Texture::get_modified
+//     Function: Texture::get_properties_modified
 //       Access: Published
 //       Access: Published
 //  Description: Returns a sequence number which is guaranteed to
 //  Description: Returns a sequence number which is guaranteed to
-//               change at least every time the texture data or
-//               properties are modified.
+//               change at least every time the texture properties
+//               (unrelated to the image) are modified.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE UpdateSeq Texture::
 INLINE UpdateSeq Texture::
-get_modified() const {
-  return _modified;
+get_properties_modified() const {
+  return _properties_modified;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::get_image_modified
+//       Access: Published
+//  Description: Returns a sequence number which is guaranteed to
+//               change at least every time the texture image data
+//               (including mipmap levels) are modified.
+////////////////////////////////////////////////////////////////////
+INLINE UpdateSeq Texture::
+get_image_modified() const {
+  return _image_modified;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1068,7 +1083,7 @@ INLINE void Texture::
 set_x_size(int x_size) {
 set_x_size(int x_size) {
   if (_x_size != x_size) {
   if (_x_size != x_size) {
     _x_size = x_size;
     _x_size = x_size;
-    ++_modified;
+    ++_image_modified;
     clear_ram_image();
     clear_ram_image();
   }
   }
 }
 }
@@ -1085,7 +1100,7 @@ set_y_size(int y_size) {
   if (_y_size != y_size) {
   if (_y_size != y_size) {
     nassertv(_texture_type != Texture::TT_1d_texture || y_size == 1);
     nassertv(_texture_type != Texture::TT_1d_texture || y_size == 1);
     _y_size = y_size;
     _y_size = y_size;
-    ++_modified;
+    ++_image_modified;
     clear_ram_image();
     clear_ram_image();
   }
   }
 }
 }
@@ -1104,7 +1119,7 @@ set_z_size(int z_size) {
              (_texture_type == Texture::TT_cube_map && z_size == 6) ||
              (_texture_type == Texture::TT_cube_map && z_size == 6) ||
              (z_size == 1));
              (z_size == 1));
     _z_size = z_size;
     _z_size = z_size;
-    ++_modified;
+    ++_image_modified;
     clear_ram_image();
     clear_ram_image();
   }
   }
 }
 }

+ 35 - 26
panda/src/gobj/texture.cxx

@@ -168,7 +168,8 @@ operator = (const Texture &copy) {
   _match_framebuffer_format = copy._match_framebuffer_format;
   _match_framebuffer_format = copy._match_framebuffer_format;
   _ram_image_compression = copy._ram_image_compression;
   _ram_image_compression = copy._ram_image_compression;
   _ram_images = copy._ram_images;
   _ram_images = copy._ram_images;
-  ++_modified;
+  ++_properties_modified;
+  ++_image_modified;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -619,7 +620,7 @@ bool Texture::
 reload() {
 reload() {
   if (_loaded_from_image && has_filename()) {
   if (_loaded_from_image && has_filename()) {
     reload_ram_image();
     reload_ram_image();
-    ++_modified;
+    ++_image_modified;
     return has_ram_image();
     return has_ram_image();
   }
   }
 
 
@@ -686,7 +687,7 @@ load_related(const InternalName *suffix) const {
 void Texture::
 void Texture::
 set_wrap_u(Texture::WrapMode wrap) {
 set_wrap_u(Texture::WrapMode wrap) {
   if (_wrap_u != wrap) {
   if (_wrap_u != wrap) {
-    ++_modified;
+    ++_properties_modified;
     _wrap_u = wrap;
     _wrap_u = wrap;
   }
   }
 }
 }
@@ -699,7 +700,7 @@ set_wrap_u(Texture::WrapMode wrap) {
 void Texture::
 void Texture::
 set_wrap_v(Texture::WrapMode wrap) {
 set_wrap_v(Texture::WrapMode wrap) {
   if (_wrap_v != wrap) {
   if (_wrap_v != wrap) {
-    ++_modified;
+    ++_properties_modified;
     _wrap_v = wrap;
     _wrap_v = wrap;
   }
   }
 }
 }
@@ -712,7 +713,7 @@ set_wrap_v(Texture::WrapMode wrap) {
 void Texture::
 void Texture::
 set_wrap_w(Texture::WrapMode wrap) {
 set_wrap_w(Texture::WrapMode wrap) {
   if (_wrap_w != wrap) {
   if (_wrap_w != wrap) {
-    ++_modified;
+    ++_properties_modified;
     _wrap_w = wrap;
     _wrap_w = wrap;
   }
   }
 }
 }
@@ -725,7 +726,7 @@ set_wrap_w(Texture::WrapMode wrap) {
 void Texture::
 void Texture::
 set_minfilter(Texture::FilterType filter) {
 set_minfilter(Texture::FilterType filter) {
   if (_minfilter != filter) {
   if (_minfilter != filter) {
-    ++_modified;
+    ++_properties_modified;
     _minfilter = filter;
     _minfilter = filter;
   }
   }
 }
 }
@@ -738,7 +739,7 @@ set_minfilter(Texture::FilterType filter) {
 void Texture::
 void Texture::
 set_magfilter(Texture::FilterType filter) {
 set_magfilter(Texture::FilterType filter) {
   if (_magfilter != filter) {
   if (_magfilter != filter) {
-    ++_modified;
+    ++_properties_modified;
     _magfilter = filter;
     _magfilter = filter;
   }
   }
 }
 }
@@ -755,7 +756,7 @@ set_magfilter(Texture::FilterType filter) {
 void Texture::
 void Texture::
 set_anisotropic_degree(int anisotropic_degree) {
 set_anisotropic_degree(int anisotropic_degree) {
   if (_anisotropic_degree != anisotropic_degree) {
   if (_anisotropic_degree != anisotropic_degree) {
-    ++_modified;
+    ++_properties_modified;
     _anisotropic_degree = anisotropic_degree;
     _anisotropic_degree = anisotropic_degree;
   }
   }
 }
 }
@@ -771,7 +772,7 @@ set_anisotropic_degree(int anisotropic_degree) {
 void Texture::
 void Texture::
 set_border_color(const Colorf &color) {
 set_border_color(const Colorf &color) {
   if (_border_color != color) {
   if (_border_color != color) {
-    ++_modified;
+    ++_properties_modified;
     _border_color = color;
     _border_color = color;
   }
   }
 }
 }
@@ -798,7 +799,7 @@ set_border_color(const Colorf &color) {
 void Texture::
 void Texture::
 set_compression(Texture::CompressionMode compression) {
 set_compression(Texture::CompressionMode compression) {
   if (_compression != compression) {
   if (_compression != compression) {
-    ++_modified;
+    ++_properties_modified;
     _compression = compression;
     _compression = compression;
   }
   }
 }
 }
@@ -993,7 +994,7 @@ set_ram_image(PTA_uchar image, Texture::CompressionMode compression,
     _ram_images[0]._image = image;
     _ram_images[0]._image = image;
     _ram_images[0]._page_size = page_size;
     _ram_images[0]._page_size = page_size;
     _ram_image_compression = compression;
     _ram_image_compression = compression;
-    ++_modified;
+    ++_image_modified;
   }
   }
 }
 }
 
 
@@ -1091,7 +1092,7 @@ make_ram_mipmap_image(int n) {
 
 
   _ram_images[n]._image = PTA_uchar::empty_array(get_expected_ram_mipmap_image_size(n));
   _ram_images[n]._image = PTA_uchar::empty_array(get_expected_ram_mipmap_image_size(n));
   _ram_images[n]._page_size = get_expected_ram_mipmap_page_size(n);
   _ram_images[n]._page_size = get_expected_ram_mipmap_page_size(n);
-  ++_modified;
+  ++_image_modified;
   return _ram_images[n]._image;
   return _ram_images[n]._image;
 }
 }
 
 
@@ -1122,7 +1123,7 @@ set_ram_mipmap_image(int n, PTA_uchar image, size_t page_size) {
       _ram_images[n]._page_size != page_size) {
       _ram_images[n]._page_size != page_size) {
     _ram_images[n]._image = image;
     _ram_images[n]._image = image;
     _ram_images[n]._page_size = page_size;
     _ram_images[n]._page_size = page_size;
-    ++_modified;
+    ++_image_modified;
   }
   }
 }
 }
 
 
@@ -2320,7 +2321,7 @@ reload_ram_image() {
 //     Function: Texture::do_modify_ram_image
 //     Function: Texture::do_modify_ram_image
 //       Access: Protected
 //       Access: Protected
 //  Description: This is called internally to uniquify the ram image
 //  Description: This is called internally to uniquify the ram image
-//               pointer without updating _modified.
+//               pointer without updating _image_modified.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Texture::
 void Texture::
 do_modify_ram_image() {
 do_modify_ram_image() {
@@ -2336,7 +2337,7 @@ do_modify_ram_image() {
 //     Function: Texture::do_make_ram_image
 //     Function: Texture::do_make_ram_image
 //       Access: Protected
 //       Access: Protected
 //  Description: This is called internally to make a new ram image
 //  Description: This is called internally to make a new ram image
-//               without updating _modified.
+//               without updating _image_modified.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Texture::
 void Texture::
 do_make_ram_image() {
 do_make_ram_image() {
@@ -2351,7 +2352,7 @@ do_make_ram_image() {
 //     Function: Texture::do_modify_ram_mipmap_image
 //     Function: Texture::do_modify_ram_mipmap_image
 //       Access: Protected
 //       Access: Protected
 //  Description: This is called internally to uniquify the nth mipmap
 //  Description: This is called internally to uniquify the nth mipmap
-//               image pointer without updating _modified.
+//               image pointer without updating _image_modified.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void Texture::
 void Texture::
 do_modify_ram_mipmap_image(int n) {
 do_modify_ram_mipmap_image(int n) {
@@ -3352,16 +3353,23 @@ make_from_bam(const FactoryParams &params) {
 void Texture::
 void Texture::
 fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
 fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
   // We have already read in the filenames; don't read them again.
   // We have already read in the filenames; don't read them again.
-  _wrap_u = (WrapMode)scan.get_uint8();
-  _wrap_v = (WrapMode)scan.get_uint8();
-  _wrap_w = (WrapMode)scan.get_uint8();
-  _minfilter = (FilterType)scan.get_uint8();
-  _magfilter = (FilterType)scan.get_uint8();
-  _anisotropic_degree = scan.get_int16();
-  _border_color.read_datagram(scan);
-  _compression = CM_default;
+
+  // We use the setters here, instead of directly assigning these
+  // values, so that we will correctly update _properties_modified
+  // only if any of these changes.
+
+  set_wrap_u((WrapMode)scan.get_uint8());
+  set_wrap_v((WrapMode)scan.get_uint8());
+  set_wrap_w((WrapMode)scan.get_uint8());
+  set_minfilter((FilterType)scan.get_uint8());
+  set_magfilter((FilterType)scan.get_uint8());
+  set_anisotropic_degree(scan.get_int16());
+  Colorf border_color;
+  border_color.read_datagram(scan);
+  set_border_color(border_color);
+
   if (manager->get_file_minor_ver() >= 1) {
   if (manager->get_file_minor_ver() >= 1) {
-    _compression = (CompressionMode)scan.get_uint8();
+    set_compression((CompressionMode)scan.get_uint8());
   }
   }
 
 
   Format format = (Format)scan.get_uint8();
   Format format = (Format)scan.get_uint8();
@@ -3413,8 +3421,9 @@ fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
       _ram_images[n]._image = image;
       _ram_images[n]._image = image;
     }
     }
     _loaded_from_image = true;
     _loaded_from_image = true;
+    ++_image_modified;
+    ++_properties_modified;
   }
   }
-  ++_modified;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 4 - 2
panda/src/gobj/texture.h

@@ -302,7 +302,8 @@ PUBLISHED:
   void clear_ram_mipmap_images();
   void clear_ram_mipmap_images();
   void generate_ram_mipmap_images();
   void generate_ram_mipmap_images();
 
 
-  INLINE UpdateSeq get_modified() const;
+  INLINE UpdateSeq get_properties_modified() const;
+  INLINE UpdateSeq get_image_modified() const;
 
 
   void prepare(PreparedGraphicsObjects *prepared_objects);
   void prepare(PreparedGraphicsObjects *prepared_objects);
   bool release(PreparedGraphicsObjects *prepared_objects);
   bool release(PreparedGraphicsObjects *prepared_objects);
@@ -520,7 +521,8 @@ protected:
   typedef pvector<RamImage> RamImages;
   typedef pvector<RamImage> RamImages;
   RamImages _ram_images;
   RamImages _ram_images;
 
 
-  UpdateSeq _modified;
+  UpdateSeq _properties_modified;
+  UpdateSeq _image_modified;
 
 
 private:
 private:
   // The auxiliary data is not recorded to a bam file.
   // The auxiliary data is not recorded to a bam file.

+ 31 - 4
panda/src/gobj/textureContext.I

@@ -40,15 +40,40 @@ get_texture() const {
   return _texture;
   return _texture;
 }
 }
 
 
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: TextureContext::was_modified
 //     Function: TextureContext::was_modified
 //       Access: Public
 //       Access: Public
-//  Description: Returns true if the texture has been modified since the
-//               last time mark_loaded() was called.
+//  Description: Returns true if the texture properties or image have
+//               been modified since the last time mark_loaded() was
+//               called.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool TextureContext::
 INLINE bool TextureContext::
 was_modified() const {
 was_modified() const {
-  return get_modified() != _texture->get_modified();
+  return was_properties_modified() || was_image_modified();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextureContext::was_properties_modified
+//       Access: Public
+//  Description: Returns true if the texture properties (unrelated to
+//               the image) have been modified since the last time
+//               mark_loaded() was called.
+////////////////////////////////////////////////////////////////////
+INLINE bool TextureContext::
+was_properties_modified() const {
+  return _properties_modified != _texture->get_properties_modified();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextureContext::was_image_modified
+//       Access: Public
+//  Description: Returns true if the texture image has been modified
+//               since the last time mark_loaded() was called.
+////////////////////////////////////////////////////////////////////
+INLINE bool TextureContext::
+was_image_modified() const {
+  return _image_modified != _texture->get_image_modified();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -61,7 +86,9 @@ was_modified() const {
 INLINE void TextureContext::
 INLINE void TextureContext::
 mark_loaded() {
 mark_loaded() {
   //  _data_size_bytes = _data->get_texture_size_bytes();
   //  _data_size_bytes = _data->get_texture_size_bytes();
-  update_modified(_texture->get_modified());
+  _properties_modified = _texture->get_properties_modified();
+  _image_modified = _texture->get_image_modified();
+  update_modified(max(_properties_modified, _image_modified));
 
 
   // Assume the texture is now resident.
   // Assume the texture is now resident.
   set_resident(true);
   set_resident(true);

+ 4 - 0
panda/src/gobj/textureContext.h

@@ -45,6 +45,8 @@ public:
   INLINE Texture *get_texture() const;
   INLINE Texture *get_texture() const;
 
 
   INLINE bool was_modified() const;
   INLINE bool was_modified() const;
+  INLINE bool was_properties_modified() const;
+  INLINE bool was_image_modified() const;
   INLINE void mark_loaded();
   INLINE void mark_loaded();
 
 
 private:
 private:
@@ -52,6 +54,8 @@ private:
   // both own their TextureContexts!  That would create a circular
   // both own their TextureContexts!  That would create a circular
   // reference count.
   // reference count.
   Texture *_texture;
   Texture *_texture;
+  UpdateSeq _properties_modified;
+  UpdateSeq _image_modified;
   
   
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {