Browse Source

text: use 64-bit coords in TextAssembler if vertices-float64 set

rdb 7 years ago
parent
commit
0f4168a304
1 changed files with 51 additions and 51 deletions
  1. 51 51
      panda/src/text/textAssembler.cxx

+ 51 - 51
panda/src/text/textAssembler.cxx

@@ -1137,52 +1137,30 @@ generate_quads(GeomNode *geom_node, const QuadMap &quad_map) {
     GeomTextGlyph::Glyphs glyphs;
     glyphs.reserve(quads.size());
 
-    static CPT(GeomVertexFormat) format;
-    if (format.is_null()) {
-      // The optimized code below assumes 32-bit floats, so let's make sure we
-      // got the right format by creating it ourselves.
-      format = GeomVertexFormat::register_format(new GeomVertexArrayFormat(
-        InternalName::get_vertex(), 3, GeomEnums::NT_float32, GeomEnums::C_point,
-        InternalName::get_texcoord(), 2, GeomEnums::NT_float32, GeomEnums::C_texcoord));
-    }
-
+    const GeomVertexFormat *format = GeomVertexFormat::get_v3t2();
     PT(GeomVertexData) vdata = new GeomVertexData("text", format, Geom::UH_static);
 
-    PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static);
-    if (quads.size() > 10922) {
-      tris->set_index_type(GeomEnums::NT_uint32);
-    } else {
-      tris->set_index_type(GeomEnums::NT_uint16);
-    }
-
-    int i = 0;
+    Thread *current_thread = Thread::get_current_thread();
 
     // This is quite a critical loop and GeomVertexWriter quickly becomes the
     // bottleneck.  So, I've written this out the hard way instead.  Two
