Support wireframe and point rendering modes in OpenGL ES

This commit is contained in:
rdb 2015-04-03 14:15:23 +02:00
parent 89acd29463
commit 87451d8000
9 changed files with 179 additions and 0 deletions

View File

@ -23,3 +23,16 @@ INLINE GraphicsStateGuardian *StandardMunger::
get_gsg() const {
return (GraphicsStateGuardian *)GeomMunger::get_gsg();
}
////////////////////////////////////////////////////////////////////
// Function: StandardMunger::get_render_mode
// Access: Protected
// Description: Returns the render mode active on this munger.
// Intended for derived classes that may have to munge
// differently depending on render mode.
////////////////////////////////////////////////////////////////////
INLINE RenderModeAttrib::Mode StandardMunger::
get_render_mode() const {
return (_render_mode != NULL) ? _render_mode->get_mode()
: RenderModeAttrib::M_filled;
}

View File

@ -49,6 +49,8 @@ protected:
virtual int geom_compare_to_impl(const GeomMunger *other) const;
virtual CPT(RenderState) munge_state_impl(const RenderState *state);
INLINE RenderModeAttrib::Mode get_render_mode() const;
private:
int _num_components;
NumericType _numeric_type;

View File

@ -362,6 +362,45 @@ premunge_format_impl(const GeomVertexFormat *orig) {
return format;
}
#ifdef OPENGLES
////////////////////////////////////////////////////////////////////
// Function: CLP(GeomMunger)::munge_geom_impl
// Access: Protected, Virtual
// Description: Converts a Geom and/or its data as necessary.
////////////////////////////////////////////////////////////////////
void CLP(GeomMunger)::
munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &vertex_data,
Thread *current_thread) {
StandardMunger::munge_geom_impl(geom, vertex_data, current_thread);
// OpenGL ES has no polygon mode, so we have to emulate it.
RenderModeAttrib::Mode render_mode = get_render_mode();
if (render_mode == RenderModeAttrib::M_point) {
geom = geom->make_points();
} else if (render_mode == RenderModeAttrib::M_wireframe) {
geom = geom->make_lines();
}
}
////////////////////////////////////////////////////////////////////
// Function: CLP(GeomMunger)::premunge_geom_impl
// Access: Protected, Virtual
// Description: Converts a Geom and/or its data as necessary.
////////////////////////////////////////////////////////////////////
void CLP(GeomMunger)::
premunge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &vertex_data) {
StandardMunger::premunge_geom_impl(geom, vertex_data);
// OpenGL ES has no polygon mode, so we have to emulate it.
RenderModeAttrib::Mode render_mode = get_render_mode();
if (render_mode == RenderModeAttrib::M_point) {
geom = geom->make_points();
} else if (render_mode == RenderModeAttrib::M_wireframe) {
geom = geom->make_lines();
}
}
#endif // OPENGLES
////////////////////////////////////////////////////////////////////
// Function: CLP(GeomMunger)::compare_to_impl
// Access: Protected, Virtual
@ -397,6 +436,11 @@ compare_to_impl(const GeomMunger *other) const {
int CLP(GeomMunger)::
geom_compare_to_impl(const GeomMunger *other) const {
const CLP(GeomMunger) *om = DCAST(CLP(GeomMunger), other);
#ifdef OPENGLES
if (get_render_mode() != om->get_render_mode()) {
return get_render_mode() < om->get_render_mode() ? -1 : 1;
}
#endif
if (_texture != om->_texture) {
return _texture < om->_texture ? -1 : 1;
}

View File

@ -42,6 +42,12 @@ protected:
const GeomVertexAnimationSpec &animation);
virtual CPT(GeomVertexFormat) premunge_format_impl(const GeomVertexFormat *orig);
#ifdef OPENGLES
virtual void munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data,
Thread *current_thread);
virtual void premunge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &data);
#endif
virtual int compare_to_impl(const GeomMunger *other) const;
virtual int geom_compare_to_impl(const GeomMunger *other) const;

View File

@ -242,6 +242,19 @@ make_points() const {
return new_geom;
}
////////////////////////////////////////////////////////////////////
// Function: Geom::make_lines
// Access: Published
// Description: Returns a new Geom with lines at all the edges.
// See GeomPrimitive::make_lines().
////////////////////////////////////////////////////////////////////
INLINE PT(Geom) Geom::
make_lines() const {
PT(Geom) new_geom = make_copy();
new_geom->make_lines_in_place();
return new_geom;
}
////////////////////////////////////////////////////////////////////
// Function: Geom::make_patches
// Access: Published

