Browse Source

gobj: Fix double-precision colors not being clamped in GeomVertexWriter

rdb 3 years ago
parent
commit
0ace26a938
3 changed files with 55 additions and 0 deletions
  1. 1 0
      doc/ReleaseNotes
  2. 50 0
      panda/src/gobj/geomVertexColumn.cxx
  3. 4 0
      panda/src/gobj/geomVertexColumn.h

+ 1 - 0
doc/ReleaseNotes

@@ -81,6 +81,7 @@ Miscellaneous
 * Add various useful functions to interrogatedb module
 * Fix Python 3 issues unpacking uint types in Python 3 (#1380)
 * Fix interrogate syntax error with C++11-style attributes in declarators
+* Fix double-precision color values not being clamped by GeomVertexWriter
 * Fix regression with BufferViewer in double-precision build (#1365)
 * Fix `PandaNode.nested_vertices` not updating properly
 * Prevent Panda calculating bounding volume of Geom with custom bounding volume

+ 50 - 0
panda/src/gobj/geomVertexColumn.cxx

@@ -4475,6 +4475,20 @@ get_data4f(const unsigned char *pointer) {
   return _v4;
 }
 
+/**
+ *
+ */
+const LVecBase4d &GeomVertexColumn::Packer_argb_packed::
+get_data4d(const unsigned char *pointer) {
+  uint32_t dword = *(const uint32_t *)pointer;
+  _v4d.set(GeomVertexData::unpack_abcd_b(dword),
+           GeomVertexData::unpack_abcd_c(dword),
+           GeomVertexData::unpack_abcd_d(dword),
+           GeomVertexData::unpack_abcd_a(dword));
+  _v4d /= 255.0;
+  return _v4d;
+}
+
 /**
  *
  */
@@ -4489,6 +4503,20 @@ set_data4f(unsigned char *pointer, const LVecBase4f &data) {
      (unsigned int)(min(max(data[2], 0.0f), 1.0f) * 255.0f));
 }
 
+/**
+ *
+ */
+void GeomVertexColumn::Packer_argb_packed::
+set_data4d(unsigned char *pointer, const LVecBase4d &data) {
+  // when packing an argb, we want to make sure we cap the input values at 1
+  // since going above one will cause the value to be truncated.
+  *(uint32_t *)pointer = GeomVertexData::pack_abcd
+    ((unsigned int)(min(max(data[3], 0.0), 1.0) * 255.0),
+     (unsigned int)(min(max(data[0], 0.0), 1.0) * 255.0),
+     (unsigned int)(min(max(data[1], 0.0), 1.0) * 255.0),
+     (unsigned int)(min(max(data[2], 0.0), 1.0) * 255.0));
+}
+
 /**
  *
  */
@@ -4500,6 +4528,17 @@ get_data4f(const unsigned char *pointer) {
   return _v4;
 }
 
+/**
+ *
+ */
+const LVecBase4d &GeomVertexColumn::Packer_rgba_uint8_4::
+get_data4d(const unsigned char *pointer) {
+  _v4d.set((double)pointer[0], (double)pointer[1],
+           (double)pointer[2], (double)pointer[3]);
+  _v4d /= 255.0;
+  return _v4d;
+}
+
 /**
  *
  */
@@ -4511,6 +4550,17 @@ set_data4f(unsigned char *pointer, const LVecBase4f &data) {
   pointer[3] = (unsigned int)(min(max(data[3], 0.0f), 1.0f) * 255.0f);
 }
 
+/**
+ *
+ */
+void GeomVertexColumn::Packer_rgba_uint8_4::
+set_data4d(unsigned char *pointer, const LVecBase4d &data) {
+  pointer[0] = (unsigned int)(min(max(data[0], 0.0), 1.0) * 255.0);
+  pointer[1] = (unsigned int)(min(max(data[1], 0.0), 1.0) * 255.0);
+  pointer[2] = (unsigned int)(min(max(data[2], 0.0), 1.0) * 255.0);
+  pointer[3] = (unsigned int)(min(max(data[3], 0.0), 1.0) * 255.0);
+}
+
 /**
  *
  */

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

@@ -381,7 +381,9 @@ private:
   class Packer_argb_packed final : public Packer_color {
   public:
     virtual const LVecBase4f &get_data4f(const unsigned char *pointer);
+    virtual const LVecBase4d &get_data4d(const unsigned char *pointer);
     virtual void set_data4f(unsigned char *pointer, const LVecBase4f &value);
+    virtual void set_data4d(unsigned char *pointer, const LVecBase4d &value);
 
     virtual const char *get_name() const {
       return "Packer_argb_packed";
@@ -391,7 +393,9 @@ private:
   class Packer_rgba_uint8_4 final : public Packer_color {
   public:
     virtual const LVecBase4f &get_data4f(const unsigned char *pointer);
+    virtual const LVecBase4d &get_data4d(const unsigned char *pointer);
     virtual void set_data4f(unsigned char *pointer, const LVecBase4f &value);
+    virtual void set_data4d(unsigned char *pointer, const LVecBase4d &value);
 
     virtual const char *get_name() const {
       return "Packer_rgba_uint8_4";