Browse Source

Add load_sub_image

rdb 11 years ago
parent
commit
340169c80c
3 changed files with 91 additions and 18 deletions
  1. 17 0
      panda/src/gobj/texture.I
  2. 64 12
      panda/src/gobj/texture.cxx
  3. 10 6
      panda/src/gobj/texture.h

+ 17 - 0
panda/src/gobj/texture.I

@@ -351,6 +351,23 @@ load(const PfmFile &pfm, int z, int n, const LoaderOptions &options) {
   return false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::load_sub_image
+//       Access: Published
+//  Description: Stores the indicated image in a region of the
+//               texture.  The texture properties remain unchanged.
+//               This can be more efficient than updating an entire
+//               texture, but has a few restrictions: for one, you
+//               must ensure that the texture is still in RAM (eg.
+//               using set_keep_ram_image) and it may not be
+//               compressed.
+////////////////////////////////////////////////////////////////////
+INLINE bool Texture::
+load_sub_image(const PNMImage &image, int x, int y, int z, int n) {
+  CDWriter cdata(_cycler, true);
+  return do_load_sub_image(cdata, image, x, y, z, n);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::store
 //       Access: Published

+ 64 - 12
panda/src/gobj/texture.cxx

@@ -1332,7 +1332,7 @@ generate_simple_ram_image() {
 
   size_t expected_page_size = (size_t)(x_size * y_size * 4);
   PTA_uchar image = PTA_uchar::empty_array(expected_page_size, get_class_type());
-  convert_from_pnmimage(image, expected_page_size, 0, scaled, 4, 1);
+  convert_from_pnmimage(image, expected_page_size, x_size, 0, 0, 0, scaled, 4, 1);
 
   do_set_simple_ram_image(cdata, image, x_size, y_size);
   cdata->_simple_image_date_generated = (PN_int32)time(NULL);
@@ -3368,7 +3368,7 @@ do_read_one(CData *cdata, const Filename &fullpath, const Filename &alpha_fullpa
         image.take_from(new_image);
       }
     }
-    
+
     if (!do_load_one(cdata, image, fullpath.get_basename(), z, n, options)) {
       return false;
     }
@@ -3438,14 +3438,16 @@ do_load_one(CData *cdata, const PNMImage &pnmimage, const string &name, int z, i
     Thread::consider_yield();
 
     convert_from_pnmimage(cdata->_ram_images[n]._image,
-                          do_get_expected_ram_mipmap_page_size(cdata, n), z,
-                          scaled, cdata->_num_components, cdata->_component_width);
+                          do_get_expected_ram_mipmap_page_size(cdata, n),
+                          x_size, 0, 0, z, scaled,
+                          cdata->_num_components, cdata->_component_width);
   } else {
     // Now copy the pixel data from the PNMImage into our internal
     // cdata->_image component.
     convert_from_pnmimage(cdata->_ram_images[n]._image,
-                          do_get_expected_ram_mipmap_page_size(cdata, n), z,
-                          pnmimage, cdata->_num_components, cdata->_component_width);
+                          do_get_expected_ram_mipmap_page_size(cdata, n),
+                          x_size, 0, 0, z, pnmimage,
+                          cdata->_num_components, cdata->_component_width);
   }
   Thread::consider_yield();
 