-    // versions of the loop: one for 32-bit indices, one for 16-bit.
+    // versions of the loop: one for 32-bit floats, the other for 64-bit.
     {
       PT(GeomVertexArrayDataHandle) vtx_handle = vdata->modify_array_handle(0);
       vtx_handle->unclean_set_num_rows(quads.size() * 4);
 
-      Thread *current_thread = Thread::get_current_thread();
       unsigned char *write_ptr = vtx_handle->get_write_pointer();
-      size_t stride = format->get_array(0)->get_stride() / sizeof(PN_float32);
-
-      PN_float32 *vtx_ptr = (PN_float32 *)
-        (write_ptr + format->get_column(InternalName::get_vertex())->get_start());
-      PN_float32 *tex_ptr = (PN_float32 *)
-        (write_ptr + format->get_column(InternalName::get_texcoord())->get_start());
 
-      if (tris->get_index_type() == GeomEnums::NT_uint32) {
-        // 32-bit index case.
-        PT(GeomVertexArrayDataHandle) idx_handle = tris->modify_vertices_handle(current_thread);
-        idx_handle->unclean_set_num_rows(quads.size() * 6);
-        uint32_t *idx_ptr = (uint32_t *)idx_handle->get_write_pointer();
+      if (format->get_vertex_column()->get_numeric_type() == GeomEnums::NT_float32) {
+        // 32-bit vertex case.
+        size_t stride = format->get_array(0)->get_stride() / sizeof(PN_float32);
 
-        QuadDefs::const_iterator qi;
-        for (qi = quads.begin(); qi != quads.end(); ++qi) {
-          const QuadDef &quad = (*qi);
+        PN_float32 *vtx_ptr = (PN_float32 *)
+          (write_ptr + format->get_column(InternalName::get_vertex())->get_start());
+        PN_float32 *tex_ptr = (PN_float32 *)
+          (write_ptr + format->get_column(InternalName::get_texcoord())->get_start());
 
+        for (const QuadDef &quad : quads) {
           vtx_ptr[0] = quad._dimensions[0] + quad._slanth;
           vtx_ptr[1] = 0;
           vtx_ptr[2] = quad._dimensions[3];
@@ -1219,26 +1197,18 @@ generate_quads(GeomNode *geom_node, const QuadMap &quad_map) {
           tex_ptr[1] = quad._uvs[1];
           tex_ptr += stride;
 
-          *(idx_ptr++) = i + 0;
-          *(idx_ptr++) = i + 1;
-          *(idx_ptr++) = i + 2;
-          *(idx_ptr++) = i + 2;
-          *(idx_ptr++) = i + 1;
-          *(idx_ptr++) = i + 3;
-          i += 4;
-
           glyphs.push_back(move(quad._glyph));
         }
       } else {
-        // 16-bit index case.
-        PT(GeomVertexArrayDataHandle) idx_handle = tris->modify_vertices_handle(current_thread);
-        idx_handle->unclean_set_num_rows(quads.size() * 6);
-        uint16_t *idx_ptr = (uint16_t *)idx_handle->get_write_pointer();
+        // 64-bit vertex case.
+        size_t stride = format->get_array(0)->get_stride() / sizeof(PN_float64);
 
-        QuadDefs::const_iterator qi;
-        for (qi = quads.begin(); qi != quads.end(); ++qi) {
-          const QuadDef &quad = (*qi);
+        PN_float64 *vtx_ptr = (PN_float64 *)
+          (write_ptr + format->get_column(InternalName::get_vertex())->get_start());
+        PN_float64 *tex_ptr = (PN_float64 *)
+          (write_ptr + format->get_column(InternalName::get_texcoord())->get_start());
 
+        for (const QuadDef &quad : quads) {
           vtx_ptr[0] = quad._dimensions[0] + quad._slanth;
           vtx_ptr[1] = 0;
           vtx_ptr[2] = quad._dimensions[3];
@@ -1275,21 +1245,51 @@ generate_quads(GeomNode *geom_node, const QuadMap &quad_map) {
           tex_ptr[1] = quad._uvs[1];
           tex_ptr += stride;
 
+          glyphs.push_back(move(quad._glyph));
+        }
+      }
+    }
+
+    // Now write the indices.  Two cases: 32-bit indices and 16-bit indices.
+    int vtx_count = quads.size() * 4;
+    PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static);
+    if (vtx_count > 65535) {
+      tris->set_index_type(GeomEnums::NT_uint32);
+    } else {
+      tris->set_index_type(GeomEnums::NT_uint16);
+    }
+    {
+      PT(GeomVertexArrayDataHandle) idx_handle = tris->modify_vertices_handle(current_thread);
+      idx_handle->unclean_set_num_rows(quads.size() * 6);
+      if (tris->get_index_type() == GeomEnums::NT_uint16) {
+        // 16-bit index case.
+        uint16_t *idx_ptr = (uint16_t *)idx_handle->get_write_pointer();
+
+        for (int i = 0; i < vtx_count; i += 4) {
           *(idx_ptr++) = i + 0;
           *(idx_ptr++) = i + 1;
           *(idx_ptr++) = i + 2;
           *(idx_ptr++) = i + 2;
           *(idx_ptr++) = i + 1;
           *(idx_ptr++) = i + 3;
-          i += 4;
+        }
+      } else {
+        // 32-bit index case.
+        uint32_t *idx_ptr = (uint32_t *)idx_handle->get_write_pointer();
 
-          glyphs.push_back(move(quad._glyph));
+        for (int i = 0; i < vtx_count; i += 4) {
+          *(idx_ptr++) = i + 0;
+          *(idx_ptr++) = i + 1;
+          *(idx_ptr++) = i + 2;
+          *(idx_ptr++) = i + 2;
+          *(idx_ptr++) = i + 1;
+          *(idx_ptr++) = i + 3;
         }
       }
     }
 
     // We can compute this value much faster than GeomPrimitive can.
-    tris->set_minmax(0, i - 1, nullptr, nullptr);
+    tris->set_minmax(0, vtx_count - 1, nullptr, nullptr);
 
     PT(GeomTextGlyph) geom = new GeomTextGlyph(vdata);
     geom->_glyphs.swap(glyphs);