Browse Source

fix various texture and OpenGL issues

David Rose 17 years ago
parent
commit
81f6ebd44e

+ 53 - 14
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -2717,7 +2717,7 @@ update_texture(TextureContext *tc, bool force) {
   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);
     bool okflag = upload_texture(gtc, force);
     if (!okflag) {
       GLCAT.error()
@@ -2728,8 +2728,20 @@ update_texture(TextureContext *tc, bool force) {
   } 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();
+    if (specify_texture(gtc)) {
+      // Actually, looks like the texture *does* need to be reloaded.
+      bool okflag = upload_texture(gtc, force);
+      if (!okflag) {
+        GLCAT.error()
+          << "Could not load " << *gtc->get_texture() << "\n";
+        return false;
+      }
+
+    } else {
+      // The texture didn't need reloading, but mark it fully updated
+      // now.
+      gtc->mark_loaded();
+    }
   }
   gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
 
@@ -3380,7 +3392,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
   CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
 
   apply_texture(gtc);
-  specify_texture(tex);
+  bool needs_reload = specify_texture(gtc);
 
   GLenum target = get_texture_target(tex->get_texture_type());
   GLint internal_format = get_internal_image_format(tex);
@@ -3395,7 +3407,12 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
     }
   }
 
-  bool new_image = gtc->was_image_modified();
+  bool new_image = needs_reload || gtc->was_image_modified();
+  if (internal_format != gtc->_internal_format) {
+    // If the internal format has changed, we need to reload the
+    // image.
+    new_image = true;
+  }
   if (z >= 0) {
     // Copy to a cube map face.
     target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
@@ -6839,14 +6856,17 @@ do_issue_tex_gen() {
 ////////////////////////////////////////////////////////////////////
 //     Function: GLGraphicsStateGuardian::specify_texture
 //       Access: Protected
-//  Description: Specifies the texture parameters.
+//  Description: Specifies the texture parameters.  Returns true if
+//               the texture may need to be reloaded.
 ////////////////////////////////////////////////////////////////////
-void CLP(GraphicsStateGuardian)::
-specify_texture(Texture *tex) {
+bool CLP(GraphicsStateGuardian)::
+specify_texture(CLP(TextureContext) *gtc) {
+  Texture *tex = gtc->get_texture();
+
   GLenum target = get_texture_target(tex->get_texture_type());
   if (target == GL_NONE) {
     // Unsupported target (e.g. 3-d texturing on GL 1.1).
-    return;
+    return false;
   }
 
   GLP(TexParameteri)(target, GL_TEXTURE_WRAP_S,
@@ -6918,6 +6938,14 @@ specify_texture(Texture *tex) {
   }
 
   report_my_gl_errors();
+
+  if (uses_mipmaps && !gtc->_uses_mipmaps) {
+    // Suddenly we require mipmaps.  This means the texture may need
+    // reloading.
+    return true;
+  }
+
+  return false;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -7319,8 +7347,8 @@ upload_texture_image(CLP(TextureContext) *gtc,
     if (GLCAT.is_debug()) {
       GLCAT.debug()
         << "loading new texture object, " << width << " x " << height
-        << " x " << depth << ", mipmaps " << mipmap_bias << " - " 
-        << num_ram_mipmap_levels << "\n";
+        << " x " << depth << ", mipmaps " << num_ram_mipmap_levels 
+        << ", uses_mipmaps = " << uses_mipmaps << "\n";
     }
 
     if (num_ram_mipmap_levels == 0) {
@@ -7418,8 +7446,8 @@ upload_texture_image(CLP(TextureContext) *gtc,
     if (GLCAT.is_debug()) {
       GLCAT.debug()
         << "subloading existing texture object, " << width << " x " << height
-        << " x " << depth << ", mipmaps " << mipmap_bias << " - " 
-        << num_ram_mipmap_levels << "\n";
+        << " x " << depth << ", mipmaps " << num_ram_mipmap_levels
+        << ", uses_mipmaps = " << uses_mipmaps << "\n";
     }
 
     for (int n = mipmap_bias; n < num_ram_mipmap_levels; ++n) {
@@ -7775,6 +7803,12 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
   }
   report_my_gl_errors();
 
+  if (width <= 0 || height <= 0 || depth <= 0) {
+    GLCAT.error()
+      << "No texture data for " << tex->get_name() << "\n";
+    return false;
+  }
+
   GLint internal_format = 0;
   GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
 
@@ -7802,6 +7836,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
     format = Texture::F_depth_stencil;
     break;
   case GL_RGBA:
+  case 4:
     format = Texture::F_rgba;
     break;
   case GL_RGBA4:
@@ -7816,6 +7851,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
     break;
 
   case GL_RGB:
+  case 3:
     format = Texture::F_rgb;
     break;
   case GL_RGB5:
@@ -7846,9 +7882,11 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
     format = Texture::F_alpha;
     break;
   case GL_LUMINANCE:
+  case 1:
     format = Texture::F_luminance;
     break;
   case GL_LUMINANCE_ALPHA:
+  case 2:
     format = Texture::F_luminance_alpha;
     break;
 
@@ -7902,6 +7940,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
     GLCAT.warning()
       << "Unhandled internal format for " << tex->get_name()
       << " : " << hex << "0x" << internal_format << dec << "\n";
+    return false;
   }
 
   // We don't want to call setup_texture() again; that resets too
@@ -8068,7 +8107,7 @@ extract_texture_image(PTA_uchar &image, size_t &page_size,
       << "Unable to extract texture for " << *tex
       << ", mipmap level " << n
       << " : " << get_error_string(error_code) << "\n";
-
+    nassertr(false, false);
     return false;
   }
 

+ 1 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -324,7 +324,7 @@ protected:
   void update_standard_texture_bindings();
 
   void do_auto_rescale_normal();
-  void specify_texture(Texture *tex);
+  bool specify_texture(CLP(TextureContext) *gtc);
   bool apply_texture(TextureContext *tc);
   bool upload_texture(CLP(TextureContext) *gtc, bool force);
   bool upload_texture_image(CLP(TextureContext) *gtc,

+ 20 - 1
panda/src/gobj/texture.cxx

@@ -2849,7 +2849,26 @@ do_unlock_and_reload_ram_image(bool allow_compression) {
     tex->do_reload_ram_image(allow_compression);
 
     _lock.acquire();
-    do_assign(*tex);
+    
+    // Rather than calling do_assign(), which would copy *all* of the
+    // reloaded texture's properties over, we only copy in the ones
+    // which are relevant to the ram image.  This way, if the
+    // properties have changed during the reload (for instance,
+    // because we reloaded a txo), it won't contaminate the original
+    // texture.
+    _x_size = tex->_x_size;
+    _y_size = tex->_y_size;
+    _z_size = tex->_z_size;
+    _orig_file_x_size = tex->_orig_file_x_size;
+    _orig_file_y_size = tex->_orig_file_y_size;
+    _num_components = tex->_num_components;
+    _component_width = tex->_component_width;
+    _texture_type = tex->_texture_type;
+    _format = tex->_format;
+    _component_type = tex->_component_type;
+    _keep_ram_image = tex->_keep_ram_image;
+    _ram_image_compression = tex->_ram_image_compression;
+    _ram_images = tex->_ram_images;
 
     nassertv(_reloading);
     _reloading = false;

+ 8 - 0
panda/src/gobj/texturePool.cxx

@@ -279,12 +279,14 @@ ns_load_texture(const Filename &orig_filename, int primary_file_num_channels,
   }
 
   if (cache->get_cache_compressed_textures() && tex->has_compression()) {
+#ifndef HAVE_SQUISH
     // We don't want to save the uncompressed version; we'll save the
     // compressed version when it becomes available.
     store_record = false;
     if (!compressed_cache_record) {
       tex->set_post_load_store_cache(true);
     }
+#endif // HAVE_SQUISH
 
   } else if (!cache->get_cache_textures()) {
     // We don't want to save this texture.
@@ -403,12 +405,14 @@ ns_load_texture(const Filename &orig_filename,
   }
 
   if (cache->get_cache_compressed_textures() && tex->has_compression()) {
+#ifndef HAVE_SQUISH
     // We don't want to save the uncompressed version; we'll save the
     // compressed version when it becomes available.
     store_record = false;
     if (!compressed_cache_record) {
       tex->set_post_load_store_cache(true);
     }
+#endif  // HAVE_SQUISH
 
   } else if (!cache->get_cache_textures()) {
     // We don't want to save this texture.
@@ -508,12 +512,14 @@ ns_load_3d_texture(const Filename &filename_pattern,
   }
 
   if (cache->get_cache_compressed_textures() && tex->has_compression()) {
+#ifndef HAVE_SQUISH
     // We don't want to save the uncompressed version; we'll save the
     // compressed version when it becomes available.
     store_record = false;
     if (!compressed_cache_record) {
       tex->set_post_load_store_cache(true);
     }
+#endif  // HAVE_SQUISH
 
   } else if (!cache->get_cache_textures()) {
     // We don't want to save this texture.
@@ -600,12 +606,14 @@ ns_load_cube_map(const Filename &filename_pattern, bool read_mipmaps,
   }
 
   if (cache->get_cache_compressed_textures() && tex->has_compression()) {
+#ifndef HAVE_SQUISH
     // We don't want to save the uncompressed version; we'll save the
     // compressed version when it becomes available.
     store_record = false;
     if (!compressed_cache_record) {
       tex->set_post_load_store_cache(true);
     }
+#endif  // HAVE_SQUISH
 
   } else if (!cache->get_cache_textures()) {
     // We don't want to save this texture.