View File

@ -750,6 +750,44 @@ unify_in_place(int max_indices, bool preserve_order) {
reset_geom_rendering(cdata);
}
////////////////////////////////////////////////////////////////////
// Function: Geom::make_lines_in_place
// Access: Published
// Description: Replaces the GeomPrimitives within this Geom with
// corresponding GeomLines, representing a wireframe
// of the primitives. See GeomPrimitive::make_lines().
//
// Don't call this in a downstream thread unless you
// don't mind it blowing away other changes you might
// have recently made in an upstream thread.
////////////////////////////////////////////////////////////////////
void Geom::
make_lines_in_place() {
Thread *current_thread = Thread::get_current_thread();
CDWriter cdata(_cycler, true, current_thread);
#ifndef NDEBUG
bool all_is_valid = true;
#endif
Primitives::iterator pi;
for (pi = cdata->_primitives.begin(); pi != cdata->_primitives.end(); ++pi) {
CPT(GeomPrimitive) new_prim = (*pi).get_read_pointer()->make_lines();
(*pi) = (GeomPrimitive *)new_prim.p();
#ifndef NDEBUG
if (!new_prim->check_valid(cdata->_data.get_read_pointer())) {
all_is_valid = false;
}
#endif
}
cdata->_modified = Geom::get_next_modified();
reset_geom_rendering(cdata);
clear_cache_stage(current_thread);
nassertv(all_is_valid);
}
////////////////////////////////////////////////////////////////////
// Function: Geom::make_points_in_place
// Access: Published

View File

@ -102,6 +102,7 @@ PUBLISHED:
INLINE PT(Geom) rotate() const;
INLINE PT(Geom) unify(int max_indices, bool preserve_order) const;
INLINE PT(Geom) make_points() const;
INLINE PT(Geom) make_lines() const;
INLINE PT(Geom) make_patches() const;
void decompose_in_place();
@ -110,6 +111,7 @@ PUBLISHED:
void rotate_in_place();
void unify_in_place(int max_indices, bool preserve_order);
void make_points_in_place();
void make_lines_in_place();
void make_patches_in_place();
virtual bool copy_primitives_from(const Geom *other);

View File

@ -1044,6 +1044,66 @@ make_points() const {
return points;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::make_lines
// Access: Published
// Description: Returns a new GeomLines primitive that represents
// each of the edges in the original primitive rendered
// as a line. If the original primitive is already a
// GeomLines primitive, returns the original primitive
// unchanged.
////////////////////////////////////////////////////////////////////
CPT(GeomPrimitive) GeomPrimitive::
make_lines() const {
if (is_exact_type(GeomLines::get_class_type())) {
return this;
}
PrimitiveType prim_type = get_primitive_type();
if (prim_type == PT_lines) {
// It's a line strip, just decompose it.
return decompose();
} else if (prim_type != PT_polygons && prim_type != PT_patches) {
// Don't know how to represent this in wireframe.
return this;
}
if (prim_type == PT_polygons && !is_exact_type(GeomTriangles::get_class_type())) {
// Decompose tristrips. We could probably make this more efficient
// by making a specific implementation of make_lines for GeomTristrips.
return decompose()->make_lines();
}
// Iterate through the primitives.
int num_primitives = get_num_primitives();
int verts_per_prim = get_num_vertices_per_primitive();
PT(GeomVertexArrayData) new_vertices = make_index_data();
new_vertices->unclean_set_num_rows(num_primitives * verts_per_prim * 2);
GeomVertexWriter new_index(new_vertices, 0);
for (int i = 0; i < num_primitives; ++i) {
int begin = get_primitive_start(i);
int end = get_primitive_end(i);
if (begin == end) {
continue;
}
for (int vi = begin; vi < end - 1; vi++) {
new_index.set_data1i(get_vertex(vi));
new_index.set_data1i(get_vertex(vi + 1));
}
new_index.set_data1i(get_vertex(end - 1));
new_index.set_data1i(get_vertex(begin));
}
PT(GeomPrimitive) lines = new GeomLines(UH_dynamic);
lines->set_vertices(new_vertices);
return lines;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::make_patches
// Access: Published

View File

@ -134,6 +134,7 @@ PUBLISHED:
CPT(GeomPrimitive) reverse() const;
CPT(GeomPrimitive) match_shade_model(ShadeModel shade_model) const;
CPT(GeomPrimitive) make_points() const;
CPT(GeomPrimitive) make_lines() const;
CPT(GeomPrimitive) make_patches() const;
int get_num_bytes() const;