Change handling of unsupported render mode so that behaviour can be shared among renderers

This commit is contained in:
rdb 2016-07-20 15:59:42 +02:00
parent 82b7728683
commit 2eba4dea9b
11 changed files with 55 additions and 101 deletions

View File

@ -18,13 +18,3 @@ INLINE GraphicsStateGuardian *StandardMunger::
get_gsg() const { get_gsg() const {
return (GraphicsStateGuardian *)GeomMunger::get_gsg(); return (GraphicsStateGuardian *)GeomMunger::get_gsg();
} }
/**
* 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

@ -38,9 +38,6 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
_auto_shader(false), _auto_shader(false),
_shader_skinning(false) _shader_skinning(false)
{ {
_render_mode = (const RenderModeAttrib *)
state->get_attrib(RenderModeAttrib::get_class_slot());
if (!get_gsg()->get_runtime_color_scale()) { if (!get_gsg()->get_runtime_color_scale()) {
// We might need to munge the colors. // We might need to munge the colors.
const ColorAttrib *color_attrib; const ColorAttrib *color_attrib;
@ -183,14 +180,14 @@ munge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &vertex_data,
// it rather than draw them one by one. // it rather than draw them one by one.
if ((unsupported_bits & Geom::GR_composite_bits) != 0 || if ((unsupported_bits & Geom::GR_composite_bits) != 0 ||
(unsupported_bits & Geom::GR_strip_cut_index) != 0) { (unsupported_bits & Geom::GR_strip_cut_index) != 0) {
/*
* This decomposes everything in the primitive, so that if (for instance) the // This decomposes everything in the primitive, so that if (for
* primitive contained both strips and fans, but the GSG didn't support fans, // instance) the primitive contained both strips and fans, but the GSG
* it would decompose the strips too. To handle this correctly, we'd need a // didn't support fans, it would decompose the strips too. To handle
* separate decompose_fans() and decompose_strips() call; but for now, we'll // this correctly, we'd need a separate decompose_fans() and
* just say it's good enough. In practice, we don't have any GSG's that can // decompose_strips() call; but for now, we'll just say it's good
* support strips without also supporting fans. // enough. In practice, we don't have any GSG's that can support strips
*/ // without also supporting fans.
geom = geom->decompose(); geom = geom->decompose();
// Decomposing might produce an indexed Geom, so re-check the // Decomposing might produce an indexed Geom, so re-check the
@ -228,14 +225,14 @@ premunge_geom_impl(CPT(Geom) &geom, CPT(GeomVertexData) &vertex_data) {
// it rather than draw them one by one. // it rather than draw them one by one.
if ((unsupported_bits & Geom::GR_composite_bits) != 0 || if ((unsupported_bits & Geom::GR_composite_bits) != 0 ||
(unsupported_bits & Geom::GR_strip_cut_index) != 0) { (unsupported_bits & Geom::GR_strip_cut_index) != 0) {
/*
* This decomposes everything in the primitive, so that if (for instance) the // This decomposes everything in the primitive, so that if (for
* primitive contained both strips and fans, but the GSG didn't support fans, // instance) the primitive contained both strips and fans, but the GSG
* it would decompose the strips too. To handle this correctly, we'd need a // didn't support fans, it would decompose the strips too. To handle
* separate decompose_fans() and decompose_strips() call; but for now, we'll // this correctly, we'd need a separate decompose_fans() and
* just say it's good enough. In practice, we don't have any GSG's that can // decompose_strips() call; but for now, we'll just say it's good
* support strips without also supporting fans. // enough. In practice, we don't have any GSG's that can support strips
*/ // without also supporting fans.
geom = geom->decompose(); geom = geom->decompose();
// Decomposing might produce an indexed Geom, so re-check the // Decomposing might produce an indexed Geom, so re-check the
@ -267,10 +264,6 @@ int StandardMunger::
compare_to_impl(const GeomMunger *other) const { compare_to_impl(const GeomMunger *other) const {
const StandardMunger *om = (const StandardMunger *)other; const StandardMunger *om = (const StandardMunger *)other;
if (_render_mode != om->_render_mode) {
return _render_mode < om->_render_mode ? -1 : 1;
}
if (_munge_color != om->_munge_color) { if (_munge_color != om->_munge_color) {
return (int)_munge_color - (int)om->_munge_color; return (int)_munge_color - (int)om->_munge_color;
} }

View File

@ -46,13 +46,10 @@ protected:
virtual int geom_compare_to_impl(const GeomMunger *other) const; virtual int geom_compare_to_impl(const GeomMunger *other) const;
virtual CPT(RenderState) munge_state_impl(const RenderState *state); virtual CPT(RenderState) munge_state_impl(const RenderState *state);
INLINE RenderModeAttrib::Mode get_render_mode() const;
private: private:
int _num_components; int _num_components;
NumericType _numeric_type; NumericType _numeric_type;
Contents _contents; Contents _contents;
CPT(RenderModeAttrib) _render_mode;
bool _munge_color; bool _munge_color;
bool _munge_color_scale; bool _munge_color_scale;

View File

@ -2209,7 +2209,8 @@ reset() {
Geom::GR_point_perspective | Geom::GR_point_sprite | Geom::GR_point_perspective | Geom::GR_point_sprite |
Geom::GR_indexed_other | Geom::GR_indexed_other |
Geom::GR_triangle_strip | Geom::GR_triangle_fan | Geom::GR_triangle_strip | Geom::GR_triangle_fan |
Geom::GR_flat_first_vertex; Geom::GR_flat_first_vertex |
Geom::GR_render_mode_wireframe | Geom::GR_render_mode_point;
// overwrite gsg defaults with these values // overwrite gsg defaults with these values
@ -2844,7 +2845,8 @@ do_issue_shader() {
*/ */
void DXGraphicsStateGuardian9:: void DXGraphicsStateGuardian9::
do_issue_render_mode() { do_issue_render_mode() {
const RenderModeAttrib *target_render_mode = DCAST(RenderModeAttrib, _target_rs->get_attrib_def(RenderModeAttrib::get_class_slot())); const RenderModeAttrib *target_render_mode;
_target_rs->get_attrib_def(target_render_mode);
RenderModeAttrib::Mode mode = target_render_mode->get_mode(); RenderModeAttrib::Mode mode = target_render_mode->get_mode();
switch (mode) { switch (mode) {

View File

@ -409,41 +409,6 @@ premunge_format_impl(const GeomVertexFormat *orig) {
return format; return format;
} }
#ifdef OPENGLES
/**
* 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();
}
}
/**
* 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
/** /**
* Called to compare two GeomMungers who are known to be of the same type, for * Called to compare two GeomMungers who are known to be of the same type, for
* an apples-to-apples comparison. This will never be called on two pointers * an apples-to-apples comparison. This will never be called on two pointers
@ -473,11 +438,6 @@ compare_to_impl(const GeomMunger *other) const {
int CLP(GeomMunger):: int CLP(GeomMunger)::
geom_compare_to_impl(const GeomMunger *other) const { geom_compare_to_impl(const GeomMunger *other) const {
const CLP(GeomMunger) *om = (CLP(GeomMunger) *)other; const CLP(GeomMunger) *om = (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) { if (_texture != om->_texture) {
return _texture < om->_texture ? -1 : 1; return _texture < om->_texture ? -1 : 1;
} }

View File

@ -40,12 +40,6 @@ protected:
const GeomVertexAnimationSpec &animation); const GeomVertexAnimationSpec &animation);
virtual CPT(GeomVertexFormat) premunge_format_impl(const GeomVertexFormat *orig); 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 compare_to_impl(const GeomMunger *other) const;
virtual int geom_compare_to_impl(const GeomMunger *other) const; virtual int geom_compare_to_impl(const GeomMunger *other) const;

View File

@ -628,6 +628,9 @@ reset() {
} }
_supported_geom_rendering = _supported_geom_rendering =
#ifndef OPENGLES
Geom::GR_render_mode_wireframe | Geom::GR_render_mode_point |
#endif
Geom::GR_indexed_point | Geom::GR_indexed_point |
Geom::GR_point | Geom::GR_point_uniform_size | Geom::GR_point | Geom::GR_point_uniform_size |
Geom::GR_indexed_other | Geom::GR_indexed_other |

View File

@ -128,6 +128,10 @@ PUBLISHED:
// The union of the above shade model types. // The union of the above shade model types.
GR_shade_model_bits = 0x06000, GR_shade_model_bits = 0x06000,
// If a particular non-fill polygon mode is used.
GR_render_mode_wireframe= 0x40000,
GR_render_mode_point = 0x80000,
}; };
// The shade model specifies whether the per-vertex colors and normals // The shade model specifies whether the per-vertex colors and normals

View File

@ -59,7 +59,20 @@ munge_geom(GraphicsStateGuardianBase *gsg,
if (_geom != (Geom *)NULL) { if (_geom != (Geom *)NULL) {
_munger = munger; _munger = munger;
GraphicsStateGuardianBase *gsg = traverser->get_gsg();
int gsg_bits = gsg->get_supported_geom_rendering();
if (!hardware_point_sprites) {
// If support for hardware point sprites or perspective-scaled points is
// disabled, we don't allow the GSG to tell us it supports them.
gsg_bits &= ~(Geom::GR_point_perspective | Geom::GR_point_sprite);
}
if (!hardware_points) {
// If hardware-points is off, we don't allow any kind of point
// rendering, except plain old one-pixel points;
gsg_bits &= ~(Geom::GR_point_bits & ~Geom::GR_point);
}
int geom_rendering; int geom_rendering;
int unsupported_bits;
{ {
GeomPipelineReader geom_reader(_geom, current_thread); GeomPipelineReader geom_reader(_geom, current_thread);
@ -76,30 +89,23 @@ munge_geom(GraphicsStateGuardianBase *gsg,
geom_rendering = geom_reader.get_geom_rendering(); geom_rendering = geom_reader.get_geom_rendering();
geom_rendering = _state->get_geom_rendering(geom_rendering); geom_rendering = _state->get_geom_rendering(geom_rendering);
geom_rendering = _internal_transform->get_geom_rendering(geom_rendering); geom_rendering = _internal_transform->get_geom_rendering(geom_rendering);
unsupported_bits = geom_rendering & ~gsg_bits;
if (geom_rendering & Geom::GR_point_bits) { if (geom_rendering & Geom::GR_point_bits) {
if (geom_reader.get_primitive_type() != Geom::PT_points) { if (geom_reader.get_primitive_type() != Geom::PT_points) {
if (singular_points) { if (singular_points ||
(unsupported_bits & Geom::GR_render_mode_point) != 0) {
// Isolate the points so there's no unneeded overlap. // Isolate the points so there's no unneeded overlap.
_geom = _geom->make_points(); _geom = _geom->make_points();
} }
} }
} }
if (unsupported_bits & Geom::GR_render_mode_wireframe) {
if (geom_reader.get_primitive_type() != Geom::PT_lines) {
_geom = _geom->make_lines();
} }
GraphicsStateGuardianBase *gsg = traverser->get_gsg();
int gsg_bits = gsg->get_supported_geom_rendering();
if (!hardware_point_sprites) {
// If support for hardware point sprites or perspective-scaled points is
// disabled, we don't allow the GSG to tell us it supports them.
gsg_bits &= ~(Geom::GR_point_perspective | Geom::GR_point_sprite);
} }
if (!hardware_points) {
// If hardware-points is off, we don't allow any kind of point
// rendering, except plain old one-pixel points;
gsg_bits &= ~(Geom::GR_point_bits & ~Geom::GR_point);
} }
int unsupported_bits = geom_rendering & ~gsg_bits;
if ((unsupported_bits & Geom::GR_point_bits) != 0) { if ((unsupported_bits & Geom::GR_point_bits) != 0) {
// The GSG doesn't support rendering these fancy points directly; we // The GSG doesn't support rendering these fancy points directly; we

View File

@ -71,8 +71,12 @@ get_wireframe_color() const {
INLINE int RenderModeAttrib:: INLINE int RenderModeAttrib::
get_geom_rendering(int geom_rendering) const { get_geom_rendering(int geom_rendering) const {
if (_mode == M_point) { if (_mode == M_point) {
geom_rendering |= Geom::GR_point; geom_rendering |= Geom::GR_point | Geom::GR_render_mode_point;
} else if (_mode == M_wireframe) {
geom_rendering |= Geom::GR_render_mode_wireframe;
} }
if ((geom_rendering & Geom::GR_point) != 0) { if ((geom_rendering & Geom::GR_point) != 0) {
if (_perspective) { if (_perspective) {
geom_rendering |= (Geom::GR_point_perspective | Geom::GR_point_uniform_size); geom_rendering |= (Geom::GR_point_perspective | Geom::GR_point_uniform_size);

View File

@ -114,7 +114,8 @@ reset() {
Geom::GR_point | Geom::GR_point |
Geom::GR_indexed_other | Geom::GR_indexed_other |
Geom::GR_triangle_strip | Geom::GR_triangle_strip |
Geom::GR_flat_last_vertex; Geom::GR_flat_last_vertex |
Geom::GR_render_mode_wireframe | Geom::GR_render_mode_point;
_max_texture_dimension = (1 << ZB_POINT_ST_FRAC_BITS); _max_texture_dimension = (1 << ZB_POINT_ST_FRAC_BITS);
_max_texture_stages = MAX_TEXTURE_STAGES; _max_texture_stages = MAX_TEXTURE_STAGES;