Browse Source

add gl-save-mipmaps

David Rose 24 years ago
parent
commit
74c8db2d68

+ 4 - 0
panda/src/glgsg/config_glgsg.cxx

@@ -53,6 +53,10 @@ bool gl_force_mipmaps = config_glgsg.GetBool("gl-force-mipmaps", false);
 // colors, using mipmap_level_*.rgb if they are available.
 // colors, using mipmap_level_*.rgb if they are available.
 bool gl_show_mipmaps = config_glgsg.GetBool("gl-show-mipmaps", false);
 bool gl_show_mipmaps = config_glgsg.GetBool("gl-show-mipmaps", false);
 
 
+// Configure this true to cause the generated mipmap images to be
+// written out to image files on the disk as they are generated.
+bool gl_save_mipmaps = config_glgsg.GetBool("gl-save-mipmaps", false);
+
 // Configure this true to cause all lighting normals to automatically
 // Configure this true to cause all lighting normals to automatically
 // be normalized by the graphics hardware before rendering.  This is
 // be normalized by the graphics hardware before rendering.  This is
 // necessary if you intend to render things under scale transforms and
 // necessary if you intend to render things under scale transforms and

+ 2 - 0
panda/src/glgsg/config_glgsg.h

@@ -31,6 +31,7 @@ extern bool gl_ignore_mipmaps;
 extern bool gl_force_mipmaps;
 extern bool gl_force_mipmaps;
 extern bool gl_show_mipmaps;
 extern bool gl_show_mipmaps;
 extern bool gl_auto_normalize_lighting;
 extern bool gl_auto_normalize_lighting;
+extern bool gl_save_mipmaps;
 
 
 // Ways to implement decals.
 // Ways to implement decals.
 enum GLDecalType {
 enum GLDecalType {
@@ -40,6 +41,7 @@ enum GLDecalType {
 };
 };
 extern GLDecalType gl_decal_type;
 extern GLDecalType gl_decal_type;
 
 
+
 extern EXPCL_PANDAGL void init_libglgsg();
 extern EXPCL_PANDAGL void init_libglgsg();
 
 
 #endif
 #endif

+ 61 - 3
panda/src/glgsg/glGraphicsStateGuardian.cxx

@@ -90,8 +90,7 @@
 #include <polygonOffsetAttribute.h>
 #include <polygonOffsetAttribute.h>
 #include <clockObject.h>
 #include <clockObject.h>
 #include <pStatTimer.h>
 #include <pStatTimer.h>
-
-#include <pandabase.h>
+#include <string_utils.h>
 
 
 #include "pvector.h"
 #include "pvector.h"
 #include <algorithm>
 #include <algorithm>
@@ -3775,6 +3774,11 @@ apply_texture_immediate(Texture *tex) {
       gluBuild2DMipmaps(GL_TEXTURE_2D, internal_format,
       gluBuild2DMipmaps(GL_TEXTURE_2D, internal_format,
                         pb->get_xsize(), pb->get_ysize(),
                         pb->get_xsize(), pb->get_ysize(),
                         external_format, type, pb->_image);
                         external_format, type, pb->_image);
+#ifndef NDEBUG
+      if (gl_save_mipmaps) {
+        save_mipmap_images(tex);
+      }
+#endif
       report_errors();
       report_errors();
       return true;
       return true;
     }
     }
@@ -4356,7 +4360,61 @@ build_phony_mipmap_level(int level, int xsize, int ysize) {
 
 
   delete pb;
   delete pb;
 }
 }
-#endif
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLGraphicsStateGuardian::save_mipmap_images
+//       Access: Protected
+//  Description: Saves out each mipmap level of the indicated texture
+//               (which must also be the currently active texture in
+//               the GL state) as a separate image file to disk.
+////////////////////////////////////////////////////////////////////
+void GLGraphicsStateGuardian::
+save_mipmap_images(Texture *tex) {
+  Filename filename = tex->get_name();
+  string name;
+  if (filename.empty()) {
+    static index = 0;
+    name = "texture" + format_string(index);
+    index++;
+  } else {
+    name = filename.get_basename_wo_extension();
+  }
+
+  PixelBuffer *pb = tex->get_ram_image();
+  nassertv(pb != (PixelBuffer *)NULL);
+
+  GLenum external_format = get_external_image_format(pb->get_format());
+  GLenum type = get_image_type(pb->get_image_type());
+
+  int xsize = pb->get_xsize();
+  int ysize = pb->get_ysize();
+
+  // Specify byte-alignment for the pixels on output.
+  glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+  int mipmap_level = 0;
+  do {
+    xsize = max(xsize, 1);
+    ysize = max(ysize, 1);
+
+    PT(PixelBuffer) mpb = 
+      new PixelBuffer(xsize, ysize, pb->get_num_components(),
+                      pb->get_component_width(), pb->get_image_type(),
+                      pb->get_format());
+    glGetTexImage(GL_TEXTURE_2D, mipmap_level, external_format, 
+                  type, mpb->_image);
+    Filename mipmap_filename = name + "_" + format_string(mipmap_level) + ".pnm";
+    nout << "Writing mipmap level " << mipmap_level
+         << " (" << xsize << " by " << ysize << ") " 
+         << mipmap_filename << "\n";
+    mpb->write(mipmap_filename);
+
+    xsize >>= 1;
+    ysize >>= 1;
+    mipmap_level++;
+  } while (xsize > 0 && ysize > 0);
+}
+#endif  // NDEBUG
 
 
 // factory and type stuff
 // factory and type stuff
 
 

+ 1 - 0
panda/src/glgsg/glGraphicsStateGuardian.h

@@ -268,6 +268,7 @@ protected:
 #ifndef NDEBUG
 #ifndef NDEBUG
   void build_phony_mipmaps(Texture *tex);
   void build_phony_mipmaps(Texture *tex);
   void build_phony_mipmap_level(int level, int xsize, int ysize);
   void build_phony_mipmap_level(int level, int xsize, int ysize);
+  void save_mipmap_images(Texture *tex);
 #endif
 #endif
 
 
   GLclampf _clear_color_red, _clear_color_green, _clear_color_blue,
   GLclampf _clear_color_red, _clear_color_green, _clear_color_blue,