handle use_qpgeom on more internal things

This commit is contained in:
David Rose 2005-04-04 22:58:35 +00:00
parent 67faf965c6
commit 20e9703887
45 changed files with 1558 additions and 586 deletions

View File

@ -310,7 +310,7 @@ fill_viz_geom() {
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("collision", qpGeomVertexFormat::get_v3cp(),
("collision", qpGeomVertexFormat::get_v3(),
qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());

View File

@ -327,7 +327,7 @@ fill_viz_geom() {
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("collision", qpGeomVertexFormat::get_v3cp(),
("collision", qpGeomVertexFormat::get_v3(),
qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());

View File

@ -819,7 +819,7 @@ draw_polygon(GeomNode *viz_geom_node, GeomNode *bounds_viz_geom_node,
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("collision", qpGeomVertexFormat::get_v3cp(),
("collision", qpGeomVertexFormat::get_v3(),
qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());

View File

@ -329,7 +329,7 @@ fill_viz_geom() {
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("collision", qpGeomVertexFormat::get_v3cp(),
("collision", qpGeomVertexFormat::get_v3(),
qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());

View File

@ -393,7 +393,7 @@ fill_viz_geom() {
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("collision", qpGeomVertexFormat::get_v3cp(),
("collision", qpGeomVertexFormat::get_v3(),
qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());

View File

@ -23,6 +23,11 @@
#include "transformState.h"
#include "workingNodePath.h"
#include "switchNode.h"
#include "qpgeom.h"
#include "qpgeomTristrips.h"
#include "qpgeomVertexWriter.h"
#include "qpgeomVertexReader.h"
#include "qpgeomVertexRewriter.h"
TypeHandle ProjectionScreen::_type_handle;
@ -193,88 +198,144 @@ generate_screen(const NodePath &projector, const string &screen_name,
NodePath this_np(this);
rel_mat = projector.get_mat(this_np);
// Create a GeomNode to hold this mesh.
PT(GeomNode) geom_node = new GeomNode(screen_name);
// Now compute all the vertices for the screen. These are arranged
// in order from left to right and bottom to top.
int num_verts = num_x_verts * num_y_verts;
Lens *lens = projector_node->get_lens();
float t = (distance - lens->get_near()) / (lens->get_far() - lens->get_near());
PTA_Vertexf coords;
PTA_Normalf norms;
coords.reserve(num_verts);
float x_scale = 2.0f / (num_x_verts - 1);
float y_scale = 2.0f / (num_y_verts - 1);
for (int yi = 0; yi < num_y_verts; yi++) {
for (int xi = 0; xi < num_x_verts; xi++) {
LPoint2f film = LPoint2f((float)xi * x_scale - 1.0f,
(float)yi * y_scale - 1.0f);
// Reduce the image by the fill ratio.
film *= fill_ratio;
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("projectionScreen", qpGeomVertexFormat::get_v3n3(),
qpGeomUsageHint::UH_dynamic);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
qpGeomVertexWriter normal(vdata, InternalName::get_normal());
for (int yi = 0; yi < num_y_verts; yi++) {
for (int xi = 0; xi < num_x_verts; xi++) {
LPoint2f film = LPoint2f((float)xi * x_scale - 1.0f,
(float)yi * y_scale - 1.0f);
// Reduce the image by the fill ratio.
film *= fill_ratio;
LPoint3f near_point, far_point;
lens->extrude(film, near_point, far_point);
LPoint3f point = near_point + t * (far_point - near_point);
// Normals aren't often needed on projection screens, but you
// never know.
LVector3f norm;
lens->extrude_vec(film, norm);
LPoint3f near_point, far_point;
lens->extrude(film, near_point, far_point);
LPoint3f point = near_point + t * (far_point - near_point);
// Normals aren't often needed on projection screens, but you
// never know.
LVector3f normal;
lens->extrude_vec(film, normal);
coords.push_back(point * rel_mat);
norms.push_back(-normalize(normal * rel_mat));
vertex.add_data3f(point * rel_mat);
normal.add_data3f(-normalize(norm * rel_mat));
}
}
}
nassertr((int)coords.size() == num_verts, NULL);
nassertr(vdata->get_num_vertices() == num_verts, NULL);
// Now synthesize a triangle mesh. We run triangle strips
// horizontally across the grid.
int num_tstrips = (num_y_verts-1);
int tstrip_length = 2*(num_x_verts-1)+2;
PTA_int lengths;
PTA_ushort vindex;
// Set the lengths array. we are creating num_tstrips t-strips,
// each of which has tstrip_length vertices.
lengths.reserve(num_tstrips);
int n;
for (n = 0; n < num_tstrips; n++) {
lengths.push_back(tstrip_length);
}
nassertr((int)lengths.size() == num_tstrips, NULL);
// Now fill up the index array into the vertices. This lays out the
// order of the vertices in each t-strip.
vindex.reserve(num_tstrips * tstrip_length);
n = 0;
int ti, si;
for (ti = 1; ti < num_y_verts; ti++) {
vindex.push_back(ti * num_x_verts);
for (si = 1; si < num_x_verts; si++) {
vindex.push_back((ti - 1) * num_x_verts + (si-1));
vindex.push_back(ti * num_x_verts + si);
// Now synthesize a triangle mesh. We run triangle strips
// horizontally across the grid.
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static);
// Fill up the index array into the vertices. This lays out the
// order of the vertices in each tristrip.
int ti, si;
for (ti = 1; ti < num_y_verts; ti++) {
strip->add_vertex(ti * num_x_verts);
for (si = 1; si < num_x_verts; si++) {
strip->add_vertex((ti - 1) * num_x_verts + (si-1));
strip->add_vertex(ti * num_x_verts + si);
}
strip->add_vertex((ti - 1) * num_x_verts + (num_x_verts-1));
strip->close_primitive();
}
vindex.push_back((ti - 1) * num_x_verts + (num_x_verts-1));
PT(qpGeom) geom = new qpGeom;
geom->set_vertex_data(vdata);
geom->add_primitive(strip);
geom_node->add_geom(geom);
} else {
PTA_Vertexf coords;
PTA_Normalf norms;
coords.reserve(num_verts);
for (int yi = 0; yi < num_y_verts; yi++) {
for (int xi = 0; xi < num_x_verts; xi++) {
LPoint2f film = LPoint2f((float)xi * x_scale - 1.0f,
(float)yi * y_scale - 1.0f);
// Reduce the image by the fill ratio.
film *= fill_ratio;
LPoint3f near_point, far_point;
lens->extrude(film, near_point, far_point);
LPoint3f point = near_point + t * (far_point - near_point);
// Normals aren't often needed on projection screens, but you
// never know.
LVector3f normal;
lens->extrude_vec(film, normal);
coords.push_back(point * rel_mat);
norms.push_back(-normalize(normal * rel_mat));
}
}
nassertr((int)coords.size() == num_verts, NULL);
// Now synthesize a triangle mesh. We run triangle strips
// horizontally across the grid.
int num_tstrips = (num_y_verts-1);
int tstrip_length = 2*(num_x_verts-1)+2;
PTA_int lengths;
PTA_ushort vindex;
// Set the lengths array. we are creating num_tstrips t-strips,
// each of which has tstrip_length vertices.
lengths.reserve(num_tstrips);
int n;
for (n = 0; n < num_tstrips; n++) {
lengths.push_back(tstrip_length);
}
nassertr((int)lengths.size() == num_tstrips, NULL);
// Now fill up the index array into the vertices. This lays out the
// order of the vertices in each t-strip.
vindex.reserve(num_tstrips * tstrip_length);
n = 0;
int ti, si;
for (ti = 1; ti < num_y_verts; ti++) {
vindex.push_back(ti * num_x_verts);
for (si = 1; si < num_x_verts; si++) {
vindex.push_back((ti - 1) * num_x_verts + (si-1));
vindex.push_back(ti * num_x_verts + si);
}
vindex.push_back((ti - 1) * num_x_verts + (num_x_verts-1));
}
nassertr((int)vindex.size() == num_tstrips * tstrip_length, NULL);
GeomTristrip *geom = new GeomTristrip;
geom->set_num_prims(num_tstrips);
geom->set_lengths(lengths);
geom->set_coords(coords, G_PER_VERTEX, vindex);
geom->set_normals(norms, G_PER_VERTEX, vindex);
// Make it white.
PTA_Colorf colors;
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
geom->set_colors(colors, G_OVERALL);
geom_node->add_geom(geom);
}
nassertr((int)vindex.size() == num_tstrips * tstrip_length, NULL);
GeomTristrip *geom = new GeomTristrip;
geom->set_num_prims(num_tstrips);
geom->set_lengths(lengths);
geom->set_coords(coords, G_PER_VERTEX, vindex);
geom->set_normals(norms, G_PER_VERTEX, vindex);
// Make it white.
PTA_Colorf colors;
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
geom->set_colors(colors, G_OVERALL);
// Now create a GeomNode to hold this mesh.
PT(GeomNode) geom_node = new GeomNode(screen_name);
geom_node->add_geom(geom);
_stale = true;
++_last_screen;
@ -535,55 +596,106 @@ recompute_geom(Geom *geom, const LMatrix4f &rel_mat) {
0.0f,-0.5f, 0.0f,
0.5f, 0.5f, 1.0f);
PTA_TexCoordf uvs;
PTA_ushort color_index;
Lens *lens = _projector_node->get_lens();
nassertv(lens != (Lens *)NULL);
const LMatrix3f &to_uv = _invert_uvs ? lens_to_uv_inverted : lens_to_uv;
// Iterate through all the vertices in the Geom.
int num_vertices = geom->get_num_vertices();
Geom::VertexIterator vi = geom->make_vertex_iterator();
if (geom->is_of_type(qpGeom::get_class_type())) {
qpGeom *qpgeom = DCAST(qpGeom, geom);
// Iterate through all the vertices in the Geom.
for (int i = 0; i < num_vertices; i++) {
const Vertexf &vert = geom->get_next_vertex(vi);
// For each vertex, project to the film plane.
LPoint2f film(0.0, 0.0);
bool good = lens->project(vert * rel_mat, film);
// Now the lens gives us coordinates in the range [-1, 1].
// Rescale these to [0, 1].
uvs.push_back(film * to_uv);
// If we have vignette color in effect, color the vertex according
// to whether it fell in front of the lens or not.
if (_vignette_on) {
color_index.push_back(good ? 1 : 0);
CPT(qpGeomVertexData) vdata = qpgeom->get_vertex_data();
if (!vdata->has_column(_texcoord_name)) {
// We need to add a new column for the new texcoords.
vdata = vdata->replace_column
(_texcoord_name, 2, qpGeomVertexColumn::NT_float32,
qpGeomVertexColumn::C_texcoord, qpGeomUsageHint::UH_dynamic, true);
qpgeom->set_vertex_data(vdata);
}
if (_vignette_on && !vdata->has_column(InternalName::get_color())) {
// We need to add a column for color.
vdata = vdata->replace_column
(InternalName::get_color(), 1, qpGeomVertexColumn::NT_packed_dabc,
qpGeomVertexColumn::C_color, qpGeomUsageHint::UH_dynamic, true);
qpgeom->set_vertex_data(vdata);
}
}
// Now set the UV's. If the geom already has indexed UV's, we need
// to make a new index for the geom.
geom->remove_texcoords(_texcoord_name);
if (!geom->are_texcoords_indexed()) {
// Simple case: no indexing needed.
geom->set_texcoords(_texcoord_name, uvs);
qpGeomVertexWriter texcoord(qpgeom->modify_vertex_data(), _texcoord_name);
qpGeomVertexWriter color(qpgeom->modify_vertex_data());
qpGeomVertexReader vertex(qpgeom->get_vertex_data(), InternalName::get_vertex());
if (_vignette_on) {
color.set_column(InternalName::get_color());
}
while (!vertex.is_at_end()) {
Vertexf vert = vertex.get_data3f();
// For each vertex, project to the film plane.
LPoint2f film(0.0, 0.0);
bool good = lens->project(vert * rel_mat, film);
// Now the lens gives us coordinates in the range [-1, 1].
// Rescale these to [0, 1].
texcoord.set_data2f(film * to_uv);
// If we have vignette color in effect, color the vertex according
// to whether it fell in front of the lens or not.
if (_vignette_on) {
if (good) {
color.set_data4f(_frame_color);
} else {
color.set_data4f(_vignette_color);
}
}
}
} else {
// Harder case: we need to make up an index. But this isn't
// terribly hard.
PTA_ushort index = PTA_ushort::empty_array(num_vertices);
// Iterate through all the vertices in the Geom.
PTA_TexCoordf uvs;
PTA_ushort color_index;
int num_vertices = geom->get_num_vertices();
Geom::VertexIterator vi = geom->make_vertex_iterator();
for (int i = 0; i < num_vertices; i++) {
index[i] = i;
const Vertexf &vert = geom->get_next_vertex(vi);
// For each vertex, project to the film plane.
LPoint2f film(0.0, 0.0);
bool good = lens->project(vert * rel_mat, film);
// Now the lens gives us coordinates in the range [-1, 1].
// Rescale these to [0, 1].
uvs.push_back(film * to_uv);
// If we have vignette color in effect, color the vertex according
// to whether it fell in front of the lens or not.
if (_vignette_on) {
color_index.push_back(good ? 1 : 0);
}
}
geom->set_texcoords(_texcoord_name, uvs, index);
}
// Now set the UV's. If the geom already has indexed UV's, we need
// to make a new index for the geom.
geom->remove_texcoords(_texcoord_name);
if (!geom->are_texcoords_indexed()) {
// Simple case: no indexing needed.
geom->set_texcoords(_texcoord_name, uvs);
} else {
// Harder case: we need to make up an index. But this isn't
// terribly hard.
PTA_ushort index = PTA_ushort::empty_array(num_vertices);
for (int i = 0; i < num_vertices; i++) {
index[i] = i;
}
geom->set_texcoords(_texcoord_name, uvs, index);
}
if (_vignette_on) {
geom->set_colors(_colors, G_PER_VERTEX, color_index);
if (_vignette_on) {
geom->set_colors(_colors, G_PER_VERTEX, color_index);
}
}
}
@ -702,29 +814,49 @@ make_mesh_geom_node(const WorkingNodePath &np, const NodePath &camera,
////////////////////////////////////////////////////////////////////
PT(Geom) ProjectionScreen::
make_mesh_geom(const Geom *geom, Lens *lens, LMatrix4f &rel_mat) {
Geom *new_geom = geom->make_copy();
PT(Geom) result = new_geom;
if (geom->is_of_type(qpGeom::get_class_type())) {
PT(qpGeom) new_geom = new qpGeom(*DCAST(qpGeom, geom));
PTA_Vertexf coords;
GeomBindType bind;
PTA_ushort vindex;
qpGeomVertexRewriter vertex(new_geom->modify_vertex_data(),
InternalName::get_vertex());
while (!vertex.is_at_end()) {
Vertexf vert = vertex.get_data3f();
// Project each vertex into the film plane, but use three
// dimensions so the Z coordinate remains meaningful.
LPoint3f film(0.0f, 0.0f, 0.0f);
lens->project(vert * rel_mat, film);
vertex.set_data3f(film);
}
new_geom->get_coords(coords, bind, vindex);
return new_geom.p();
} else {
Geom *new_geom = geom->make_copy();
PT(Geom) result = new_geom;
PTA_Vertexf new_coords;
new_coords.reserve(coords.size());
for (int i = 0; i < (int)coords.size(); i++) {
const Vertexf &vert = coords[i];
PTA_Vertexf coords;
GeomBindType bind;
PTA_ushort vindex;
new_geom->get_coords(coords, bind, vindex);
PTA_Vertexf new_coords;
new_coords.reserve(coords.size());
for (int i = 0; i < (int)coords.size(); i++) {
const Vertexf &vert = coords[i];
// Project each vertex into the film plane, but use three
// dimensions so the Z coordinate remains meaningful.
LPoint3f film(0.0f, 0.0f, 0.0f);
lens->project(vert * rel_mat, film);
new_coords.push_back(film);
}
new_geom->set_coords(new_coords, bind, vindex);
// Project each vertex into the film plane, but use three
// dimensions so the Z coordinate remains meaningful.
LPoint3f film(0.0f, 0.0f, 0.0f);
lens->project(vert * rel_mat, film);
new_coords.push_back(film);
return result;
}
new_geom->set_coords(new_coords, bind, vindex);
return result;
}

View File

@ -250,6 +250,28 @@ has_colors() const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexPool::has_nonwhite_colors
// Access: Public
// Description: Returns true if any vertex in the pool has a color
// defined other than white, false if no vertices have
// colors, or if all colors are white.
////////////////////////////////////////////////////////////////////
bool EggVertexPool::
has_nonwhite_colors() const {
IndexVertices::const_iterator ivi;
for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
EggVertex *vertex = (*ivi).second;
if (vertex->has_color() &&
(vertex->get_color() != Colorf(1.0, 1.0, 1.0, 1.0) ||
!vertex->_drgbas.empty())) {
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: EggVertexPool::has_uvs
// Access: Public

View File

@ -96,6 +96,7 @@ PUBLISHED:
int get_num_dimensions() const;
bool has_normals() const;
bool has_colors() const;
bool has_nonwhite_colors() const;
bool has_uvs() const;
void get_uv_names(vector_string &uv_names) const;

View File

@ -19,6 +19,8 @@
#include "eggBinner.h"
#include "eggRenderState.h"
#include "eggPrimitive.h"
#include "eggNurbsSurface.h"
#include "eggNurbsCurve.h"
#include "eggSwitchCondition.h"
#include "eggGroup.h"
#include "dcast.h"
@ -58,7 +60,13 @@ prepare_node(EggNode *node) {
////////////////////////////////////////////////////////////////////
int EggBinner::
get_bin_number(const EggNode *node) {
if (node->is_of_type(EggPrimitive::get_class_type())) {
if (node->is_of_type(EggNurbsSurface::get_class_type())) {
return (int)BN_nurbs_surface;
} else if (node->is_of_type(EggNurbsCurve::get_class_type())) {
return (int)BN_nurbs_curve;
} else if (node->is_of_type(EggPrimitive::get_class_type())) {
return (int)BN_polyset;
} else if (node->is_of_type(EggGroup::get_class_type())) {
@ -115,6 +123,11 @@ sorts_less(int bin_number, const EggNode *a, const EggNode *b) {
// Group LOD nodes in order by switching center.
return (swda._center.compare_to(swdb._center) < 0);
}
case BN_nurbs_surface:
case BN_nurbs_curve:
// Nurbs curves and surfaces are always binned individually.
return a < b;
case BN_none:
break;

View File

@ -43,6 +43,8 @@ public:
BN_none = 0,
BN_polyset,
BN_lod,
BN_nurbs_surface,
BN_nurbs_curve,
};
EggBinner(EggLoader &loader);

View File

@ -420,7 +420,7 @@ make_indexed_primitive(EggPrimitive *egg_prim, PandaNode *parent,
int nindex =
comp_verts_maker.add_normal(egg_prim->get_normal(),
egg_prim->_dnormals, mat);
egg_prim->_dnormals, mat);
bprim.set_normal(nindex);
}
@ -428,7 +428,7 @@ make_indexed_primitive(EggPrimitive *egg_prim, PandaNode *parent,
if (egg_prim->has_color() && !egg_false_color) {
int cindex =
comp_verts_maker.add_color(egg_prim->get_color(),
egg_prim->_drgbas);
egg_prim->_drgbas);
bprim.set_color(cindex);
}
@ -1541,6 +1541,28 @@ make_node(EggBin *egg_bin, PandaNode *parent) {
case EggBinner::BN_lod:
return make_lod(egg_bin, parent);
case EggBinner::BN_nurbs_surface:
{
nassertr(!egg_bin->empty(), NULL);
EggNode *child = egg_bin->get_first_child();
EggNurbsSurface *egg_nurbs;
DCAST_INTO_R(egg_nurbs, child, NULL);
const LMatrix4d &mat = egg_nurbs->get_vertex_to_node();
make_nurbs_surface(egg_nurbs, parent, mat);
}
return NULL;
case EggBinner::BN_nurbs_curve:
{
nassertr(!egg_bin->empty(), NULL);
EggNode *child = egg_bin->get_first_child();
EggNurbsCurve *egg_nurbs;
DCAST_INTO_R(egg_nurbs, child, NULL);
const LMatrix4d &mat = egg_nurbs->get_vertex_to_node();
make_nurbs_curve(egg_nurbs, parent, mat);
}
return NULL;
case EggBinner::BN_none:
break;
}
@ -1929,7 +1951,8 @@ make_vertex_data(const EggRenderState *render_state,
qpGeomVertexColumn::NT_float32, qpGeomVertexColumn::C_vector);
}
if (vertex_pool->has_colors()) {
bool has_colors = vertex_pool->has_nonwhite_colors();
if (has_colors) {
array_format->add_column
(InternalName::get_color(), 1,
qpGeomVertexColumn::NT_packed_dabc, qpGeomVertexColumn::C_color);
@ -1994,7 +2017,7 @@ make_vertex_data(const EggRenderState *render_state,
InternalName::get_normal(), 3);
}
}
if (vertex->has_color()) {
if (has_colors && vertex->has_color()) {
EggMorphColorList::const_iterator mci;
for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
slider_names.insert((*mci).get_name());
@ -2090,7 +2113,7 @@ make_vertex_data(const EggRenderState *render_state,
}
}
if (vertex->has_color()) {
if (has_colors && vertex->has_color()) {
gvw.set_column(InternalName::get_color());
gvw.add_data4f(vertex->get_color());
@ -2372,13 +2395,8 @@ make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
//egg2pg_cat.debug() << "make_sphere radius: " << radius << "\n";
vi = vertices.begin();
EggVertex *clr_vtx = (*vi);
if (clr_vtx->has_color()) {
color = clr_vtx->get_color();
} else {
color = Colorf(1.0,1.0,1.0,1.0);
}
color = clr_vtx->get_color();
success = true;
}
}
return success;

View File

@ -1060,7 +1060,7 @@ load_image_as_model(const Filename &filename) {
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
(string(), qpGeomVertexFormat::get_v3cpt2(),
(string(), qpGeomVertexFormat::get_v3t2(),
qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());

View File

@ -2324,6 +2324,10 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
GLP(EnableClientState)(GL_COLOR_ARRAY);
} else {
GLP(DisableClientState)(GL_COLOR_ARRAY);
// Since we don't have per-vertex color, the implicit color is
// white.
GLP(Color4f)(1.0f, 1.0f, 1.0f, 1.0f);
}
// Now set up each of the active texture coordinate stages--or at

View File

@ -329,6 +329,17 @@ transform_vertices(const LMatrix4f &mat) {
set_coords(new_coords, index);
}
////////////////////////////////////////////////////////////////////
// Function: Geom::check_valid
// Access: Published
// Description: This is only here temporarily; it has meaning at the
// qpGeom level.
////////////////////////////////////////////////////////////////////
bool Geom::
check_valid() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: Geom::set_coords
// Access: Published

View File

@ -136,6 +136,7 @@ public:
PUBLISHED:
virtual void transform_vertices(const LMatrix4f &mat);
virtual bool check_valid() const;
void set_coords(const PTA_Vertexf &coords,
const PTA_ushort &vindex = PTA_ushort());

View File

@ -21,6 +21,9 @@
#include "compose_matrix.h"
#include "look_at.h"
#include "geomLinestrip.h"
#include "qpgeom.h"
#include "qpgeomLinestrips.h"
#include "qpgeomVertexWriter.h"
#include "boundingHexahedron.h"
#include "indent.h"
#include "config_gobj.h"
@ -67,8 +70,7 @@ operator = (const Lens &copy) {
_user_flags = copy._user_flags;
_comp_flags = 0;
// We don't copy the _geom_coords array. That's unique to each
// Lens.
// We don't copy the _geom_data. That's unique to each Lens.
}
////////////////////////////////////////////////////////////////////
@ -873,74 +875,137 @@ PT(Geom) Lens::
make_geometry() {
// The default behavior for make_geometry() will be to draw a
// hexahedron around the eight vertices of the frustum. If the lens
// is non-linear, the hexahedron will be curved; in this case, we'll
// is non-linear, the hexahedron will be curved; in that case, we'll
// subdivide the lines into several segments to get an approximation
// of the curve.
// First, define all the points we'll use in this Geom. That's one
// point at each corner of the near and far planes (and possibly
// more points along the edges).
int num_segments = define_geom_coords();
if (num_segments == 0) {
// Can't do a frustum.
_geom_coords.clear();
return (Geom *)NULL;
if (use_qpgeom) {
// First, define all the points we'll use in this Geom. That's one
// point at each corner of the near and far planes (and possibly
// more points along the edges).
int num_segments = define_geom_data();
if (num_segments == 0) {
// Can't do a frustum.
_geom_data.clear();
return (Geom *)NULL;
}
// Now string together the line segments.
PT(qpGeomLinestrips) line = new qpGeomLinestrips(qpGeomUsageHint::UH_static);
// Draw a frame around the near plane.
int i, si;
for (i = 0; i < 4; ++i) {
for (si = 0; si < num_segments; ++si) {
line->add_vertex(i * 2 + si * (4 * 2) + 0);
}
}
line->add_vertex(0);
line->close_primitive();
// Draw a frame around the far plane.
for (i = 0; i < 4; ++i) {
for (si = 0; si < num_segments; ++si) {
line->add_vertex(i * 2 + si * (4 * 2) + 1);
}
}
line->add_vertex(1);
line->close_primitive();
// Draw connecting lines at the corners.
line->add_vertex(0 * 2 + 0);
line->add_vertex(0 * 2 + 1);
line->close_primitive();
line->add_vertex(1 * 2 + 0);
line->add_vertex(1 * 2 + 1);
line->close_primitive();
line->add_vertex(2 * 2 + 0);
line->add_vertex(2 * 2 + 1);
line->close_primitive();
line->add_vertex(3 * 2 + 0);
line->add_vertex(3 * 2 + 1);
line->close_primitive();
// And one more line for the viewing axis.
line->add_vertex(num_segments * (4 * 2) + 0);
line->add_vertex(num_segments * (4 * 2) + 1);
line->close_primitive();
PT(qpGeom) geom = new qpGeom;
geom->set_vertex_data(_geom_data);
geom->add_primitive(line);
return geom.p();
} else {
// First, define all the points we'll use in this Geom. That's one
// point at each corner of the near and far planes (and possibly
// more points along the edges).
int num_segments = define_geom_coords();
if (num_segments == 0) {
// Can't do a frustum.
_geom_coords.clear();
return (Geom *)NULL;
}
// Now string together the line segments.
PTA_ushort vindex;
PTA_int lengths;
PTA_Colorf colors;
int num_points = num_segments * 4;
// Draw a frame around the near plane.
int i;
for (i = 0; i < num_points; i++) {
vindex.push_back(i * num_segments * 2);
}
vindex.push_back(0);
lengths.push_back(num_points + 1);
// Draw a frame around the far plane.
for (i = 0; i < num_points; i++) {
vindex.push_back(i * num_segments * 2 + 1);
}
vindex.push_back(1);
lengths.push_back(num_points + 1);
// Draw connecting lines at the corners.
vindex.push_back(0);
vindex.push_back(1);
lengths.push_back(2);
vindex.push_back(num_segments * 2 + 0);
vindex.push_back(num_segments * 2+ 1);
lengths.push_back(2);
vindex.push_back(num_segments * 4 + 0);
vindex.push_back(num_segments * 4 + 1);
lengths.push_back(2);
vindex.push_back(num_segments * 6 + 0);
vindex.push_back(num_segments * 6 + 1);
lengths.push_back(2);
// And one more line for the viewing axis.
vindex.push_back(num_segments * 8 + 0);
vindex.push_back(num_segments * 8 + 1);
lengths.push_back(2);
// We just specify overall color.
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
GeomLinestrip *gline = new GeomLinestrip;
gline->set_coords(_geom_coords, vindex);
gline->set_colors(colors, G_OVERALL);
gline->set_lengths(lengths);
gline->set_num_prims(lengths.size());
return gline;
}
// Now string together the line segments.
PTA_ushort vindex;
PTA_int lengths;
PTA_Colorf colors;
int num_points = num_segments * 4;
// Draw a frame around the near plane.
int i;
for (i = 0; i < num_points; i++) {
vindex.push_back(i * num_segments * 2);
}
vindex.push_back(0);
lengths.push_back(num_points + 1);
// Draw a frame around the far plane.
for (i = 0; i < num_points; i++) {
vindex.push_back(i * num_segments * 2 + 1);
}
vindex.push_back(1);
lengths.push_back(num_points + 1);
// Draw connecting lines at the corners.
vindex.push_back(0);
vindex.push_back(1);
lengths.push_back(2);
vindex.push_back(num_segments * 2 + 0);
vindex.push_back(num_segments * 2+ 1);
lengths.push_back(2);
vindex.push_back(num_segments * 4 + 0);
vindex.push_back(num_segments * 4 + 1);
lengths.push_back(2);
vindex.push_back(num_segments * 6 + 0);
vindex.push_back(num_segments * 6 + 1);
lengths.push_back(2);
// And one more line for the viewing axis.
vindex.push_back(num_segments * 8 + 0);
vindex.push_back(num_segments * 8 + 1);
lengths.push_back(2);
// We just specify overall color.
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
GeomLinestrip *gline = new GeomLinestrip;
gline->set_coords(_geom_coords, vindex);
gline->set_colors(colors, G_OVERALL);
gline->set_lengths(lengths);
gline->set_num_prims(lengths.size());
return gline;
}
////////////////////////////////////////////////////////////////////
@ -1070,6 +1135,18 @@ throw_change_event() {
define_geom_coords();
}
}
if (!_geom_data.is_null()) {
if (_geom_data->get_ref_count() == 1) {
// No one's using the data any more (there are no references to
// it other than this one), so don't bother to recompute it;
// just release it.
_geom_data.clear();
} else {
// Someone still has a handle to the data, so recompute it for
// them.
define_geom_data();
}
}
}
////////////////////////////////////////////////////////////////////
@ -1659,6 +1736,83 @@ define_geom_coords() {
return num_segments;
}
////////////////////////////////////////////////////////////////////
// Function: Lens::define_geom_data
// Access: Private
// Description: Adjusts (or defines for the first time) all the
// vertices in the _geom_data to match the properties of
// the lens. This will update the visual representation
// of the lens's frustum to match the changing
// parameters. Returns the number of line segments per
// edge.
////////////////////////////////////////////////////////////////////
int Lens::
define_geom_data() {
int num_segments = 1;
if (!is_linear()) {
num_segments = 10;
}
if (_geom_data == (qpGeomVertexData *)NULL) {
_geom_data = new qpGeomVertexData
("lens", qpGeomVertexFormat::get_v3(),
qpGeomUsageHint::UH_dynamic);
}
qpGeomVertexWriter vertex(_geom_data, InternalName::get_vertex());
LPoint3f near_point, far_point;
for (int si = 0; si < num_segments; si++) {
float t = 2.0f * (float)si / (float)num_segments;
// Upper left, top edge.
LPoint2f p1(-1.0f + t, 1.0f);
if (!extrude(p1, near_point, far_point)) {
// Hey, this point is off the lens! Can't do a frustum.
return 0;
}
vertex.add_data3f(near_point);
vertex.add_data3f(far_point);
// Upper right, right edge.
LPoint2f p2(1.0f, 1.0f - t);
if (!extrude(p2, near_point, far_point)) {
// Hey, this point is off the lens! Can't do a frustum.
return 0;
}
vertex.add_data3f(near_point);
vertex.add_data3f(far_point);
// Lower right, bottom edge.
LPoint2f p3(1.0f - t, -1.0f);
if (!extrude(p3, near_point, far_point)) {
// Hey, this point is off the lens! Can't do a frustum.
return 0;
}
vertex.add_data3f(near_point);
vertex.add_data3f(far_point);
// Lower left, left edge.
LPoint2f p4(-1.0f, -1.0f + t);
if (!extrude(p4, near_point, far_point)) {
// Hey, this point is off the lens! Can't do a frustum.
return 0;
}
vertex.add_data3f(near_point);
vertex.add_data3f(far_point);
}
// Finally, add one more pair for the viewing axis.
LPoint3f near_axis = LPoint3f::origin(_cs) + LVector3f::forward(_cs) * _near_distance;
LPoint3f far_axis = LPoint3f::origin(_cs) + LVector3f::forward(_cs) * _far_distance;
const LMatrix4f &lens_mat = get_lens_mat();
near_axis = near_axis * lens_mat;
far_axis = far_axis * lens_mat;
vertex.add_data3f(near_axis);
vertex.add_data3f(far_axis);
return num_segments;
}
////////////////////////////////////////////////////////////////////
// Function: Lens::build_shear_mat
// Access: Private, Static

View File

@ -25,6 +25,8 @@
#include "luse.h"
#include "geom.h"
#include "updateSeq.h"
#include "qpgeomVertexData.h"
#include "pointerTo.h"
class BoundingVolume;
@ -182,6 +184,7 @@ protected:
private:
static void resequence_fov_triad(char &newest, char &older_a, char &older_b);
int define_geom_coords();
int define_geom_data();
static void build_shear_mat(LMatrix4f &shear_mat,
const LPoint3f &cul, const LPoint3f &cur,
const LPoint3f &cll, const LPoint3f &clr);
@ -252,6 +255,7 @@ protected:
char _focal_length_seq, _fov_seq, _film_size_seq;
PTA_Vertexf _geom_coords;
PT(qpGeomVertexData) _geom_data;
public:
virtual void write_datagram(BamWriter *manager, Datagram &dg);

View File

@ -107,40 +107,6 @@ modify_primitive(int i) {
return cdata->_primitives[i];
}
////////////////////////////////////////////////////////////////////
// Function: qpGeom::set_primitive
// Access: Published
// Description: Replaces the ith GeomPrimitive object stored within
// the Geom with the new object.
////////////////////////////////////////////////////////////////////
INLINE void qpGeom::
set_primitive(int i, const qpGeomPrimitive *primitive) {
clear_cache();
CDWriter cdata(_cycler);
nassertv(i >= 0 && i < (int)cdata->_primitives.size());
// All primitives within a particular Geom must have the same
// primitive type.
nassertv(cdata->_primitive_type == qpGeomPrimitive::PT_none ||
cdata->_primitive_type == primitive->get_primitive_type());
if (cdata->_got_usage_hint &&
cdata->_primitives[i]->get_usage_hint() != primitive->get_usage_hint()) {
if (cdata->_primitives[i]->get_usage_hint() < primitive->get_usage_hint()) {
// If we're reducing the usage hint, we might also be reducing
// the minimum usage hit.
cdata->_usage_hint = min(cdata->_usage_hint, primitive->get_usage_hint());
} else { // (cdata->_primitives[i]->get_usage_hint() > primitive->get_usage_hint())
// If we're increasing it, we might have to rederive the minimum.
if (cdata->_usage_hint == cdata->_primitives[i]->get_usage_hint()) {
cdata->_got_usage_hint = false;
}
}
}
cdata->_primitives[i] = (qpGeomPrimitive *)primitive;
cdata->_primitive_type = primitive->get_primitive_type();
cdata->_modified = qpGeom::get_next_modified();
}
////////////////////////////////////////////////////////////////////
// Function: qpGeom::get_modified
// Access: Published

View File

@ -133,12 +133,49 @@ modify_vertex_data() {
////////////////////////////////////////////////////////////////////
void qpGeom::
set_vertex_data(const qpGeomVertexData *data) {
nassertv(check_will_be_valid(data));
clear_cache();
CDWriter cdata(_cycler);
cdata->_data = (qpGeomVertexData *)data;
mark_bound_stale();
}
////////////////////////////////////////////////////////////////////
// Function: qpGeom::set_primitive
// Access: Published
// Description: Replaces the ith GeomPrimitive object stored within
// the Geom with the new object.
////////////////////////////////////////////////////////////////////
void qpGeom::
set_primitive(int i, const qpGeomPrimitive *primitive) {
clear_cache();
CDWriter cdata(_cycler);
nassertv(i >= 0 && i < (int)cdata->_primitives.size());
nassertv(primitive->check_valid(cdata->_data));
// All primitives within a particular Geom must have the same
// fundamental primitive type (triangles, points, or lines).
nassertv(cdata->_primitive_type == qpGeomPrimitive::PT_none ||
cdata->_primitive_type == primitive->get_primitive_type());
if (cdata->_got_usage_hint &&
cdata->_primitives[i]->get_usage_hint() != primitive->get_usage_hint()) {
if (cdata->_primitives[i]->get_usage_hint() < primitive->get_usage_hint()) {
// If we're reducing the usage hint, we might also be reducing
// the minimum usage hit.
cdata->_usage_hint = min(cdata->_usage_hint, primitive->get_usage_hint());
} else { // (cdata->_primitives[i]->get_usage_hint() > primitive->get_usage_hint())
// If we're increasing it, we might have to rederive the minimum.
if (cdata->_usage_hint == cdata->_primitives[i]->get_usage_hint()) {
cdata->_got_usage_hint = false;
}
}
}
cdata->_primitives[i] = (qpGeomPrimitive *)primitive;
cdata->_primitive_type = primitive->get_primitive_type();
cdata->_modified = qpGeom::get_next_modified();
}
////////////////////////////////////////////////////////////////////
// Function: qpGeom::add_primitive
// Access: Published
@ -151,8 +188,11 @@ void qpGeom::
add_primitive(const qpGeomPrimitive *primitive) {
clear_cache();
CDWriter cdata(_cycler);
nassertv(primitive->check_valid(cdata->_data));
// All primitives within a particular Geom must have the same
// primitive type.
// fundamental primitive type (triangles, points, or lines).
nassertv(cdata->_primitive_type == qpGeomPrimitive::PT_none ||
cdata->_primitive_type == primitive->get_primitive_type());
@ -340,6 +380,30 @@ munge_geom(const qpGeomMunger *munger,
}
}
////////////////////////////////////////////////////////////////////
// Function: qpGeom::check_valid
// Access: Published
// Description: Verifies that the all of the primitives within the
// geom reference vertices that actually exist within
// the geom's GeomVertexData. Returns true if the geom
// appears to be valid, false otherwise.
////////////////////////////////////////////////////////////////////
bool qpGeom::
check_valid() const {
CDReader cdata(_cycler);
Primitives::const_iterator pi;
for (pi = cdata->_primitives.begin();
pi != cdata->_primitives.end();
++pi) {
if (!(*pi)->check_valid(cdata->_data)) {
return false;
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeom::output
// Access: Published
@ -523,6 +587,32 @@ recompute_bound() {
return bound;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeom::check_will_be_valid
// Access: Private
// Description: Verifies that the all of the primitives within the
// geom reference vertices that actually exist within
// the indicated GeomVertexData (presumably in
// preparation for assigning the geom to use this data).
// Returns true if the data appears to be valid, false
// otherwise.
////////////////////////////////////////////////////////////////////
bool qpGeom::
check_will_be_valid(const qpGeomVertexData *vertex_data) const {
CDReader cdata(_cycler);
Primitives::const_iterator pi;
for (pi = cdata->_primitives.begin();
pi != cdata->_primitives.end();
++pi) {
if (!(*pi)->check_valid(vertex_data)) {
return false;
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeom::reset_usage_hint
// Access: Private

View File

@ -76,7 +76,7 @@ PUBLISHED:
INLINE int get_num_primitives() const;
INLINE const qpGeomPrimitive *get_primitive(int i) const;
INLINE qpGeomPrimitive *modify_primitive(int i);
INLINE void set_primitive(int i, const qpGeomPrimitive *primitive);
void set_primitive(int i, const qpGeomPrimitive *primitive);
void add_primitive(const qpGeomPrimitive *primitive);
void remove_primitive(int i);
void clear_primitives();
@ -84,11 +84,15 @@ PUBLISHED:
int get_num_bytes() const;
INLINE UpdateSeq get_modified() const;
// Temporarily virtual.
virtual void transform_vertices(const LMatrix4f &mat);
void munge_geom(const qpGeomMunger *munger,
CPT(qpGeom) &result, CPT(qpGeomVertexData) &data) const;
// Temporarily virtual.
virtual bool check_valid() const;
void output(ostream &out) const;
void write(ostream &out, int indent_level = 0) const;
@ -109,6 +113,9 @@ public:
protected:
virtual BoundingVolume *recompute_bound();
private:
bool check_will_be_valid(const qpGeomVertexData *vertex_data) const;
private:
typedef pvector<PT(qpGeomPrimitive) > Primitives;

View File

@ -94,6 +94,17 @@ get_num_vertices_per_primitive() const {
return 2;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomLines::get_min_num_vertices_per_primitive
// Access: Public, Virtual
// Description: Returns the minimum number of vertices that must be
// added before close_primitive() may legally be called.
////////////////////////////////////////////////////////////////////
int qpGeomLines::
get_min_num_vertices_per_primitive() const {
return 2;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomLines::draw
// Access: Public, Virtual

View File

@ -39,6 +39,7 @@ public:
virtual PrimitiveType get_primitive_type() const;
virtual int get_num_vertices_per_primitive() const;
virtual int get_min_num_vertices_per_primitive() const;
public:
virtual void draw(GraphicsStateGuardianBase *gsg) const;

View File

@ -79,6 +79,17 @@ get_primitive_type() const {
return PT_lines;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomLinestrips::get_min_num_vertices_per_primitive
// Access: Public, Virtual
// Description: Returns the minimum number of vertices that must be
// added before close_primitive() may legally be called.
////////////////////////////////////////////////////////////////////
int qpGeomLinestrips::
get_min_num_vertices_per_primitive() const {
return 2;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomLinestrips::draw
// Access: Public, Virtual

View File

@ -38,6 +38,8 @@ public:
virtual PT(qpGeomPrimitive) make_copy() const;
virtual PrimitiveType get_primitive_type() const;
virtual int get_min_num_vertices_per_primitive() const;
public:
virtual void draw(GraphicsStateGuardianBase *gsg) const;

View File

@ -94,6 +94,17 @@ get_num_vertices_per_primitive() const {
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomPoints::get_min_num_vertices_per_primitive
// Access: Public, Virtual
// Description: Returns the minimum number of vertices that must be
// added before close_primitive() may legally be called.
////////////////////////////////////////////////////////////////////
int qpGeomPoints::
get_min_num_vertices_per_primitive() const {
return 1;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomPoints::draw
// Access: Public, Virtual

View File

@ -39,6 +39,7 @@ public:
virtual PrimitiveType get_primitive_type() const;
virtual int get_num_vertices_per_primitive() const;
virtual int get_min_num_vertices_per_primitive() const;
public:
virtual void draw(GraphicsStateGuardianBase *gsg) const;

View File

@ -462,6 +462,19 @@ get_num_bytes() const {
cdata->_ends.size() * sizeof(int) + sizeof(qpGeomPrimitive);
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomPrimitive::check_valid
// Access: Published
// Description: Verifies that the primitive only references vertices
// that actually exist within the indicated
// GeomVertexData. Returns true if the primitive
// appears to be valid, false otherwise.
////////////////////////////////////////////////////////////////////
bool qpGeomPrimitive::
check_valid(const qpGeomVertexData *vertex_data) const {
return get_max_vertex() < vertex_data->get_num_vertices();
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomPrimitive::output
// Access: Published, Virtual

View File

@ -139,6 +139,8 @@ PUBLISHED:
INLINE int get_data_size_bytes() const;
INLINE UpdateSeq get_modified() const;
bool check_valid(const qpGeomVertexData *vertex_data) const;
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level) const;

View File

@ -590,6 +590,9 @@ convert_to(const qpGeomVertexFormat *new_format) const {
// Access: Published
// Description: Returns a new GeomVertexData object with the color
// table modified in-place to apply the indicated scale.
//
// If the vertex data does not include a color column, a
// new one will not be added.
////////////////////////////////////////////////////////////////////
CPT(qpGeomVertexData) qpGeomVertexData::
scale_color(const LVecBase4f &color_scale) const {
@ -665,6 +668,9 @@ scale_color(const LVecBase4f &color_scale, int num_components,
// Access: Published
// Description: Returns a new GeomVertexData object with the color
// data modified in-place with the new value.
//
// If the vertex data does not include a color column, a
// new one will not be added.
////////////////////////////////////////////////////////////////////
CPT(qpGeomVertexData) qpGeomVertexData::
set_color(const Colorf &color) const {

View File

@ -22,6 +22,9 @@
#include "transformState.h"
#include "colorAttrib.h"
#include "sceneGraphReducer.h"
#include "qpgeom.h"
#include "qpgeomTristrips.h"
#include "qpgeomVertexWriter.h"
////////////////////////////////////////////////////////////////////
@ -55,39 +58,82 @@ generate() {
}
PT(GeomNode) gnode = new GeomNode(get_name());
Geom *geom = new GeomTristrip;
gnode->add_geom(geom);
float left = _frame[0];
float right = _frame[1];
float bottom = _frame[2];
float top = _frame[3];
PTA_int lengths=PTA_int::empty_array(0);
lengths.push_back(4);
if (use_qpgeom) {
CPT(qpGeomVertexFormat) format;
if (_has_uvs) {
format = qpGeomVertexFormat::get_v3cpt2();
} else {
format = qpGeomVertexFormat::get_v3cp();
}
PTA_Vertexf verts;
verts.push_back(Vertexf::rfu(left, 0.0f, top));
verts.push_back(Vertexf::rfu(left, 0.0f, bottom));
verts.push_back(Vertexf::rfu(right, 0.0f, top));
verts.push_back(Vertexf::rfu(right, 0.0f, bottom));
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("card", format, qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
qpGeomVertexWriter color(vdata, InternalName::get_color());
geom->set_num_prims(1);
geom->set_lengths(lengths);
vertex.add_data3f(Vertexf::rfu(left, 0.0f, top));
vertex.add_data3f(Vertexf::rfu(left, 0.0f, bottom));
vertex.add_data3f(Vertexf::rfu(right, 0.0f, top));
vertex.add_data3f(Vertexf::rfu(right, 0.0f, bottom));
geom->set_coords(verts);
color.add_data4f(_color);
color.add_data4f(_color);
color.add_data4f(_color);
color.add_data4f(_color);
PTA_Colorf colors;
colors.push_back(_color);
geom->set_colors(colors, G_OVERALL);
if (_has_uvs) {
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
texcoord.add_data2f(_ll[0], _ur[1]);
texcoord.add_data2f(_ll[0], _ll[1]);
texcoord.add_data2f(_ur[0], _ur[1]);
texcoord.add_data2f(_ur[0], _ll[1]);
}
if (_has_uvs) {
PTA_TexCoordf uvs;
uvs.push_back(TexCoordf(_ll[0], _ur[1]));
uvs.push_back(TexCoordf(_ll[0], _ll[1]));
uvs.push_back(TexCoordf(_ur[0], _ur[1]));
uvs.push_back(TexCoordf(_ur[0], _ll[1]));
geom->set_texcoords(uvs, G_PER_VERTEX);
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static);
strip->add_next_vertices(4);
PT(qpGeom) geom = new qpGeom;
geom->set_vertex_data(vdata);
geom->add_primitive(strip);
gnode->add_geom(geom);
} else {
Geom *geom = new GeomTristrip;
gnode->add_geom(geom);
PTA_int lengths = PTA_int::empty_array(0);
lengths.push_back(4);
PTA_Vertexf verts;
verts.push_back(Vertexf::rfu(left, 0.0f, top));
verts.push_back(Vertexf::rfu(left, 0.0f, bottom));
verts.push_back(Vertexf::rfu(right, 0.0f, top));
verts.push_back(Vertexf::rfu(right, 0.0f, bottom));
geom->set_num_prims(1);
geom->set_lengths(lengths);
geom->set_coords(verts);
PTA_Colorf colors;
colors.push_back(_color);
geom->set_colors(colors, G_OVERALL);
if (_has_uvs) {
PTA_TexCoordf uvs;
uvs.push_back(TexCoordf(_ll[0], _ur[1]));
uvs.push_back(TexCoordf(_ll[0], _ll[1]));
uvs.push_back(TexCoordf(_ur[0], _ur[1]));
uvs.push_back(TexCoordf(_ur[0], _ll[1]));
geom->set_texcoords(uvs, G_PER_VERTEX);
}
}
return gnode.p();

View File

@ -133,15 +133,14 @@ draw_to(float x, float y, float z) {
// created with the color and thickness established by
// calls to set_color() and set_thick().
//
// If frame_accurate is true, the line segments will be
// created as a frame-accurate index, so that later
// calls to set_vertex or set_vertex_color will be
// visually correct.
// If dynamic is true, the line segments will be created
// with the dynamic Geom setting, optimizing them for
// runtime vertex animation.
////////////////////////////////////////////////////////////////////
INLINE GeomNode *LineSegs::
create(bool frame_accurate) {
create(bool dynamic) {
GeomNode *gnode = new GeomNode(get_name());
return create(gnode, frame_accurate);
return create(gnode, dynamic);
}
////////////////////////////////////////////////////////////////////

View File

@ -19,6 +19,10 @@
#include "lineSegs.h"
#include "renderState.h"
#include "renderModeAttrib.h"
#include "qpgeom.h"
#include "qpgeomLinestrips.h"
#include "qpgeomPoints.h"
#include "qpgeomVertexWriter.h"
////////////////////////////////////////////////////////////////////
// Function: LineSegs::Constructor
@ -140,86 +144,141 @@ get_current_position() {
// thickness established by calls to set_color() and
// set_thick().
//
// If frame_accurate is true, the line segments will be
// created as a frame-accurate index, so that later
// calls to set_vertex or set_vertex_color will be
// visually correct.
// If dynamic is true, the line segments will be created
// with the dynamic Geom setting, optimizing them for
// runtime vertex animation.
////////////////////////////////////////////////////////////////////
GeomNode *LineSegs::
create(GeomNode *previous, bool) {
create(GeomNode *previous, bool dynamic) {
if (!_list.empty()) {
_created_verts.clear();
_created_colors.clear();
// One array each for the indices into these arrays for points
// and lines, and one for our line-segment lengths array.
PTA_ushort point_index;
PTA_ushort line_index;
PTA_int lengths;
// Now fill up the arrays.
int v = 0;
LineList::const_iterator ll;
SegmentList::const_iterator sl;
for (ll = _list.begin(); ll != _list.end(); ll++) {
const SegmentList &segs = (*ll);
if (segs.size() < 2) {
point_index.push_back(v);
} else {
lengths.push_back(segs.size());
}
for (sl = segs.begin(); sl != segs.end(); sl++) {
if (segs.size() >= 2) {
line_index.push_back(v);
}
_created_verts.push_back((*sl)._point);
_created_colors.push_back((*sl)._color);
v++;
nassertr(v == (int)_created_verts.size(), previous);
}
}
_created_data = NULL;
CPT(RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, _thick);
CPT(RenderState) state = RenderState::make(thick);
// Now create the lines.
if (line_index.size() > 0) {
// Create a new Geom and add the line segments.
Geom *geom;
if (line_index.size() <= 2) {
// Here's a special case: just one line segment.
GeomLine *geom_line = new GeomLine;
geom_line->set_num_prims(1);
geom = geom_line;
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("lineSegs", qpGeomVertexFormat::get_v3cp(),
dynamic ? qpGeomUsageHint::UH_dynamic : qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
qpGeomVertexWriter color(vdata, InternalName::get_color());
} else {
// The more normal case: multiple line segments, connected
// end-to-end like a series of linestrips.
GeomLinestrip *geom_linestrip = new GeomLinestrip;
geom_linestrip->set_num_prims(lengths.size());
geom_linestrip->set_lengths(lengths);
geom = geom_linestrip;
PT(qpGeomLinestrips) lines = new qpGeomLinestrips(qpGeomUsageHint::UH_static);
PT(qpGeomPoints) points = new qpGeomPoints(qpGeomUsageHint::UH_static);
int v = 0;
LineList::const_iterator ll;
SegmentList::const_iterator sl;
for (ll = _list.begin(); ll != _list.end(); ll++) {
const SegmentList &segs = (*ll);
if (segs.size() < 2) {
// A segment of length 1 is just a point.
for (sl = segs.begin(); sl != segs.end(); sl++) {
points->add_vertex(v);
vertex.add_data3f((*sl)._point);
color.add_data4f((*sl)._color);
v++;
}
points->close_primitive();
} else {
// A segment of length 2 or more is a line segment or
// segments.
for (sl = segs.begin(); sl != segs.end(); sl++) {
lines->add_vertex(v);
vertex.add_data3f((*sl)._point);
color.add_data4f((*sl)._color);
v++;
}
lines->close_primitive();
}
}
geom->set_colors(_created_colors, G_PER_VERTEX, line_index);
geom->set_coords(_created_verts, line_index);
if (lines->get_num_vertices() != 0) {
PT(qpGeom) geom = new qpGeom;
geom->set_vertex_data(vdata);
geom->add_primitive(lines);
previous->add_geom(geom, state);
}
if (points->get_num_vertices() != 0) {
PT(qpGeom) geom = new qpGeom;
geom->set_vertex_data(vdata);
geom->add_primitive(points);
previous->add_geom(geom, state);
}
previous->add_geom(geom, state);
}
} else {
// One array each for the indices into these arrays for points
// and lines, and one for our line-segment lengths array.
PTA_ushort point_index;
PTA_ushort line_index;
PTA_int lengths;
// Now fill up the arrays.
int v = 0;
LineList::const_iterator ll;
SegmentList::const_iterator sl;
for (ll = _list.begin(); ll != _list.end(); ll++) {
const SegmentList &segs = (*ll);
if (segs.size() < 2) {
point_index.push_back(v);
} else {
lengths.push_back(segs.size());
}
for (sl = segs.begin(); sl != segs.end(); sl++) {
if (segs.size() >= 2) {
line_index.push_back(v);
}
_created_verts.push_back((*sl)._point);
_created_colors.push_back((*sl)._color);
v++;
nassertr(v == (int)_created_verts.size(), previous);
}
}
// Now create the lines.
if (line_index.size() > 0) {
// Create a new Geom and add the line segments.
Geom *geom;
if (line_index.size() <= 2) {
// Here's a special case: just one line segment.
GeomLine *geom_line = new GeomLine;
geom_line->set_num_prims(1);
geom = geom_line;
} else {
// The more normal case: multiple line segments, connected
// end-to-end like a series of linestrips.
GeomLinestrip *geom_linestrip = new GeomLinestrip;
geom_linestrip->set_num_prims(lengths.size());
geom_linestrip->set_lengths(lengths);
geom = geom_linestrip;
}
geom->set_colors(_created_colors, G_PER_VERTEX, line_index);
geom->set_coords(_created_verts, line_index);
previous->add_geom(geom, state);
}
// And now create the points.
if (point_index.size() > 0) {
// Create a new Geom and add the points.
GeomPoint *geom = new GeomPoint;
geom->set_num_prims(point_index.size());
geom->set_colors(_created_colors, G_PER_VERTEX, point_index);
geom->set_coords(_created_verts, point_index);
previous->add_geom(geom, state);
// And now create the points.
if (point_index.size() > 0) {
// Create a new Geom and add the points.
GeomPoint *geom = new GeomPoint;
geom->set_num_prims(point_index.size());
geom->set_colors(_created_colors, G_PER_VERTEX, point_index);
geom->set_coords(_created_verts, point_index);
previous->add_geom(geom, state);
}
}
// And reset for next time.

View File

@ -27,6 +27,7 @@
#include "geomLine.h"
#include "geomLinestrip.h"
#include "geomNode.h"
#include "qpgeomVertexData.h"
#include "namable.h"
#include "pvector.h"
@ -58,8 +59,8 @@ PUBLISHED:
const Vertexf &get_current_position();
bool is_empty();
INLINE GeomNode *create(bool frame_accurate = false);
GeomNode *create(GeomNode *previous, bool frame_accurate = false);
INLINE GeomNode *create(bool dynamic = false);
GeomNode *create(GeomNode *previous, bool dynamic = false);
// Functions to move the line vertices after they have been created.
INLINE int get_num_vertices() const;
@ -93,6 +94,7 @@ private:
PTA_Vertexf _created_verts;
PTA_Colorf _created_colors;
PT(qpGeomVertexData) _created_data;
};
#include "lineSegs.I"

View File

@ -37,6 +37,9 @@
#include "config_grutil.h"
#include "config_gobj.h"
#include "dcast.h"
#include "qpgeom.h"
#include "qpgeomVertexWriter.h"
#include "qpgeomVertexReader.h"
////////////////////////////////////////////////////////////////////
// Function: MultitexReducer::Constructor
@ -804,25 +807,39 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
GeomList::const_iterator gi;
for (gi = geom_list.begin(); gi != geom_list.end(); ++gi) {
const GeomInfo &geom_info = (*gi);
PT(Geom) geom =
geom_info._geom_node->get_geom(geom_info._index)->make_copy();
const Geom *orig_geom = geom_info._geom_node->get_geom(geom_info._index);
PTA_Vertexf coords = PTA_Vertexf::empty_array(0);
PTA_TexCoordf texcoords = geom->get_texcoords_array(_target_stage->get_texcoord_name());
if (!texcoords.empty()) {
coords.reserve(texcoords.size());
for (size_t i = 0; i < texcoords.size(); i++) {
const TexCoordf &tc = texcoords[i];
Vertexf v(tc[0], 0.0f, tc[1]);
coords.push_back(v);
if (orig_geom->is_of_type(qpGeom::get_class_type())) {
PT(qpGeom) geom = new qpGeom(*DCAST(qpGeom, orig_geom));
PT(qpGeomVertexData) vdata = geom->modify_vertex_data();
if (vdata->has_column(_target_stage->get_texcoord_name())) {
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
qpGeomVertexReader texcoord(vdata, _target_stage->get_texcoord_name());
while (!texcoord.is_at_end()) {
const LVecBase2f &tc = texcoord.get_data2f();
vertex.set_data3f(tc[0], 0.0f, tc[1]);
}
}
geom->set_coords(coords, geom->get_texcoords_index(_target_stage->get_texcoord_name()));
if (texcoord_name != (const InternalName *)NULL) {
geom->set_texcoords(InternalName::get_texcoord(),
geom->get_texcoords_array(texcoord_name),
geom->get_texcoords_index(texcoord_name));
if (texcoord_name != (const InternalName *)NULL &&
texcoord_name != InternalName::get_texcoord()) {
// Copy the texture coordinates from the indicated name over
// to the default name.
const qpGeomVertexColumn *column =
vdata->get_format()->get_column(texcoord_name);
vdata = vdata->replace_column
(InternalName::get_texcoord(), column->get_num_components(),
column->get_numeric_type(), column->get_contents(),
qpGeomUsageHint::UH_stream, true);
geom->set_vertex_data(vdata);
qpGeomVertexReader from(vdata, texcoord_name);
qpGeomVertexWriter to(vdata, InternalName::get_texcoord());
while (!from.is_at_end()) {
to.add_data2f(from.get_data2f());
}
}
CPT(RenderState) geom_state = RenderState::make_empty();
@ -839,6 +856,42 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
}
geom_node->add_geom(geom, geom_state);
} else {
PT(Geom) geom = orig_geom->make_copy();
PTA_Vertexf coords = PTA_Vertexf::empty_array(0);
PTA_TexCoordf texcoords = geom->get_texcoords_array(_target_stage->get_texcoord_name());
if (!texcoords.empty()) {
coords.reserve(texcoords.size());
for (size_t i = 0; i < texcoords.size(); i++) {
const TexCoordf &tc = texcoords[i];
Vertexf v(tc[0], 0.0f, tc[1]);
coords.push_back(v);
}
geom->set_coords(coords, geom->get_texcoords_index(_target_stage->get_texcoord_name()));
if (texcoord_name != (const InternalName *)NULL) {
geom->set_texcoords(InternalName::get_texcoord(),
geom->get_texcoords_array(texcoord_name),
geom->get_texcoords_index(texcoord_name));
}
CPT(RenderState) geom_state = RenderState::make_empty();
if (preserve_color) {
// Be sure to preserve whatever colors are on the geom.
const RenderAttrib *ca = geom_info._geom_net_state->get_attrib(ColorAttrib::get_class_type());
if (ca != (const RenderAttrib *)NULL) {
geom_state = geom_state->add_attrib(ca);
}
const RenderAttrib *csa = geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_type());
if (csa != (const RenderAttrib *)NULL) {
geom_state = geom_state->add_attrib(csa);
}
}
geom_node->add_geom(geom, geom_state);
}
}
}
}

View File

@ -30,6 +30,10 @@
#include "datagram.h"
#include "datagramIterator.h"
#include "pStatTimer.h"
#include "qpgeom.h"
#include "qpgeomLinestrips.h"
#include "qpgeomTristrips.h"
#include "qpgeomVertexWriter.h"
TypeHandle RopeNode::_type_handle;

View File

@ -27,6 +27,9 @@
#include "datagram.h"
#include "datagramIterator.h"
#include "pStatTimer.h"
#include "qpgeom.h"
#include "qpgeomTristrips.h"
#include "qpgeomVertexWriter.h"
TypeHandle SheetNode::_type_handle;
@ -261,82 +264,148 @@ do_recompute_bound(const NodePath &rel_to) {
////////////////////////////////////////////////////////////////////
void SheetNode::
render_sheet(CullTraverser *trav, CullTraverserData &data,
NurbsSurfaceResult *result) {
NurbsSurfaceResult *result) {
bool use_vertex_color = get_use_vertex_color();
PTA_Vertexf verts;
PTA_Normalf normals;
PTA_TexCoordf uvs;
PTA_Colorf colors;
PTA_int lengths;
// We define a series of triangle strips, parallel to the V
// direction.
int num_u_segments = result->get_num_u_segments();
int num_v_segments = result->get_num_v_segments();
int num_u_verts = get_num_u_subdiv() + 1;
int num_v_verts = get_num_v_subdiv() + 1;
for (int ui = 0; ui < num_u_segments; ui++) {
for (int uni = 0; uni < num_u_verts; uni++) {
float u0 = (float)uni / (float)num_u_verts;
float u1 = (float)(uni + 1) / (float)num_u_verts;
float u0_tc = result->get_segment_u(ui, u0);
float u1_tc = result->get_segment_u(ui, u1);
if (use_qpgeom) {
CPT(qpGeomVertexFormat) format;
if (use_vertex_color) {
format = qpGeomVertexFormat::get_v3n3cpt2();
} else {
format = qpGeomVertexFormat::get_v3n3t2();
}
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("sheet", format, qpGeomUsageHint::UH_stream);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
qpGeomVertexWriter normal(vdata, InternalName::get_normal());
qpGeomVertexWriter color(vdata, InternalName::get_color());
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_stream);
for (int ui = 0; ui < num_u_segments; ui++) {
for (int uni = 0; uni < num_u_verts; uni++) {
float u0 = (float)uni / (float)num_u_verts;
float u1 = (float)(uni + 1) / (float)num_u_verts;
float u0_tc = result->get_segment_u(ui, u0);
float u1_tc = result->get_segment_u(ui, u1);
for (int vi = 0; vi < num_v_segments; vi++) {
for (int vni = 0; vni < num_v_verts; vni++) {
float v = (float)vni / (float)(num_v_verts - 1);
float v_tc = result->get_segment_v(vi, v);
for (int vi = 0; vi < num_v_segments; vi++) {
for (int vni = 0; vni < num_v_verts; vni++) {
float v = (float)vni / (float)(num_v_verts - 1);
float v_tc = result->get_segment_v(vi, v);
LPoint3f point;
LVector3f normal;
result->eval_segment_point(ui, vi, u0, v, point);
result->eval_segment_normal(ui, vi, u0, v, normal);
verts.push_back(point);
normals.push_back(normal);
uvs.push_back(TexCoordf(u0_tc, v_tc));
LPoint3f point;
LVector3f norm;
result->eval_segment_point(ui, vi, u0, v, point);
result->eval_segment_normal(ui, vi, u0, v, norm);
vertex.add_data3f(point);
normal.add_data3f(norm);
texcoord.add_data2f(u0_tc, v_tc);
result->eval_segment_point(ui, vi, u1, v, point);
result->eval_segment_normal(ui, vi, u1, v, normal);
verts.push_back(point);
normals.push_back(normal);
uvs.push_back(TexCoordf(u1_tc, v_tc));
result->eval_segment_point(ui, vi, u1, v, point);
result->eval_segment_normal(ui, vi, u1, v, norm);
vertex.add_data3f(point);
normal.add_data3f(norm);
texcoord.add_data2f(u1_tc, v_tc);
if (use_vertex_color) {
Colorf c0, c1;
result->eval_segment_extended_points(ui, vi, u0, v, 0, &c0[0], 4);
result->eval_segment_extended_points(ui, vi, u1, v, 0, &c1[0], 4);
if (use_vertex_color) {
Colorf c0, c1;
result->eval_segment_extended_points(ui, vi, u0, v, 0, &c0[0], 4);
result->eval_segment_extended_points(ui, vi, u1, v, 0, &c1[0], 4);
colors.push_back(c0);
colors.push_back(c1);
color.add_data4f(c0);
color.add_data4f(c1);
}
}
strip->add_next_vertices(num_v_verts * 2);
strip->close_primitive();
}
lengths.push_back(num_v_verts * 2);
}
}
}
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
PT(GeomTristrip) geom = new GeomTristrip;
geom->set_num_prims(lengths.size());
geom->set_coords(verts);
geom->set_normals(normals, G_PER_VERTEX);
geom->set_texcoords(uvs, G_PER_VERTEX);
PT(qpGeom) geom = new qpGeom;
geom->set_vertex_data(vdata);
geom->add_primitive(strip);
CullableObject *object = new CullableObject(geom, data._state,
data._render_transform);
trav->get_cull_handler()->record_object(object);
if (use_vertex_color) {
geom->set_colors(colors, G_PER_VERTEX);
} else {
PTA_Vertexf verts;
PTA_Normalf normals;
PTA_TexCoordf uvs;
PTA_Colorf colors;
PTA_int lengths;
// We define a series of triangle strips, parallel to the V
// direction.
for (int ui = 0; ui < num_u_segments; ui++) {
for (int uni = 0; uni < num_u_verts; uni++) {
float u0 = (float)uni / (float)num_u_verts;
float u1 = (float)(uni + 1) / (float)num_u_verts;
float u0_tc = result->get_segment_u(ui, u0);
float u1_tc = result->get_segment_u(ui, u1);
for (int vi = 0; vi < num_v_segments; vi++) {
for (int vni = 0; vni < num_v_verts; vni++) {
float v = (float)vni / (float)(num_v_verts - 1);
float v_tc = result->get_segment_v(vi, v);
LPoint3f point;
LVector3f normal;
result->eval_segment_point(ui, vi, u0, v, point);
result->eval_segment_normal(ui, vi, u0, v, normal);
verts.push_back(point);
normals.push_back(normal);
uvs.push_back(TexCoordf(u0_tc, v_tc));
result->eval_segment_point(ui, vi, u1, v, point);
result->eval_segment_normal(ui, vi, u1, v, normal);
verts.push_back(point);
normals.push_back(normal);
uvs.push_back(TexCoordf(u1_tc, v_tc));
if (use_vertex_color) {
Colorf c0, c1;
result->eval_segment_extended_points(ui, vi, u0, v, 0, &c0[0], 4);
result->eval_segment_extended_points(ui, vi, u1, v, 0, &c1[0], 4);
colors.push_back(c0);
colors.push_back(c1);
}
}
lengths.push_back(num_v_verts * 2);
}
}
}
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
geom->set_colors(colors, G_OVERALL);
}
geom->set_lengths(lengths);
CullableObject *object = new CullableObject(geom, data._state,
data._render_transform);
trav->get_cull_handler()->record_object(object);
PT(GeomTristrip) geom = new GeomTristrip;
geom->set_num_prims(lengths.size());
geom->set_coords(verts);
geom->set_normals(normals, G_PER_VERTEX);
geom->set_texcoords(uvs, G_PER_VERTEX);
if (use_vertex_color) {
geom->set_colors(colors, G_PER_VERTEX);
} else {
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
geom->set_colors(colors, G_OVERALL);
}
geom->set_lengths(lengths);
CullableObject *object = new CullableObject(geom, data._state,
data._render_transform);
trav->get_cull_handler()->record_object(object);
}
}
////////////////////////////////////////////////////////////////////

View File

@ -33,6 +33,9 @@
#include "boundingHexahedron.h"
#include "geomSphere.h"
#include "portalClipper.h"
#include "qpgeom.h"
#include "qpgeomTristrips.h"
#include "qpgeomVertexWriter.h"
PStatCollector CullTraverser::_nodes_pcollector("Nodes");
PStatCollector CullTraverser::_geom_nodes_pcollector("Nodes:GeomNodes");
@ -293,15 +296,47 @@ make_bounds_viz(const BoundingVolume &vol) {
} else if (vol.is_of_type(BoundingSphere::get_class_type())) {
const BoundingSphere *sphere = DCAST(BoundingSphere, &vol);
geom = new GeomSphere;
PTA_Vertexf verts;
LPoint3f center = sphere->get_center();
verts.push_back(center);
center[0] += sphere->get_radius();
verts.push_back(center);
geom->set_coords(verts);
geom->set_num_prims(1);
if (use_qpgeom) {
static const int num_slices = 16;
static const int num_stacks = 8;
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("collision", qpGeomVertexFormat::get_v3(),
qpGeomUsageHint::UH_stream);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_stream);
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(sphere, 0.0, longitude0));
for (int st = 1; st < num_stacks; ++st) {
float latitude = (float)st / (float)num_stacks;
vertex.add_data3f(compute_point(sphere, latitude, longitude0));
vertex.add_data3f(compute_point(sphere, latitude, longitude1));
}
vertex.add_data3f(compute_point(sphere, 1.0, longitude0));
strip->add_next_vertices(num_stacks * 2);
strip->close_primitive();
}
PT(qpGeom) qpgeom = new qpGeom;
qpgeom->set_vertex_data(vdata);
qpgeom->add_primitive(strip);
geom = qpgeom.p();
} else {
geom = new GeomSphere;
PTA_Vertexf verts;
LPoint3f center = sphere->get_center();
verts.push_back(center);
center[0] += sphere->get_radius();
verts.push_back(center);
geom->set_coords(verts);
geom->set_num_prims(1);
}
} else {
pgraph_cat.warning()
@ -312,6 +347,25 @@ make_bounds_viz(const BoundingVolume &vol) {
return geom;
}
////////////////////////////////////////////////////////////////////
// Function: CullTraverser::compute_point
// Access: Private, Static
// Description: Returns a point on the surface of the sphere.
// latitude and longitude range from 0.0 to 1.0.
////////////////////////////////////////////////////////////////////
Vertexf CullTraverser::
compute_point(const BoundingSphere *sphere,
float latitude, float longitude) {
float s1, c1;
csincos(latitude * MathNumbers::pi_f, &s1, &c1);
float s2, c2;
csincos(longitude * 2.0f * MathNumbers::pi_f, &s2, &c2);
Vertexf p(s1 * c2, s1 * s2, c1);
return p * sphere->get_radius() + sphere->get_center();
}
////////////////////////////////////////////////////////////////////
// Function: CullTraverser::get_bounds_outer_viz_state
// Access: Private, Static

View File

@ -94,6 +94,8 @@ public:
private:
void show_bounds(CullTraverserData &data);
PT(Geom) make_bounds_viz(const BoundingVolume &vol);
static Vertexf compute_point(const BoundingSphere *sphere,
float latitude, float longitude);
CPT(RenderState) get_bounds_outer_viz_state();
CPT(RenderState) get_bounds_inner_viz_state();
CPT(RenderState) get_depth_offset_state();

View File

@ -121,27 +121,6 @@ set_geom_state(int n, const RenderState *state) {
cdata->_geoms[n]._state = state;
}
////////////////////////////////////////////////////////////////////
// Function: GeomNode::add_geom
// Access: Published
// Description: Adds a new Geom to the node. The geom is given the
// indicated state (which may be
// RenderState::make_empty(), to completely inherit its
// state from the scene graph).
//
// The return value is the index number of the new Geom.
////////////////////////////////////////////////////////////////////
INLINE int GeomNode::
add_geom(Geom *geom, const RenderState *state) {
nassertr(geom != (Geom *)NULL, -1);
nassertr(state != (RenderState *)NULL, -1);
CDWriter cdata(_cycler);
cdata->_geoms.push_back(GeomEntry(geom, state));
mark_bound_stale();
return cdata->_geoms.size() - 1;
}
////////////////////////////////////////////////////////////////////
// Function: GeomNode::remove_geom
// Access: Published

View File

@ -405,6 +405,28 @@ get_legal_collide_mask() const {
return CollideMask::all_on();
}
////////////////////////////////////////////////////////////////////
// Function: GeomNode::add_geom
// Access: Published
// Description: Adds a new Geom to the node. The geom is given the
// indicated state (which may be
// RenderState::make_empty(), to completely inherit its
// state from the scene graph).
//
// The return value is the index number of the new Geom.
////////////////////////////////////////////////////////////////////
int GeomNode::
add_geom(Geom *geom, const RenderState *state) {
nassertr(geom != (Geom *)NULL, -1);
nassertr(geom->check_valid(), -1);
nassertr(state != (RenderState *)NULL, -1);
CDWriter cdata(_cycler);
cdata->_geoms.push_back(GeomEntry(geom, state));
mark_bound_stale();
return cdata->_geoms.size() - 1;
}
////////////////////////////////////////////////////////////////////
// Function: GeomNode::add_geoms_from
// Access: Published
@ -415,15 +437,16 @@ void GeomNode::
add_geoms_from(const GeomNode *other) {
CDReader cdata_other(other->_cycler);
CDWriter cdata(_cycler);
mark_bound_stale();
Geoms::const_iterator gi;
for (gi = cdata_other->_geoms.begin();
gi != cdata_other->_geoms.end();
++gi) {
const GeomEntry &entry = (*gi);
nassertv(entry._geom->check_valid());
cdata->_geoms.push_back(entry);
}
mark_bound_stale();
}
////////////////////////////////////////////////////////////////////

View File

@ -62,7 +62,7 @@ PUBLISHED:
INLINE const RenderState *get_geom_state(int n) const;
INLINE void set_geom_state(int n, const RenderState *state);
INLINE int add_geom(Geom *geom, const RenderState *state = RenderState::make_empty());
int add_geom(Geom *geom, const RenderState *state = RenderState::make_empty());
void add_geoms_from(const GeomNode *other);
INLINE void remove_geom(int n);
INLINE void remove_all_geoms();

View File

@ -324,7 +324,13 @@ set_color(Geom *geom, const Colorf &color) {
CPT(qpGeomVertexData) &new_data = _qpfcolors[sc];
if (new_data.is_null()) {
// We have not yet converted these colors. Do so now.
new_data = sc._vertex_data->set_color(color);
if (sc._vertex_data->has_column(InternalName::get_color())) {
new_data = sc._vertex_data->set_color(color);
} else {
new_data = sc._vertex_data->set_color
(color, 1, qpGeomVertexColumn::NT_packed_dabc,
qpGeomVertexColumn::C_color);
}
}
qpgeom->set_vertex_data(new_data);
@ -399,7 +405,13 @@ transform_colors(Geom *geom, const LVecBase4f &scale) {
CPT(qpGeomVertexData) &new_data = _qptcolors[sc];
if (new_data.is_null()) {
// We have not yet converted these colors. Do so now.
new_data = sc._vertex_data->scale_color(scale);
if (sc._vertex_data->has_column(InternalName::get_color())) {
new_data = sc._vertex_data->scale_color(scale);
} else {
new_data = sc._vertex_data->set_color
(scale, 1, qpGeomVertexColumn::NT_packed_dabc,
qpGeomVertexColumn::C_color);
}
}
qpgeom->set_vertex_data(new_data);

View File

@ -26,6 +26,10 @@
#include "nodePath.h"
#include "textureAttrib.h"
#include "renderState.h"
#include "shadeModelAttrib.h"
#include "qpgeom.h"
#include "qpgeomTristrips.h"
#include "qpgeomVertexWriter.h"
// Specifies the UV range of textures applied to the frame. Maybe
// we'll have a reason to make this a parameter of the frame style one
@ -170,49 +174,98 @@ generate_into(const NodePath &parent, const LVecBase4f &frame) {
PT(PandaNode) PGFrameStyle::
generate_flat_geom(const LVecBase4f &frame) {
PT(GeomNode) gnode = new GeomNode("flat");
Geom *geom = new GeomTristrip;
gnode->add_geom(geom);
float left = frame[0];
float right = frame[1];
float bottom = frame[2];
float top = frame[3];
PTA_int lengths;
lengths.push_back(4);
if (use_qpgeom) {
CPT(qpGeomVertexFormat) format;
if (has_texture()) {
format = qpGeomVertexFormat::get_v3cpt2();
} else {
format = qpGeomVertexFormat::get_v3cp();
}
PTA_Vertexf verts;
verts.push_back(Vertexf(left, 0.0f, top));
verts.push_back(Vertexf(left, 0.0f, bottom));
verts.push_back(Vertexf(right, 0.0f, top));
verts.push_back(Vertexf(right, 0.0f, bottom));
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("PGFrame", format, qpGeomUsageHint::UH_static);
geom->set_num_prims(1);
geom->set_lengths(lengths);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
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);
geom->set_coords(verts);
PTA_Colorf colors;
colors.push_back(_color);
geom->set_colors(colors, G_OVERALL);
if (has_texture()) {
// Generate UV's.
left = uv_range[0];
right = uv_range[1];
bottom = uv_range[2];
top = uv_range[3];
if (has_texture()) {
// Generate UV's.
left = uv_range[0];
right = uv_range[1];
bottom = uv_range[2];
top = uv_range[3];
PTA_TexCoordf uvs;
uvs.push_back(TexCoordf(left, top));
uvs.push_back(TexCoordf(left, bottom));
uvs.push_back(TexCoordf(right, top));
uvs.push_back(TexCoordf(right, bottom));
geom->set_texcoords(uvs, G_PER_VERTEX);
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
texcoord.add_data2f(left, top);
texcoord.add_data2f(left, bottom);
texcoord.add_data2f(right, top);
texcoord.add_data2f(right, bottom);
}
CPT(RenderState) state =
RenderState::make(TextureAttrib::make(get_texture()));
gnode->set_geom_state(0, state);
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static);
strip->add_next_vertices(4);
strip->close_primitive();
PT(qpGeom) geom = new qpGeom;
geom->set_vertex_data(vdata);
geom->add_primitive(strip);
gnode->add_geom(geom);
if (has_texture()) {
CPT(RenderState) state =
RenderState::make(TextureAttrib::make(get_texture()));
gnode->set_geom_state(0, state);
}
} else {
Geom *geom = new GeomTristrip;
gnode->add_geom(geom);
PTA_int lengths;
lengths.push_back(4);
PTA_Vertexf verts;
verts.push_back(Vertexf(left, 0.0f, top));
verts.push_back(Vertexf(left, 0.0f, bottom));
verts.push_back(Vertexf(right, 0.0f, top));
verts.push_back(Vertexf(right, 0.0f, bottom));
geom->set_num_prims(1);
geom->set_lengths(lengths);
geom->set_coords(verts);
PTA_Colorf colors;
colors.push_back(_color);
geom->set_colors(colors, G_OVERALL);
if (has_texture()) {
// Generate UV's.
left = uv_range[0];
right = uv_range[1];
bottom = uv_range[2];
top = uv_range[3];
PTA_TexCoordf uvs;
uvs.push_back(TexCoordf(left, top));
uvs.push_back(TexCoordf(left, bottom));
uvs.push_back(TexCoordf(right, top));
uvs.push_back(TexCoordf(right, bottom));
geom->set_texcoords(uvs, G_PER_VERTEX);
CPT(RenderState) state =
RenderState::make(TextureAttrib::make(get_texture()));
gnode->set_geom_state(0, state);
}
}
return gnode.p();
@ -328,52 +381,109 @@ generate_bevel_geom(const LVecBase4f &frame, bool in) {
min(_color[2] * top_color_scale, 1.0f),
_color[3]);
// Now make the tristrips.
Geom *geom = new GeomTristrip;
gnode->add_geom(geom);
PTA_int lengths;
PTA_Vertexf verts;
PTA_Colorf colors;
if (use_qpgeom) {
CPT(qpGeomVertexFormat) format = qpGeomVertexFormat::get_v3cp();
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("PGFrame", format, qpGeomUsageHint::UH_static);
// Tristrip 1.
lengths.push_back(8);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
qpGeomVertexWriter color(vdata, InternalName::get_color());
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static);
// Tristrip 1.
vertex.add_data3f(right, 0.0f, bottom);
vertex.add_data3f(inner_right, 0.0f, inner_bottom);
vertex.add_data3f(left, 0.0f, bottom);
vertex.add_data3f(inner_left, 0.0f, inner_bottom);
vertex.add_data3f(left, 0.0f, top);
vertex.add_data3f(inner_left, 0.0f, inner_top);
vertex.add_data3f(right, 0.0f, top);
vertex.add_data3f(inner_right, 0.0f, inner_top);
color.add_data4f(cbottom);
color.add_data4f(cbottom);
color.add_data4f(cbottom);
color.add_data4f(cbottom);
color.add_data4f(cleft);
color.add_data4f(cleft);
color.add_data4f(ctop);
color.add_data4f(ctop);
strip->add_next_vertices(8);
strip->close_primitive();
// Tristrip 2.
vertex.add_data3f(right, 0.0f, bottom);
vertex.add_data3f(right, 0.0f, top);
vertex.add_data3f(inner_right, 0.0f, inner_bottom);
vertex.add_data3f(inner_right, 0.0f, inner_top);
vertex.add_data3f(inner_left, 0.0f, inner_bottom);
vertex.add_data3f(inner_left, 0.0f, inner_top);
color.add_data4f(cright);
color.add_data4f(cright);
color.add_data4f(cright);
color.add_data4f(cright);
color.add_data4f(_color);
color.add_data4f(_color);
strip->add_next_vertices(6);
strip->close_primitive();
strip->set_shade_model(qpGeomPrimitive::SM_flat_last_vertex);
PT(qpGeom) geom = new qpGeom;
geom->set_vertex_data(vdata);
geom->add_primitive(strip);
CPT(RenderState) flat_state = RenderState::make(ShadeModelAttrib::make(ShadeModelAttrib::M_flat));
gnode->add_geom(geom, flat_state);
} else {
// Now make the tristrips.
Geom *geom = new GeomTristrip;
gnode->add_geom(geom);
verts.push_back(Vertexf(right, 0.0f, bottom));
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
verts.push_back(Vertexf(left, 0.0f, bottom));
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
verts.push_back(Vertexf(left, 0.0f, top));
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
verts.push_back(Vertexf(right, 0.0f, top));
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
PTA_int lengths;
PTA_Vertexf verts;
PTA_Colorf colors;
// Tristrip 1.
lengths.push_back(8);
verts.push_back(Vertexf(right, 0.0f, bottom));
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
verts.push_back(Vertexf(left, 0.0f, bottom));
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
verts.push_back(Vertexf(left, 0.0f, top));
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
verts.push_back(Vertexf(right, 0.0f, top));
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
colors.push_back(cbottom);
colors.push_back(cbottom);
colors.push_back(cleft);
colors.push_back(cleft);
colors.push_back(ctop);
colors.push_back(ctop);
colors.push_back(cbottom);
colors.push_back(cbottom);
colors.push_back(cleft);
colors.push_back(cleft);
colors.push_back(ctop);
colors.push_back(ctop);
// Tristrip 2.
lengths.push_back(6);
// Tristrip 2.
lengths.push_back(6);
verts.push_back(Vertexf(right, 0.0f, bottom));
verts.push_back(Vertexf(right, 0.0f, top));
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
verts.push_back(Vertexf(right, 0.0f, bottom));
verts.push_back(Vertexf(right, 0.0f, top));
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
colors.push_back(cright);
colors.push_back(cright);
colors.push_back(_color);
colors.push_back(_color);
colors.push_back(cright);
colors.push_back(cright);
colors.push_back(_color);
colors.push_back(_color);
geom->set_num_prims(2);
geom->set_lengths(lengths);
geom->set_coords(verts);
geom->set_colors(colors, G_PER_COMPONENT);
geom->set_num_prims(2);
geom->set_lengths(lengths);
geom->set_coords(verts);
geom->set_colors(colors, G_PER_COMPONENT);
}
// For now, beveled and grooved geoms don't support textures. Easy
// to add if anyone really wants this.
@ -537,75 +647,158 @@ generate_groove_geom(const LVecBase4f &frame, bool in) {
min(_color[2] * top_color_scale, 1.0f),
_color[3]);
// Now make the tristrips.
Geom *geom = new GeomTristrip;
gnode->add_geom(geom);
PTA_int lengths;
PTA_Vertexf verts;
PTA_Colorf colors;
if (use_qpgeom) {
CPT(qpGeomVertexFormat) format = qpGeomVertexFormat::get_v3cp();
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("PGFrame", format, qpGeomUsageHint::UH_static);
// Tristrip 1.
lengths.push_back(8);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
qpGeomVertexWriter color(vdata, InternalName::get_color());
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static);
// Tristrip 1.
vertex.add_data3f(right, 0.0f, bottom);
vertex.add_data3f(mid_right, 0.0f, mid_bottom);
vertex.add_data3f(left, 0.0f, bottom);
vertex.add_data3f(mid_left, 0.0f, mid_bottom);
vertex.add_data3f(left, 0.0f, top);
vertex.add_data3f(mid_left, 0.0f, mid_top);
vertex.add_data3f(right, 0.0f, top);
vertex.add_data3f(mid_right, 0.0f, mid_top);
color.add_data4f(cbottom);
color.add_data4f(cbottom);
color.add_data4f(cbottom);
color.add_data4f(cbottom);
color.add_data4f(cleft);
color.add_data4f(cleft);
color.add_data4f(ctop);
color.add_data4f(ctop);
strip->add_next_vertices(8);
strip->close_primitive();
// Tristrip 2.
vertex.add_data3f(mid_right, 0.0f, mid_bottom);
vertex.add_data3f(inner_right, 0.0f, inner_bottom);
vertex.add_data3f(mid_left, 0.0f, mid_bottom);
vertex.add_data3f(inner_left, 0.0f, inner_bottom);
vertex.add_data3f(mid_left, 0.0f, mid_top);
vertex.add_data3f(inner_left, 0.0f, inner_top);
vertex.add_data3f(mid_right, 0.0f, mid_top);
vertex.add_data3f(inner_right, 0.0f, inner_top);
color.add_data4f(ctop);
color.add_data4f(ctop);
color.add_data4f(ctop);
color.add_data4f(ctop);
color.add_data4f(cright);
color.add_data4f(cright);
color.add_data4f(cbottom);
color.add_data4f(cbottom);
strip->add_next_vertices(8);
strip->close_primitive();
// Tristrip 3.
vertex.add_data3f(right, 0.0f, bottom);
vertex.add_data3f(right, 0.0f, top);
vertex.add_data3f(mid_right, 0.0f, mid_bottom);
vertex.add_data3f(mid_right, 0.0f, mid_top);
vertex.add_data3f(inner_right, 0.0f, inner_bottom);
vertex.add_data3f(inner_right, 0.0f, inner_top);
vertex.add_data3f(inner_left, 0.0f, inner_bottom);
vertex.add_data3f(inner_left, 0.0f, inner_top);
color.add_data4f(cright);
color.add_data4f(cright);
color.add_data4f(cright);
color.add_data4f(cright);
color.add_data4f(cleft);
color.add_data4f(cleft);
color.add_data4f(_color);
color.add_data4f(_color);
strip->add_next_vertices(8);
strip->close_primitive();
strip->set_shade_model(qpGeomPrimitive::SM_flat_last_vertex);
PT(qpGeom) geom = new qpGeom;
geom->set_vertex_data(vdata);
geom->add_primitive(strip);
CPT(RenderState) flat_state = RenderState::make(ShadeModelAttrib::make(ShadeModelAttrib::M_flat));
gnode->add_geom(geom, flat_state);
} else {
// Now make the tristrips.
Geom *geom = new GeomTristrip;
gnode->add_geom(geom);
verts.push_back(Vertexf(right, 0.0f, bottom));
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
verts.push_back(Vertexf(left, 0.0f, bottom));
verts.push_back(Vertexf(mid_left, 0.0f, mid_bottom));
verts.push_back(Vertexf(left, 0.0f, top));
verts.push_back(Vertexf(mid_left, 0.0f, mid_top));
verts.push_back(Vertexf(right, 0.0f, top));
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
PTA_int lengths;
PTA_Vertexf verts;
PTA_Colorf colors;
// Tristrip 1.
lengths.push_back(8);
verts.push_back(Vertexf(right, 0.0f, bottom));
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
verts.push_back(Vertexf(left, 0.0f, bottom));
verts.push_back(Vertexf(mid_left, 0.0f, mid_bottom));
verts.push_back(Vertexf(left, 0.0f, top));
verts.push_back(Vertexf(mid_left, 0.0f, mid_top));
verts.push_back(Vertexf(right, 0.0f, top));
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
colors.push_back(cbottom);
colors.push_back(cbottom);
colors.push_back(cleft);
colors.push_back(cleft);
colors.push_back(ctop);
colors.push_back(ctop);
colors.push_back(cbottom);
colors.push_back(cbottom);
colors.push_back(cleft);
colors.push_back(cleft);
colors.push_back(ctop);
colors.push_back(ctop);
// Tristrip 2.
lengths.push_back(8);
// Tristrip 2.
lengths.push_back(8);
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
verts.push_back(Vertexf(mid_left, 0.0f, mid_bottom));
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
verts.push_back(Vertexf(mid_left, 0.0f, mid_top));
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
verts.push_back(Vertexf(mid_left, 0.0f, mid_bottom));
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
verts.push_back(Vertexf(mid_left, 0.0f, mid_top));
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
colors.push_back(ctop);
colors.push_back(ctop);
colors.push_back(cright);
colors.push_back(cright);
colors.push_back(cbottom);
colors.push_back(cbottom);
colors.push_back(ctop);
colors.push_back(ctop);
colors.push_back(cright);
colors.push_back(cright);
colors.push_back(cbottom);
colors.push_back(cbottom);
// Tristrip 3.
lengths.push_back(8);
// Tristrip 3.
lengths.push_back(8);
verts.push_back(Vertexf(right, 0.0f, bottom));
verts.push_back(Vertexf(right, 0.0f, top));
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
verts.push_back(Vertexf(right, 0.0f, bottom));
verts.push_back(Vertexf(right, 0.0f, top));
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
colors.push_back(cright);
colors.push_back(cright);
colors.push_back(cleft);
colors.push_back(cleft);
colors.push_back(_color);
colors.push_back(_color);
colors.push_back(cright);
colors.push_back(cright);
colors.push_back(cleft);
colors.push_back(cleft);
colors.push_back(_color);
colors.push_back(_color);
geom->set_num_prims(3);
geom->set_lengths(lengths);
geom->set_coords(verts);
geom->set_colors(colors, G_PER_COMPONENT);
geom->set_num_prims(3);
geom->set_lengths(lengths);
geom->set_coords(verts);
geom->set_colors(colors, G_PER_COMPONENT);
}
// For now, beveled and grooved geoms don't support textures. Easy
// to add if anyone really wants this.

View File

@ -125,21 +125,15 @@ make_geom(int bitmap_top, int bitmap_left, float advance, float poly_margin,
// Create a corresponding tristrip.
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
(string(), qpGeomVertexFormat::get_v3cpt2(),
(string(), qpGeomVertexFormat::get_v3t2(),
qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
qpGeomVertexWriter color(vdata, InternalName::get_color());
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
vertex.add_data3f(left, 0, top);
vertex.add_data3f(left, 0, bottom);
vertex.add_data3f(right, 0, top);
vertex.add_data3f(right, 0, bottom);
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);

View File

@ -607,7 +607,7 @@ make_frame() {
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("text", qpGeomVertexFormat::get_v3cp(),
("text", qpGeomVertexFormat::get_v3(),
qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
@ -681,7 +681,7 @@ make_card() {
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("text", qpGeomVertexFormat::get_v3cpt2(),
("text", qpGeomVertexFormat::get_v3t2(),
qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
@ -766,7 +766,7 @@ make_card_with_border() {
if (use_qpgeom) {
PT(qpGeomVertexData) vdata = new qpGeomVertexData
("text", qpGeomVertexFormat::get_v3cpt2(),
("text", qpGeomVertexFormat::get_v3t2(),
qpGeomUsageHint::UH_static);
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());