From 2aad0846b9bc62817ff97632bfe7193763afc68a Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 1 Apr 2005 01:47:36 +0000 Subject: [PATCH] use_qpgeom for TextNode, CollisionSolid --- panda/src/collide/collisionInvSphere.cxx | 76 +++- panda/src/collide/collisionLine.cxx | 75 +++- panda/src/collide/collisionPlane.cxx | 65 ++- panda/src/collide/collisionPolygon.cxx | 78 +++- panda/src/collide/collisionRay.cxx | 75 +++- panda/src/collide/collisionSegment.cxx | 48 ++- panda/src/collide/collisionSphere.cxx | 79 +++- panda/src/collide/collisionTube.cxx | 140 ++++-- panda/src/framework/windowFramework.cxx | 2 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 2 +- panda/src/gobj/config_gobj.cxx | 10 + panda/src/gobj/config_gobj.h | 1 + panda/src/gobj/geom.cxx | 5 +- panda/src/gobj/geom.h | 2 +- panda/src/gobj/qpgeom.cxx | 38 ++ panda/src/gobj/qpgeom.h | 2 + panda/src/gobj/qpgeomPrimitive.cxx | 31 +- panda/src/gobj/qpgeomPrimitive.h | 1 + panda/src/gobj/qpgeomVertexArrayData.I | 28 +- panda/src/gobj/qpgeomVertexArrayData.cxx | 112 ++--- panda/src/gobj/qpgeomVertexArrayData.h | 17 +- panda/src/gobj/qpgeomVertexData.I | 12 +- panda/src/gobj/qpgeomVertexData.cxx | 52 ++- panda/src/gobj/qpgeomVertexData.h | 6 + panda/src/gobj/qpgeomVertexReader.I | 4 +- panda/src/gobj/qpgeomVertexReader.cxx | 7 + panda/src/gobj/qpgeomVertexReader.h | 6 + panda/src/gobj/qpgeomVertexWriter.I | 4 +- panda/src/gobj/qpgeomVertexWriter.cxx | 7 + panda/src/gobj/qpgeomVertexWriter.h | 6 + panda/src/pgraph/cullableObject.cxx | 2 +- panda/src/pgraph/geomNode.cxx | 2 +- panda/src/pgraph/geomTransformer.cxx | 8 +- panda/src/pgraph/geomTransformer.h | 12 +- panda/src/text/Sources.pp | 3 + panda/src/text/config_text.cxx | 4 + panda/src/text/dynamicTextGlyph.cxx | 105 +++-- panda/src/text/qpgeomTextGlyph.I | 47 ++ panda/src/text/qpgeomTextGlyph.cxx | 101 +++++ panda/src/text/qpgeomTextGlyph.h | 77 ++++ panda/src/text/staticTextFont.cxx | 74 +++- panda/src/text/staticTextFont.h | 8 +- panda/src/text/textNode.I | 2 + panda/src/text/textNode.cxx | 408 ++++++++++++------ panda/src/text/textProperties.cxx | 2 +- panda/src/text/text_composite1.cxx | 1 + 46 files changed, 1401 insertions(+), 446 deletions(-) create mode 100644 panda/src/text/qpgeomTextGlyph.I create mode 100644 panda/src/text/qpgeomTextGlyph.cxx create mode 100644 panda/src/text/qpgeomTextGlyph.h diff --git a/panda/src/collide/collisionInvSphere.cxx b/panda/src/collide/collisionInvSphere.cxx index 83e882f87f..7b2e62e31e 100644 --- a/panda/src/collide/collisionInvSphere.cxx +++ b/panda/src/collide/collisionInvSphere.cxx @@ -24,7 +24,6 @@ #include "collisionHandler.h" #include "collisionEntry.h" #include "config_collide.h" - #include "omniBoundingVolume.h" #include "datagram.h" #include "datagramIterator.h" @@ -32,6 +31,9 @@ #include "bamWriter.h" #include "geomTristrip.h" #include "nearly_zero.h" +#include "qpgeom.h" +#include "qpgeomTristrips.h" +#include "qpgeomVertexWriter.h" TypeHandle CollisionInvSphere::_type_handle; @@ -306,31 +308,61 @@ fill_viz_geom() { static const int num_slices = 16; static const int num_stacks = 8; - GeomTristrip *sphere = new GeomTristrip; - PTA_Vertexf verts; - PTA_int lengths; - verts.reserve((num_stacks * 2) * num_slices); - lengths.reserve(num_slices); + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + ("collision", qpGeomVertexFormat::get_v3cp(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + + PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static); + for (int sl = 0; sl < num_slices; ++sl) { + float longitude0 = (float)sl / (float)num_slices; + float longitude1 = (float)(sl + 1) / (float)num_slices; + vertex.add_data3f(compute_point(0.0, longitude0)); + for (int st = 1; st < num_stacks; ++st) { + float latitude = (float)st / (float)num_stacks; + vertex.add_data3f(compute_point(latitude, longitude1)); + vertex.add_data3f(compute_point(latitude, longitude0)); + } + vertex.add_data3f(compute_point(1.0, longitude0)); - for (int sl = 0; sl < num_slices; sl++) { - float longitude0 = (float)sl / (float)num_slices; - float longitude1 = (float)(sl + 1) / (float)num_slices; - verts.push_back(compute_point(0.0, longitude0)); - for (int st = 1; st < num_stacks; st++) { - float latitude = (float)st / (float)num_stacks; - verts.push_back(compute_point(latitude, longitude1)); - verts.push_back(compute_point(latitude, longitude0)); + strip->add_next_vertices(num_stacks * 2); + strip->close_primitive(); } - verts.push_back(compute_point(1.0, longitude0)); - lengths.push_back(num_stacks * 2); + PT(qpGeom) geom = new qpGeom; + geom->set_vertex_data(vdata); + geom->add_primitive(strip); + + _viz_geom->add_geom(geom, get_solid_viz_state()); + + } else { + GeomTristrip *sphere = new GeomTristrip; + PTA_Vertexf verts; + PTA_int lengths; + verts.reserve((num_stacks * 2) * num_slices); + lengths.reserve(num_slices); + + for (int sl = 0; sl < num_slices; sl++) { + float longitude0 = (float)sl / (float)num_slices; + float longitude1 = (float)(sl + 1) / (float)num_slices; + verts.push_back(compute_point(0.0, longitude0)); + for (int st = 1; st < num_stacks; st++) { + float latitude = (float)st / (float)num_stacks; + verts.push_back(compute_point(latitude, longitude1)); + verts.push_back(compute_point(latitude, longitude0)); + } + verts.push_back(compute_point(1.0, longitude0)); + + lengths.push_back(num_stacks * 2); + } + + sphere->set_coords(verts); + sphere->set_lengths(lengths); + sphere->set_num_prims(num_slices); + + _viz_geom->add_geom(sphere, get_solid_viz_state()); } - - sphere->set_coords(verts); - sphere->set_lengths(lengths); - sphere->set_num_prims(num_slices); - - _viz_geom->add_geom(sphere, get_solid_viz_state()); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/collide/collisionLine.cxx b/panda/src/collide/collisionLine.cxx index 43a63660d5..1189c74bd7 100644 --- a/panda/src/collide/collisionLine.cxx +++ b/panda/src/collide/collisionLine.cxx @@ -30,6 +30,9 @@ #include "datagramIterator.h" #include "bamReader.h" #include "bamWriter.h" +#include "qpgeom.h" +#include "qpgeomLinestrips.h" +#include "qpgeomVertexWriter.h" TypeHandle CollisionLine::_type_handle; @@ -77,34 +80,62 @@ fill_viz_geom() { << "Recomputing viz for " << *this << "\n"; } - GeomLinestrip *line = new GeomLinestrip; - PTA_Vertexf verts; - PTA_Colorf colors; - PTA_int lengths; - static const int num_points = 100; static const double scale = 100.0; - verts.reserve(num_points); - colors.reserve(num_points); + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + ("collision", qpGeomVertexFormat::get_v3cp(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + qpGeomVertexWriter color(vdata, InternalName::get_color()); + + for (int i = 0; i < num_points; i++) { + double t = ((double)i / (double)num_points - 0.5) * 2.0; + vertex.add_data3f(get_origin() + t * scale * get_direction()); + + color.add_data4f(Colorf(1.0f, 1.0f, 1.0f, 1.0f) + + fabs(t) * Colorf(0.0f, 0.0f, 0.0f, -1.0f)); + } - for (int i = 0; i < num_points; i++) { - double t = ((double)i / (double)num_points - 0.5) * 2.0; - verts.push_back(get_origin() + t * scale * get_direction()); + PT(qpGeomLinestrips) line = new qpGeomLinestrips(qpGeomUsageHint::UH_static); + line->add_next_vertices(num_points); + line->close_primitive(); - colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f) + - fabs(t) * Colorf(0.0f, 0.0f, 0.0f, -1.0f)); + PT(qpGeom) geom = new qpGeom; + geom->set_vertex_data(vdata); + geom->add_primitive(line); + + _viz_geom->add_geom(geom, get_other_viz_state()); + _bounds_viz_geom->add_geom(geom, get_other_bounds_viz_state()); + + } else { + GeomLinestrip *line = new GeomLinestrip; + PTA_Vertexf verts; + PTA_Colorf colors; + PTA_int lengths; + + verts.reserve(num_points); + colors.reserve(num_points); + + for (int i = 0; i < num_points; i++) { + double t = ((double)i / (double)num_points - 0.5) * 2.0; + verts.push_back(get_origin() + t * scale * get_direction()); + + colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f) + + fabs(t) * Colorf(0.0f, 0.0f, 0.0f, -1.0f)); + } + line->set_coords(verts); + line->set_colors(colors, G_PER_VERTEX); + + lengths.push_back(num_points-1); + line->set_lengths(lengths); + + line->set_num_prims(1); + + _viz_geom->add_geom(line, get_other_viz_state()); + _bounds_viz_geom->add_geom(line, get_other_bounds_viz_state()); } - line->set_coords(verts); - line->set_colors(colors, G_PER_VERTEX); - - lengths.push_back(num_points-1); - line->set_lengths(lengths); - - line->set_num_prims(1); - - _viz_geom->add_geom(line, get_other_viz_state()); - _bounds_viz_geom->add_geom(line, get_other_bounds_viz_state()); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/collide/collisionPlane.cxx b/panda/src/collide/collisionPlane.cxx index 5cd35faae4..9ccf9456a6 100644 --- a/panda/src/collide/collisionPlane.cxx +++ b/panda/src/collide/collisionPlane.cxx @@ -25,7 +25,6 @@ #include "collisionRay.h" #include "collisionSegment.h" #include "config_collide.h" - #include "pointerToArray.h" #include "geomNode.h" #include "geom.h" @@ -35,6 +34,10 @@ #include "bamWriter.h" #include "omniBoundingVolume.h" #include "geomQuad.h" +#include "qpgeom.h" +#include "qpgeomTrifans.h" +#include "qpgeomLinestrips.h" +#include "qpgeomVertexWriter.h" TypeHandle CollisionPlane::_type_handle; @@ -322,20 +325,56 @@ fill_viz_geom() { static const double plane_scale = 10.0; - PTA_Vertexf verts; - verts.push_back(cp + p1 * plane_scale); - verts.push_back(cp + p2 * plane_scale); - verts.push_back(cp + p3 * plane_scale); - verts.push_back(cp + p4 * plane_scale); + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + ("collision", qpGeomVertexFormat::get_v3cp(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); - GeomQuad *quad = new GeomQuad; - quad->set_coords(verts); - quad->set_num_prims(1); + vertex.add_data3f(cp + p1 * plane_scale); + vertex.add_data3f(cp + p2 * plane_scale); + vertex.add_data3f(cp + p3 * plane_scale); + vertex.add_data3f(cp + p4 * plane_scale); + + PT(qpGeomTrifans) body = new qpGeomTrifans(qpGeomUsageHint::UH_static); + body->add_consecutive_vertices(0, 4); + body->close_primitive(); - _viz_geom->add_geom(quad, get_solid_viz_state()); - _viz_geom->add_geom(quad, get_wireframe_viz_state()); - _bounds_viz_geom->add_geom(quad, get_solid_bounds_viz_state()); - _bounds_viz_geom->add_geom(quad, get_wireframe_bounds_viz_state()); + PT(qpGeomLinestrips) border = new qpGeomLinestrips(qpGeomUsageHint::UH_static); + border->add_consecutive_vertices(0, 4); + border->add_vertex(0); + border->close_primitive(); + + PT(qpGeom) geom1 = new qpGeom; + geom1->set_vertex_data(vdata); + geom1->add_primitive(body); + + PT(qpGeom) geom2 = new qpGeom; + geom2->set_vertex_data(vdata); + geom2->add_primitive(border); + + _viz_geom->add_geom(geom1, get_solid_viz_state()); + _viz_geom->add_geom(geom2, get_wireframe_viz_state()); + + _bounds_viz_geom->add_geom(geom1, get_solid_bounds_viz_state()); + _bounds_viz_geom->add_geom(geom2, get_wireframe_bounds_viz_state()); + + } else { + PTA_Vertexf verts; + verts.push_back(cp + p1 * plane_scale); + verts.push_back(cp + p2 * plane_scale); + verts.push_back(cp + p3 * plane_scale); + verts.push_back(cp + p4 * plane_scale); + + GeomQuad *quad = new GeomQuad; + quad->set_coords(verts); + quad->set_num_prims(1); + + _viz_geom->add_geom(quad, get_solid_viz_state()); + _viz_geom->add_geom(quad, get_wireframe_viz_state()); + _bounds_viz_geom->add_geom(quad, get_solid_bounds_viz_state()); + _bounds_viz_geom->add_geom(quad, get_wireframe_bounds_viz_state()); + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/collide/collisionPolygon.cxx b/panda/src/collide/collisionPolygon.cxx index a95bb1289e..138d721f7b 100644 --- a/panda/src/collide/collisionPolygon.cxx +++ b/panda/src/collide/collisionPolygon.cxx @@ -24,7 +24,6 @@ #include "collisionRay.h" #include "collisionSegment.h" #include "config_collide.h" - #include "cullTraverserData.h" #include "boundingSphere.h" #include "pointerToArray.h" @@ -38,6 +37,10 @@ #include "transformState.h" #include "clipPlaneAttrib.h" #include "nearly_zero.h" +#include "qpgeom.h" +#include "qpgeomTrifans.h" +#include "qpgeomLinestrips.h" +#include "qpgeomVertexWriter.h" #include @@ -813,25 +816,62 @@ draw_polygon(GeomNode *viz_geom_node, GeomNode *bounds_viz_geom_node, LMatrix4f to_3d_mat; rederive_to_3d_mat(to_3d_mat); - PTA_Vertexf verts; - Points::const_iterator pi; - for (pi = points.begin(); pi != points.end(); ++pi) { - verts.push_back(to_3d((*pi)._p, to_3d_mat)); + + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + ("collision", qpGeomVertexFormat::get_v3cp(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + + Points::const_iterator pi; + for (pi = points.begin(); pi != points.end(); ++pi) { + vertex.add_data3f(to_3d((*pi)._p, to_3d_mat)); + } + + PT(qpGeomTrifans) body = new qpGeomTrifans(qpGeomUsageHint::UH_static); + body->add_consecutive_vertices(0, points.size()); + body->close_primitive(); + + PT(qpGeomLinestrips) border = new qpGeomLinestrips(qpGeomUsageHint::UH_static); + border->add_consecutive_vertices(0, points.size()); + border->add_vertex(0); + border->close_primitive(); + + PT(qpGeom) geom1 = new qpGeom; + geom1->set_vertex_data(vdata); + geom1->add_primitive(body); + + PT(qpGeom) geom2 = new qpGeom; + geom2->set_vertex_data(vdata); + geom2->add_primitive(border); + + _viz_geom->add_geom(geom1, ((CollisionPolygon *)this)->get_solid_viz_state()); + _viz_geom->add_geom(geom2, ((CollisionPolygon *)this)->get_wireframe_viz_state()); + + _bounds_viz_geom->add_geom(geom1, ((CollisionPolygon *)this)->get_solid_bounds_viz_state()); + _bounds_viz_geom->add_geom(geom2, ((CollisionPolygon *)this)->get_wireframe_bounds_viz_state()); + + } else { + PTA_Vertexf verts; + Points::const_iterator pi; + for (pi = points.begin(); pi != points.end(); ++pi) { + verts.push_back(to_3d((*pi)._p, to_3d_mat)); + } + + PTA_int lengths; + lengths.push_back(points.size()); + + GeomPolygon *polygon = new GeomPolygon; + polygon->set_coords(verts); + polygon->set_num_prims(1); + polygon->set_lengths(lengths); + + viz_geom_node->add_geom(polygon, ((CollisionPolygon *)this)->get_solid_viz_state()); + viz_geom_node->add_geom(polygon, ((CollisionPolygon *)this)->get_wireframe_viz_state()); + + bounds_viz_geom_node->add_geom(polygon, ((CollisionPolygon *)this)->get_solid_bounds_viz_state()); + bounds_viz_geom_node->add_geom(polygon, ((CollisionPolygon *)this)->get_wireframe_bounds_viz_state()); } - - PTA_int lengths; - lengths.push_back(points.size()); - - GeomPolygon *polygon = new GeomPolygon; - polygon->set_coords(verts); - polygon->set_num_prims(1); - polygon->set_lengths(lengths); - - viz_geom_node->add_geom(polygon, ((CollisionPolygon *)this)->get_solid_viz_state()); - viz_geom_node->add_geom(polygon, ((CollisionPolygon *)this)->get_wireframe_viz_state()); - - bounds_viz_geom_node->add_geom(polygon, ((CollisionPolygon *)this)->get_solid_bounds_viz_state()); - bounds_viz_geom_node->add_geom(polygon, ((CollisionPolygon *)this)->get_wireframe_bounds_viz_state()); } diff --git a/panda/src/collide/collisionRay.cxx b/panda/src/collide/collisionRay.cxx index 0e74da28f5..88d9e3925e 100644 --- a/panda/src/collide/collisionRay.cxx +++ b/panda/src/collide/collisionRay.cxx @@ -30,6 +30,9 @@ #include "datagramIterator.h" #include "bamReader.h" #include "bamWriter.h" +#include "qpgeom.h" +#include "qpgeomLinestrips.h" +#include "qpgeomVertexWriter.h" TypeHandle CollisionRay::_type_handle; @@ -149,34 +152,62 @@ fill_viz_geom() { << "Recomputing viz for " << *this << "\n"; } - GeomLinestrip *line = new GeomLinestrip; - PTA_Vertexf verts; - PTA_Colorf colors; - PTA_int lengths; - static const int num_points = 100; static const double scale = 100.0; - verts.reserve(num_points); - colors.reserve(num_points); + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + ("collision", qpGeomVertexFormat::get_v3cp(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + qpGeomVertexWriter color(vdata, InternalName::get_color()); + + for (int i = 0; i < num_points; i++) { + double t = ((double)i / (double)num_points); + vertex.add_data3f(get_origin() + t * scale * get_direction()); + + color.add_data4f(Colorf(1.0f, 1.0f, 1.0f, 1.0f) + + t * Colorf(0.0f, 0.0f, 0.0f, -1.0f)); + } - for (int i = 0; i < num_points; i++) { - double t = ((double)i / (double)num_points); - verts.push_back(get_origin() + t * scale * get_direction()); + PT(qpGeomLinestrips) line = new qpGeomLinestrips(qpGeomUsageHint::UH_static); + line->add_next_vertices(num_points); + line->close_primitive(); - colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f) + - t * Colorf(0.0f, 0.0f, 0.0f, -1.0f)); + PT(qpGeom) geom = new qpGeom; + geom->set_vertex_data(vdata); + geom->add_primitive(line); + + _viz_geom->add_geom(geom, get_other_viz_state()); + _bounds_viz_geom->add_geom(geom, get_other_bounds_viz_state()); + + } else { + GeomLinestrip *line = new GeomLinestrip; + PTA_Vertexf verts; + PTA_Colorf colors; + PTA_int lengths; + + verts.reserve(num_points); + colors.reserve(num_points); + + for (int i = 0; i < num_points; i++) { + double t = ((double)i / (double)num_points); + verts.push_back(get_origin() + t * scale * get_direction()); + + colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f) + + t * Colorf(0.0f, 0.0f, 0.0f, -1.0f)); + } + line->set_coords(verts); + line->set_colors(colors, G_PER_VERTEX); + + lengths.push_back(num_points-1); + line->set_lengths(lengths); + + line->set_num_prims(1); + + _viz_geom->add_geom(line, get_other_viz_state()); + _bounds_viz_geom->add_geom(line, get_other_bounds_viz_state()); } - line->set_coords(verts); - line->set_colors(colors, G_PER_VERTEX); - - lengths.push_back(num_points-1); - line->set_lengths(lengths); - - line->set_num_prims(1); - - _viz_geom->add_geom(line, get_other_viz_state()); - _bounds_viz_geom->add_geom(line, get_other_bounds_viz_state()); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/collide/collisionSegment.cxx b/panda/src/collide/collisionSegment.cxx index f1db398517..7453310f19 100644 --- a/panda/src/collide/collisionSegment.cxx +++ b/panda/src/collide/collisionSegment.cxx @@ -21,7 +21,6 @@ #include "collisionHandler.h" #include "collisionEntry.h" #include "config_collide.h" - #include "geom.h" #include "lensNode.h" #include "geomNode.h" @@ -32,6 +31,9 @@ #include "datagramIterator.h" #include "bamReader.h" #include "bamWriter.h" +#include "qpgeom.h" +#include "qpgeomLines.h" +#include "qpgeomVertexWriter.h" TypeHandle CollisionSegment::_type_handle; @@ -157,19 +159,41 @@ fill_viz_geom() { << "Recomputing viz for " << *this << "\n"; } - GeomLine *segment = new GeomLine; - PTA_Vertexf verts; - PTA_Colorf colors; - verts.push_back(_a); - verts.push_back(_b); - colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); - segment->set_coords(verts); - segment->set_colors(colors, G_OVERALL); + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + ("collision", qpGeomVertexFormat::get_v3cp(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + + vertex.add_data3f(_a); + vertex.add_data3f(_b); - segment->set_num_prims(1); + PT(qpGeomLines) line = new qpGeomLines(qpGeomUsageHint::UH_static); + line->add_next_vertices(2); + line->close_primitive(); - _viz_geom->add_geom(segment, get_other_viz_state()); - _bounds_viz_geom->add_geom(segment, get_other_bounds_viz_state()); + PT(qpGeom) geom = new qpGeom; + geom->set_vertex_data(vdata); + geom->add_primitive(line); + + _viz_geom->add_geom(geom, get_other_viz_state()); + _bounds_viz_geom->add_geom(geom, get_other_bounds_viz_state()); + + } else { + GeomLine *segment = new GeomLine; + PTA_Vertexf verts; + PTA_Colorf colors; + verts.push_back(_a); + verts.push_back(_b); + colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); + segment->set_coords(verts); + segment->set_colors(colors, G_OVERALL); + + segment->set_num_prims(1); + + _viz_geom->add_geom(segment, get_other_viz_state()); + _bounds_viz_geom->add_geom(segment, get_other_bounds_viz_state()); + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/collide/collisionSphere.cxx b/panda/src/collide/collisionSphere.cxx index 142a57e0f8..8c1f09b8ec 100644 --- a/panda/src/collide/collisionSphere.cxx +++ b/panda/src/collide/collisionSphere.cxx @@ -24,7 +24,6 @@ #include "collisionHandler.h" #include "collisionEntry.h" #include "config_collide.h" - #include "boundingSphere.h" #include "datagram.h" #include "datagramIterator.h" @@ -34,6 +33,9 @@ #include "nearly_zero.h" #include "cmath.h" #include "mathNumbers.h" +#include "qpgeom.h" +#include "qpgeomTristrips.h" +#include "qpgeomVertexWriter.h" TypeHandle CollisionSphere::_type_handle; @@ -325,32 +327,63 @@ fill_viz_geom() { static const int num_slices = 16; static const int num_stacks = 8; - GeomTristrip *sphere = new GeomTristrip; - PTA_Vertexf verts; - PTA_int lengths; - verts.reserve((num_stacks * 2) * num_slices); - lengths.reserve(num_slices); + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + ("collision", qpGeomVertexFormat::get_v3cp(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + + PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static); + for (int sl = 0; sl < num_slices; ++sl) { + float longitude0 = (float)sl / (float)num_slices; + float longitude1 = (float)(sl + 1) / (float)num_slices; + vertex.add_data3f(compute_point(0.0, longitude0)); + for (int st = 1; st < num_stacks; ++st) { + float latitude = (float)st / (float)num_stacks; + vertex.add_data3f(compute_point(latitude, longitude0)); + vertex.add_data3f(compute_point(latitude, longitude1)); + } + vertex.add_data3f(compute_point(1.0, longitude0)); - for (int sl = 0; sl < num_slices; sl++) { - float longitude0 = (float)sl / (float)num_slices; - float longitude1 = (float)(sl + 1) / (float)num_slices; - verts.push_back(compute_point(0.0, longitude0)); - for (int st = 1; st < num_stacks; st++) { - float latitude = (float)st / (float)num_stacks; - verts.push_back(compute_point(latitude, longitude0)); - verts.push_back(compute_point(latitude, longitude1)); + strip->add_next_vertices(num_stacks * 2); + strip->close_primitive(); } - verts.push_back(compute_point(1.0, longitude0)); - lengths.push_back(num_stacks * 2); + PT(qpGeom) geom = new qpGeom; + geom->set_vertex_data(vdata); + geom->add_primitive(strip); + + _viz_geom->add_geom(geom, get_solid_viz_state()); + _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state()); + + } else { + GeomTristrip *sphere = new GeomTristrip; + PTA_Vertexf verts; + PTA_int lengths; + verts.reserve((num_stacks * 2) * num_slices); + lengths.reserve(num_slices); + + for (int sl = 0; sl < num_slices; sl++) { + float longitude0 = (float)sl / (float)num_slices; + float longitude1 = (float)(sl + 1) / (float)num_slices; + verts.push_back(compute_point(0.0, longitude0)); + for (int st = 1; st < num_stacks; st++) { + float latitude = (float)st / (float)num_stacks; + verts.push_back(compute_point(latitude, longitude0)); + verts.push_back(compute_point(latitude, longitude1)); + } + verts.push_back(compute_point(1.0, longitude0)); + + lengths.push_back(num_stacks * 2); + } + + sphere->set_coords(verts); + sphere->set_lengths(lengths); + sphere->set_num_prims(num_slices); + + _viz_geom->add_geom(sphere, get_solid_viz_state()); + _bounds_viz_geom->add_geom(sphere, get_solid_bounds_viz_state()); } - - sphere->set_coords(verts); - sphere->set_lengths(lengths); - sphere->set_num_prims(num_slices); - - _viz_geom->add_geom(sphere, get_solid_viz_state()); - _bounds_viz_geom->add_geom(sphere, get_solid_bounds_viz_state()); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/collide/collisionTube.cxx b/panda/src/collide/collisionTube.cxx index 368c552bb2..278dd2e756 100644 --- a/panda/src/collide/collisionTube.cxx +++ b/panda/src/collide/collisionTube.cxx @@ -24,7 +24,6 @@ #include "collisionHandler.h" #include "collisionEntry.h" #include "config_collide.h" - #include "look_at.h" #include "geom.h" #include "geomNode.h" @@ -36,6 +35,9 @@ #include "bamWriter.h" #include "cmath.h" #include "transformState.h" +#include "qpgeom.h" +#include "qpgeomTristrips.h" +#include "qpgeomVertexWriter.h" TypeHandle CollisionTube::_type_handle; @@ -389,54 +391,108 @@ fill_viz_geom() { LVector3f direction = (_b - _a); float length = direction.length(); - PTA_Vertexf verts; - PTA_int lengths; + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + ("collision", qpGeomVertexFormat::get_v3cp(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + + PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static); + // Generate the first endcap. + static const int num_slices = 8; + static const int num_rings = 4; + int ri, si; + for (ri = 0; ri < num_rings; ri++) { + for (si = 0; si <= num_slices; si++) { + vertex.add_data3f(calc_sphere1_vertex(ri, si, num_rings, num_slices)); + vertex.add_data3f(calc_sphere1_vertex(ri + 1, si, num_rings, num_slices)); + } + strip->add_next_vertices((num_slices + 1) * 2); + strip->close_primitive(); + } - // Generate the first endcap. - static const int num_slices = 8; - static const int num_rings = 4; - int ri, si; - for (ri = 0; ri < num_rings; ri++) { + // Now the cylinder sides. for (si = 0; si <= num_slices; si++) { - verts.push_back(calc_sphere1_vertex(ri, si, num_rings, num_slices)); - verts.push_back(calc_sphere1_vertex(ri + 1, si, num_rings, num_slices)); + vertex.add_data3f(calc_sphere1_vertex(num_rings, si, num_rings, num_slices)); + vertex.add_data3f(calc_sphere2_vertex(num_rings, si, num_rings, num_slices, + length)); + } + strip->add_next_vertices((num_slices + 1) * 2); + strip->close_primitive(); + + // And the second endcap. + for (ri = num_rings - 1; ri >= 0; ri--) { + for (si = 0; si <= num_slices; si++) { + vertex.add_data3f(calc_sphere2_vertex(ri + 1, si, num_rings, num_slices, length)); + vertex.add_data3f(calc_sphere2_vertex(ri, si, num_rings, num_slices, length)); + } + strip->add_next_vertices((num_slices + 1) * 2); + strip->close_primitive(); + } + + PT(qpGeom) geom = new qpGeom; + geom->set_vertex_data(vdata); + geom->add_primitive(strip); + + // Now transform the vertices to their actual location. + LMatrix4f mat; + look_at(mat, direction, LVector3f(0.0f, 0.0f, 1.0f), CS_zup_right); + mat.set_row(3, _a); + geom->transform_vertices(mat); + + _viz_geom->add_geom(geom, get_solid_viz_state()); + _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state()); + + } else { + PTA_Vertexf verts; + PTA_int lengths; + + // Generate the first endcap. + static const int num_slices = 8; + static const int num_rings = 4; + int ri, si; + for (ri = 0; ri < num_rings; ri++) { + for (si = 0; si <= num_slices; si++) { + verts.push_back(calc_sphere1_vertex(ri, si, num_rings, num_slices)); + verts.push_back(calc_sphere1_vertex(ri + 1, si, num_rings, num_slices)); + } + lengths.push_back((num_slices + 1) * 2); + } + + // Now the cylinder sides. + for (si = 0; si <= num_slices; si++) { + verts.push_back(calc_sphere1_vertex(num_rings, si, num_rings, num_slices)); + verts.push_back(calc_sphere2_vertex(num_rings, si, num_rings, num_slices, + length)); } lengths.push_back((num_slices + 1) * 2); - } - // Now the cylinder sides. - for (si = 0; si <= num_slices; si++) { - verts.push_back(calc_sphere1_vertex(num_rings, si, num_rings, num_slices)); - verts.push_back(calc_sphere2_vertex(num_rings, si, num_rings, num_slices, - length)); - } - lengths.push_back((num_slices + 1) * 2); - - // And the second endcap. - for (ri = num_rings - 1; ri >= 0; ri--) { - for (si = 0; si <= num_slices; si++) { - verts.push_back(calc_sphere2_vertex(ri + 1, si, num_rings, num_slices, length)); - verts.push_back(calc_sphere2_vertex(ri, si, num_rings, num_slices, length)); + // And the second endcap. + for (ri = num_rings - 1; ri >= 0; ri--) { + for (si = 0; si <= num_slices; si++) { + verts.push_back(calc_sphere2_vertex(ri + 1, si, num_rings, num_slices, length)); + verts.push_back(calc_sphere2_vertex(ri, si, num_rings, num_slices, length)); + } + lengths.push_back((num_slices + 1) * 2); } - lengths.push_back((num_slices + 1) * 2); + + // Now transform the vertices to their actual location. + LMatrix4f mat; + look_at(mat, direction, LVector3f(0.0f, 0.0f, 1.0f), CS_zup_right); + mat.set_row(3, _a); + + for (size_t i = 0; i < verts.size(); i++) { + verts[i] = verts[i] * mat; + } + + GeomTristrip *tube = new GeomTristrip; + tube->set_coords(verts); + tube->set_num_prims(lengths.size()); + tube->set_lengths(lengths); + + _viz_geom->add_geom(tube, get_solid_viz_state()); + _bounds_viz_geom->add_geom(tube, get_solid_bounds_viz_state()); } - - // Now transform the vertices to their actual location. - LMatrix4f mat; - look_at(mat, direction, LVector3f(0.0f, 0.0f, 1.0f), CS_zup_right); - mat.set_row(3, _a); - - for (size_t i = 0; i < verts.size(); i++) { - verts[i] = verts[i] * mat; - } - - GeomTristrip *tube = new GeomTristrip; - tube->set_coords(verts); - tube->set_num_prims(lengths.size()); - tube->set_lengths(lengths); - - _viz_geom->add_geom(tube, get_solid_viz_state()); - _bounds_viz_geom->add_geom(tube, get_solid_bounds_viz_state()); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/framework/windowFramework.cxx b/panda/src/framework/windowFramework.cxx index 61b87feec1..c8046b174b 100644 --- a/panda/src/framework/windowFramework.cxx +++ b/panda/src/framework/windowFramework.cxx @@ -1060,7 +1060,7 @@ load_image_as_model(const Filename &filename) { if (use_qpgeom) { PT(qpGeomVertexData) vdata = new qpGeomVertexData - (string(), qpGeomVertexFormat::get_v3t2(), + (string(), qpGeomVertexFormat::get_v3cpt2(), qpGeomUsageHint::UH_static); qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index f712f61caa..9fcf92dee6 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -2635,7 +2635,7 @@ GeomContext *CLP(GraphicsStateGuardian):: prepare_geom(Geom *geom) { // Temporary test until the experimental Geom rewrite becomes the // actual Geom implementation. - if (geom->is_exact_type(qpGeom::get_class_type())) { + if (geom->is_of_type(qpGeom::get_class_type())) { CLP(GeomContext) *ggc = new CLP(GeomContext)(geom); return ggc; diff --git a/panda/src/gobj/config_gobj.cxx b/panda/src/gobj/config_gobj.cxx index 7a918189da..ddc7cf58be 100644 --- a/panda/src/gobj/config_gobj.cxx +++ b/panda/src/gobj/config_gobj.cxx @@ -167,6 +167,16 @@ ConfigVariableBool use_qpgeom "underway. Set this true if you want to use the experimental " "code. You don't really want to set this true.")); +ConfigVariableBool support_old_geom +("support-old-geom", true, + PRC_DESC("A temporary variable while the experimental Geom rewrite is " + "underway. Set this false if you DON't want to see anything " + "rendered from a legacy Geom. This is intended to help " + "prove visually that the experimental Geoms are actually " + "being used. You don't really want to set this false, and " + "you certainly don't want to monkey with it if you haven't " + "also set use-qpgeom true.")); + ConfigVariableEnum bam_texture_mode ("bam-texture-mode", BTM_relative, diff --git a/panda/src/gobj/config_gobj.h b/panda/src/gobj/config_gobj.h index cdaa68de13..750d91a4f3 100644 --- a/panda/src/gobj/config_gobj.h +++ b/panda/src/gobj/config_gobj.h @@ -59,6 +59,7 @@ extern EXPCL_PANDA ConfigVariableBool display_list_animation; extern EXPCL_PANDA ConfigVariableBool connect_triangle_strips; extern EXPCL_PANDA ConfigVariableBool use_qpgeom; +extern EXPCL_PANDA ConfigVariableBool support_old_geom; extern EXPCL_PANDA ConfigVariableEnum bam_texture_mode; extern EXPCL_PANDA ConfigVariableEnum textures_power_2; diff --git a/panda/src/gobj/geom.cxx b/panda/src/gobj/geom.cxx index afdc5c84d9..90a325c920 100644 --- a/panda/src/gobj/geom.cxx +++ b/panda/src/gobj/geom.cxx @@ -303,7 +303,7 @@ operator = (const Geom ©) { //////////////////////////////////////////////////////////////////// // Function: Geom::transform_vertices -// Access: Published +// Access: Published, Virtual // Description: Applies the indicated transform to all of the // vertices in the Geom. If the Geom happens to share a // vertex table with another Geom, this operation will @@ -917,6 +917,9 @@ release_all() { void Geom:: draw(GraphicsStateGuardianBase *gsg, const qpGeomMunger *, const qpGeomVertexData *) const { + if (!support_old_geom) { + return; + } PreparedGraphicsObjects *prepared_objects = gsg->get_prepared_objects(); if (is_dirty()) { ((Geom *)this)->config(); diff --git a/panda/src/gobj/geom.h b/panda/src/gobj/geom.h index 219bbdc1b9..95c4bd8983 100644 --- a/panda/src/gobj/geom.h +++ b/panda/src/gobj/geom.h @@ -135,7 +135,7 @@ public: virtual Geom *make_copy() const=0; PUBLISHED: - void transform_vertices(const LMatrix4f &mat); + virtual void transform_vertices(const LMatrix4f &mat); void set_coords(const PTA_Vertexf &coords, const PTA_ushort &vindex = PTA_ushort()); diff --git a/panda/src/gobj/qpgeom.cxx b/panda/src/gobj/qpgeom.cxx index 4cb4f7327e..4664d6edc7 100644 --- a/panda/src/gobj/qpgeom.cxx +++ b/panda/src/gobj/qpgeom.cxx @@ -18,6 +18,7 @@ #include "qpgeom.h" #include "qpgeomVertexReader.h" +#include "qpgeomVertexRewriter.h" #include "pStatTimer.h" #include "bamReader.h" #include "bamWriter.h" @@ -224,6 +225,43 @@ get_num_bytes() const { return num_bytes; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeom::transform_vertices +// Access: Published, Virtual +// Description: Applies the indicated transform to all of the +// vertices in the Geom. If the Geom happens to share a +// vertex table with another Geom, this operation will +// duplicate the vertex table instead of breaking the +// other Geom; however, if multiple Geoms with shared +// tables are transformed by the same matrix, they will +// no longer share tables after the operation. Consider +// using the GeomTransformer if you will be applying the +// same transform to multiple Geoms. +//////////////////////////////////////////////////////////////////// +void qpGeom:: +transform_vertices(const LMatrix4f &mat) { + PT(qpGeomVertexData) new_data = modify_vertex_data(); + CPT(qpGeomVertexFormat) format = new_data->get_format(); + + int ci; + for (ci = 0; ci < format->get_num_points(); ci++) { + qpGeomVertexRewriter data(new_data, format->get_point(ci)); + + while (!data.is_at_end()) { + const LPoint3f &point = data.get_data3f(); + data.set_data3f(point * mat); + } + } + for (ci = 0; ci < format->get_num_vectors(); ci++) { + qpGeomVertexRewriter data(new_data, format->get_vector(ci)); + + while (!data.is_at_end()) { + const LVector3f &vector = data.get_data3f(); + data.set_data3f(normalize(vector * mat)); + } + } +} + //////////////////////////////////////////////////////////////////// // Function: qpGeom::munge_geom // Access: Published diff --git a/panda/src/gobj/qpgeom.h b/panda/src/gobj/qpgeom.h index 4943cda0af..40635baf20 100644 --- a/panda/src/gobj/qpgeom.h +++ b/panda/src/gobj/qpgeom.h @@ -84,6 +84,8 @@ PUBLISHED: int get_num_bytes() const; INLINE UpdateSeq get_modified() const; + virtual void transform_vertices(const LMatrix4f &mat); + void munge_geom(const qpGeomMunger *munger, CPT(qpGeom) &result, CPT(qpGeomVertexData) &data) const; diff --git a/panda/src/gobj/qpgeomPrimitive.cxx b/panda/src/gobj/qpgeomPrimitive.cxx index c9b9fed202..64530e0760 100644 --- a/panda/src/gobj/qpgeomPrimitive.cxx +++ b/panda/src/gobj/qpgeomPrimitive.cxx @@ -101,7 +101,7 @@ add_vertex(int vertex) { int num_primitives = get_num_primitives(); if (num_primitives > 0 && - cdata->_vertices.size() == get_primitive_end(num_primitives - 1)) { + (int)cdata->_vertices.size() == get_primitive_end(num_primitives - 1)) { // If we are beginning a new primitive, give the derived class a // chance to insert some degenerate vertices. append_unused_vertices(cdata->_vertices, vertex); @@ -145,6 +145,15 @@ add_consecutive_vertices(int start, int num_vertices) { nassertv((int)short_start == start && (int)short_end == end); CDWriter cdata(_cycler); + + int num_primitives = get_num_primitives(); + if (num_primitives > 0 && + (int)cdata->_vertices.size() == get_primitive_end(num_primitives - 1)) { + // If we are beginning a new primitive, give the derived class a + // chance to insert some degenerate vertices. + append_unused_vertices(cdata->_vertices, start); + } + for (unsigned short v = short_start; v <= short_end; ++v) { cdata->_vertices.push_back(v); } @@ -170,6 +179,26 @@ add_consecutive_vertices(int start, int num_vertices) { } } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomPrimitive::add_next_vertices +// Access: Published +// Description: Adds the next n vertices in sequence, beginning from +// the last vertex added to the primitive + 1. +// +// This is most useful when you are building up a +// primitive and a GeomVertexData at the same time, and +// you just want the primitive to reference the first n +// vertices from the data, then the next n, and so on. +//////////////////////////////////////////////////////////////////// +void qpGeomPrimitive:: +add_next_vertices(int num_vertices) { + if (get_num_vertices() == 0) { + add_consecutive_vertices(0, num_vertices); + } else { + add_consecutive_vertices(get_vertex(get_num_vertices() - 1) + 1, num_vertices); + } +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomPrimitive::close_primitive // Access: Published diff --git a/panda/src/gobj/qpgeomPrimitive.h b/panda/src/gobj/qpgeomPrimitive.h index ba80a41061..f9ec63fc95 100644 --- a/panda/src/gobj/qpgeomPrimitive.h +++ b/panda/src/gobj/qpgeomPrimitive.h @@ -116,6 +116,7 @@ PUBLISHED: INLINE int get_vertex(int i) const; void add_vertex(int vertex); void add_consecutive_vertices(int start, int num_vertices); + void add_next_vertices(int num_vertices); bool close_primitive(); void clear_vertices(); diff --git a/panda/src/gobj/qpgeomVertexArrayData.I b/panda/src/gobj/qpgeomVertexArrayData.I index b73db4db84..4f8a4e7595 100644 --- a/panda/src/gobj/qpgeomVertexArrayData.I +++ b/panda/src/gobj/qpgeomVertexArrayData.I @@ -40,16 +40,15 @@ get_usage_hint() const { } //////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexArrayData::get_data +// Function: qpGeomVertexArrayData::has_column // Access: Published -// Description: Returns a const pointer to the actual vertex data, -// for application code to directly examine (but not -// modify). +// Description: Returns true if the array has the named column, +// false otherwise. This is really just a shortcut for +// asking the same thing from the format. //////////////////////////////////////////////////////////////////// -INLINE CPTA_uchar qpGeomVertexArrayData:: -get_data() const { - CDReader cdata(_cycler); - return cdata->_data; +INLINE bool qpGeomVertexArrayData:: +has_column(const InternalName *name) const { + return _array_format->has_column(name); } //////////////////////////////////////////////////////////////////// @@ -100,6 +99,19 @@ get_modified() const { return cdata->_modified; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexArrayData::get_data +// Access: Public +// Description: Returns a const pointer to the actual vertex data, +// for application code to directly examine (but not +// modify). +//////////////////////////////////////////////////////////////////// +INLINE CPTA_uchar qpGeomVertexArrayData:: +get_data() const { + CDReader cdata(_cycler); + return cdata->_data; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexArrayData::CData::Constructor // Access: Public diff --git a/panda/src/gobj/qpgeomVertexArrayData.cxx b/panda/src/gobj/qpgeomVertexArrayData.cxx index aa7262bb18..cfaf029a04 100644 --- a/panda/src/gobj/qpgeomVertexArrayData.cxx +++ b/panda/src/gobj/qpgeomVertexArrayData.cxx @@ -84,8 +84,63 @@ qpGeomVertexArrayData:: //////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexArrayData::modify_data +// Function: qpGeomVertexArrayData::set_num_vertices // Access: Published +// Description: Sets the length of the array to n vertices. +// Normally, you would not call this directly, since all +// of the arrays in a particular GeomVertexData must +// have the same number of vertices; instead, call +// GeomVertexData::set_num_vertices(). +// +// The return value is true if the number of vertices +// was changed, false if the object already contained n +// vertices (or if there was some error). +// +// The new vertex data is initialized to 0, including +// the "color" column (but see +// GeomVertexData::set_num_vertices()). +//////////////////////////////////////////////////////////////////// +bool qpGeomVertexArrayData:: +set_num_vertices(int n) { + CDWriter cdata(_cycler); + + int stride = _array_format->get_stride(); + int delta = n - (cdata->_data.size() / stride); + + if (delta != 0) { + if (cdata->_data.get_ref_count() > 1) { + // Copy-on-write: the data is already reffed somewhere else, + // so we're just going to make a copy. + PTA_uchar new_data; + new_data.reserve(n * stride); + new_data.insert(new_data.end(), n * stride, 0); + memcpy(new_data, cdata->_data, + min((size_t)(n * stride), cdata->_data.size())); + cdata->_data = new_data; + + } else { + // We've got the only reference to the data, so we can change + // it directly. + if (delta > 0) { + cdata->_data.insert(cdata->_data.end(), delta * stride, 0); + + } else { + cdata->_data.erase(cdata->_data.begin() + n * stride, + cdata->_data.end()); + } + } + + cdata->_modified = qpGeom::get_next_modified(); + + return true; + } + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexArrayData::modify_data +// Access: Public // Description: Returns a modifiable pointer to the actual vertex // array, so that application code may directly // manipulate the vertices. @@ -109,7 +164,7 @@ modify_data() { //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexArrayData::set_data -// Access: Published +// Access: Public // Description: Replaces the vertex data array with a completely new // array. //////////////////////////////////////////////////////////////////// @@ -120,60 +175,9 @@ set_data(CPTA_uchar array) { cdata->_modified = qpGeom::get_next_modified(); } -//////////////////////////////////////////////////////////////////// -// Function: qpGeomVertexArrayData::set_num_vertices -// Access: Published -// Description: Sets the length of the array to n vertices. -// Normally, you would not call this directly, since all -// of the arrays in a particular GeomVertexData must -// have the same number of vertices; instead, call -// GeomVertexData::set_num_vertices(). -// -// The return value is true if the number of vertices -// was changed, false if the object already contained n -// vertices (or if there was some error). -//////////////////////////////////////////////////////////////////// -bool qpGeomVertexArrayData:: -set_num_vertices(int n) { - CDWriter cdata(_cycler); - - int stride = _array_format->get_stride(); - int delta = n - (cdata->_data.size() / stride); - - if (delta != 0) { - if (cdata->_data.get_ref_count() > 1) { - // Copy-on-write: the data is already reffed somewhere else, - // so we're just going to make a copy. - PTA_uchar new_data; - new_data.reserve(n * stride); - new_data.insert(new_data.end(), n * stride, uchar()); - memcpy(new_data, cdata->_data, - min((size_t)(n * stride), cdata->_data.size())); - cdata->_data = new_data; - - } else { - // We've got the only reference to the data, so we can change - // it directly. - if (delta > 0) { - cdata->_data.insert(cdata->_data.end(), delta * stride, uchar()); - - } else { - cdata->_data.erase(cdata->_data.begin() + n * stride, - cdata->_data.end()); - } - } - - cdata->_modified = qpGeom::get_next_modified(); - - return true; - } - - return false; -} - //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexArrayData::prepare -// Access: Published +// Access: Public // Description: Indicates that the data should be enqueued to be // prepared in the indicated prepared_objects at the // beginning of the next frame. This will ensure the diff --git a/panda/src/gobj/qpgeomVertexArrayData.h b/panda/src/gobj/qpgeomVertexArrayData.h index 85b1ea0f2e..a95c0e0e86 100644 --- a/panda/src/gobj/qpgeomVertexArrayData.h +++ b/panda/src/gobj/qpgeomVertexArrayData.h @@ -47,8 +47,12 @@ class GraphicsStateGuardianBase; // It also closely correlates with the concept of a // vertex buffer. // -// This object is just a block of data. See -// GeomVertexData for the organizing structure. +// This object is just a block of data. In general, you +// should not be directly messing with this object from +// application code. See GeomVertexData for the +// organizing structure, and see +// GeomVertexReader/Writer/Rewriter for high-level tools +// to manipulate the actual vertex data. // // This is part of the experimental Geom rewrite. //////////////////////////////////////////////////////////////////// @@ -68,9 +72,7 @@ PUBLISHED: INLINE const qpGeomVertexArrayFormat *get_array_format() const; INLINE qpGeomUsageHint::UsageHint get_usage_hint() const; - INLINE CPTA_uchar get_data() const; - PTA_uchar modify_data(); - void set_data(CPTA_uchar data); + INLINE bool has_column(const InternalName *name) const; INLINE int get_num_vertices() const; bool set_num_vertices(int n); @@ -79,6 +81,11 @@ PUBLISHED: INLINE int get_data_size_bytes() const; INLINE UpdateSeq get_modified() const; +public: + INLINE CPTA_uchar get_data() const; + PTA_uchar modify_data(); + void set_data(CPTA_uchar data); + void prepare(PreparedGraphicsObjects *prepared_objects); public: diff --git a/panda/src/gobj/qpgeomVertexData.I b/panda/src/gobj/qpgeomVertexData.I index 9d06fef856..d32c0edbce 100644 --- a/panda/src/gobj/qpgeomVertexData.I +++ b/panda/src/gobj/qpgeomVertexData.I @@ -91,11 +91,21 @@ has_column(const InternalName *name) const { // Access: Published // Description: Sets the length of the array to n vertices in all of // the various arrays (presumably by adding vertices). -// The new vertex data is uninitialized. +// +// The new vertex data is initialized to 0, except for +// the "color" column, which is initialized to (1, 1, 1, +// 1). // // The return value is true if the number of vertices // was changed, false if the object already contained n // vertices (or if there was some error). +// +// Although this method is Published, application code +// only very rarely has any need to call it. Instead, +// you should use the GeomVertexWriter to build up the +// vertices in a GeomVertexData object automatically, +// without need to explicitly set the number of +// vertices. //////////////////////////////////////////////////////////////////// INLINE bool qpGeomVertexData:: set_num_vertices(int n) { diff --git a/panda/src/gobj/qpgeomVertexData.cxx b/panda/src/gobj/qpgeomVertexData.cxx index f9c55d4a80..57c06b033d 100644 --- a/panda/src/gobj/qpgeomVertexData.cxx +++ b/panda/src/gobj/qpgeomVertexData.cxx @@ -170,7 +170,8 @@ clear_vertices() { // array, so that application code may directly // manipulate the vertices. You should avoid changing // the length of this array, since all of the arrays -// should be kept in sync--use add_vertices() instead. +// should be kept in sync--use set_num_vertices() +// instead. //////////////////////////////////////////////////////////////////// qpGeomVertexArrayData *qpGeomVertexData:: modify_array(int i) { @@ -1024,17 +1025,66 @@ do_set_num_vertices(int n, qpGeomVertexData::CDWriter &cdata) { bool any_changed = false; + int color_array = -1; + int orig_color_vertices = -1; + for (size_t i = 0; i < cdata->_arrays.size(); i++) { if (cdata->_arrays[i]->get_num_vertices() != n) { // Copy-on-write. if (cdata->_arrays[i]->get_ref_count() > 1) { cdata->_arrays[i] = new qpGeomVertexArrayData(*cdata->_arrays[i]); } + if (cdata->_arrays[i]->has_column(InternalName::get_color())) { + color_array = i; + orig_color_vertices = cdata->_arrays[i]->get_num_vertices(); + } cdata->_arrays[i]->set_num_vertices(n); any_changed = true; } } + if (color_array >= 0 && orig_color_vertices < n) { + // We have just added some vertices, fill the "color" column with + // (1, 1, 1, 1), for the programmer's convenience. + qpGeomVertexArrayData *array_data = cdata->_arrays[color_array]; + const qpGeomVertexColumn *column = + array_data->get_array_format()->get_column(InternalName::get_color()); + int stride = array_data->get_array_format()->get_stride(); + unsigned char *start = + array_data->modify_data() + column->get_start(); + unsigned char *stop = start + array_data->get_data_size_bytes(); + unsigned char *pointer = start + stride * orig_color_vertices; + int num_values = column->get_num_values(); + + switch (column->get_numeric_type()) { + case qpGeomVertexColumn::NT_packed_dcba: + case qpGeomVertexColumn::NT_packed_dabc: + case qpGeomVertexColumn::NT_uint8: + while (pointer < stop) { + memset(pointer, 0xff, num_values); + pointer += stride; + } + break; + + case qpGeomVertexColumn::NT_uint16: + while (pointer < stop) { + memset(pointer, 0xff, num_values * 2); + pointer += stride; + } + break; + + case qpGeomVertexColumn::NT_float32: + while (pointer < stop) { + PN_float32 *pi = (PN_float32 *)pointer; + for (int i = 0; i < num_values; i++) { + pi[i] = 1.0f; + } + pointer += stride; + } + break; + } + } + if (any_changed) { cdata->_modified = qpGeom::get_next_modified(); cdata->_animated_vertices.clear(); diff --git a/panda/src/gobj/qpgeomVertexData.h b/panda/src/gobj/qpgeomVertexData.h index 96fdfa4a2b..93063bd661 100644 --- a/panda/src/gobj/qpgeomVertexData.h +++ b/panda/src/gobj/qpgeomVertexData.h @@ -64,6 +64,12 @@ class qpGeomVertexColumn; // single table of vertices, where each vertex is // represented by one row of the table. // +// In general, application code should not attempt to +// directly manipulate the vertex data through this +// structure; instead, use the GeomVertexReader, +// GeomVertexWriter, and GeomVertexRewriter objects to +// read and write vertex data at a high level. +// // This is part of the experimental Geom rewrite. //////////////////////////////////////////////////////////////////// class EXPCL_PANDA qpGeomVertexData : public TypedWritableReferenceCount { diff --git a/panda/src/gobj/qpgeomVertexReader.I b/panda/src/gobj/qpgeomVertexReader.I index 7e362843fa..133d9a0b10 100644 --- a/panda/src/gobj/qpgeomVertexReader.I +++ b/panda/src/gobj/qpgeomVertexReader.I @@ -382,8 +382,8 @@ set_pointer(int vertex) { //////////////////////////////////////////////////////////////////// INLINE const unsigned char *qpGeomVertexReader:: inc_pointer() { - nassertr(_read_vertex < _num_vertices, NULL); - nassertr(_pointer == _vertex_data->get_array(_array)->get_data() + _column->get_start() + _stride * _read_vertex, NULL); + nassertr(_read_vertex < _num_vertices, empty_buffer); + nassertr(_pointer == _vertex_data->get_array(_array)->get_data() + _column->get_start() + _stride * _read_vertex, empty_buffer); const unsigned char *orig_pointer = _pointer; _pointer += _stride; diff --git a/panda/src/gobj/qpgeomVertexReader.cxx b/panda/src/gobj/qpgeomVertexReader.cxx index 27b742395a..705f67f6e6 100644 --- a/panda/src/gobj/qpgeomVertexReader.cxx +++ b/panda/src/gobj/qpgeomVertexReader.cxx @@ -18,6 +18,13 @@ #include "qpgeomVertexReader.h" + +#ifndef NDEBUG + // This is defined just for the benefit of having something non-NULL + // to return from a nassertr() call. +const unsigned char qpGeomVertexReader::empty_buffer[100] = { 0 }; +#endif + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexReader::set_column // Access: Published diff --git a/panda/src/gobj/qpgeomVertexReader.h b/panda/src/gobj/qpgeomVertexReader.h index fc3f5799f6..99da8474ac 100644 --- a/panda/src/gobj/qpgeomVertexReader.h +++ b/panda/src/gobj/qpgeomVertexReader.h @@ -116,6 +116,12 @@ private: Reader *_reader; +#ifndef NDEBUG + // This is defined just for the benefit of having something non-NULL + // to return from a nassertr() call. + static const unsigned char empty_buffer[100]; +#endif + // This nested class provides the implementation for unpacking data // in a very general way, but also provides the hooks for // implementing the common, very direct code paths (for instance, diff --git a/panda/src/gobj/qpgeomVertexWriter.I b/panda/src/gobj/qpgeomVertexWriter.I index b32ef67e4c..941c8d5d52 100644 --- a/panda/src/gobj/qpgeomVertexWriter.I +++ b/panda/src/gobj/qpgeomVertexWriter.I @@ -686,8 +686,8 @@ set_pointer(int vertex) { //////////////////////////////////////////////////////////////////// INLINE unsigned char *qpGeomVertexWriter:: inc_pointer() { - nassertr(_write_vertex < _num_vertices, NULL); - nassertr(_pointer == _vertex_data->get_array(_array)->get_data() + _column->get_start() + _stride * _write_vertex, NULL); + nassertr(_write_vertex < _num_vertices, empty_buffer); + nassertr(_pointer == _vertex_data->get_array(_array)->get_data() + _column->get_start() + _stride * _write_vertex, empty_buffer); unsigned char *orig_pointer = _pointer; _pointer += _stride; diff --git a/panda/src/gobj/qpgeomVertexWriter.cxx b/panda/src/gobj/qpgeomVertexWriter.cxx index c66b0f8b7f..abd057df54 100644 --- a/panda/src/gobj/qpgeomVertexWriter.cxx +++ b/panda/src/gobj/qpgeomVertexWriter.cxx @@ -18,6 +18,13 @@ #include "qpgeomVertexWriter.h" + +#ifndef NDEBUG + // This is defined just for the benefit of having something non-NULL + // to return from a nassertr() call. +unsigned char qpGeomVertexWriter::empty_buffer[100] = { 0 }; +#endif + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexWriter::set_column // Access: Published diff --git a/panda/src/gobj/qpgeomVertexWriter.h b/panda/src/gobj/qpgeomVertexWriter.h index 0932849821..c11daa44b5 100644 --- a/panda/src/gobj/qpgeomVertexWriter.h +++ b/panda/src/gobj/qpgeomVertexWriter.h @@ -152,6 +152,12 @@ private: Writer *_writer; +#ifndef NDEBUG + // This is defined just for the benefit of having something non-NULL + // to return from a nassertr() call. + static unsigned char empty_buffer[100]; +#endif + // This nested class provides the implementation for unpacking data // in a very general way, but also provides the hooks for // implementing the common, very direct code paths (for instance, diff --git a/panda/src/pgraph/cullableObject.cxx b/panda/src/pgraph/cullableObject.cxx index 5b8af8bd82..7848eadbfd 100644 --- a/panda/src/pgraph/cullableObject.cxx +++ b/panda/src/pgraph/cullableObject.cxx @@ -37,7 +37,7 @@ munge_geom(const qpGeomMunger *munger) { if (_geom != (Geom *)NULL) { // Temporary test and dcast until the experimental Geom rewrite // becomes the actual Geom rewrite. - if (_geom->is_exact_type(qpGeom::get_class_type())) { + if (_geom->is_of_type(qpGeom::get_class_type())) { _munger = munger; CPT(qpGeom) qpgeom = DCAST(qpGeom, _geom); qpgeom->munge_geom(munger, qpgeom, _munged_data); diff --git a/panda/src/pgraph/geomNode.cxx b/panda/src/pgraph/geomNode.cxx index 0f50326c79..3ce403edd0 100644 --- a/panda/src/pgraph/geomNode.cxx +++ b/panda/src/pgraph/geomNode.cxx @@ -354,7 +354,7 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, const Geom *geom = get_geom(i); // Temporary test until the experimental Geom rewrite is final. - if (geom->is_exact_type(qpGeom::get_class_type())) { + if (geom->is_of_type(qpGeom::get_class_type())) { const qpGeom *qpgeom = DCAST(qpGeom, geom); qpgeom->calc_tight_bounds(min_point, max_point, found_any, qpgeom->get_vertex_data()->animate_vertices(), diff --git a/panda/src/pgraph/geomTransformer.cxx b/panda/src/pgraph/geomTransformer.cxx index e1034fb17e..569e38c635 100644 --- a/panda/src/pgraph/geomTransformer.cxx +++ b/panda/src/pgraph/geomTransformer.cxx @@ -53,7 +53,7 @@ transform_vertices(Geom *geom, const LMatrix4f &mat) { nassertr(geom != (Geom *)NULL, false); - if (geom->is_exact_type(qpGeom::get_class_type())) { + if (geom->is_of_type(qpGeom::get_class_type())) { qpGeom *qpgeom = DCAST(qpGeom, geom); qpSourceVertices sv; @@ -194,7 +194,7 @@ transform_texcoords(Geom *geom, const InternalName *from_name, bool transformed = false; nassertr(geom != (Geom *)NULL, false); - if (geom->is_exact_type(qpGeom::get_class_type())) { + if (geom->is_of_type(qpGeom::get_class_type())) { qpGeom *qpgeom = DCAST(qpGeom, geom); qpSourceTexCoords st; @@ -314,7 +314,7 @@ bool GeomTransformer:: set_color(Geom *geom, const Colorf &color) { bool transformed = false; - if (geom->is_exact_type(qpGeom::get_class_type())) { + if (geom->is_of_type(qpGeom::get_class_type())) { qpGeom *qpgeom = DCAST(qpGeom, geom); qpSourceColors sc; @@ -389,7 +389,7 @@ transform_colors(Geom *geom, const LVecBase4f &scale) { nassertr(geom != (Geom *)NULL, false); - if (geom->is_exact_type(qpGeom::get_class_type())) { + if (geom->is_of_type(qpGeom::get_class_type())) { qpGeom *qpgeom = DCAST(qpGeom, geom); qpSourceColors sc; diff --git a/panda/src/pgraph/geomTransformer.h b/panda/src/pgraph/geomTransformer.h index b1c52a9dd1..8ff8424e49 100644 --- a/panda/src/pgraph/geomTransformer.h +++ b/panda/src/pgraph/geomTransformer.h @@ -101,9 +101,9 @@ private: typedef pmap NewColors; // We have two concepts of colors: the "fixed" colors, which are - // slapped in complete replacement of the original colors (e.g. via - // a ColorAttrib), and the "transformed" colors, which are modified - // from the original colors (e.g. via a ColorScaleAttrib). + // slapped in as a complete replacement of the original colors + // (e.g. via a ColorAttrib), and the "transformed" colors, which are + // modified from the original colors (e.g. via a ColorScaleAttrib). NewColors _qpfcolors, _qptcolors; @@ -138,9 +138,9 @@ private: TexCoords _texcoords; // We have two concepts of colors: the "fixed" colors, which are - // slapped in complete replacement of the original colors (e.g. via - // a ColorAttrib), and the "transformed" colors, which are modified - // from the original colors (e.g. via a ColorScaleAttrib). + // slapped in as a complete replacement of the original colors + // (e.g. via a ColorAttrib), and the "transformed" colors, which are + // modified from the original colors (e.g. via a ColorScaleAttrib). typedef pmap FColors; FColors _fcolors; diff --git a/panda/src/text/Sources.pp b/panda/src/text/Sources.pp index db91aaff10..c79ee6827a 100644 --- a/panda/src/text/Sources.pp +++ b/panda/src/text/Sources.pp @@ -19,6 +19,7 @@ dynamicTextPage.I dynamicTextPage.h \ fontPool.I fontPool.h \ geomTextGlyph.I geomTextGlyph.h \ + qpgeomTextGlyph.I qpgeomTextGlyph.h \ staticTextFont.I staticTextFont.h \ textAssembler.I textAssembler.h \ textFont.I textFont.h \ @@ -35,6 +36,7 @@ dynamicTextPage.cxx \ fontPool.cxx \ geomTextGlyph.cxx \ + qpgeomTextGlyph.cxx \ staticTextFont.cxx \ textAssembler.cxx \ textFont.cxx textGlyph.cxx \ @@ -49,6 +51,7 @@ dynamicTextPage.I dynamicTextPage.h \ fontPool.I fontPool.h \ geomTextGlyph.I geomTextGlyph.h \ + qpgeomTextGlyph.I qpgeomTextGlyph.h \ staticTextFont.I staticTextFont.h \ textAssembler.I textAssembler.h \ textFont.I textFont.h \ diff --git a/panda/src/text/config_text.cxx b/panda/src/text/config_text.cxx index 91eac2d4f3..d3efde74d2 100644 --- a/panda/src/text/config_text.cxx +++ b/panda/src/text/config_text.cxx @@ -24,6 +24,7 @@ #include "dynamicTextFont.h" #include "dynamicTextPage.h" #include "geomTextGlyph.h" +#include "qpgeomTextGlyph.h" #include "unicodeLatinMap.h" #include "pandaSystem.h" @@ -167,7 +168,10 @@ init_libtext() { DynamicTextFont::init_type(); DynamicTextPage::init_type(); GeomTextGlyph::init_type(); + qpGeomTextGlyph::init_type(); + GeomTextGlyph::register_with_read_factory(); + qpGeomTextGlyph::register_with_read_factory(); PandaSystem *ps = PandaSystem::get_global_ptr(); ps->add_system("Freetype"); diff --git a/panda/src/text/dynamicTextGlyph.cxx b/panda/src/text/dynamicTextGlyph.cxx index e4e908a106..469d299dd4 100644 --- a/panda/src/text/dynamicTextGlyph.cxx +++ b/panda/src/text/dynamicTextGlyph.cxx @@ -22,9 +22,15 @@ #include "dynamicTextPage.h" #include "geomTextGlyph.h" +#include "qpgeomTextGlyph.h" +#include "qpgeomVertexData.h" +#include "qpgeomVertexFormat.h" +#include "qpgeomTristrips.h" +#include "qpgeomVertexWriter.h" #include "textureAttrib.h" #include "transparencyAttrib.h" #include "renderState.h" +#include "config_gobj.h" //////////////////////////////////////////////////////////////////// // Function: DynamicTextGlyph::Destructor @@ -116,40 +122,79 @@ make_geom(int bitmap_top, int bitmap_left, float advance, float poly_margin, float uv_left = (float)(_x - poly_margin) / _page->get_x_size(); float uv_bottom = 1.0f - (float)(_y + poly_margin + tex_y_size) / _page->get_y_size(); float uv_right = (float)(_x + poly_margin + tex_x_size) / _page->get_x_size(); - // Create a corresponding tristrip. - PT(Geom) geom = new GeomTextGlyph(this); - _geom = geom; + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + (string(), qpGeomVertexFormat::get_v3cpt2(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + qpGeomVertexWriter color(vdata, InternalName::get_color()); + qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); - // The above will increment our _geom_count to 1. Reset it back - // down to 0, since our own internal Geom doesn't count. - nassertv(_geom_count == 1); - _geom_count--; + vertex.add_data3f(left, 0, top); + vertex.add_data3f(left, 0, bottom); + vertex.add_data3f(right, 0, top); + vertex.add_data3f(right, 0, bottom); - PTA_Vertexf coords; - coords.push_back(Vertexf(left, 0, top)); - coords.push_back(Vertexf(left, 0, bottom)); - coords.push_back(Vertexf(right, 0, top)); - coords.push_back(Vertexf(right, 0, bottom)); - - PTA_TexCoordf texcoords; - texcoords.push_back(TexCoordf(uv_left, uv_top)); - texcoords.push_back(TexCoordf(uv_left, uv_bottom)); - texcoords.push_back(TexCoordf(uv_right, uv_top)); - texcoords.push_back(TexCoordf(uv_right, uv_bottom)); - - PTA_Colorf colors; - colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); - - PTA_int lengths; - lengths.push_back(4); - - geom->set_coords(coords); - geom->set_texcoords(texcoords, G_PER_VERTEX); - geom->set_colors(colors, G_OVERALL); - geom->set_lengths(lengths); - geom->set_num_prims(1); + color.add_data4f(1.0f, 1.0f, 1.0f, 1.0f); + color.add_data4f(1.0f, 1.0f, 1.0f, 1.0f); + color.add_data4f(1.0f, 1.0f, 1.0f, 1.0f); + color.add_data4f(1.0f, 1.0f, 1.0f, 1.0f); + + texcoord.add_data2f(uv_left, uv_top); + texcoord.add_data2f(uv_left, uv_bottom); + texcoord.add_data2f(uv_right, uv_top); + texcoord.add_data2f(uv_right, uv_bottom); + + PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static); + strip->add_consecutive_vertices(0, 4); + strip->close_primitive(); + + PT(qpGeom) geom = new qpGeomTextGlyph(this); + geom->set_vertex_data(vdata); + geom->add_primitive(strip); + + _geom = geom; + + // The above will increment our _geom_count to 1. Reset it back + // down to 0, since our own internal Geom doesn't count. + nassertv(_geom_count == 1); + _geom_count--; + } else { + PT(Geom) geom = new GeomTextGlyph(this); + _geom = geom; + + // The above will increment our _geom_count to 1. Reset it back + // down to 0, since our own internal Geom doesn't count. + nassertv(_geom_count == 1); + _geom_count--; + + PTA_Vertexf coords; + coords.push_back(Vertexf(left, 0, top)); + coords.push_back(Vertexf(left, 0, bottom)); + coords.push_back(Vertexf(right, 0, top)); + coords.push_back(Vertexf(right, 0, bottom)); + + PTA_TexCoordf texcoords; + texcoords.push_back(TexCoordf(uv_left, uv_top)); + texcoords.push_back(TexCoordf(uv_left, uv_bottom)); + texcoords.push_back(TexCoordf(uv_right, uv_top)); + texcoords.push_back(TexCoordf(uv_right, uv_bottom)); + + PTA_Colorf colors; + colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); + + PTA_int lengths; + lengths.push_back(4); + + geom->set_coords(coords); + geom->set_texcoords(texcoords, G_PER_VERTEX); + geom->set_colors(colors, G_OVERALL); + geom->set_lengths(lengths); + geom->set_num_prims(1); + } + _state = RenderState::make(TextureAttrib::make(_page), TransparencyAttrib::make(TransparencyAttrib::M_alpha)); diff --git a/panda/src/text/qpgeomTextGlyph.I b/panda/src/text/qpgeomTextGlyph.I new file mode 100644 index 0000000000..2f21757708 --- /dev/null +++ b/panda/src/text/qpgeomTextGlyph.I @@ -0,0 +1,47 @@ +// Filename: qpgeomTextGlyph.I +// Created by: drose (31Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomTextGlyph::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE qpGeomTextGlyph:: +qpGeomTextGlyph(DynamicTextGlyph *glyph) : + _glyph(glyph) +{ + if (_glyph != (DynamicTextGlyph *)NULL) { + _glyph->_geom_count++; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomTextGlyph::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE qpGeomTextGlyph:: +qpGeomTextGlyph(const qpGeomTextGlyph ©) : + qpGeom(copy), + _glyph(copy._glyph) +{ + if (_glyph != (DynamicTextGlyph *)NULL) { + _glyph->_geom_count++; + } +} diff --git a/panda/src/text/qpgeomTextGlyph.cxx b/panda/src/text/qpgeomTextGlyph.cxx new file mode 100644 index 0000000000..f2f7b5376d --- /dev/null +++ b/panda/src/text/qpgeomTextGlyph.cxx @@ -0,0 +1,101 @@ +// Filename: qpgeomTextGlyph.cxx +// Created by: drose (31Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "geomTextGlyph.h" + +#ifdef HAVE_FREETYPE + +#include "datagramIterator.h" +#include "bamReader.h" + +TypeHandle qpGeomTextGlyph::_type_handle; + + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomTextGlyph::Copy Assignment Operator +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void qpGeomTextGlyph:: +operator = (const qpGeomTextGlyph ©) { + qpGeom::operator = (copy); + if (_glyph != copy._glyph) { + if (_glyph != (DynamicTextGlyph *)NULL) { + _glyph->_geom_count--; + } + _glyph = copy._glyph; + if (_glyph != (DynamicTextGlyph *)NULL) { + _glyph->_geom_count++; + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomTextGlyph::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomTextGlyph:: +~qpGeomTextGlyph() { + if (_glyph != (DynamicTextGlyph *)NULL) { + _glyph->_geom_count--; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomTextGlyph::make_copy +// Access: Public, Virtual +// Description: Returns a newly-allocated qpGeom that is a shallow copy +// of this one. It will be a different qpGeom pointer, +// but its internal data may or may not be shared with +// that of the original qpGeom. +//////////////////////////////////////////////////////////////////// +qpGeom *qpGeomTextGlyph:: +make_copy() const { + return new qpGeomTextGlyph(*this); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomTextGlyph::register_with_factory +// Access: Public, Static +// Description: Factory method to generate a qpGeomTextGlyph object +//////////////////////////////////////////////////////////////////// +void qpGeomTextGlyph:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_qpGeomTextGlyph); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomTextGlyph::make_qpGeomTextGlyph +// Access: Public +// Description: Factory method to generate a qpGeomTextGlyph object +//////////////////////////////////////////////////////////////////// +TypedWritable* qpGeomTextGlyph:: +make_qpGeomTextGlyph(const FactoryParams ¶ms) { + qpGeomTextGlyph *me = new qpGeomTextGlyph((DynamicTextGlyph *)NULL); + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + me->fillin(scan, manager); + me->make_dirty(); + me->config(); + return me; +} + +#endif // HAVE_FREETYPE diff --git a/panda/src/text/qpgeomTextGlyph.h b/panda/src/text/qpgeomTextGlyph.h new file mode 100644 index 0000000000..597e03490b --- /dev/null +++ b/panda/src/text/qpgeomTextGlyph.h @@ -0,0 +1,77 @@ +// Filename: qpgeomTextGlyph.h +// Created by: drose (31Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef qpGEOMTEXTGLYPH_H +#define qpGEOMTEXTGLYPH_H + +#include "pandabase.h" + +#ifdef HAVE_FREETYPE + +#include "qpgeom.h" +#include "dynamicTextGlyph.h" + +//////////////////////////////////////////////////////////////////// +// Class : qpGeomTextGlyph +// Description : This is a specialization on Geom for containing a +// triangle strip intended to represent a +// DynamicTextGlyph. Its sole purpose is to maintain +// the geom count on the glyph, so we can determine the +// actual usage count on a dynamic glyph (and thus know +// when it is safe to recycle the glyph). +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA qpGeomTextGlyph : public qpGeom { +public: + INLINE qpGeomTextGlyph(DynamicTextGlyph *glyph); + INLINE qpGeomTextGlyph(const qpGeomTextGlyph ©); + void operator = (const qpGeomTextGlyph ©); + virtual ~qpGeomTextGlyph(); + + virtual qpGeom *make_copy() const; + +private: + PT(DynamicTextGlyph) _glyph; + +public: + static void register_with_read_factory(); + static TypedWritable *make_qpGeomTextGlyph(const FactoryParams ¶ms); + +PUBLISHED: + static TypeHandle get_class_type() { + return _type_handle; + } +public: + static void init_type() { + qpGeom::init_type(); + register_type(_type_handle, "qpGeomTextGlyph", + qpGeom::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "qpgeomTextGlyph.I" + +#endif // HAVE_FREETYPE + +#endif // GEOMTEXTGLYPH_H diff --git a/panda/src/text/staticTextFont.cxx b/panda/src/text/staticTextFont.cxx index a066e6d462..27cfc41aeb 100644 --- a/panda/src/text/staticTextFont.cxx +++ b/panda/src/text/staticTextFont.cxx @@ -22,6 +22,8 @@ #include "geom.h" #include "geomPoint.h" #include "geomNode.h" +#include "qpgeomVertexReader.h" +#include "qpgeomPoints.h" #include "renderState.h" #include "dcast.h" @@ -184,7 +186,8 @@ get_glyph(int character, const TextGlyph *&glyph) { // those two Geoms. //////////////////////////////////////////////////////////////////// void StaticTextFont:: -find_character_gsets(PandaNode *root, const Geom *&ch, const GeomPoint *&dot, +find_character_gsets(PandaNode *root, CPT(Geom) &ch, + const GeomPoint *&dot1, CPT(qpGeom) &dot2, const RenderState *&state, const RenderState *net_state) { CPT(RenderState) next_net_state = net_state->compose(root->get_state()); @@ -193,11 +196,29 @@ find_character_gsets(PandaNode *root, const Geom *&ch, const GeomPoint *&dot, for (int i = 0; i < geode->get_num_geoms(); i++) { const Geom *geom = geode->get_geom(i); - if (geom->is_of_type(GeomPoint::get_class_type())) { - dot = DCAST(GeomPoint, geom); + if (geom->is_of_type(qpGeom::get_class_type())) { + CPT(qpGeom) qpgeom = DCAST(qpGeom, geom); - } else if (geom->is_of_type(Geom::get_class_type())) { - ch = DCAST(Geom, geom); + bool found_points = false; + for (int j = 0; j < qpgeom->get_num_primitives() && !found_points; j++) { + const qpGeomPrimitive *primitive = qpgeom->get_primitive(j); + if (primitive->is_of_type(qpGeomPoints::get_class_type())) { + dot2 = qpgeom; + found_points = true; + } + } + if (!found_points) { + // If it doesn't have any points, it must be the regular + // letter. + ch = geom; + state = next_net_state->compose(geode->get_geom_state(i)); + } + + } else if (geom->is_of_type(GeomPoint::get_class_type())) { + dot1 = DCAST(GeomPoint, geom); + + } else { + ch = geom; state = next_net_state->compose(geode->get_geom_state(i)); } } @@ -206,7 +227,8 @@ find_character_gsets(PandaNode *root, const Geom *&ch, const GeomPoint *&dot, PandaNode::Children cr = root->get_children(); int num_children = cr.get_num_children(); for (int i = 0; i < num_children; i++) { - find_character_gsets(cr.get_child(i), ch, dot, state, next_net_state); + find_character_gsets(cr.get_child(i), ch, dot1, dot2, state, + next_net_state); } } } @@ -236,46 +258,64 @@ find_characters(PandaNode *root, const RenderState *net_state) { if (all_digits) { int character = atoi(name.c_str()); - const Geom *ch = NULL; - const GeomPoint *dot = NULL; + CPT(Geom) ch; + const GeomPoint *dot1 = NULL; + CPT(qpGeom) dot2; const RenderState *state = NULL; - find_character_gsets(root, ch, dot, state, next_net_state); - if (dot != NULL) { + find_character_gsets(root, ch, dot1, dot2, state, next_net_state); + if (dot1 != NULL) { // Get the first vertex from the "dot" geoset. This will be the // origin of the next character. PTA_Vertexf alist; PTA_ushort ilist; float width; - dot->get_coords(alist, ilist); + dot1->get_coords(alist, ilist); if (ilist.empty()) { width = alist[0][0]; } else { width = alist[ilist[0]][0]; } + _glyphs[character] = new TextGlyph(ch, state, width); + + } else if (ch != (Geom *)NULL && dot2 != (qpGeom *)NULL) { + // Get the first vertex from the "dot" geoset. This will be the + // origin of the next character. + qpGeomVertexReader reader(dot2->get_vertex_data(), InternalName::get_vertex()); + float width = reader.get_data1f(); + _glyphs[character] = new TextGlyph(ch, state, width); } } else if (name == "ds") { - // The group "ds" is a special node that indicate's the font's + // The group "ds" is a special node that indicates the font's // design size, or line height. - const Geom *ch = NULL; - const GeomPoint *dot = NULL; + CPT(Geom) ch; + const GeomPoint *dot1 = NULL; + CPT(qpGeom) dot2; const RenderState *state = NULL; - find_character_gsets(root, ch, dot, state, next_net_state); - if (dot != NULL) { + find_character_gsets(root, ch, dot1, dot2, state, next_net_state); + if (dot1 != NULL) { // Get the first vertex from the "dot" geoset. This will be the // design size indicator. PTA_Vertexf alist; PTA_ushort ilist; - dot->get_coords(alist, ilist); + dot1->get_coords(alist, ilist); if (ilist.empty()) { _line_height = alist[0][2]; } else { _line_height = alist[ilist[0]][2]; } _space_advance = 0.25f * _line_height; + + } else if (ch != (Geom *)NULL && dot2 != (qpGeom *)NULL) { + // Get the first vertex from the "dot" geoset. This will be the + // design size indicator. + const qpGeom *qpgeom = DCAST(qpGeom, ch); + qpGeomVertexReader reader(qpgeom->get_vertex_data(), InternalName::get_vertex()); + _line_height = reader.get_data3f()[2]; + _space_advance = 0.25f * _line_height; } } else { diff --git a/panda/src/text/staticTextFont.h b/panda/src/text/staticTextFont.h index b263621754..16e1164880 100644 --- a/panda/src/text/staticTextFont.h +++ b/panda/src/text/staticTextFont.h @@ -25,11 +25,12 @@ #include "textFont.h" #include "textGlyph.h" #include "pandaNode.h" +#include "geom.h" +#include "qpgeom.h" #include "pointerTo.h" #include "pmap.h" class Node; -class Geom; class GeomPoint; //////////////////////////////////////////////////////////////////// @@ -50,8 +51,9 @@ public: virtual bool get_glyph(int character, const TextGlyph *&glyph); private: - void find_character_gsets(PandaNode *root, const Geom *&ch, - const GeomPoint *&dot, + void find_character_gsets(PandaNode *root, CPT(Geom) &ch, + const GeomPoint *&dot1, + CPT(qpGeom) &dot2, const RenderState *&state, const RenderState *net_state); void find_characters(PandaNode *root, diff --git a/panda/src/text/textNode.I b/panda/src/text/textNode.I index 829a97efc8..8c1aa03ea8 100644 --- a/panda/src/text/textNode.I +++ b/panda/src/text/textNode.I @@ -407,6 +407,7 @@ get_frame_actual() const { INLINE void TextNode:: set_frame_line_width(float frame_width) { _frame_width = frame_width; + invalidate_no_measure(); } //////////////////////////////////////////////////////////////////// @@ -435,6 +436,7 @@ set_frame_corners(bool corners) { } else { _flags &= ~F_frame_corners; } + invalidate_no_measure(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/text/textNode.cxx b/panda/src/text/textNode.cxx index 4a540d422f..02a7ecd452 100644 --- a/panda/src/text/textNode.cxx +++ b/panda/src/text/textNode.cxx @@ -27,6 +27,11 @@ #include "geomTristrip.h" #include "geomLinestrip.h" #include "geomPoint.h" +#include "qpgeom.h" +#include "qpgeomLinestrips.h" +#include "qpgeomPoints.h" +#include "qpgeomTristrips.h" +#include "qpgeomVertexWriter.h" #include "geomNode.h" #include "notify.h" #include "transformState.h" @@ -589,42 +594,74 @@ do_measure() { //////////////////////////////////////////////////////////////////// PT(PandaNode) TextNode:: make_frame() { - PT(GeomNode) frame_geode = new GeomNode("frame"); + PT(GeomNode) frame_node = new GeomNode("frame"); LVector4f dimensions = get_frame_actual(); float left = dimensions[0]; float right = dimensions[1]; float bottom = dimensions[2]; float top = dimensions[3]; - - GeomLinestrip *geoset = new GeomLinestrip; - PTA_int lengths=PTA_int::empty_array(0); - PTA_Vertexf verts; - lengths.push_back(5); - verts.push_back(Vertexf(left, 0.0f, top)); - verts.push_back(Vertexf(left, 0.0f, bottom)); - verts.push_back(Vertexf(right, 0.0f, bottom)); - verts.push_back(Vertexf(right, 0.0f, top)); - verts.push_back(Vertexf(left, 0.0f, top)); - + CPT(RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, _frame_width); CPT(RenderState) state = RenderState::make(thick); - geoset->set_num_prims(1); - geoset->set_lengths(lengths); + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + ("text", qpGeomVertexFormat::get_v3cp(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); - geoset->set_coords(verts); - frame_geode->add_geom(geoset, state); + vertex.add_data3f(left, 0.0f, top); + vertex.add_data3f(left, 0.0f, bottom); + vertex.add_data3f(right, 0.0f, bottom); + vertex.add_data3f(right, 0.0f, top); + + PT(qpGeomLinestrips) frame = new qpGeomLinestrips(qpGeomUsageHint::UH_static); + frame->add_consecutive_vertices(0, 4); + frame->add_vertex(0); + frame->close_primitive(); + + PT(qpGeom) geom = new qpGeom; + geom->set_vertex_data(vdata); + geom->add_primitive(frame); + frame_node->add_geom(geom, state); - if (get_frame_corners()) { - GeomPoint *geoset = new GeomPoint; + if (get_frame_corners()) { + PT(qpGeomPoints) corners = new qpGeomPoints(qpGeomUsageHint::UH_static); + corners->add_consecutive_vertices(0, 4); + PT(qpGeom) geom2 = new qpGeom; + geom2->set_vertex_data(vdata); + geom2->add_primitive(corners); + frame_node->add_geom(geom2, state); + } + + } else { + GeomLinestrip *geoset = new GeomLinestrip; + PTA_int lengths=PTA_int::empty_array(0); + PTA_Vertexf verts; + lengths.push_back(5); + verts.push_back(Vertexf(left, 0.0f, top)); + verts.push_back(Vertexf(left, 0.0f, bottom)); + verts.push_back(Vertexf(right, 0.0f, bottom)); + verts.push_back(Vertexf(right, 0.0f, top)); + verts.push_back(Vertexf(left, 0.0f, top)); + + geoset->set_num_prims(1); + geoset->set_lengths(lengths); - geoset->set_num_prims(4); geoset->set_coords(verts); - frame_geode->add_geom(geoset, state); + frame_node->add_geom(geoset, state); + + if (get_frame_corners()) { + GeomPoint *geoset = new GeomPoint; + + geoset->set_num_prims(4); + geoset->set_coords(verts); + frame_node->add_geom(geoset, state); + } } - return frame_geode.p(); + return frame_node.p(); } //////////////////////////////////////////////////////////////////// @@ -634,7 +671,7 @@ make_frame() { //////////////////////////////////////////////////////////////////// PT(PandaNode) TextNode:: make_card() { - PT(GeomNode) card_geode = new GeomNode("card"); + PT(GeomNode) card_node = new GeomNode("card"); LVector4f dimensions = get_card_actual(); float left = dimensions[0]; @@ -642,34 +679,63 @@ make_card() { float bottom = dimensions[2]; float top = dimensions[3]; - GeomTristrip *geoset = new GeomTristrip; - PTA_int lengths=PTA_int::empty_array(0); - lengths.push_back(4); + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + ("text", qpGeomVertexFormat::get_v3cpt2(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); - PTA_Vertexf verts; - verts.push_back(Vertexf(left, 0.02f, top)); - verts.push_back(Vertexf(left, 0.02f, bottom)); - verts.push_back(Vertexf(right, 0.02f, top)); - verts.push_back(Vertexf(right, 0.02f, bottom)); + vertex.add_data3f(left, 0.0f, top); + vertex.add_data3f(left, 0.0f, bottom); + vertex.add_data3f(right, 0.0f, top); + vertex.add_data3f(right, 0.0f, bottom); - geoset->set_num_prims(1); - geoset->set_lengths(lengths); + texcoord.add_data2f(0.0f, 1.0f); + texcoord.add_data2f(0.0f, 0.0f); + texcoord.add_data2f(1.0f, 1.0f); + texcoord.add_data2f(1.0f, 0.0f); + + PT(qpGeomTristrips) card = new qpGeomTristrips(qpGeomUsageHint::UH_static); + card->add_consecutive_vertices(0, 4); + card->close_primitive(); + + PT(qpGeom) geom = new qpGeom; + geom->set_vertex_data(vdata); + geom->add_primitive(card); - geoset->set_coords(verts); + card_node->add_geom(geom); - if (has_card_texture()) { - PTA_TexCoordf uvs; - uvs.push_back(TexCoordf(0.0f, 1.0f)); - uvs.push_back(TexCoordf(0.0f, 0.0f)); - uvs.push_back(TexCoordf(1.0f, 1.0f)); - uvs.push_back(TexCoordf(1.0f, 0.0f)); + } else { + GeomTristrip *geoset = new GeomTristrip; + PTA_int lengths=PTA_int::empty_array(0); + lengths.push_back(4); - geoset->set_texcoords(uvs, G_PER_VERTEX); + PTA_Vertexf verts; + verts.push_back(Vertexf(left, 0.02f, top)); + verts.push_back(Vertexf(left, 0.02f, bottom)); + verts.push_back(Vertexf(right, 0.02f, top)); + verts.push_back(Vertexf(right, 0.02f, bottom)); + + geoset->set_num_prims(1); + geoset->set_lengths(lengths); + + geoset->set_coords(verts); + + if (has_card_texture()) { + PTA_TexCoordf uvs; + uvs.push_back(TexCoordf(0.0f, 1.0f)); + uvs.push_back(TexCoordf(0.0f, 0.0f)); + uvs.push_back(TexCoordf(1.0f, 1.0f)); + uvs.push_back(TexCoordf(1.0f, 0.0f)); + + geoset->set_texcoords(uvs, G_PER_VERTEX); + } + + card_node->add_geom(geoset); } - card_geode->add_geom(geoset); - - return card_geode.p(); + return card_node.p(); } @@ -681,7 +747,7 @@ make_card() { //////////////////////////////////////////////////////////////////// PT(PandaNode) TextNode:: make_card_with_border() { - PT(GeomNode) card_geode = new GeomNode("card"); + PT(GeomNode) card_node = new GeomNode("card"); LVector4f dimensions = get_card_actual(); float left = dimensions[0]; @@ -697,103 +763,185 @@ make_card_with_border() { // 9 11 13 15 \ / // 10 12 14 16 - three // - GeomTristrip *geoset = new GeomTristrip; - PTA_int lengths; - lengths.push_back(8); - lengths.push_back(8); - lengths.push_back(8); - PTA_Vertexf verts; - // verts 1,2,3,4 - verts.push_back(Vertexf(left, 0.02f, top)); - verts.push_back(Vertexf(left, 0.02f, top - _card_border_size)); - verts.push_back(Vertexf(left + _card_border_size, 0.02f, top)); - verts.push_back(Vertexf(left + _card_border_size, 0.02f, - top - _card_border_size)); - // verts 5,6,7,8 - verts.push_back(Vertexf(right - _card_border_size, 0.02f, top)); - verts.push_back(Vertexf(right - _card_border_size, 0.02f, - top - _card_border_size)); - verts.push_back(Vertexf(right, 0.02f, top)); - verts.push_back(Vertexf(right, 0.02f, top - _card_border_size)); - // verts 9,10,11,12 - verts.push_back(Vertexf(left, 0.02f, bottom + _card_border_size)); - verts.push_back(Vertexf(left, 0.02f, bottom)); - verts.push_back(Vertexf(left + _card_border_size, 0.02f, - bottom + _card_border_size)); - verts.push_back(Vertexf(left + _card_border_size, 0.02f, bottom)); - // verts 13,14,15,16 - verts.push_back(Vertexf(right - _card_border_size, 0.02f, - bottom + _card_border_size)); - verts.push_back(Vertexf(right - _card_border_size, 0.02f, bottom)); - verts.push_back(Vertexf(right, 0.02f, bottom + _card_border_size)); - verts.push_back(Vertexf(right, 0.02f, bottom)); + if (use_qpgeom) { + PT(qpGeomVertexData) vdata = new qpGeomVertexData + ("text", qpGeomVertexFormat::get_v3cpt2(), + qpGeomUsageHint::UH_static); + qpGeomVertexWriter vertex(vdata, InternalName::get_vertex()); + qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord()); - PTA_ushort indices; - // tristrip #1 - indices.push_back(0); - indices.push_back(1); - indices.push_back(2); - indices.push_back(3); - indices.push_back(4); - indices.push_back(5); - indices.push_back(6); - indices.push_back(7); - // tristrip #2 - indices.push_back(1); - indices.push_back(8); - indices.push_back(3); - indices.push_back(10); - indices.push_back(5); - indices.push_back(12); - indices.push_back(7); - indices.push_back(14); - // tristrip #3 - indices.push_back(8); - indices.push_back(9); - indices.push_back(10); - indices.push_back(11); - indices.push_back(12); - indices.push_back(13); - indices.push_back(14); - indices.push_back(15); + // verts 1,2,3,4 + vertex.add_data3f(left, 0.02f, top); + vertex.add_data3f(left, 0.02f, top - _card_border_size); + vertex.add_data3f(left + _card_border_size, 0.02f, top); + vertex.add_data3f(left + _card_border_size, 0.02f, + top - _card_border_size); + // verts 5,6,7,8 + vertex.add_data3f(right - _card_border_size, 0.02f, top); + vertex.add_data3f(right - _card_border_size, 0.02f, + top - _card_border_size); + vertex.add_data3f(right, 0.02f, top); + vertex.add_data3f(right, 0.02f, top - _card_border_size); + // verts 9,10,11,12 + vertex.add_data3f(left, 0.02f, bottom + _card_border_size); + vertex.add_data3f(left, 0.02f, bottom); + vertex.add_data3f(left + _card_border_size, 0.02f, + bottom + _card_border_size); + vertex.add_data3f(left + _card_border_size, 0.02f, bottom); + // verts 13,14,15,16 + vertex.add_data3f(right - _card_border_size, 0.02f, + bottom + _card_border_size); + vertex.add_data3f(right - _card_border_size, 0.02f, bottom); + vertex.add_data3f(right, 0.02f, bottom + _card_border_size); + vertex.add_data3f(right, 0.02f, bottom); - geoset->set_num_prims(3); - geoset->set_lengths(lengths); + texcoord.add_data2f(0.0f, 1.0f); //1 + texcoord.add_data2f(0.0f, 1.0f - _card_border_uv_portion); //2 + texcoord.add_data2f(0.0f + _card_border_uv_portion, 1.0f); //3 + texcoord.add_data2f(0.0f + _card_border_uv_portion, + 1.0f - _card_border_uv_portion); //4 + texcoord.add_data2f(1.0f -_card_border_uv_portion, 1.0f); //5 + texcoord.add_data2f(1.0f -_card_border_uv_portion, + 1.0f - _card_border_uv_portion); //6 + texcoord.add_data2f(1.0f, 1.0f); //7 + texcoord.add_data2f(1.0f, 1.0f - _card_border_uv_portion); //8 - geoset->set_coords(verts,indices); + texcoord.add_data2f(0.0f, _card_border_uv_portion); //9 + texcoord.add_data2f(0.0f, 0.0f); //10 + texcoord.add_data2f(_card_border_uv_portion, _card_border_uv_portion); //11 + texcoord.add_data2f(_card_border_uv_portion, 0.0f); //12 - if (has_card_texture()) { - PTA_TexCoordf uvs; - uvs.push_back(TexCoordf(0.0f, 1.0f)); //1 - uvs.push_back(TexCoordf(0.0f, 1.0f - _card_border_uv_portion)); //2 - uvs.push_back(TexCoordf(0.0f + _card_border_uv_portion, 1.0f)); //3 - uvs.push_back(TexCoordf(0.0f + _card_border_uv_portion, - 1.0f - _card_border_uv_portion)); //4 - uvs.push_back(TexCoordf( 1.0f -_card_border_uv_portion, 1.0f)); //5 - uvs.push_back(TexCoordf( 1.0f -_card_border_uv_portion, - 1.0f - _card_border_uv_portion)); //6 - uvs.push_back(TexCoordf(1.0f, 1.0f)); //7 - uvs.push_back(TexCoordf(1.0f, 1.0f - _card_border_uv_portion)); //8 + texcoord.add_data2f(1.0f - _card_border_uv_portion, _card_border_uv_portion);//13 + texcoord.add_data2f(1.0f - _card_border_uv_portion, 0.0f);//14 + texcoord.add_data2f(1.0f, _card_border_uv_portion);//15 + texcoord.add_data2f(1.0f, 0.0f);//16 + + PT(qpGeomTristrips) card = new qpGeomTristrips(qpGeomUsageHint::UH_static); - uvs.push_back(TexCoordf(0.0f, _card_border_uv_portion)); //9 - uvs.push_back(TexCoordf(0.0f, 0.0f)); //10 - uvs.push_back(TexCoordf(_card_border_uv_portion, _card_border_uv_portion)); //11 - uvs.push_back(TexCoordf(_card_border_uv_portion, 0.0f)); //12 + // tristrip #1 + card->add_consecutive_vertices(0, 8); + card->close_primitive(); - uvs.push_back(TexCoordf(1.0f - _card_border_uv_portion, _card_border_uv_portion));//13 - uvs.push_back(TexCoordf(1.0f - _card_border_uv_portion, 0.0f));//14 - uvs.push_back(TexCoordf(1.0f, _card_border_uv_portion));//15 - uvs.push_back(TexCoordf(1.0f, 0.0f));//16 + // tristrip #2 + card->add_vertex(1); + card->add_vertex(8); + card->add_vertex(3); + card->add_vertex(10); + card->add_vertex(5); + card->add_vertex(12); + card->add_vertex(7); + card->add_vertex(14); + card->close_primitive(); - // we can use same ref's as before (same order) - geoset->set_texcoords(uvs, G_PER_VERTEX, indices); + // tristrip #3 + card->add_consecutive_vertices(8, 8); + card->close_primitive(); + PT(qpGeom) geom = new qpGeom; + geom->set_vertex_data(vdata); + geom->add_primitive(card); + + card_node->add_geom(geom); + + } else { + GeomTristrip *geoset = new GeomTristrip; + PTA_int lengths; + lengths.push_back(8); + lengths.push_back(8); + lengths.push_back(8); + + PTA_Vertexf verts; + // verts 1,2,3,4 + verts.push_back(Vertexf(left, 0.02f, top)); + verts.push_back(Vertexf(left, 0.02f, top - _card_border_size)); + verts.push_back(Vertexf(left + _card_border_size, 0.02f, top)); + verts.push_back(Vertexf(left + _card_border_size, 0.02f, + top - _card_border_size)); + // verts 5,6,7,8 + verts.push_back(Vertexf(right - _card_border_size, 0.02f, top)); + verts.push_back(Vertexf(right - _card_border_size, 0.02f, + top - _card_border_size)); + verts.push_back(Vertexf(right, 0.02f, top)); + verts.push_back(Vertexf(right, 0.02f, top - _card_border_size)); + // verts 9,10,11,12 + verts.push_back(Vertexf(left, 0.02f, bottom + _card_border_size)); + verts.push_back(Vertexf(left, 0.02f, bottom)); + verts.push_back(Vertexf(left + _card_border_size, 0.02f, + bottom + _card_border_size)); + verts.push_back(Vertexf(left + _card_border_size, 0.02f, bottom)); + // verts 13,14,15,16 + verts.push_back(Vertexf(right - _card_border_size, 0.02f, + bottom + _card_border_size)); + verts.push_back(Vertexf(right - _card_border_size, 0.02f, bottom)); + verts.push_back(Vertexf(right, 0.02f, bottom + _card_border_size)); + verts.push_back(Vertexf(right, 0.02f, bottom)); + + PTA_ushort indices; + // tristrip #1 + indices.push_back(0); + indices.push_back(1); + indices.push_back(2); + indices.push_back(3); + indices.push_back(4); + indices.push_back(5); + indices.push_back(6); + indices.push_back(7); + // tristrip #2 + indices.push_back(1); + indices.push_back(8); + indices.push_back(3); + indices.push_back(10); + indices.push_back(5); + indices.push_back(12); + indices.push_back(7); + indices.push_back(14); + // tristrip #3 + indices.push_back(8); + indices.push_back(9); + indices.push_back(10); + indices.push_back(11); + indices.push_back(12); + indices.push_back(13); + indices.push_back(14); + indices.push_back(15); + + geoset->set_num_prims(3); + geoset->set_lengths(lengths); + + geoset->set_coords(verts,indices); + + if (has_card_texture()) { + PTA_TexCoordf uvs; + uvs.push_back(TexCoordf(0.0f, 1.0f)); //1 + uvs.push_back(TexCoordf(0.0f, 1.0f - _card_border_uv_portion)); //2 + uvs.push_back(TexCoordf(0.0f + _card_border_uv_portion, 1.0f)); //3 + uvs.push_back(TexCoordf(0.0f + _card_border_uv_portion, + 1.0f - _card_border_uv_portion)); //4 + uvs.push_back(TexCoordf( 1.0f -_card_border_uv_portion, 1.0f)); //5 + uvs.push_back(TexCoordf( 1.0f -_card_border_uv_portion, + 1.0f - _card_border_uv_portion)); //6 + uvs.push_back(TexCoordf(1.0f, 1.0f)); //7 + uvs.push_back(TexCoordf(1.0f, 1.0f - _card_border_uv_portion)); //8 + + uvs.push_back(TexCoordf(0.0f, _card_border_uv_portion)); //9 + uvs.push_back(TexCoordf(0.0f, 0.0f)); //10 + uvs.push_back(TexCoordf(_card_border_uv_portion, _card_border_uv_portion)); //11 + uvs.push_back(TexCoordf(_card_border_uv_portion, 0.0f)); //12 + + uvs.push_back(TexCoordf(1.0f - _card_border_uv_portion, _card_border_uv_portion));//13 + uvs.push_back(TexCoordf(1.0f - _card_border_uv_portion, 0.0f));//14 + uvs.push_back(TexCoordf(1.0f, _card_border_uv_portion));//15 + uvs.push_back(TexCoordf(1.0f, 0.0f));//16 + + // we can use same ref's as before (same order) + geoset->set_texcoords(uvs, G_PER_VERTEX, indices); + } + + card_node->add_geom(geoset); } - card_geode->add_geom(geoset); - - return card_geode.p(); + return card_node.p(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/text/textProperties.cxx b/panda/src/text/textProperties.cxx index be2e8ec7f5..fe6cd723d4 100644 --- a/panda/src/text/textProperties.cxx +++ b/panda/src/text/textProperties.cxx @@ -278,7 +278,7 @@ load_default_font() { if (!text_default_font.empty()) { // First, attempt to load the user-specified filename. _default_font = FontPool::load_font(text_default_font.get_value()); - if (_default_font->is_valid()) { + if (_default_font != (TextFont *)NULL && _default_font->is_valid()) { return; } } diff --git a/panda/src/text/text_composite1.cxx b/panda/src/text/text_composite1.cxx index a7329d5eb7..eff5c128c0 100644 --- a/panda/src/text/text_composite1.cxx +++ b/panda/src/text/text_composite1.cxx @@ -5,4 +5,5 @@ #include "dynamicTextPage.cxx" #include "fontPool.cxx" #include "geomTextGlyph.cxx" +#include "qpgeomTextGlyph.cxx" #include "staticTextFont.cxx"