@@ -3520,6 +3522,40 @@ do_load_one(CData *cdata, const PfmFile &pfm, const string &name, int z, int n,
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::do_load_sub_image
+//       Access: Protected, Virtual
+//  Description: Internal method to load an image into a section of
+//               a texture page or mipmap level.
+////////////////////////////////////////////////////////////////////
+bool Texture::
+do_load_sub_image(CData *cdata, const PNMImage &image, int x, int y, int z, int n) {
+  nassertr(n >= 0 && n < cdata->_ram_images.size(), false);
+
+  int tex_x_size = do_get_expected_mipmap_x_size(cdata, n);
+  int tex_y_size = do_get_expected_mipmap_y_size(cdata, n);
+  int tex_z_size = do_get_expected_mipmap_z_size(cdata, n);
+
+  nassertr(x >= 0 && x < tex_x_size, false);
+  nassertr(y >= 0 && y < tex_y_size, false);
+  nassertr(z >= 0 && z < tex_z_size, false);
+
+  nassertr(image.get_x_size() + x < tex_x_size, false);
+  nassertr(image.get_y_size() + y < tex_y_size, false);
+
+  // Flip y
+  y = cdata->_y_size - (image.get_y_size() + y);
+
+  cdata->inc_image_modified();
+  do_modify_ram_mipmap_image(cdata, n);
+  convert_from_pnmimage(cdata->_ram_images[n]._image,
+                        do_get_expected_ram_mipmap_page_size(cdata, n),
+                        tex_x_size, x, y, z, image,
+                        cdata->_num_components, cdata->_component_width);
+
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::do_read_txo_file
 //       Access: Protected
@@ -6009,12 +6045,22 @@ do_get_bam_rawdata(CData *cdata) {
 //               indicated PNMImage into the given ram_image.
 ////////////////////////////////////////////////////////////////////
 void Texture::
-convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
-                      const PNMImage &pnmimage,
-                      int num_components, int component_width) {
+convert_from_pnmimage(PTA_uchar &image, size_t page_size,
+                      int row_stride, int x, int y, int z,
+                      const PNMImage &pnmimage, int num_components,
+                      int component_width) {
   int x_size = pnmimage.get_x_size();
   int y_size = pnmimage.get_y_size();
   xelval maxval = pnmimage.get_maxval();
+  int pixel_size = num_components * component_width;
+
+  int row_skip = 0;
+  if (row_stride == 0) {
+    row_stride = x_size;
+  } else {
+    row_skip = (row_stride - x_size) * pixel_size;
+    nassertv(row_skip >= 0);
+  }
 
   bool is_grayscale = (num_components == 1 || num_components == 2);
   bool has_alpha = (num_components == 2 || num_components == 4);
@@ -6024,6 +6070,10 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
   nassertv(idx + page_size <= image.size());
   unsigned char *p = &image[idx];
 
+  if (x != 0 || y != 0) {
+    p += (row_stride * y + x) * pixel_size;
+  }
+
   if (maxval == 255 && component_width == 1) {
     // Most common case: one byte per pixel, and the source image
     // shows a maxval of 255.  No scaling is necessary.
@@ -6044,6 +6094,7 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
           }
         }
       }
+      p += row_skip;
     }
 
   } else if (maxval == 65535 && component_width == 2) {
@@ -6052,7 +6103,7 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
     for (int j = y_size-1; j >= 0; j--) {
       for (int i = 0; i < x_size; i++) {
         if (is_grayscale) {
-          store_unscaled_short(p, pnmimage.get_gray_val(i, j));
+           store_unscaled_short(p, pnmimage.get_gray_val(i, j));
         } else {
           store_unscaled_short(p, pnmimage.get_blue_val(i, j));
           store_unscaled_short(p, pnmimage.get_green_val(i, j));
@@ -6066,6 +6117,7 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
           }
         }
       }
+      p += row_skip;
     }
 
   } else if (component_width == 1) {
@@ -6091,6 +6143,7 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
           }
         }
       }
+      p += row_skip;
     }
 
   } else {  // component_width == 2
@@ -6116,10 +6169,9 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
           }
         }
       }
+      p += row_skip;
     }
   }
-
-  nassertv(p == &image[idx] + page_size);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 10 - 6
panda/src/gobj/texture.h

@@ -279,6 +279,7 @@ PUBLISHED:
   BLOCKING INLINE bool load(const PNMImage &pnmimage, int z, int n, const LoaderOptions &options = LoaderOptions());
   BLOCKING INLINE bool load(const PfmFile &pfm, const LoaderOptions &options = LoaderOptions());
   BLOCKING INLINE bool load(const PfmFile &pfm, int z, int n, const LoaderOptions &options = LoaderOptions());
+  BLOCKING INLINE bool load_sub_image(const PNMImage &pnmimage, int x, int y, int z=0, int n=0);
   BLOCKING INLINE bool store(PNMImage &pnmimage) const;
   BLOCKING INLINE bool store(PNMImage &pnmimage, int z, int n) const;
   BLOCKING INLINE bool store(PfmFile &pfm) const;
@@ -569,6 +570,8 @@ protected:
   virtual bool do_load_one(CData *cdata,
                            const PfmFile &pfm, const string &name,
                            int z, int n, const LoaderOptions &options);
+  virtual bool do_load_sub_image(CData *cdata, const PNMImage &image,
+                                 int x, int y, int z, int n);
   bool do_read_txo_file(CData *cdata, const Filename &fullpath);
   bool do_read_txo(CData *cdata, istream &in, const string &filename);
   bool do_read_dds_file(CData *cdata, const Filename &fullpath, bool header_only);
@@ -682,19 +685,20 @@ protected:
   };
 
 private:
-  static void convert_from_pnmimage(PTA_uchar &image, size_t page_size, 
-                                    int z, const PNMImage &pnmimage,
+  static void convert_from_pnmimage(PTA_uchar &image, size_t page_size,
+                                    int row_stride, int x, int y, int z,
+                                    const PNMImage &pnmimage,
                                     int num_components, int component_width);
-  static void convert_from_pfm(PTA_uchar &image, size_t page_size, 
-                               int z, const PfmFile &pfm, 
+  static void convert_from_pfm(PTA_uchar &image, size_t page_size,
+                               int z, const PfmFile &pfm,
                                int num_components, int component_width);
   static bool convert_to_pnmimage(PNMImage &pnmimage, int x_size, int y_size,
                                   int num_components, int component_width,
-                                  CPTA_uchar image, size_t page_size, 
+                                  CPTA_uchar image, size_t page_size,
                                   int z);
   static bool convert_to_pfm(PfmFile &pfm, int x_size, int y_size,
                              int num_components, int component_width,
-                             CPTA_uchar image, size_t page_size, 
+                             CPTA_uchar image, size_t page_size,
                              int z);
   static PTA_uchar read_dds_level_bgr8(Texture *tex, CData *cdata, const DDSHeader &header, 
                                        int n, istream &in);