diff --git a/panda/src/collide/collisionEntry.cxx b/panda/src/collide/collisionEntry.cxx index 1cbe54bc3d..6d412e7d71 100644 --- a/panda/src/collide/collisionEntry.cxx +++ b/panda/src/collide/collisionEntry.cxx @@ -300,6 +300,6 @@ write(ostream &out, int indent_level) const { //////////////////////////////////////////////////////////////////// void CollisionEntry:: check_clip_planes() { - _into_clip_planes = _into_node_path.get_net_state()->get_clip_plane(); + _into_clip_planes = DCAST(ClipPlaneAttrib, _into_node_path.get_net_state()->get_attrib(ClipPlaneAttrib::get_class_slot())); _flags |= F_checked_clip_planes; } diff --git a/panda/src/collide/collisionPolygon.cxx b/panda/src/collide/collisionPolygon.cxx index 827a263409..ddce719349 100644 --- a/panda/src/collide/collisionPolygon.cxx +++ b/panda/src/collide/collisionPolygon.cxx @@ -253,7 +253,7 @@ get_collision_origin() const { PT(PandaNode) CollisionPolygon:: get_viz(const CullTraverser *trav, const CullTraverserData &data, bool bounds_only) const { - const ClipPlaneAttrib *cpa = data._state->get_clip_plane(); + const ClipPlaneAttrib *cpa = DCAST(ClipPlaneAttrib, data._state->get_attrib(ClipPlaneAttrib::get_class_slot())); if (cpa == (const ClipPlaneAttrib *)NULL) { // Fortunately, the polygon is not clipped. This is the normal, // easy case. diff --git a/panda/src/cull/cullBinStateSorted.I b/panda/src/cull/cullBinStateSorted.I index 3f7c163068..53141cc9c6 100644 --- a/panda/src/cull/cullBinStateSorted.I +++ b/panda/src/cull/cullBinStateSorted.I @@ -45,29 +45,16 @@ ObjectData(CullableObject *object) : //////////////////////////////////////////////////////////////////// INLINE bool CullBinStateSorted::ObjectData:: operator < (const ObjectData &other) const { - const RenderState *sa = _object->_state; - const RenderState *sb = other._object->_state; - - if (sa != sb) { - // First, group objects by texture, since conventional wisdom is - // that texture changes are the most expensive state changes in a - // graphics context. - const TextureAttrib *ta = sa->get_texture(); - const TextureAttrib *tb = sb->get_texture(); - if (ta != tb) { - return ta < tb; - } - } - - // Then group objects by transform, since these are supposed to be - // expensive too. + // First group objects by transform, since transform changes are + // supposed to be expensive. if (_object->_modelview_transform != other._object->_modelview_transform) { return _object->_modelview_transform < other._object->_modelview_transform; } - - // Then, sort by all the other states, in no particular order, - // just as long as objects with identical state are all grouped - // together. - return sa < sb; + + // Then group by other state changes, in approximate order from + // heaviest change to lightest change. + const RenderState *sa = _object->_state; + const RenderState *sb = other._object->_state; + return sa->compare_sort(*sb) < 0; } diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index f4774f8291..c4195ace92 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -18,7 +18,6 @@ #include "vertexBufferContext.h" #include "indexBufferContext.h" #include "renderBuffer.h" -#include "attribSlots.h" #include "light.h" #include "planeNode.h" #include "ambientLight.h" @@ -41,6 +40,11 @@ #include "pointLight.h" #include "spotlight.h" #include "textureReloadRequest.h" +#include "shaderAttrib.h" +#include "materialAttrib.h" +#include "depthWriteAttrib.h" +#include "lightAttrib.h" +#include "texGenAttrib.h" #include #include @@ -810,7 +814,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f return &t; } case Shader::SMO_texpad_x: { - Texture *tex = _target._shader->get_shader_input_texture(name); + Texture *tex = _target_shader->get_shader_input_texture(name); nassertr(tex != 0, &LMatrix4f::zeros_mat()); int sx = tex->get_x_size() - tex->get_pad_x_size(); int sy = tex->get_y_size() - tex->get_pad_y_size(); @@ -822,7 +826,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f return &t; } case Shader::SMO_texpix_x: { - Texture *tex = _target._shader->get_shader_input_texture(name); + Texture *tex = _target_shader->get_shader_input_texture(name); nassertr(tex != 0, &LMatrix4f::zeros_mat()); double px = 1.0 / tex->get_x_size(); double py = 1.0 / tex->get_y_size(); @@ -831,12 +835,13 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f return &t; } case Shader::SMO_attr_material: { + const MaterialAttrib *target_material = DCAST(MaterialAttrib, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot())); // Material matrix contains AMBIENT, DIFFUSE, EMISSION, SPECULAR+SHININESS - if (_target._material->is_off()) { + if (target_material->is_off()) { t = LMatrix4f(1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0); return &t; } - Material *m = _target._material->get_material(); + Material *m = target_material->get_material(); LVecBase4f const &amb = m->get_ambient(); LVecBase4f const &dif = m->get_diffuse(); LVecBase4f const &emm = m->get_emission(); @@ -849,15 +854,16 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f return &t; } case Shader::SMO_attr_color: { - if (_target._color->get_color_type() != ColorAttrib::T_flat) { + const ColorAttrib *target_color = DCAST(ColorAttrib, _target_rs->get_attrib_def(ColorAttrib::get_class_slot())); + if (target_color->get_color_type() != ColorAttrib::T_flat) { return &LMatrix4f::ones_mat(); } - LVecBase4f c = _target._color->get_color(); + LVecBase4f c = target_color->get_color(); t = LMatrix4f(0,0,0,0,0,0,0,0,0,0,0,0,c[0],c[1],c[2],c[3]); return &t; } case Shader::SMO_alight_x: { - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::zeros_mat()); AmbientLight *lt; DCAST_INTO_R(lt, np.node(), &LMatrix4f::zeros_mat()); @@ -866,7 +872,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f return &t; } case Shader::SMO_satten_x: { - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::ones_mat()); Spotlight *lt; DCAST_INTO_R(lt, np.node(), &LMatrix4f::ones_mat()); @@ -877,7 +883,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f } case Shader::SMO_dlight_x: { // The dlight matrix contains COLOR, SPECULAR, DIRECTION, PSEUDOHALFANGLE - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::zeros_mat()); DirectionalLight *lt; DCAST_INTO_R(lt, np.node(), &LMatrix4f::zeros_mat()); @@ -894,7 +900,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f } case Shader::SMO_plight_x: { // The plight matrix contains COLOR, SPECULAR, POINT, ATTENUATION - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::ones_mat()); PointLight *lt; DCAST_INTO_R(lt, np.node(), &LMatrix4f::zeros_mat()); @@ -909,7 +915,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f } case Shader::SMO_slight_x: { // The slight matrix contains COLOR, SPECULAR, POINT, DIRECTION - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::zeros_mat()); Spotlight *lt; DCAST_INTO_R(lt, np.node(), &LMatrix4f::zeros_mat()); @@ -926,12 +932,12 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f return &t; } case Shader::SMO_mat_constant_x: { - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::ident_mat()); return &(np.node()->get_transform()->get_mat()); } case Shader::SMO_vec_constant_x: { - const LVector4f &input = _target._shader->get_shader_input_vector(name); + const LVector4f &input = _target_shader->get_shader_input_vector(name); const float *data = input.get_data(); t = LMatrix4f(data[0],data[1],data[2],data[3], data[0],data[1],data[2],data[3], @@ -987,21 +993,21 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f return &t; } case Shader::SMO_view_x_to_view: { - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::ident_mat()); t = np.get_net_transform()->get_mat() * get_scene()->get_world_transform()->get_mat(); return &t; } case Shader::SMO_view_to_view_x: { - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::ident_mat()); t = get_scene()->get_camera_transform()->get_mat() * invert(np.get_net_transform()->get_mat()); return &t; } case Shader::SMO_apiview_x_to_view: { - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::ident_mat()); t = LMatrix4f::convert_mat(_internal_coordinate_system, _coordinate_system) * np.get_net_transform()->get_mat() * @@ -1009,7 +1015,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f return &t; } case Shader::SMO_view_to_apiview_x: { - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::ident_mat()); t = (get_scene()->get_camera_transform()->get_mat() * invert(np.get_net_transform()->get_mat()) * @@ -1017,7 +1023,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f return &t; } case Shader::SMO_clip_x_to_view: { - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::ident_mat()); Lens *lens = DCAST(LensNode, np.node())->get_lens(); t = lens->get_projection_mat_inv(_current_stereo_channel) * @@ -1027,7 +1033,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4f return &t; } case Shader::SMO_view_to_clip_x: { - const NodePath &np = _target._shader->get_shader_input_nodepath(name); + const NodePath &np = _target_shader->get_shader_input_nodepath(name); nassertr(!np.is_empty(), &LMatrix4f::ident_mat()); Lens *lens = DCAST(LensNode, np.node())->get_lens(); t = get_scene()->get_camera_transform()->get_mat() * @@ -1151,8 +1157,8 @@ begin_frame(Thread *current_thread) { // have changed properties since last time without changing // attribute pointers--like textures, lighting, or fog--will still // be accurately updated. - _state_rs = 0; - _state.clear_to_zero(); + _state_rs = RenderState::make_empty(); + _state_mask.clear(); return true; } @@ -1210,8 +1216,8 @@ end_scene() { _num_clip_planes_enabled = 0; // Put the state into the 'unknown' state, forcing a reload. - _state_rs = 0; - _state.clear_to_zero(); + _state_rs = RenderState::make_empty(); + _state_mask.clear(); } //////////////////////////////////////////////////////////////////// @@ -1452,10 +1458,9 @@ reset() { _needs_reset = false; _is_valid = false; - _state_rs = NULL; + _state_rs = RenderState::make_empty(); _target_rs = NULL; - _state.clear_to_zero(); - _target.clear_to_defaults(); + _state_mask.clear(); _internal_transform = _cs_transform; _scene_null = new SceneSetup; _scene_setup = _scene_null; @@ -1568,8 +1573,9 @@ do_issue_clip_plane() { int num_enabled = 0; int num_on_planes = 0; - if (_target._clip_plane != (ClipPlaneAttrib *)NULL) { - CPT(ClipPlaneAttrib) new_plane = _target._clip_plane->filter_to_max(_max_clip_planes); + const ClipPlaneAttrib *target_clip_plane = DCAST(ClipPlaneAttrib, _target_rs->get_attrib_def(ClipPlaneAttrib::get_class_slot())); + if (target_clip_plane != (ClipPlaneAttrib *)NULL) { + CPT(ClipPlaneAttrib) new_plane = target_clip_plane->filter_to_max(_max_clip_planes); num_on_planes = new_plane->get_num_on_planes(); for (int li = 0; li < num_on_planes; li++) { @@ -1627,12 +1633,12 @@ do_issue_clip_plane() { //////////////////////////////////////////////////////////////////// void GraphicsStateGuardian:: do_issue_color() { - const ColorAttrib *attrib = _target._color; - switch (attrib->get_color_type()) { + const ColorAttrib *target_color = DCAST(ColorAttrib, _target_rs->get_attrib_def(ColorAttrib::get_class_slot())); + switch (target_color->get_color_type()) { case ColorAttrib::T_flat: // Color attribute flat: it specifies a scene graph color that // overrides the vertex color. - _scene_graph_color = attrib->get_color(); + _scene_graph_color = target_color->get_color(); _has_scene_graph_color = true; _vertex_colors_enabled = false; break; @@ -1655,9 +1661,8 @@ do_issue_color() { } if (_color_scale_via_lighting) { - _state_rs = 0; - _state._light = 0; - _state._material = 0; + _state_mask.clear_bit(LightAttrib::get_class_slot()); + _state_mask.clear_bit(MaterialAttrib::get_class_slot()); determine_light_color_scale(); } @@ -1673,36 +1678,33 @@ do_issue_color_scale() { // If the previous color scale had set a special texture, clear the // texture now. if (_has_texture_alpha_scale) { - _state._texture = 0; + _state_mask.clear_bit(TextureAttrib::get_class_slot()); } - const ColorScaleAttrib *attrib = _target._color_scale; - _color_scale_enabled = attrib->has_scale(); - _current_color_scale = attrib->get_scale(); + const ColorScaleAttrib *target_color_scale = DCAST(ColorScaleAttrib, _target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot())); + _color_scale_enabled = target_color_scale->has_scale(); + _current_color_scale = target_color_scale->get_scale(); _has_texture_alpha_scale = false; if (_color_blend_involves_color_scale) { - _state_rs = 0; - _state._transparency = 0; + _state_mask.clear_bit(TransparencyAttrib::get_class_slot()); } if (_texture_involves_color_scale) { - _state_rs = 0; - _state._texture = 0; + _state_mask.clear_bit(TextureAttrib::get_class_slot()); } if (_color_scale_via_lighting) { - _state_rs = 0; - _state._light = 0; - _state._material = 0; + _state_mask.clear_bit(LightAttrib::get_class_slot()); + _state_mask.clear_bit(MaterialAttrib::get_class_slot()); determine_light_color_scale(); } if (_alpha_scale_via_texture && !_has_scene_graph_color && - attrib->has_alpha_scale()) { + target_color_scale->has_alpha_scale()) { // This color scale will set a special texture--so again, clear // the texture. - _state._texture = 0; - _state._tex_matrix = 0; + _state_mask.clear_bit(TextureAttrib::get_class_slot()); + _state_mask.clear_bit(TexMatrixAttrib::get_class_slot()); _has_texture_alpha_scale = true; } @@ -1738,12 +1740,13 @@ do_issue_light() { int num_enabled = 0; int num_on_lights = 0; + const LightAttrib *target_light = DCAST(LightAttrib, _target_rs->get_attrib_def(LightAttrib::get_class_slot())); if (display_cat.is_spam()) { display_cat.spam() - << "do_issue_light: " << _target._light << "\n"; + << "do_issue_light: " << target_light << "\n"; } - if (_target._light != (LightAttrib *)NULL) { - CPT(LightAttrib) new_light = _target._light->filter_to_max(_max_lights); + if (target_light != (LightAttrib *)NULL) { + CPT(LightAttrib) new_light = target_light->filter_to_max(_max_lights); if (display_cat.is_spam()) { new_light->write(display_cat.spam(false), 2); } @@ -2063,30 +2066,32 @@ end_bind_clip_planes() { } //////////////////////////////////////////////////////////////////// -// Function: GraphicsStateGuardian::determine_effective_texture +// Function: GraphicsStateGuardian::determine_target_texture // Access: Protected -// Description: Assigns _effective_texture and _effective_tex_gen -// based on the current settings of _target._texture and -// _target._color_scale. +// Description: Assigns _target_texture and _target_tex_gen +// based on the _target_rs. //////////////////////////////////////////////////////////////////// void GraphicsStateGuardian:: -determine_effective_texture() { - nassertv(_target._texture != (TextureAttrib *)NULL && - _target._tex_gen != (TexGenAttrib *)NULL); +determine_target_texture() { + const TextureAttrib *target_texture = DCAST(TextureAttrib, _target_rs->get_attrib_def(TextureAttrib::get_class_slot())); + const TexGenAttrib *target_tex_gen = DCAST(TexGenAttrib, _target_rs->get_attrib_def(TexGenAttrib::get_class_slot())); + + nassertv(target_texture != (TextureAttrib *)NULL && + target_tex_gen != (TexGenAttrib *)NULL); int max_texture_stages = get_max_texture_stages(); - _effective_texture = _target._texture->filter_to_max(max_texture_stages); - _effective_tex_gen = _target._tex_gen; + _target_texture = target_texture->filter_to_max(max_texture_stages); + _target_tex_gen = target_tex_gen; if (_has_texture_alpha_scale) { PT(TextureStage) stage = get_alpha_scale_texture_stage(); PT(Texture) texture = TexturePool::get_alpha_scale_map(); - _effective_texture = DCAST(TextureAttrib, _effective_texture->add_on_stage(stage, texture)); - _effective_tex_gen = DCAST(TexGenAttrib, _effective_tex_gen->add_stage + _target_texture = DCAST(TextureAttrib, _target_texture->add_on_stage(stage, texture)); + _target_tex_gen = DCAST(TexGenAttrib, _target_tex_gen->add_stage (stage, TexGenAttrib::M_constant, TexCoord3f(_current_color_scale[3], 0.0f, 0.0f))); } - nassertv(_effective_texture->get_num_on_stages() <= max_texture_stages); + nassertv(_target_texture->get_num_on_stages() <= max_texture_stages); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 35037fdc9c..80561d1ae7 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -38,13 +38,15 @@ #include "geomVertexData.h" #include "pnotify.h" #include "pvector.h" -#include "attribSlots.h" #include "shaderContext.h" #include "bitMask.h" #include "texture.h" #include "occlusionQueryContext.h" #include "stencilRenderStates.h" #include "loader.h" +#include "textureAttrib.h" +#include "texGenAttrib.h" +#include "shaderAttrib.h" class DrawableRegion; class GraphicsEngine; @@ -291,7 +293,7 @@ protected: virtual void bind_clip_plane(const NodePath &plane, int plane_id); virtual void end_bind_clip_planes(); - void determine_effective_texture(); + void determine_target_texture(); virtual void free_pointers(); virtual void close_gsg(); @@ -309,18 +311,36 @@ protected: PT(SceneSetup) _scene_null; PT(SceneSetup) _scene_setup; - AttribSlots _state; - AttribSlots _target; + // The current state of the graphics context, as of the last call to + // set_state_and_transform(). CPT(RenderState) _state_rs; + + // The desired state of the graphics context, during processing of + // set_state_and_transform(). CPT(RenderState) _target_rs; + + // This bitmask contains a 1 bit everywhere that _state_rs has a + // known value. If a bit is 0, the corresponding state must be + // re-sent. + RenderState::SlotMask _state_mask; + + // The current transform, as of the last call to + // set_state_and_transform(). CPT(TransformState) _internal_transform; // The current TextureAttrib is a special case; we may further // restrict it (according to graphics cards limits) or extend it // (according to ColorScaleAttribs in effect) beyond what is // specifically requested in the scene graph. - CPT(TextureAttrib) _effective_texture; - CPT(TexGenAttrib) _effective_tex_gen; + CPT(TextureAttrib) _target_texture; + CPT(TextureAttrib) _state_texture; + CPT(TexGenAttrib) _target_tex_gen; + CPT(TexGenAttrib) _state_tex_gen; + + // Also, the shader might be the explicitly-requested shader, or it + // might be an auto-generated one. + CPT(ShaderAttrib) _state_shader; + CPT(ShaderAttrib) _target_shader; // These are set by begin_draw_primitives(), and are only valid // between begin_draw_primitives() and end_draw_primitives(). diff --git a/panda/src/display/standardMunger.cxx b/panda/src/display/standardMunger.cxx index a54794283a..d9b14708ae 100644 --- a/panda/src/display/standardMunger.cxx +++ b/panda/src/display/standardMunger.cxx @@ -39,15 +39,15 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state, _numeric_type(numeric_type), _contents(contents) { - _render_mode = state->get_render_mode(); + _render_mode = DCAST(RenderModeAttrib, state->get_attrib(RenderModeAttrib::get_class_slot())); _munge_color = false; _munge_color_scale = false; if (!get_gsg()->get_runtime_color_scale()) { // We might need to munge the colors. - CPT(ColorAttrib) color_attrib = state->get_color(); - CPT(ColorScaleAttrib) color_scale_attrib = state->get_color_scale(); + CPT(ColorAttrib) color_attrib = DCAST(ColorAttrib, state->get_attrib(ColorAttrib::get_class_slot())); + CPT(ColorScaleAttrib) color_scale_attrib = DCAST(ColorScaleAttrib, state->get_attrib(ColorScaleAttrib::get_class_slot())); if (color_attrib != (ColorAttrib *)NULL && color_attrib->get_color_type() == ColorAttrib::T_flat) { @@ -72,7 +72,7 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state, color_scale_attrib->has_scale()) { _color_scale = color_scale_attrib->get_scale(); - CPT(TextureAttrib) tex_attrib = state->get_texture(); + CPT(TextureAttrib) tex_attrib = DCAST(TextureAttrib, state->get_attrib(TextureAttrib::get_class_slot())); // If the GSG says it can't cheat this RGB or alpha scale, we have // to apply the color scale directly. @@ -339,10 +339,10 @@ munge_state_impl(const RenderState *state) { CPT(RenderState) munged_state = state; if (_munge_color) { - munged_state = munged_state->remove_attrib(ColorAttrib::get_class_type()); - munged_state = munged_state->remove_attrib(ColorScaleAttrib::get_class_type()); + munged_state = munged_state->remove_attrib(ColorAttrib::get_class_slot()); + munged_state = munged_state->remove_attrib(ColorScaleAttrib::get_class_slot()); } else if (_munge_color_scale) { - munged_state = munged_state->remove_attrib(ColorScaleAttrib::get_class_type()); + munged_state = munged_state->remove_attrib(ColorScaleAttrib::get_class_slot()); } return munged_state; diff --git a/panda/src/dxgsg8/dxGeomMunger8.I b/panda/src/dxgsg8/dxGeomMunger8.I index 3df080704f..b0a3911417 100644 --- a/panda/src/dxgsg8/dxGeomMunger8.I +++ b/panda/src/dxgsg8/dxGeomMunger8.I @@ -21,8 +21,8 @@ INLINE DXGeomMunger8:: DXGeomMunger8(GraphicsStateGuardian *gsg, const RenderState *state) : StandardMunger(gsg, state, 1, NT_packed_dabc, C_color), - _texture(state->get_texture()), - _tex_gen(state->get_tex_gen()) + _texture(DCAST(TextureAttrib, state->get_attrib(TextureAttrib::get_class_slot()))), + _tex_gen(DCAST(TexGenAttrib, state->get_attrib(TexGenAttrib::get_class_slot()))) { _filtered_texture = (TextureAttrib *)NULL; _reffed_filtered_texture = false; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 01a5de8f5c..cb6aae56d8 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -39,6 +39,9 @@ #include "rescaleNormalAttrib.h" #include "fogAttrib.h" #include "depthOffsetAttrib.h" +#include "lightAttrib.h" +#include "stencilAttrib.h" +#include "scissorAttrib.h" #include "fog.h" #include "throw_event.h" #include "geomVertexFormat.h" @@ -970,7 +973,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector); + //PStatTimer timer(_draw_primitive_pcollector); _vertices_tri_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_tri_pcollector.add_level(1); if (reader->is_indexed()) { @@ -1039,7 +1042,7 @@ draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector); + //PStatTimer timer(_draw_primitive_pcollector); if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) { // One long triangle strip, connected by the degenerate vertices // that have already been set up within the primitive. @@ -1214,7 +1217,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector); + //PStatTimer timer(_draw_primitive_pcollector); CPTA_int ends = reader->get_ends(); _primitive_batches_trifan_pcollector.add_level(ends.size()); @@ -1325,7 +1328,7 @@ draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: draw_lines(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector); + //PStatTimer timer(_draw_primitive_pcollector); _vertices_other_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_other_pcollector.add_level(1); @@ -1406,7 +1409,7 @@ draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: draw_points(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector); + //PStatTimer timer(_draw_primitive_pcollector); _vertices_other_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_other_pcollector.add_level(1); @@ -2102,15 +2105,15 @@ do_issue_transform() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: do_issue_alpha_test() { - const AlphaTestAttrib *attrib = _target._alpha_test; - AlphaTestAttrib::PandaCompareFunc mode = attrib->get_mode(); + const AlphaTestAttrib *target_alpha_test = DCAST(AlphaTestAttrib, _target_rs->get_attrib_def(AlphaTestAttrib::get_class_slot())); + AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->get_mode(); if (mode == AlphaTestAttrib::M_none) { _d3d_device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); } else { // AlphaTestAttrib::PandaCompareFunc === D3DCMPFUNC _d3d_device->SetRenderState(D3DRS_ALPHAFUNC, (D3DCMPFUNC)mode); - _d3d_device->SetRenderState(D3DRS_ALPHAREF, (UINT) (attrib->get_reference_alpha()*255.0f)); //d3d uses 0x0-0xFF, not a float + _d3d_device->SetRenderState(D3DRS_ALPHAREF, (UINT) (target_alpha_test->get_reference_alpha()*255.0f)); //d3d uses 0x0-0xFF, not a float _d3d_device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); } } @@ -2122,8 +2125,8 @@ do_issue_alpha_test() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: do_issue_render_mode() { - const RenderModeAttrib *attrib = _target._render_mode; - RenderModeAttrib::Mode mode = attrib->get_mode(); + const RenderModeAttrib *target_render_mode = DCAST(RenderModeAttrib, _target_rs->get_attrib_def(RenderModeAttrib::get_class_slot())); + RenderModeAttrib::Mode mode = target_render_mode->get_mode(); switch (mode) { case RenderModeAttrib::M_unchanged: @@ -2146,10 +2149,10 @@ do_issue_render_mode() { } // This might also specify the point size. - float point_size = attrib->get_thickness(); + float point_size = target_render_mode->get_thickness(); _d3d_device->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&point_size)); - if (attrib->get_perspective()) { + if (target_render_mode->get_perspective()) { _d3d_device->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); LVector3f height(0.0f, point_size, 1.0f); @@ -2176,8 +2179,8 @@ do_issue_render_mode() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: do_issue_rescale_normal() { - const RescaleNormalAttrib *attrib = _target._rescale_normal; - RescaleNormalAttrib::Mode mode = attrib->get_mode(); + const RescaleNormalAttrib *target_rescale_normal = DCAST(RescaleNormalAttrib, _target_rs->get_attrib_def(RescaleNormalAttrib::get_class_slot())); + RescaleNormalAttrib::Mode mode = target_rescale_normal->get_mode(); _auto_rescale_normal = false; @@ -2209,8 +2212,8 @@ do_issue_rescale_normal() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: do_issue_depth_test() { - const DepthTestAttrib *attrib = _target._depth_test; - DepthTestAttrib::PandaCompareFunc mode = attrib->get_mode(); + const DepthTestAttrib *target_depth_test = DCAST(DepthTestAttrib, _target_rs->get_attrib_def(DepthTestAttrib::get_class_slot())); + DepthTestAttrib::PandaCompareFunc mode = target_depth_test->get_mode(); if (mode == DepthTestAttrib::M_none) { _d3d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); } else { @@ -2226,8 +2229,8 @@ do_issue_depth_test() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: do_issue_depth_write() { - const DepthWriteAttrib *attrib = _target._depth_write; - if (attrib->get_mode() == DepthWriteAttrib::M_on) { + const DepthWriteAttrib *target_depth_write = DCAST(DepthWriteAttrib, _target_rs->get_attrib_def(DepthWriteAttrib::get_class_slot())); + if (target_depth_write->get_mode() == DepthWriteAttrib::M_on) { _d3d_device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); } else { _d3d_device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); @@ -2241,8 +2244,8 @@ do_issue_depth_write() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: do_issue_cull_face() { - const CullFaceAttrib *attrib = _target._cull_face; - _cull_face_mode = attrib->get_effective_mode(); + const CullFaceAttrib *target_cull_face = DCAST(CullFaceAttrib, _target_rs->get_attrib_def(CullFaceAttrib::get_class_slot())); + _cull_face_mode = target_cull_face->get_effective_mode(); switch (_cull_face_mode) { case CullFaceAttrib::M_cull_none: @@ -2268,10 +2271,10 @@ do_issue_cull_face() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: do_issue_fog() { - const FogAttrib *attrib = _target._fog; - if (!attrib->is_off()) { + const FogAttrib *target_fog = DCAST(FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot())); + if (!target_fog->is_off()) { _d3d_device->SetRenderState(D3DRS_FOGENABLE, TRUE); - Fog *fog = attrib->get_fog(); + Fog *fog = target_fog->get_fog(); nassertv(fog != (Fog *)NULL); apply_fog(fog); } else { @@ -2286,8 +2289,8 @@ do_issue_fog() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: do_issue_depth_offset() { - const DepthOffsetAttrib *attrib = _target._depth_offset; - int offset = attrib->get_offset(); + const DepthOffsetAttrib *target_depth_offset = DCAST(DepthOffsetAttrib, _target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot())); + int offset = target_depth_offset->get_offset(); _d3d_device->SetRenderState(D3DRS_ZBIAS, offset); } @@ -2298,8 +2301,8 @@ do_issue_depth_offset() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: do_issue_shade_model() { - const ShadeModelAttrib *attrib = _target._shade_model; - switch (attrib->get_mode()) { + const ShadeModelAttrib *target_shade_model = DCAST(ShadeModelAttrib, _target_rs->get_attrib_def(ShadeModelAttrib::get_class_slot())); + switch (target_shade_model->get_mode()) { case ShadeModelAttrib::M_smooth: _d3d_device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); break; @@ -2337,8 +2340,10 @@ set_state_and_transform(const RenderState *target, } #endif _state_pcollector.add_level(1); + PStatTimer timer1(_draw_set_state_pcollector); if (transform != _internal_transform) { + //PStatTimer timer(_draw_set_state_transform_pcollector); _state_pcollector.add_level(1); _internal_transform = transform; do_issue_transform(); @@ -2348,95 +2353,127 @@ set_state_and_transform(const RenderState *target, return; } _target_rs = target; - _target.clear_to_defaults(); - target->store_into_slots(&_target); - _state_rs = 0; - if (_target._alpha_test != _state._alpha_test) { + int alpha_test_slot = AlphaTestAttrib::get_class_slot(); + if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) || + !_state_mask.get_bit(alpha_test_slot)) { + //PStatTimer timer(_draw_set_state_alpha_test_pcollector); do_issue_alpha_test(); - _state._alpha_test = _target._alpha_test; + _state_mask.set_bit(alpha_test_slot); } - if (_target._antialias != _state._antialias) { - // Antialias not implemented under DX8 - _state._antialias = _target._antialias; - } - - if (_target._clip_plane != _state._clip_plane) { + int clip_plane_slot = ClipPlaneAttrib::get_class_slot(); + if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) || + !_state_mask.get_bit(clip_plane_slot)) { + //PStatTimer timer(_draw_set_state_clip_plane_pcollector); do_issue_clip_plane(); - _state._clip_plane = _target._clip_plane; + _state_mask.set_bit(clip_plane_slot); } - if (_target._color != _state._color || - _target._color_scale != _state._color_scale) { + int color_slot = ColorAttrib::get_class_slot(); + int color_scale_slot = ColorScaleAttrib::get_class_slot(); + if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) || + _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) || + !_state_mask.get_bit(color_slot) || + !_state_mask.get_bit(color_scale_slot)) { + //PStatTimer timer(_draw_set_state_color_pcollector); do_issue_color(); do_issue_color_scale(); - _state._color = _target._color; - _state._color_scale = _target._color_scale; + _state_mask.set_bit(color_slot); + _state_mask.set_bit(color_scale_slot); } - if (_target._cull_face != _state._cull_face) { + int cull_face_slot = CullFaceAttrib::get_class_slot(); + if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) || + !_state_mask.get_bit(cull_face_slot)) { + //PStatTimer timer(_draw_set_state_cull_face_pcollector); do_issue_cull_face(); - _state._cull_face = _target._cull_face; + _state_mask.set_bit(cull_face_slot); } - if (_target._depth_offset != _state._depth_offset) { + int depth_offset_slot = DepthOffsetAttrib::get_class_slot(); + if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) || + !_state_mask.get_bit(depth_offset_slot)) { + //PStatTimer timer(_draw_set_state_depth_offset_pcollector); do_issue_depth_offset(); - _state._depth_offset = _target._depth_offset; + _state_mask.set_bit(depth_offset_slot); } - if (_target._depth_test != _state._depth_test) { + int depth_test_slot = DepthTestAttrib::get_class_slot(); + if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) || + !_state_mask.get_bit(depth_test_slot)) { + //PStatTimer timer(_draw_set_state_depth_test_pcollector); do_issue_depth_test(); - _state._depth_test = _target._depth_test; + _state_mask.set_bit(depth_test_slot); } - if (_target._depth_write != _state._depth_write) { + int depth_write_slot = DepthWriteAttrib::get_class_slot(); + if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) || + !_state_mask.get_bit(depth_write_slot)) { + //PStatTimer timer(_draw_set_state_depth_write_pcollector); do_issue_depth_write(); - _state._depth_write = _target._depth_write; + _state_mask.set_bit(depth_write_slot); } - - if (_target._fog != _state._fog) { + + int fog_slot = FogAttrib::get_class_slot(); + if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) || + !_state_mask.get_bit(fog_slot)) { + //PStatTimer timer(_draw_set_state_fog_pcollector); do_issue_fog(); - _state._fog = _target._fog; + _state_mask.set_bit(fog_slot); } - if (_target._render_mode != _state._render_mode) { + int render_mode_slot = RenderModeAttrib::get_class_slot(); + if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) || + !_state_mask.get_bit(render_mode_slot)) { + //PStatTimer timer(_draw_set_state_render_mode_pcollector); do_issue_render_mode(); - _state._render_mode = _target._render_mode; + _state_mask.set_bit(render_mode_slot); } - if (_target._rescale_normal != _state._rescale_normal) { + int rescale_normal_slot = RescaleNormalAttrib::get_class_slot(); + if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) || + !_state_mask.get_bit(rescale_normal_slot)) { + //PStatTimer timer(_draw_set_state_rescale_normal_pcollector); do_issue_rescale_normal(); - _state._rescale_normal = _target._rescale_normal; + _state_mask.set_bit(rescale_normal_slot); } - if (_target._shade_model != _state._shade_model) { + int shade_model_slot = ShadeModelAttrib::get_class_slot(); + if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) || + !_state_mask.get_bit(shade_model_slot)) { + //PStatTimer timer(_draw_set_state_shade_model_pcollector); do_issue_shade_model(); - _state._shade_model = _target._shade_model; + _state_mask.set_bit(shade_model_slot); } - // Shaders not implemented under DX8 - if (_target._shader != _state._shader) { - _state._shader = _target._shader; - } - - if ((_target._transparency != _state._transparency)|| - (_target._color_write != _state._color_write)|| - (_target._color_blend != _state._color_blend)) { + int transparency_slot = TransparencyAttrib::get_class_slot(); + int color_write_slot = ColorWriteAttrib::get_class_slot(); + int color_blend_slot = ColorBlendAttrib::get_class_slot(); + if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) || + _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) || + _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) || + !_state_mask.get_bit(transparency_slot) || + !_state_mask.get_bit(color_write_slot) || + !_state_mask.get_bit(color_blend_slot)) { + //PStatTimer timer(_draw_set_state_blending_pcollector); do_issue_blending(); - _state._transparency = _target._transparency; - _state._color_write = _target._color_write; - _state._color_blend = _target._color_blend; + _state_mask.set_bit(transparency_slot); + _state_mask.set_bit(color_write_slot); + _state_mask.set_bit(color_blend_slot); } - if (_target._tex_matrix != _state._tex_matrix) { - _state._texture = 0; - _state._tex_matrix = _target._tex_matrix; - } - - if (_target._texture != _state._texture || - _target._tex_gen != _state._tex_gen) { - determine_effective_texture(); + int texture_slot = TextureAttrib::get_class_slot(); + int tex_matrix_slot = TexMatrixAttrib::get_class_slot(); + int tex_gen_slot = TexGenAttrib::get_class_slot(); + if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) || + _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) || + _target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) || + !_state_mask.get_bit(texture_slot) || + !_state_mask.get_bit(tex_matrix_slot) || + !_state_mask.get_bit(tex_gen_slot)) { + //PStatTimer timer(_draw_set_state_texture_pcollector); + determine_target_texture(); // For some mysterious and disturbing reason, making this call // here--which should have no effect--actually prevents the DX @@ -2444,31 +2481,46 @@ set_state_and_transform(const RenderState *target, // context goes foobar when switching states and refuses to draw // anything at all. I strongly suspect memory corruption // somewhere, but can't locate it. - _target._texture->filter_to_max(_max_texture_stages); + // _target_texture->filter_to_max(_max_texture_stages); do_issue_texture(); - _state._texture = _target._texture; - _state._tex_gen = _target._tex_gen; + + _state_texture = _target_texture; + _state_mask.set_bit(texture_slot); + _state_mask.set_bit(tex_matrix_slot); + _state_mask.set_bit(tex_gen_slot); } - if (_target._material != _state._material) { + int material_slot = MaterialAttrib::get_class_slot(); + if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) || + !_state_mask.get_bit(material_slot)) { + //PStatTimer timer(_draw_set_state_material_pcollector); do_issue_material(); - _state._material = _target._material; + _state_mask.set_bit(material_slot); } - if (_target._light != _state._light) { + int light_slot = LightAttrib::get_class_slot(); + if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) || + !_state_mask.get_bit(light_slot)) { + //PStatTimer timer(_draw_set_state_light_pcollector); do_issue_light(); - _state._light = _target._light; + _state_mask.set_bit(light_slot); } - if (_target._stencil != _state._stencil) { + int stencil_slot = StencilAttrib::get_class_slot(); + if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) || + !_state_mask.get_bit(stencil_slot)) { + //PStatTimer timer(_draw_set_state_stencil_pcollector); do_issue_stencil(); - _state._stencil = _target._stencil; + _state_mask.set_bit(stencil_slot); } - if (_target._scissor != _state._scissor) { + int scissor_slot = ScissorAttrib::get_class_slot(); + if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) || + !_state_mask.get_bit(scissor_slot)) { + //PStatTimer timer(_draw_set_state_scissor_pcollector); do_issue_scissor(); - _state._scissor = _target._scissor; + _state_mask.set_bit(scissor_slot); } _state_rs = _target_rs; @@ -2531,7 +2583,7 @@ bind_light(PointLight *light_obj, const NodePath &light, int light_id) { void DXGraphicsStateGuardian8:: bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) { static PStatCollector _draw_set_state_light_bind_directional_pcollector("Draw:Set State:Light:Bind:Directional"); - PStatTimer timer(_draw_set_state_light_bind_directional_pcollector); + //PStatTimer timer(_draw_set_state_light_bind_directional_pcollector); pair lookup = _dlights.insert(DirectionalLights::value_type(light, D3DLIGHT8())); D3DLIGHT8 &fdata = (*lookup.first).second; @@ -2663,11 +2715,11 @@ void DXGraphicsStateGuardian8:: do_issue_material() { static Material empty; const Material *material; - if (_target._material == (MaterialAttrib *)NULL || - _target._material->is_off()) { + const MaterialAttrib *target_material = DCAST(MaterialAttrib, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot())); + if (target_material->is_off()) { material = ∅ } else { - material = _target._material->get_material(); + material = target_material->get_material(); } D3DMATERIAL8 cur_material; @@ -2726,7 +2778,7 @@ void DXGraphicsStateGuardian8:: do_issue_texture() { DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1)); - int num_stages = _effective_texture->get_num_on_ff_stages(); + int num_stages = _target_texture->get_num_on_ff_stages(); nassertv(num_stages <= _max_texture_stages && _num_active_texture_stages <= _max_texture_stages); @@ -2738,10 +2790,10 @@ do_issue_texture() { int si; for (si = 0; si < num_stages; si++) { - TextureStage *stage = _effective_texture->get_on_ff_stage(si); - int texcoord_index = _effective_texture->get_ff_tc_index(si); + TextureStage *stage = _target_texture->get_on_ff_stage(si); + int texcoord_index = _target_texture->get_ff_tc_index(si); - Texture *texture = _effective_texture->get_on_texture(stage); + Texture *texture = _target_texture->get_on_texture(stage); nassertv(texture != (Texture *)NULL); // We always reissue every stage in DX, just in case the texcoord @@ -2753,12 +2805,13 @@ do_issue_texture() { int texcoord_dimensions = 2; CPT(TransformState) tex_mat = TransformState::make_identity(); - if (_state._tex_matrix->has_stage(stage)) { - tex_mat = _state._tex_matrix->get_transform(stage); + const TexMatrixAttrib *target_tex_matrix = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot())); + if (target_tex_matrix->has_stage(stage)) { + tex_mat = target_tex_matrix->get_transform(stage); } // Issue the texgen mode. - TexGenAttrib::Mode mode = _effective_tex_gen->get_mode(stage); + TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage); bool any_point_sprite = false; switch (mode) { @@ -2867,7 +2920,7 @@ do_issue_texture() { texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION); texcoord_dimensions = 3; - const TexCoord3f &v = _effective_tex_gen->get_constant_value(stage); + const TexCoord3f &v = _target_tex_gen->get_constant_value(stage); CPT(TransformState) squash = TransformState::make_pos_hpr_scale(v, LVecBase3f::zero(), LVecBase3f::zero()); @@ -3032,31 +3085,30 @@ do_issue_blending() { // all the other blending-related stuff doesn't matter. If the // device doesn't support color-write, we use blending tricks // to effectively disable color write. + const ColorWriteAttrib *target_color_write = DCAST(ColorWriteAttrib, _target_rs->get_attrib_def(ColorWriteAttrib::get_class_slot())); unsigned int color_channels = - _target._color_write->get_channels() & _color_write_mask; + target_color_write->get_channels() & _color_write_mask; if (color_channels == ColorWriteAttrib::C_off) { - if (_target._color_write != _state._color_write) { - if (_screen->_can_direct_disable_color_writes) { - _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, (DWORD)0x0); - } else { - _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - _d3d_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); - _d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); - } + if (_screen->_can_direct_disable_color_writes) { + _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, (DWORD)0x0); + } else { + _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + _d3d_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); + _d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); } return; - } else { - if (_target._color_write != _state._color_write) { - if (_screen->_can_direct_disable_color_writes) { - _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, color_channels); - } - } } - CPT(ColorBlendAttrib) color_blend = _target._color_blend; - ColorBlendAttrib::Mode color_blend_mode = _target._color_blend->get_mode(); - TransparencyAttrib::Mode transparency_mode = _target._transparency->get_mode(); + if (_screen->_can_direct_disable_color_writes) { + _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, color_channels); + } + + const ColorBlendAttrib *target_color_blend = DCAST(ColorBlendAttrib, _target_rs->get_attrib_def(ColorBlendAttrib::get_class_slot())); + ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode(); + + const TransparencyAttrib *target_transparency = DCAST(TransparencyAttrib, _target_rs->get_attrib_def(TransparencyAttrib::get_class_slot())); + TransparencyAttrib::Mode transparency_mode = target_transparency->get_mode(); // Is there a color blend set? if (color_blend_mode != ColorBlendAttrib::M_none) { @@ -3085,9 +3137,9 @@ do_issue_blending() { } _d3d_device->SetRenderState(D3DRS_SRCBLEND, - get_blend_func(color_blend->get_operand_a())); + get_blend_func(target_color_blend->get_operand_a())); _d3d_device->SetRenderState(D3DRS_DESTBLEND, - get_blend_func(color_blend->get_operand_b())); + get_blend_func(target_color_blend->get_operand_b())); return; } @@ -3161,8 +3213,9 @@ free_nondx_resources() { void DXGraphicsStateGuardian8:: free_d3d_device() { // dont want a full reset of gsg, just a state clear - _state_rs = 0; - _state.clear_to_zero(); + _state_rs = RenderState::make_empty(); + _state_mask.clear(); + // want gsg to pass all state settings through _dx_is_ready = false; @@ -4207,8 +4260,7 @@ void dx_stencil_function (StencilRenderStates::StencilRenderState stencil_render render_state_value = stencil_render_states -> get_stencil_render_state (stencil_render_state); - // DEBUG - if (false) { + if (dxgsg8_cat.is_debug()) { dxgsg8_cat.debug() << "SRS: " << StencilAttrib::stencil_render_state_name_array [stencil_render_state] << ", " << render_state_value << "\n"; } @@ -4283,15 +4335,12 @@ void dx_set_stencil_functions (StencilRenderStates *stencil_render_states) { void DXGraphicsStateGuardian8:: do_issue_stencil() { - const StencilAttrib *stencil; StencilRenderStates *stencil_render_states; - - stencil = _target._stencil; + const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib_def(StencilAttrib::get_class_slot())); stencil_render_states = this -> _stencil_render_states; if (stencil && stencil_render_states) { - // DEBUG - if (false) { + if (dxgsg8_cat.is_debug()) { dxgsg8_cat.debug() << "STENCIL STATE CHANGE\n"; dxgsg8_cat.debug() << "\n" << "SRS_front_enable " << stencil -> get_render_state (StencilAttrib::SRS_front_enable) << "\n" @@ -4318,8 +4367,7 @@ do_issue_stencil() { } else { - // DEBUG - if (false) { + if (dxgsg8_cat.is_debug()) { dxgsg8_cat.debug() << "STENCIL STATE CHANGE TO OFF \n"; } @@ -4339,7 +4387,8 @@ get_d3d_device() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: do_issue_scissor() { - const LVecBase4f &frame = _target._scissor->get_frame(); + const ScissorAttrib *target_scissor = DCAST(ScissorAttrib, _target_rs->get_attrib_def(ScissorAttrib::get_class_slot())); + const LVecBase4f &frame = target_scissor->get_frame(); set_scissor(frame[0], frame[1], frame[2], frame[3]); } diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index a5f15d9df7..8fb3224a0f 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -26,6 +26,7 @@ #include "depthTestAttrib.h" #include "cullFaceAttrib.h" #include "renderModeAttrib.h" +#include "colorBlendAttrib.h" #include "fog.h" #include "pointerToArray.h" diff --git a/panda/src/dxgsg9/dxGeomMunger9.I b/panda/src/dxgsg9/dxGeomMunger9.I index 17b460611e..f8da07223a 100755 --- a/panda/src/dxgsg9/dxGeomMunger9.I +++ b/panda/src/dxgsg9/dxGeomMunger9.I @@ -21,8 +21,8 @@ INLINE DXGeomMunger9:: DXGeomMunger9(GraphicsStateGuardian *gsg, const RenderState *state) : StandardMunger(gsg, state, 1, NT_packed_dabc, C_color), - _texture(state->get_texture()), - _tex_gen(state->get_tex_gen()) + _texture(DCAST(TextureAttrib, state->get_attrib(TextureAttrib::get_class_slot()))), + _tex_gen(DCAST(TexGenAttrib, state->get_attrib(TexGenAttrib::get_class_slot()))) { _filtered_texture = (TextureAttrib *)NULL; _reffed_filtered_texture = false; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 4e79d26adf..81ae5368b4 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -39,6 +39,9 @@ #include "rescaleNormalAttrib.h" #include "fogAttrib.h" #include "depthOffsetAttrib.h" +#include "lightAttrib.h" +#include "stencilAttrib.h" +#include "scissorAttrib.h" #include "fog.h" #include "throw_event.h" #include "geomVertexFormat.h" @@ -1471,7 +1474,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector); + //PStatTimer timer(_draw_primitive_pcollector); _vertices_tri_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_tri_pcollector.add_level(1); @@ -1546,7 +1549,7 @@ draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector); + //PStatTimer timer(_draw_primitive_pcollector); if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) { // One long triangle strip, connected by the degenerate vertices @@ -1731,7 +1734,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector); + //PStatTimer timer(_draw_primitive_pcollector); CPTA_int ends = reader->get_ends(); _primitive_batches_trifan_pcollector.add_level(ends.size()); @@ -1843,7 +1846,7 @@ draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: draw_lines(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector); + //PStatTimer timer(_draw_primitive_pcollector); _vertices_other_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_other_pcollector.add_level(1); @@ -1924,7 +1927,7 @@ draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian9:: draw_points(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector); + //PStatTimer timer(_draw_primitive_pcollector); _vertices_other_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_other_pcollector.add_level(1); @@ -2878,17 +2881,17 @@ do_issue_transform() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: do_issue_alpha_test() { - if (_target._shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) { + if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) { set_render_state(D3DRS_ALPHATESTENABLE, FALSE); } else { - const AlphaTestAttrib *attrib = _target._alpha_test; - AlphaTestAttrib::PandaCompareFunc mode = attrib->get_mode(); + const AlphaTestAttrib *target_alpha_test = DCAST(AlphaTestAttrib, _target_rs->get_attrib_def(AlphaTestAttrib::get_class_slot())); + AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->get_mode(); if (mode == AlphaTestAttrib::M_none) { set_render_state(D3DRS_ALPHATESTENABLE, FALSE); } else { // AlphaTestAttrib::PandaCompareFunc === D3DCMPFUNC set_render_state(D3DRS_ALPHAFUNC, (D3DCMPFUNC)mode); - set_render_state(D3DRS_ALPHAREF, (UINT) (attrib->get_reference_alpha()*255.0f)); //d3d uses 0x0-0xFF, not a float + set_render_state(D3DRS_ALPHAREF, (UINT) (target_alpha_test->get_reference_alpha()*255.0f)); //d3d uses 0x0-0xFF, not a float set_render_state(D3DRS_ALPHATESTENABLE, TRUE); } } @@ -2904,8 +2907,8 @@ do_issue_shader() { CLP(ShaderContext) *context = 0; Shader *shader = 0; - if (_target._shader) { - shader = (Shader *)(_target._shader->get_shader()); + if (_target_shader) { + shader = (Shader *)(_target_shader->get_shader()); } if (shader) { context = (CLP(ShaderContext) *)(shader->prepare_now(get_prepared_objects(), this)); @@ -2948,8 +2951,8 @@ do_issue_shader() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: do_issue_render_mode() { - const RenderModeAttrib *attrib = _target._render_mode; - RenderModeAttrib::Mode mode = attrib->get_mode(); + const RenderModeAttrib *target_render_mode = DCAST(RenderModeAttrib, _target_rs->get_attrib_def(RenderModeAttrib::get_class_slot())); + RenderModeAttrib::Mode mode = target_render_mode->get_mode(); switch (mode) { case RenderModeAttrib::M_unchanged: @@ -2972,10 +2975,10 @@ do_issue_render_mode() { } // This might also specify the point size. - float point_size = attrib->get_thickness(); + float point_size = target_render_mode->get_thickness(); set_render_state(D3DRS_POINTSIZE, *((DWORD*)&point_size)); - if (attrib->get_perspective()) { + if (target_render_mode->get_perspective()) { set_render_state(D3DRS_POINTSCALEENABLE, TRUE); LVector3f height(0.0f, point_size, 1.0f); @@ -3002,8 +3005,8 @@ do_issue_render_mode() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: do_issue_rescale_normal() { - const RescaleNormalAttrib *attrib = _target._rescale_normal; - RescaleNormalAttrib::Mode mode = attrib->get_mode(); + const RescaleNormalAttrib *target_rescale_normal = DCAST(RescaleNormalAttrib, _target_rs->get_attrib_def(RescaleNormalAttrib::get_class_slot())); + RescaleNormalAttrib::Mode mode = target_rescale_normal->get_mode(); _auto_rescale_normal = false; @@ -3035,8 +3038,8 @@ do_issue_rescale_normal() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: do_issue_depth_test() { - const DepthTestAttrib *attrib = _target._depth_test; - DepthTestAttrib::PandaCompareFunc mode = attrib->get_mode(); + const DepthTestAttrib *target_depth_test = DCAST(DepthTestAttrib, _target_rs->get_attrib_def(DepthTestAttrib::get_class_slot())); + DepthTestAttrib::PandaCompareFunc mode = target_depth_test->get_mode(); if (mode == DepthTestAttrib::M_none) { set_render_state(D3DRS_ZENABLE, D3DZB_FALSE); } else { @@ -3052,8 +3055,9 @@ do_issue_depth_test() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: do_issue_depth_write() { - const DepthWriteAttrib *attrib = _target._depth_write; - if (attrib->get_mode() == DepthWriteAttrib::M_on) { + const DepthWriteAttrib *target_depth_write = DCAST(DepthWriteAttrib, _target_rs->get_attrib_def(DepthWriteAttrib::get_class_slot())); + DepthWriteAttrib::Mode mode = target_depth_write->get_mode(); + if (mode == DepthWriteAttrib::M_on) { set_render_state(D3DRS_ZWRITEENABLE, TRUE); } else { set_render_state(D3DRS_ZWRITEENABLE, FALSE); @@ -3067,8 +3071,8 @@ do_issue_depth_write() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: do_issue_cull_face() { - const CullFaceAttrib *attrib = _target._cull_face; - _cull_face_mode = attrib->get_effective_mode(); + const CullFaceAttrib *target_cull_face = DCAST(CullFaceAttrib, _target_rs->get_attrib_def(CullFaceAttrib::get_class_slot())); + _cull_face_mode = target_cull_face->get_effective_mode(); switch (_cull_face_mode) { case CullFaceAttrib::M_cull_none: @@ -3103,10 +3107,10 @@ do_issue_cull_face() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: do_issue_fog() { - const FogAttrib *attrib = _target._fog; - if (!attrib->is_off()) { + const FogAttrib *target_fog = DCAST(FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot())); + if (!target_fog->is_off()) { set_render_state(D3DRS_FOGENABLE, TRUE); - Fog *fog = attrib->get_fog(); + Fog *fog = target_fog->get_fog(); nassertv(fog != (Fog *)NULL); apply_fog(fog); } else { @@ -3121,8 +3125,8 @@ do_issue_fog() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: do_issue_depth_offset() { - const DepthOffsetAttrib *attrib = _target._depth_offset; - int offset = attrib->get_offset(); + const DepthOffsetAttrib *target_depth_offset = DCAST(DepthOffsetAttrib, _target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot())); + int offset = target_depth_offset->get_offset(); if (_supports_depth_bias) { set_render_state(D3DRS_DEPTHBIAS, offset); @@ -3146,8 +3150,8 @@ do_issue_depth_offset() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: do_issue_shade_model() { - const ShadeModelAttrib *attrib = _target._shade_model; - switch (attrib->get_mode()) { + const ShadeModelAttrib *target_shade_model = DCAST(ShadeModelAttrib, _target_rs->get_attrib_def(ShadeModelAttrib::get_class_slot())); + switch (target_shade_model->get_mode()) { case ShadeModelAttrib::M_smooth: set_render_state(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); break; @@ -3185,8 +3189,10 @@ set_state_and_transform(const RenderState *target, } #endif _state_pcollector.add_level(1); + PStatTimer timer1(_draw_set_state_pcollector); if (transform != _internal_transform) { + //PStatTimer timer(_draw_set_state_transform_pcollector); _state_pcollector.add_level(1); _internal_transform = transform; do_issue_transform(); @@ -3196,133 +3202,184 @@ set_state_and_transform(const RenderState *target, return; } _target_rs = target; - _target.clear_to_defaults(); - target->store_into_slots(&_target); - _state_rs = 0; - if (_target._shader && (_target._shader->auto_shader())) { - _target._shader = _target_rs->get_generated_shader(); + _target_shader = DCAST(ShaderAttrib, _target_rs->get_attrib_def(ShaderAttrib::get_class_slot())); + if (_target_shader->auto_shader()) { + _target_shader = _target_rs->get_generated_shader(); } - - if ((_target._alpha_test != _state._alpha_test)|| - (_target._shader->get_flag(ShaderAttrib::F_subsume_alpha_test) != - _state._shader->get_flag(ShaderAttrib::F_subsume_alpha_test))) { + + int alpha_test_slot = AlphaTestAttrib::get_class_slot(); + if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) || + !_state_mask.get_bit(alpha_test_slot)) { + //PStatTimer timer(_draw_set_state_alpha_test_pcollector); do_issue_alpha_test(); - _state._alpha_test = _target._alpha_test; + _state_mask.set_bit(alpha_test_slot); } - if (_target._antialias != _state._antialias) { - // Antialias not implemented under DX8 - _state._antialias = _target._antialias; - } - - if (_target._clip_plane != _state._clip_plane) { + int clip_plane_slot = ClipPlaneAttrib::get_class_slot(); + if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) || + !_state_mask.get_bit(clip_plane_slot)) { + //PStatTimer timer(_draw_set_state_clip_plane_pcollector); do_issue_clip_plane(); - _state._clip_plane = _target._clip_plane; + _state_mask.set_bit(clip_plane_slot); } - if (_target._color != _state._color || - _target._color_scale != _state._color_scale) { + int color_slot = ColorAttrib::get_class_slot(); + int color_scale_slot = ColorScaleAttrib::get_class_slot(); + if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) || + _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) || + !_state_mask.get_bit(color_slot) || + !_state_mask.get_bit(color_scale_slot)) { + //PStatTimer timer(_draw_set_state_color_pcollector); do_issue_color(); do_issue_color_scale(); - _state._color = _target._color; - _state._color_scale = _target._color_scale; - if (_current_shader_context) { - _current_shader_context->issue_parameters(this, Shader::SSD_color); - } + _state_mask.set_bit(color_slot); + _state_mask.set_bit(color_scale_slot); } - if (_target._cull_face != _state._cull_face) { + int cull_face_slot = CullFaceAttrib::get_class_slot(); + if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) || + !_state_mask.get_bit(cull_face_slot)) { + //PStatTimer timer(_draw_set_state_cull_face_pcollector); do_issue_cull_face(); - _state._cull_face = _target._cull_face; + _state_mask.set_bit(cull_face_slot); } - if (_target._depth_offset != _state._depth_offset) { + int depth_offset_slot = DepthOffsetAttrib::get_class_slot(); + if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) || + !_state_mask.get_bit(depth_offset_slot)) { + //PStatTimer timer(_draw_set_state_depth_offset_pcollector); do_issue_depth_offset(); - _state._depth_offset = _target._depth_offset; + _state_mask.set_bit(depth_offset_slot); } - if (_target._depth_test != _state._depth_test) { + int depth_test_slot = DepthTestAttrib::get_class_slot(); + if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) || + !_state_mask.get_bit(depth_test_slot)) { + //PStatTimer timer(_draw_set_state_depth_test_pcollector); do_issue_depth_test(); - _state._depth_test = _target._depth_test; + _state_mask.set_bit(depth_test_slot); } - if (_target._depth_write != _state._depth_write) { + int depth_write_slot = DepthWriteAttrib::get_class_slot(); + if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) || + !_state_mask.get_bit(depth_write_slot)) { + //PStatTimer timer(_draw_set_state_depth_write_pcollector); do_issue_depth_write(); - _state._depth_write = _target._depth_write; + _state_mask.set_bit(depth_write_slot); } - if (_target._fog != _state._fog) { - do_issue_fog(); - _state._fog = _target._fog; - } - - if (_target._render_mode != _state._render_mode) { + int render_mode_slot = RenderModeAttrib::get_class_slot(); + if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) || + !_state_mask.get_bit(render_mode_slot)) { + //PStatTimer timer(_draw_set_state_render_mode_pcollector); do_issue_render_mode(); - _state._render_mode = _target._render_mode; + _state_mask.set_bit(render_mode_slot); } - if (_target._rescale_normal != _state._rescale_normal) { + int rescale_normal_slot = RescaleNormalAttrib::get_class_slot(); + if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) || + !_state_mask.get_bit(rescale_normal_slot)) { + //PStatTimer timer(_draw_set_state_rescale_normal_pcollector); do_issue_rescale_normal(); - _state._rescale_normal = _target._rescale_normal; + _state_mask.set_bit(rescale_normal_slot); } - if (_target._shade_model != _state._shade_model) { + int shade_model_slot = ShadeModelAttrib::get_class_slot(); + if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) || + !_state_mask.get_bit(shade_model_slot)) { + //PStatTimer timer(_draw_set_state_shade_model_pcollector); do_issue_shade_model(); - _state._shade_model = _target._shade_model; + _state_mask.set_bit(shade_model_slot); } - if ((_target._transparency != _state._transparency)|| - (_target._color_write != _state._color_write)|| - (_target._color_blend != _state._color_blend)|| - (_target._shader->get_flag(ShaderAttrib::F_disable_alpha_write) != - _state._shader->get_flag(ShaderAttrib::F_disable_alpha_write))) { + int transparency_slot = TransparencyAttrib::get_class_slot(); + int color_write_slot = ColorWriteAttrib::get_class_slot(); + int color_blend_slot = ColorBlendAttrib::get_class_slot(); + if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) || + _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) || + _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) || + !_state_mask.get_bit(transparency_slot) || + !_state_mask.get_bit(color_write_slot) || + !_state_mask.get_bit(color_blend_slot) || + (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) != + _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))) { + //PStatTimer timer(_draw_set_state_blending_pcollector); do_issue_blending(); - _state._transparency = _target._transparency; - _state._color_write = _target._color_write; - _state._color_blend = _target._color_blend; + _state_mask.set_bit(transparency_slot); + _state_mask.set_bit(color_write_slot); + _state_mask.set_bit(color_blend_slot); } - if (_target._shader != _state._shader) { + if (_target_shader != _state_shader) { + //PStatTimer timer(_draw_set_state_shader_pcollector); do_issue_shader(); - _state._shader = _target._shader; - _state._texture = 0; + _state_shader = _target_shader; + _state_mask.clear_bit(TextureAttrib::get_class_slot()); } - if (_target._tex_matrix != _state._tex_matrix) { - _state._texture = 0; - _state._tex_matrix = _target._tex_matrix; - } - - if (_target._texture != _state._texture || - _target._tex_gen != _state._tex_gen) { - determine_effective_texture(); + int texture_slot = TextureAttrib::get_class_slot(); + int tex_matrix_slot = TexMatrixAttrib::get_class_slot(); + int tex_gen_slot = TexGenAttrib::get_class_slot(); + if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) || + _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) || + _target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) || + !_state_mask.get_bit(texture_slot) || + !_state_mask.get_bit(tex_matrix_slot) || + !_state_mask.get_bit(tex_gen_slot)) { + //PStatTimer timer(_draw_set_state_texture_pcollector); + determine_target_texture(); do_issue_texture(); - _state._texture = _target._texture; - _state._tex_gen = _target._tex_gen; + + _state_texture = _target_texture; + _state_mask.set_bit(texture_slot); + _state_mask.set_bit(tex_matrix_slot); + _state_mask.set_bit(tex_gen_slot); } - if (_target._material != _state._material) { + int material_slot = MaterialAttrib::get_class_slot(); + if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) || + !_state_mask.get_bit(material_slot)) { + //PStatTimer timer(_draw_set_state_material_pcollector); do_issue_material(); - _state._material = _target._material; + _state_mask.set_bit(material_slot); if (_current_shader_context) { _current_shader_context->issue_parameters(this, Shader::SSD_material); } } - if (_target._light != _state._light) { + int light_slot = LightAttrib::get_class_slot(); + if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) || + !_state_mask.get_bit(light_slot)) { + //PStatTimer timer(_draw_set_state_light_pcollector); do_issue_light(); - _state._light = _target._light; + _state_mask.set_bit(light_slot); } - if (_target._stencil != _state._stencil) { + int stencil_slot = StencilAttrib::get_class_slot(); + if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) || + !_state_mask.get_bit(stencil_slot)) { + //PStatTimer timer(_draw_set_state_stencil_pcollector); do_issue_stencil(); - _state._stencil = _target._stencil; + _state_mask.set_bit(stencil_slot); + } + + if (_current_shader_context == 0) { + int fog_slot = FogAttrib::get_class_slot(); + if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) || + !_state_mask.get_bit(fog_slot)) { + //PStatTimer timer(_draw_set_state_fog_pcollector); + do_issue_fog(); + _state_mask.set_bit(fog_slot); + } } - if (_target._scissor != _state._scissor) { + int scissor_slot = ScissorAttrib::get_class_slot(); + if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) || + !_state_mask.get_bit(scissor_slot)) { + //PStatTimer timer(_draw_set_state_scissor_pcollector); do_issue_scissor(); - _state._scissor = _target._scissor; + _state_mask.set_bit(scissor_slot); } _state_rs = _target_rs; @@ -3385,7 +3442,7 @@ bind_light(PointLight *light_obj, const NodePath &light, int light_id) { void DXGraphicsStateGuardian9:: bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) { static PStatCollector _draw_set_state_light_bind_directional_pcollector("Draw:Set State:Light:Bind:Directional"); - PStatTimer timer(_draw_set_state_light_bind_directional_pcollector); + //PStatTimer timer(_draw_set_state_light_bind_directional_pcollector); pair lookup = _dlights.insert(DirectionalLights::value_type(light, D3DLIGHT9())); D3DLIGHT9 &fdata = (*lookup.first).second; @@ -3517,11 +3574,11 @@ void DXGraphicsStateGuardian9:: do_issue_material() { static Material empty; const Material *material; - if (_target._material == (MaterialAttrib *)NULL || - _target._material->is_off()) { + const MaterialAttrib *target_material = DCAST(MaterialAttrib, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot())); + if (target_material->is_off()) { material = ∅ } else { - material = _target._material->get_material(); + material = target_material->get_material(); } D3DMATERIAL9 cur_material; @@ -3634,10 +3691,10 @@ void DXGraphicsStateGuardian9:: update_standard_texture_bindings() { DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1)); - int num_stages = _effective_texture->get_num_on_ff_stages(); + int num_stages = _target_texture->get_num_on_ff_stages(); int num_old_stages = _max_texture_stages; - if (_state._texture != (TextureAttrib *)NULL) { - num_old_stages = _state._texture->get_num_on_ff_stages(); + if (_state_texture != (TextureAttrib *)NULL) { + num_old_stages = _state_texture->get_num_on_ff_stages(); } nassertv(num_stages <= _max_texture_stages && @@ -3651,10 +3708,10 @@ update_standard_texture_bindings() { int si; for (si = 0; si < num_stages; si++) { - TextureStage *stage = _effective_texture->get_on_ff_stage(si); - int texcoord_index = _effective_texture->get_ff_tc_index(si); + TextureStage *stage = _target_texture->get_on_ff_stage(si); + int texcoord_index = _target_texture->get_ff_tc_index(si); - Texture *texture = _effective_texture->get_on_texture(stage); + Texture *texture = _target_texture->get_on_texture(stage); nassertv(texture != (Texture *)NULL); // We always reissue every stage in DX, just in case the texcoord @@ -3666,12 +3723,13 @@ update_standard_texture_bindings() { int texcoord_dimensions = 2; CPT(TransformState) tex_mat = TransformState::make_identity(); - if (_state._tex_matrix->has_stage(stage)) { - tex_mat = _state._tex_matrix->get_transform(stage); + const TexMatrixAttrib *target_tex_matrix = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot())); + if (target_tex_matrix->has_stage(stage)) { + tex_mat = target_tex_matrix->get_transform(stage); } // Issue the texgen mode. - TexGenAttrib::Mode mode = _effective_tex_gen->get_mode(stage); + TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage); bool any_point_sprite = false; switch (mode) { @@ -3780,7 +3838,7 @@ update_standard_texture_bindings() { texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION); texcoord_dimensions = 3; - const TexCoord3f &v = _effective_tex_gen->get_constant_value(stage); + const TexCoord3f &v = _target_tex_gen->get_constant_value(stage); CPT(TransformState) squash = TransformState::make_pos_hpr_scale(v, LVecBase3f::zero(), LVecBase3f::zero()); @@ -3849,36 +3907,34 @@ do_issue_blending() { // all the other blending-related stuff doesn't matter. If the // device doesn't support color-write, we use blending tricks // to effectively disable color write. + const ColorWriteAttrib *target_color_write = DCAST(ColorWriteAttrib, _target_rs->get_attrib_def(ColorWriteAttrib::get_class_slot())); unsigned int color_channels = - _target._color_write->get_channels() & _color_write_mask; - if (_target._shader->get_flag(ShaderAttrib::F_disable_alpha_write)) { + target_color_write->get_channels() & _color_write_mask; + if (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write)) { color_channels &= ~(ColorWriteAttrib::C_alpha); } if (color_channels == ColorWriteAttrib::C_off) { - if (_target._color_write != _state._color_write) { - if (_screen->_can_direct_disable_color_writes) { - set_render_state(D3DRS_ALPHABLENDENABLE, FALSE); - set_render_state(D3DRS_COLORWRITEENABLE, (DWORD)0x0); - } else { - set_render_state(D3DRS_ALPHABLENDENABLE, TRUE); - set_render_state(D3DRS_SRCBLEND, D3DBLEND_ZERO); - set_render_state(D3DRS_DESTBLEND, D3DBLEND_ONE); - } + if (_screen->_can_direct_disable_color_writes) { + set_render_state(D3DRS_ALPHABLENDENABLE, FALSE); + set_render_state(D3DRS_COLORWRITEENABLE, (DWORD)0x0); + } else { + set_render_state(D3DRS_ALPHABLENDENABLE, TRUE); + set_render_state(D3DRS_SRCBLEND, D3DBLEND_ZERO); + set_render_state(D3DRS_DESTBLEND, D3DBLEND_ONE); } return; } else { - if ((_target._color_write != _state._color_write)|| - (_target._shader->get_flag(ShaderAttrib::F_disable_alpha_write) != - _state._shader->get_flag(ShaderAttrib::F_disable_alpha_write))) { - if (_screen->_can_direct_disable_color_writes) { - set_render_state(D3DRS_COLORWRITEENABLE, color_channels); - } + if (_screen->_can_direct_disable_color_writes) { + set_render_state(D3DRS_COLORWRITEENABLE, color_channels); } } - CPT(ColorBlendAttrib) color_blend = _target._color_blend; - ColorBlendAttrib::Mode color_blend_mode = _target._color_blend->get_mode(); - TransparencyAttrib::Mode transparency_mode = _target._transparency->get_mode(); + const ColorBlendAttrib *target_color_blend = DCAST(ColorBlendAttrib, _target_rs->get_attrib_def(ColorBlendAttrib::get_class_slot())); + CPT(ColorBlendAttrib) color_blend = target_color_blend; + ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode(); + + const TransparencyAttrib *target_transparency = DCAST(TransparencyAttrib, _target_rs->get_attrib_def(TransparencyAttrib::get_class_slot())); + TransparencyAttrib::Mode transparency_mode = target_transparency->get_mode(); // Is there a color blend set? if (color_blend_mode != ColorBlendAttrib::M_none) { @@ -4085,8 +4141,9 @@ free_nondx_resources() { void DXGraphicsStateGuardian9:: free_d3d_device() { // dont want a full reset of gsg, just a state clear - _state_rs = 0; - _state.clear_to_zero(); + _state_rs = RenderState::make_empty(); + _state_mask.clear(); + // want gsg to pass all state settings through _dx_is_ready = false; @@ -5286,10 +5343,8 @@ void dx_set_stencil_functions (StencilRenderStates *stencil_render_states) { void DXGraphicsStateGuardian9:: do_issue_stencil() { - const StencilAttrib *stencil; StencilRenderStates *stencil_render_states; - - stencil = _target._stencil; + const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib_def(StencilAttrib::get_class_slot())); stencil_render_states = this -> _stencil_render_states; if (stencil && stencil_render_states) { @@ -5362,7 +5417,8 @@ do_issue_stencil() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: do_issue_scissor() { - const LVecBase4f &frame = _target._scissor->get_frame(); + const ScissorAttrib *target_scissor = DCAST(ScissorAttrib, _target_rs->get_attrib_def(ScissorAttrib::get_class_slot())); + const LVecBase4f &frame = target_scissor->get_frame(); RECT r; r.left = _current_viewport.X + _current_viewport.Width * frame[0]; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index f344e749ea..b12c586d3a 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -26,6 +26,7 @@ #include "depthTestAttrib.h" #include "cullFaceAttrib.h" #include "renderModeAttrib.h" +#include "colorBlendAttrib.h" #include "fog.h" #include "pointerToArray.h" diff --git a/panda/src/dxgsg9/dxShaderContext9.cxx b/panda/src/dxgsg9/dxShaderContext9.cxx index d24eed4092..55c6dfa1ff 100644 --- a/panda/src/dxgsg9/dxShaderContext9.cxx +++ b/panda/src/dxgsg9/dxShaderContext9.cxx @@ -469,8 +469,8 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg) } InternalName *name = _shader->_var_spec[i]._name; int texslot = _shader->_var_spec[i]._append_uv; - if (texslot >= 0 && texslot < gsg->_state._texture->get_num_on_stages()) { - TextureStage *stage = gsg->_state._texture->get_on_stage(texslot); + if (texslot >= 0 && texslot < gsg->_state_texture->get_num_on_stages()) { + TextureStage *stage = gsg->_state_texture->get_on_stage(texslot); InternalName *texname = stage->get_texcoord_name(); if (name == InternalName::get_texcoord()) { name = texname; @@ -697,14 +697,14 @@ update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg) Texture *tex = 0; InternalName *id = _shader->_tex_spec[i]._name; if (id != 0) { - const ShaderInput *input = gsg->_target._shader->get_shader_input(id); + const ShaderInput *input = gsg->_target_shader->get_shader_input(id); tex = input->get_texture(); } else { - if (_shader->_tex_spec[i]._stage >= gsg->_target._texture->get_num_on_stages()) { + if (_shader->_tex_spec[i]._stage >= gsg->_target_texture->get_num_on_stages()) { continue; } - TextureStage *stage = gsg->_target._texture->get_on_stage(_shader->_tex_spec[i]._stage); - tex = gsg->_target._texture->get_on_texture(stage); + TextureStage *stage = gsg->_target_texture->get_on_stage(_shader->_tex_spec[i]._stage); + tex = gsg->_target_texture->get_on_texture(stage); } if (_shader->_tex_spec[i]._suffix != 0) { // The suffix feature is inefficient. It is a temporary hack. diff --git a/panda/src/glstuff/glGeomMunger_src.cxx b/panda/src/glstuff/glGeomMunger_src.cxx index 1f39e5846e..cb93bccf2d 100644 --- a/panda/src/glstuff/glGeomMunger_src.cxx +++ b/panda/src/glstuff/glGeomMunger_src.cxx @@ -26,8 +26,8 @@ ALLOC_DELETED_CHAIN_DEF(CLP(GeomMunger)); CLP(GeomMunger):: CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state) : StandardMunger(gsg, state, 4, NT_uint8, C_color), - _texture(state->get_texture()), - _tex_gen(state->get_tex_gen()) + _texture(DCAST(TextureAttrib, state->get_attrib(TextureAttrib::get_class_slot()))), + _tex_gen(DCAST(TexGenAttrib, state->get_attrib(TexGenAttrib::get_class_slot()))) { // Set a callback to unregister ourselves when either the Texture or // the TexGen object gets deleted. diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 3b9f49007e..a88835e796 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -523,7 +523,7 @@ generate_mipmaps() { for (int slot=0; slotuses_mipmaps())) { - glgsg->_state._texture = 0; + glgsg->_state_texture = 0; TextureContext *tc = tex->prepare_now(glgsg->get_prepared_objects(), glgsg); nassertv(tc != (TextureContext *)NULL); CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.I b/panda/src/glstuff/glGraphicsStateGuardian_src.I index 2d4728bb62..fa5c3c2d88 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.I +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.I @@ -245,7 +245,7 @@ enable_multisample_alpha_mask(bool val) { INLINE void CLP(GraphicsStateGuardian):: enable_line_smooth(bool val) { if (_line_smooth_enabled != val) { - _state._transparency = 0; + _state_mask.clear_bit(TransparencyAttrib::get_class_slot()); _line_smooth_enabled = val; if (val) { GLP(Enable)(GL_LINE_SMOOTH); @@ -263,7 +263,7 @@ enable_line_smooth(bool val) { INLINE void CLP(GraphicsStateGuardian):: enable_point_smooth(bool val) { if (_point_smooth_enabled != val) { - _state._transparency = 0; + _state_mask.clear_bit(TransparencyAttrib::get_class_slot()); _point_smooth_enabled = val; if (val) { GLP(Enable)(GL_POINT_SMOOTH); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index ec460f3b05..9a34db70fd 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -31,7 +31,6 @@ #include "pointLight.h" #include "spotlight.h" #include "planeNode.h" -#include "attribSlots.h" #include "fog.h" #include "clockObject.h" #include "string_utils.h" @@ -48,6 +47,18 @@ #include "load_prc_file.h" #include "bamCache.h" #include "bamCacheRecord.h" +#include "colorWriteAttrib.h" +#include "depthWriteAttrib.h" +#include "shadeModelAttrib.h" +#include "rescaleNormalAttrib.h" +#include "alphaTestAttrib.h" +#include "cullFaceAttrib.h" +#include "fogAttrib.h" +#include "depthOffsetAttrib.h" +#include "materialAttrib.h" +#include "stencilAttrib.h" +#include "lightAttrib.h" +#include "scissorAttrib.h" #ifdef HAVE_CG #include "Cg/cgGL.h" @@ -1400,16 +1411,20 @@ clear(DrawableRegion *clearable) { GLP(Clear)(GL_COLOR_BUFFER_BIT); } } - + if (clearable->get_clear_color_active()) { Colorf v = clearable->get_clear_color(); GLP(ClearColor)(v[0],v[1],v[2],v[3]); + GLP(ColorMask)(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + _state_mask.clear_bit(ColorWriteAttrib::get_class_slot()); mask |= GL_COLOR_BUFFER_BIT; set_draw_buffer(clearable->get_draw_buffer_type()); } if (clearable->get_clear_depth_active()) { GLP(ClearDepth)(clearable->get_clear_depth()); + GLP(DepthMask)(GL_TRUE); + _state_mask.clear_bit(DepthWriteAttrib::get_class_slot()); mask |= GL_DEPTH_BUFFER_BIT; } @@ -1426,7 +1441,7 @@ clear(DrawableRegion *clearable) { // change the draw buffer. In time, I think there will need // to be a draw buffer attrib. Until then, this little hack // to put things back the way they were after - // prepare_display_region will bdo. + // prepare_display_region will do. set_draw_buffer(_draw_buffer_type); @@ -1754,13 +1769,17 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, case GeomPrimitive::PT_none: break; } - if ((_target._transparency != _state._transparency)|| - (_target._color_write != _state._color_write)|| - (_target._color_blend != _state._color_blend)) { + + int transparency_slot = TransparencyAttrib::get_class_slot(); + int color_write_slot = ColorWriteAttrib::get_class_slot(); + int color_blend_slot = ColorBlendAttrib::get_class_slot(); + if (!_state_mask.get_bit(transparency_slot) || + !_state_mask.get_bit(color_write_slot) || + !_state_mask.get_bit(color_blend_slot)) { do_issue_blending(); - _state._transparency = _target._transparency; - _state._color_write = _target._color_write; - _state._color_blend = _target._color_blend; + _state_mask.set_bit(transparency_slot); + _state_mask.set_bit(color_write_slot); + _state_mask.set_bit(color_blend_slot); } } @@ -2011,11 +2030,11 @@ update_standard_vertex_arrays(bool force) { // Now set up each of the active texture coordinate stages--or at // least those for which we're not generating texture coordinates // automatically. - int max_stage_index = _effective_texture->get_num_on_ff_stages(); + int max_stage_index = _target_texture->get_num_on_ff_stages(); int stage_index = 0; while (stage_index < max_stage_index) { - TextureStage *stage = _effective_texture->get_on_ff_stage(stage_index); - if (!_effective_tex_gen->has_gen_texcoord_stage(stage)) { + TextureStage *stage = _target_texture->get_on_ff_stage(stage_index); + if (!_target_tex_gen->has_gen_texcoord_stage(stage)) { // This stage is not one of the stages that doesn't need // texcoords issued for it. const InternalName *name = stage->get_texcoord_name(); @@ -2107,12 +2126,12 @@ update_standard_vertex_arrays(bool force) { // Now set up each of the active texture coordinate stages--or at // least those for which we're not generating texture coordinates // automatically. - int max_stage_index = _effective_texture->get_num_on_ff_stages(); + int max_stage_index = _target_texture->get_num_on_ff_stages(); int stage_index = 0; while (stage_index < max_stage_index) { _glClientActiveTexture(GL_TEXTURE0 + stage_index); - TextureStage *stage = _effective_texture->get_on_ff_stage(stage_index); - if (!_effective_tex_gen->has_gen_texcoord_stage(stage)) { + TextureStage *stage = _target_texture->get_on_ff_stage(stage_index); + if (!_target_tex_gen->has_gen_texcoord_stage(stage)) { // This stage is not one of the stages that doesn't need // texcoords issued for it. const InternalName *name = stage->get_texcoord_name(); @@ -2250,7 +2269,7 @@ disable_standard_vertex_arrays() //////////////////////////////////////////////////////////////////// bool CLP(GraphicsStateGuardian):: draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); + //PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { @@ -2299,7 +2318,7 @@ draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool CLP(GraphicsStateGuardian):: draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); + //PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); report_my_gl_errors(); @@ -2390,7 +2409,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool CLP(GraphicsStateGuardian):: draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); + //PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { GLCAT.spam() << "draw_trifans: " << *(reader->get_object()) << "\n"; @@ -2451,7 +2470,7 @@ draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool CLP(GraphicsStateGuardian):: draw_lines(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); + //PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { GLCAT.spam() << "draw_lines: " << *(reader->get_object()) << "\n"; @@ -2507,7 +2526,7 @@ draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// bool CLP(GraphicsStateGuardian):: draw_points(const GeomPrimitivePipelineReader *reader, bool force) { - PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); + //PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { GLCAT.spam() << "draw_points: " << *(reader->get_object()) << "\n"; @@ -3366,8 +3385,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, report_my_gl_errors(); // Force reload of texture state, since we've just monkeyed with it. - _state_rs = 0; - _state._texture = 0; + _state_mask.clear_bit(TextureAttrib::get_class_slot()); return true; } @@ -3585,8 +3603,8 @@ do_issue_transform() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_shade_model() { - const ShadeModelAttrib *attrib = _target._shade_model; - switch (attrib->get_mode()) { + const ShadeModelAttrib *target_shade_model = DCAST(ShadeModelAttrib, _target_rs->get_attrib_def(ShadeModelAttrib::get_class_slot())); + switch (target_shade_model->get_mode()) { case ShadeModelAttrib::M_smooth: GLP(ShadeModel)(GL_SMOOTH); _flat_shade_model = false; @@ -3607,10 +3625,7 @@ do_issue_shade_model() { void CLP(GraphicsStateGuardian):: do_issue_shader() { CLP(ShaderContext) *context = 0; - Shader *shader = 0; - if (_target._shader) { - shader = (Shader *)(_target._shader->get_shader()); - } + Shader *shader = (Shader *)(_target_shader->get_shader()); if (shader) { context = (CLP(ShaderContext) *)(shader->prepare_now(get_prepared_objects(), this)); } @@ -3647,10 +3662,10 @@ do_issue_shader() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_render_mode() { - const RenderModeAttrib *attrib = _target._render_mode; - _render_mode = attrib->get_mode(); - _point_size = attrib->get_thickness(); - _point_perspective = attrib->get_perspective(); + const RenderModeAttrib *target_render_mode = DCAST(RenderModeAttrib, _target_rs->get_attrib_def(RenderModeAttrib::get_class_slot())); + _render_mode = target_render_mode->get_mode(); + _point_size = target_render_mode->get_thickness(); + _point_perspective = target_render_mode->get_perspective(); switch (_render_mode) { case RenderModeAttrib::M_unchanged: @@ -3687,8 +3702,8 @@ do_issue_render_mode() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_antialias() { - const AntialiasAttrib *attrib = _target._antialias; - if (attrib->get_mode_type() == AntialiasAttrib::M_auto) { + const AntialiasAttrib *target_antialias = DCAST(AntialiasAttrib, _target_rs->get_attrib_def(AntialiasAttrib::get_class_slot())); + if (target_antialias->get_mode_type() == AntialiasAttrib::M_auto) { // In this special mode, we must enable antialiasing on a // case-by-case basis, because we enable it differently for // polygons and for points and lines. @@ -3700,7 +3715,7 @@ do_issue_antialias() { // don't use the other bits at all (they will be ignored by GL // anyway). _auto_antialias_mode = false; - unsigned short mode = attrib->get_mode(); + unsigned short mode = target_antialias->get_mode(); if (_supports_multisample && (mode & AntialiasAttrib::M_multisample) != 0) { @@ -3714,7 +3729,7 @@ do_issue_antialias() { } } - switch (attrib->get_mode_quality()) { + switch (target_antialias->get_mode_quality()) { case AntialiasAttrib::M_faster: GLP(Hint)(GL_LINE_SMOOTH_HINT, GL_FASTEST); GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_FASTEST); @@ -3744,8 +3759,8 @@ do_issue_antialias() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_rescale_normal() { - const RescaleNormalAttrib *attrib = _target._rescale_normal; - RescaleNormalAttrib::Mode mode = attrib->get_mode(); + const RescaleNormalAttrib *target_rescale_normal = DCAST(RescaleNormalAttrib, _target_rs->get_attrib_def(RescaleNormalAttrib::get_class_slot())); + RescaleNormalAttrib::Mode mode = target_rescale_normal->get_mode(); _auto_rescale_normal = false; @@ -3795,8 +3810,8 @@ do_issue_rescale_normal() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_depth_test() { - const DepthTestAttrib *attrib = _target._depth_test; - DepthTestAttrib::PandaCompareFunc mode = attrib->get_mode(); + const DepthTestAttrib *target_depth_test = DCAST(DepthTestAttrib, _target_rs->get_attrib_def(DepthTestAttrib::get_class_slot())); + DepthTestAttrib::PandaCompareFunc mode = target_depth_test->get_mode(); if (mode == DepthTestAttrib::M_none) { enable_depth_test(false); } else { @@ -3813,16 +3828,16 @@ do_issue_depth_test() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_alpha_test() { - if (_target._shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) { + if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) { enable_alpha_test(false); } else { - const AlphaTestAttrib *attrib = _target._alpha_test; - AlphaTestAttrib::PandaCompareFunc mode = attrib->get_mode(); + const AlphaTestAttrib *target_alpha_test = DCAST(AlphaTestAttrib, _target_rs->get_attrib_def(AlphaTestAttrib::get_class_slot())); + AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->get_mode(); if (mode == AlphaTestAttrib::M_none) { enable_alpha_test(false); } else { - assert(GL_NEVER==(AlphaTestAttrib::M_never-1+0x200)); - GLP(AlphaFunc)(PANDA_TO_GL_COMPAREFUNC(mode), attrib->get_reference_alpha()); + nassertv(GL_NEVER == (AlphaTestAttrib::M_never-1+0x200)); + GLP(AlphaFunc)(PANDA_TO_GL_COMPAREFUNC(mode), target_alpha_test->get_reference_alpha()); enable_alpha_test(true); } } @@ -3835,8 +3850,8 @@ do_issue_alpha_test() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_depth_write() { - const DepthWriteAttrib *attrib = _target._depth_write; - DepthWriteAttrib::Mode mode = attrib->get_mode(); + const DepthWriteAttrib *target_depth_write = DCAST(DepthWriteAttrib, _target_rs->get_attrib_def(DepthWriteAttrib::get_class_slot())); + DepthWriteAttrib::Mode mode = target_depth_write->get_mode(); if (mode == DepthWriteAttrib::M_off) { GLP(DepthMask)(GL_FALSE); } else { @@ -3852,8 +3867,8 @@ do_issue_depth_write() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_cull_face() { - const CullFaceAttrib *attrib = _target._cull_face; - CullFaceAttrib::Mode mode = attrib->get_effective_mode(); + const CullFaceAttrib *target_cull_face = DCAST(CullFaceAttrib, _target_rs->get_attrib_def(CullFaceAttrib::get_class_slot())); + CullFaceAttrib::Mode mode = target_cull_face->get_effective_mode(); switch (mode) { case CullFaceAttrib::M_cull_none: @@ -3882,10 +3897,10 @@ do_issue_cull_face() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_fog() { - const FogAttrib *attrib = _target._fog; - if (!attrib->is_off()) { + const FogAttrib *target_fog = DCAST(FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot())); + if (!target_fog->is_off()) { enable_fog(true); - Fog *fog = attrib->get_fog(); + Fog *fog = target_fog->get_fog(); nassertv(fog != (Fog *)NULL); apply_fog(fog); } else { @@ -3901,8 +3916,8 @@ do_issue_fog() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_depth_offset() { - const DepthOffsetAttrib *attrib = _target._depth_offset; - int offset = attrib->get_offset(); + const DepthOffsetAttrib *target_depth_offset = DCAST(DepthOffsetAttrib, _target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot())); + int offset = target_depth_offset->get_offset(); if (offset != 0) { // The relationship between these two parameters is a little @@ -3926,11 +3941,14 @@ void CLP(GraphicsStateGuardian):: do_issue_material() { static Material empty; const Material *material; - if (_target._material == (MaterialAttrib *)NULL || - _target._material->is_off()) { + + const MaterialAttrib *target_material = DCAST(MaterialAttrib, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot())); + + if (target_material == (MaterialAttrib *)NULL || + target_material->is_off()) { material = ∅ } else { - material = _target._material->get_material(); + material = target_material->get_material(); } GLenum face = material->get_twoside() ? GL_FRONT_AND_BACK : GL_FRONT; @@ -3995,47 +4013,46 @@ do_issue_material() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_blending() { - // Handle the color_write attrib. If color_write is off, then // all the other blending-related stuff doesn't matter. If the // device doesn't support color-write, we use blending tricks // to effectively disable color write. + const ColorWriteAttrib *target_color_write = DCAST(ColorWriteAttrib, _target_rs->get_attrib_def(ColorWriteAttrib::get_class_slot())); + unsigned int color_channels = - _target._color_write->get_channels() & _color_write_mask; - if (_target._shader->get_flag(ShaderAttrib::F_disable_alpha_write)) { + target_color_write->get_channels() & _color_write_mask; + if (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write)) { color_channels &= ~(ColorWriteAttrib::C_alpha); } if (color_channels == ColorWriteAttrib::C_off) { - if (_target._color_write != _state._color_write) { - enable_multisample_alpha_one(false); - enable_multisample_alpha_mask(false); - if (CLP(color_mask)) { - enable_blend(false); - GLP(ColorMask)(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - } else { - enable_blend(true); - _glBlendEquation(GL_FUNC_ADD); - GLP(BlendFunc)(GL_ZERO, GL_ONE); - } + int color_write_slot = ColorWriteAttrib::get_class_slot(); + enable_multisample_alpha_one(false); + enable_multisample_alpha_mask(false); + if (CLP(color_mask)) { + enable_blend(false); + GLP(ColorMask)(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + } else { + enable_blend(true); + _glBlendEquation(GL_FUNC_ADD); + GLP(BlendFunc)(GL_ZERO, GL_ONE); } return; } else { - if ((_target._color_write != _state._color_write)|| - (_target._shader->get_flag(ShaderAttrib::F_disable_alpha_write) != - _state._shader->get_flag(ShaderAttrib::F_disable_alpha_write))) { - if (CLP(color_mask)) { - GLP(ColorMask)((color_channels & ColorWriteAttrib::C_red) != 0, - (color_channels & ColorWriteAttrib::C_green) != 0, - (color_channels & ColorWriteAttrib::C_blue) != 0, - (color_channels & ColorWriteAttrib::C_alpha) != 0); - } + if (CLP(color_mask)) { + GLP(ColorMask)((color_channels & ColorWriteAttrib::C_red) != 0, + (color_channels & ColorWriteAttrib::C_green) != 0, + (color_channels & ColorWriteAttrib::C_blue) != 0, + (color_channels & ColorWriteAttrib::C_alpha) != 0); } } - CPT(ColorBlendAttrib) color_blend = _target._color_blend; - ColorBlendAttrib::Mode color_blend_mode = _target._color_blend->get_mode(); - TransparencyAttrib::Mode transparency_mode = _target._transparency->get_mode(); + const ColorBlendAttrib *target_color_blend = DCAST(ColorBlendAttrib, _target_rs->get_attrib_def(ColorBlendAttrib::get_class_slot())); + CPT(ColorBlendAttrib) color_blend = target_color_blend; + ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode(); + + const TransparencyAttrib *target_transparency = DCAST(TransparencyAttrib, _target_rs->get_attrib_def(TransparencyAttrib::get_class_slot())); + TransparencyAttrib::Mode transparency_mode = target_transparency->get_mode(); _color_blend_involves_color_scale = color_blend->involves_color_scale(); @@ -4131,8 +4148,8 @@ do_issue_blending() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: bind_light(PointLight *light_obj, const NodePath &light, int light_id) { - static PStatCollector _draw_set_state_light_bind_point_pcollector("Draw:Set State:Light:Bind:Point"); - PStatTimer timer(_draw_set_state_light_bind_point_pcollector); + // static PStatCollector _draw_set_state_light_bind_point_pcollector("Draw:Set State:Light:Bind:Point"); + // PStatTimer timer(_draw_set_state_light_bind_point_pcollector); float light_color[4]; GLenum id = get_light_id(light_id); @@ -4175,8 +4192,8 @@ bind_light(PointLight *light_obj, const NodePath &light, int light_id) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) { - static PStatCollector _draw_set_state_light_bind_directional_pcollector("Draw:Set State:Light:Bind:Directional"); - PStatTimer timer(_draw_set_state_light_bind_directional_pcollector); + // static PStatCollector _draw_set_state_light_bind_directional_pcollector("Draw:Set State:Light:Bind:Directional"); + // PStatTimer timer(_draw_set_state_light_bind_directional_pcollector); pair lookup = _dlights.insert(DirectionalLights::value_type(light, DirectionalLightFrameData())); DirectionalLightFrameData &fdata = (*lookup.first).second; @@ -4226,8 +4243,8 @@ bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: bind_light(Spotlight *light_obj, const NodePath &light, int light_id) { - static PStatCollector _draw_set_state_light_bind_spotlight_pcollector("Draw:Set State:Light:Bind:Spotlight"); - PStatTimer timer(_draw_set_state_light_bind_spotlight_pcollector); + // static PStatCollector _draw_set_state_light_bind_spotlight_pcollector("Draw:Set State:Light:Bind:Spotlight"); + // PStatTimer timer(_draw_set_state_light_bind_spotlight_pcollector); Lens *lens = light_obj->get_lens(); nassertv(lens != (Lens *)NULL); @@ -5723,8 +5740,8 @@ get_light_color(float light_color[4], Light *light) const { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: enable_lighting(bool enable) { - static PStatCollector _draw_set_state_light_enable_lighting_pcollector("Draw:Set State:Light:Enable lighting"); - PStatTimer timer(_draw_set_state_light_enable_lighting_pcollector); + // static PStatCollector _draw_set_state_light_enable_lighting_pcollector("Draw:Set State:Light:Enable lighting"); + // PStatTimer timer(_draw_set_state_light_enable_lighting_pcollector); if (enable) { GLP(Enable)(GL_LIGHTING); @@ -5743,8 +5760,8 @@ enable_lighting(bool enable) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: set_ambient_light(const Colorf &color) { - static PStatCollector _draw_set_state_light_ambient_pcollector("Draw:Set State:Light:Ambient"); - PStatTimer timer(_draw_set_state_light_ambient_pcollector); + // static PStatCollector _draw_set_state_light_ambient_pcollector("Draw:Set State:Light:Ambient"); + // PStatTimer timer(_draw_set_state_light_ambient_pcollector); Colorf c = color; c.set(c[0] * _light_color_scale[0], @@ -5763,8 +5780,8 @@ set_ambient_light(const Colorf &color) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: enable_light(int light_id, bool enable) { - static PStatCollector _draw_set_state_light_enable_light_pcollector("Draw:Set State:Light:Enable light"); - PStatTimer timer(_draw_set_state_light_enable_light_pcollector); + // static PStatCollector _draw_set_state_light_enable_light_pcollector("Draw:Set State:Light:Enable light"); + // PStatTimer timer(_draw_set_state_light_enable_light_pcollector); if (enable) { GLP(Enable)(get_light_id(light_id)); @@ -5787,8 +5804,8 @@ enable_light(int light_id, bool enable) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: begin_bind_lights() { - static PStatCollector _draw_set_state_light_begin_bind_pcollector("Draw:Set State:Light:Begin bind"); - PStatTimer timer(_draw_set_state_light_begin_bind_pcollector); + // static PStatCollector _draw_set_state_light_begin_bind_pcollector("Draw:Set State:Light:Begin bind"); + // PStatTimer timer(_draw_set_state_light_begin_bind_pcollector); // We need to temporarily load a new matrix so we can define the // light in a known coordinate system. We pick the transform of the @@ -5816,8 +5833,8 @@ begin_bind_lights() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: end_bind_lights() { - static PStatCollector _draw_set_state_light_end_bind_pcollector("Draw:Set State:Light:End bind"); - PStatTimer timer(_draw_set_state_light_end_bind_pcollector); + // static PStatCollector _draw_set_state_light_end_bind_pcollector("Draw:Set State:Light:End bind"); + // PStatTimer timer(_draw_set_state_light_end_bind_pcollector); GLP(MatrixMode)(GL_MODELVIEW); GLP(PopMatrix)(); @@ -5938,7 +5955,7 @@ set_state_and_transform(const RenderState *target, PStatTimer timer1(_draw_set_state_pcollector); if (transform != _internal_transform) { - PStatTimer timer(_draw_set_state_transform_pcollector); + //PStatTimer timer(_draw_set_state_transform_pcollector); _state_pcollector.add_level(1); _internal_transform = transform; do_issue_transform(); @@ -5948,177 +5965,225 @@ set_state_and_transform(const RenderState *target, return; } _target_rs = target; - _target.clear_to_defaults(); - target->store_into_slots(&_target); - _state_rs = 0; - if (_target._shader && (_target._shader->auto_shader())) { - _target._shader = _target_rs->get_generated_shader(); + _target_shader = DCAST(ShaderAttrib, _target_rs->get_attrib_def(ShaderAttrib::get_class_slot())); + if (_target_shader->auto_shader()) { + _target_shader = _target_rs->get_generated_shader(); } - - if ((_target._alpha_test != _state._alpha_test)|| - (_target._shader->get_flag(ShaderAttrib::F_subsume_alpha_test) != - _state._shader->get_flag(ShaderAttrib::F_subsume_alpha_test))) { - PStatTimer timer(_draw_set_state_alpha_test_pcollector); + + int alpha_test_slot = AlphaTestAttrib::get_class_slot(); + if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) || + !_state_mask.get_bit(alpha_test_slot) || + (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test) != + _state_shader->get_flag(ShaderAttrib::F_subsume_alpha_test))) { + //PStatTimer timer(_draw_set_state_alpha_test_pcollector); do_issue_alpha_test(); - _state._alpha_test = _target._alpha_test; + _state_mask.set_bit(alpha_test_slot); } - if (_target._antialias != _state._antialias) { - PStatTimer timer(_draw_set_state_antialias_pcollector); + int antialias_slot = AntialiasAttrib::get_class_slot(); + if (_target_rs->get_attrib(antialias_slot) != _state_rs->get_attrib(antialias_slot) || + !_state_mask.get_bit(antialias_slot)) { + //PStatTimer timer(_draw_set_state_antialias_pcollector); do_issue_antialias(); - _state._antialias = _target._antialias; + _state_mask.set_bit(antialias_slot); } - if (_target._clip_plane != _state._clip_plane) { - PStatTimer timer(_draw_set_state_clip_plane_pcollector); + int clip_plane_slot = ClipPlaneAttrib::get_class_slot(); + if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) || + !_state_mask.get_bit(clip_plane_slot)) { + //PStatTimer timer(_draw_set_state_clip_plane_pcollector); do_issue_clip_plane(); - _state._clip_plane = _target._clip_plane; + _state_mask.set_bit(clip_plane_slot); } - if (_target._color != _state._color || - _target._color_scale != _state._color_scale) { - PStatTimer timer(_draw_set_state_color_pcollector); + int color_slot = ColorAttrib::get_class_slot(); + int color_scale_slot = ColorScaleAttrib::get_class_slot(); + if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) || + _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) || + !_state_mask.get_bit(color_slot) || + !_state_mask.get_bit(color_scale_slot)) { + //PStatTimer timer(_draw_set_state_color_pcollector); do_issue_color(); do_issue_color_scale(); - _state._color = _target._color; - _state._color_scale = _target._color_scale; - if (_current_shader_context) { - _current_shader_context->issue_parameters(this, Shader::SSD_color); - } + _state_mask.set_bit(color_slot); + _state_mask.set_bit(color_scale_slot); } - if (_target._cull_face != _state._cull_face) { - PStatTimer timer(_draw_set_state_cull_face_pcollector); + int cull_face_slot = CullFaceAttrib::get_class_slot(); + if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) || + !_state_mask.get_bit(cull_face_slot)) { + //PStatTimer timer(_draw_set_state_cull_face_pcollector); do_issue_cull_face(); - _state._cull_face = _target._cull_face; + _state_mask.set_bit(cull_face_slot); } - if (_target._depth_offset != _state._depth_offset) { - PStatTimer timer(_draw_set_state_depth_offset_pcollector); + int depth_offset_slot = DepthOffsetAttrib::get_class_slot(); + if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) || + !_state_mask.get_bit(depth_offset_slot)) { + //PStatTimer timer(_draw_set_state_depth_offset_pcollector); do_issue_depth_offset(); - _state._depth_offset = _target._depth_offset; + _state_mask.set_bit(depth_offset_slot); } - if (_target._depth_test != _state._depth_test) { - PStatTimer timer(_draw_set_state_depth_test_pcollector); + int depth_test_slot = DepthTestAttrib::get_class_slot(); + if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) || + !_state_mask.get_bit(depth_test_slot)) { + //PStatTimer timer(_draw_set_state_depth_test_pcollector); do_issue_depth_test(); - _state._depth_test = _target._depth_test; + _state_mask.set_bit(depth_test_slot); } - if (_target._depth_write != _state._depth_write) { - PStatTimer timer(_draw_set_state_depth_write_pcollector); + int depth_write_slot = DepthWriteAttrib::get_class_slot(); + if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) || + !_state_mask.get_bit(depth_write_slot)) { + //PStatTimer timer(_draw_set_state_depth_write_pcollector); do_issue_depth_write(); - _state._depth_write = _target._depth_write; + _state_mask.set_bit(depth_write_slot); } - if (_target._render_mode != _state._render_mode) { - PStatTimer timer(_draw_set_state_render_mode_pcollector); + int render_mode_slot = RenderModeAttrib::get_class_slot(); + if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) || + !_state_mask.get_bit(render_mode_slot)) { + //PStatTimer timer(_draw_set_state_render_mode_pcollector); do_issue_render_mode(); - _state._render_mode = _target._render_mode; + _state_mask.set_bit(render_mode_slot); } - - if (_target._rescale_normal != _state._rescale_normal) { - PStatTimer timer(_draw_set_state_rescale_normal_pcollector); + + int rescale_normal_slot = RescaleNormalAttrib::get_class_slot(); + if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) || + !_state_mask.get_bit(rescale_normal_slot)) { + //PStatTimer timer(_draw_set_state_rescale_normal_pcollector); do_issue_rescale_normal(); - _state._rescale_normal = _target._rescale_normal; + _state_mask.set_bit(rescale_normal_slot); } - if (_target._shade_model != _state._shade_model) { - PStatTimer timer(_draw_set_state_shade_model_pcollector); + int shade_model_slot = ShadeModelAttrib::get_class_slot(); + if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) || + !_state_mask.get_bit(shade_model_slot)) { + //PStatTimer timer(_draw_set_state_shade_model_pcollector); do_issue_shade_model(); - _state._shade_model = _target._shade_model; + _state_mask.set_bit(shade_model_slot); } - if ((_target._transparency != _state._transparency)|| - (_target._color_write != _state._color_write)|| - (_target._color_blend != _state._color_blend)|| - (_target._shader->get_flag(ShaderAttrib::F_disable_alpha_write) != - _state._shader->get_flag(ShaderAttrib::F_disable_alpha_write))) { - PStatTimer timer(_draw_set_state_blending_pcollector); + int transparency_slot = TransparencyAttrib::get_class_slot(); + int color_write_slot = ColorWriteAttrib::get_class_slot(); + int color_blend_slot = ColorBlendAttrib::get_class_slot(); + if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) || + _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) || + _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) || + !_state_mask.get_bit(transparency_slot) || + !_state_mask.get_bit(color_write_slot) || + !_state_mask.get_bit(color_blend_slot) || + (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) != + _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))) { + //PStatTimer timer(_draw_set_state_blending_pcollector); do_issue_blending(); - _state._transparency = _target._transparency; - _state._color_write = _target._color_write; - _state._color_blend = _target._color_blend; + _state_mask.set_bit(transparency_slot); + _state_mask.set_bit(color_write_slot); + _state_mask.set_bit(color_blend_slot); } - if (_target._shader != _state._shader) { - PStatTimer timer(_draw_set_state_shader_pcollector); + if (_target_shader != _state_shader) { + //PStatTimer timer(_draw_set_state_shader_pcollector); do_issue_shader(); - _state._shader = _target._shader; - _state._texture = 0; + _state_shader = _target_shader; + _state_mask.clear_bit(TextureAttrib::get_class_slot()); } - if (_target._texture != _state._texture) { - PStatTimer timer(_draw_set_state_texture_pcollector); - determine_effective_texture(); + int texture_slot = TextureAttrib::get_class_slot(); + if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) || + !_state_mask.get_bit(texture_slot)) { + //PStatTimer timer(_draw_set_state_texture_pcollector); + determine_target_texture(); int prev_active = _num_active_texture_stages; do_issue_texture(); // Since the TexGen and TexMatrix states depend partly on the // particular set of textures in use, we should force both of // those to be reissued every time we change the texture state. - _state._tex_gen = 0; - _state._tex_matrix = 0; + _state_mask.clear_bit(TexGenAttrib::get_class_slot()); + _state_mask.clear_bit(TexMatrixAttrib::get_class_slot()); - _state._texture = _target._texture; + _state_texture = _target_texture; + _state_mask.set_bit(texture_slot); } // If one of the previously-loaded TexGen modes modified the texture // matrix, then if either state changed, we have to change both of // them now. if (_tex_gen_modifies_mat) { - if ((_target._tex_gen != _state._tex_gen) || - (_target._tex_matrix != _state._tex_matrix)) { - _state._tex_matrix = 0; - _state._tex_gen = 0; + int tex_gen_slot = TexGenAttrib::get_class_slot(); + int tex_matrix_slot = TexMatrixAttrib::get_class_slot(); + if (_target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) || + _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) || + !_state_mask.get_bit(tex_gen_slot) || + !_state_mask.get_bit(tex_matrix_slot)) { + _state_mask.clear_bit(tex_gen_slot); + _state_mask.clear_bit(tex_matrix_slot); } } - - if (_target._tex_matrix != _state._tex_matrix) { - PStatTimer timer(_draw_set_state_tex_matrix_pcollector); + + int tex_matrix_slot = TexMatrixAttrib::get_class_slot(); + if (_target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) || + !_state_mask.get_bit(tex_matrix_slot)) { + //PStatTimer timer(_draw_set_state_tex_matrix_pcollector); do_issue_tex_matrix(); - _state._tex_matrix = _target._tex_matrix; + _state_mask.set_bit(tex_matrix_slot); } - if (_effective_tex_gen != _state._tex_gen) { - PStatTimer timer(_draw_set_state_tex_gen_pcollector); + int tex_gen_slot = TexGenAttrib::get_class_slot(); + if (_target_tex_gen != _state_tex_gen || + !_state_mask.get_bit(tex_gen_slot)) { + //PStatTimer timer(_draw_set_state_tex_gen_pcollector); do_issue_tex_gen(); - _state._tex_gen = _effective_tex_gen; + _state_tex_gen = _target_tex_gen; + _state_mask.set_bit(tex_gen_slot); } - - if (_target._material != _state._material) { - PStatTimer timer(_draw_set_state_material_pcollector); + + int material_slot = MaterialAttrib::get_class_slot(); + if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) || + !_state_mask.get_bit(material_slot)) { + //PStatTimer timer(_draw_set_state_material_pcollector); do_issue_material(); - _state._material = _target._material; + _state_mask.set_bit(material_slot); if (_current_shader_context) { _current_shader_context->issue_parameters(this, Shader::SSD_material); } } - if (_target._light != _state._light) { - PStatTimer timer(_draw_set_state_light_pcollector); + int light_slot = LightAttrib::get_class_slot(); + if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) || + !_state_mask.get_bit(light_slot)) { + //PStatTimer timer(_draw_set_state_light_pcollector); do_issue_light(); - _state._light = _target._light; + _state_mask.set_bit(light_slot); } - if (_target._stencil != _state._stencil) { - PStatTimer timer(_draw_set_state_stencil_pcollector); + int stencil_slot = StencilAttrib::get_class_slot(); + if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) || + !_state_mask.get_bit(stencil_slot)) { + //PStatTimer timer(_draw_set_state_stencil_pcollector); do_issue_stencil(); - _state._stencil = _target._stencil; + _state_mask.set_bit(stencil_slot); } if (_current_shader_context == 0) { - if (_target._fog != _state._fog) { - PStatTimer timer(_draw_set_state_fog_pcollector); + int fog_slot = FogAttrib::get_class_slot(); + if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) || + !_state_mask.get_bit(fog_slot)) { + //PStatTimer timer(_draw_set_state_fog_pcollector); do_issue_fog(); - _state._fog = _target._fog; + _state_mask.set_bit(fog_slot); } } - if (_target._scissor != _state._scissor) { + int scissor_slot = ScissorAttrib::get_class_slot(); + if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) || + !_state_mask.get_bit(scissor_slot)) { + //PStatTimer timer(_draw_set_state_scissor_pcollector); do_issue_scissor(); - _state._scissor = _target._scissor; + _state_mask.set_bit(scissor_slot); } _state_rs = _target_rs; @@ -6226,7 +6291,7 @@ do_issue_texture() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: update_standard_texture_bindings() { - int num_stages = _effective_texture->get_num_on_ff_stages(); + int num_stages = _target_texture->get_num_on_ff_stages(); nassertv(num_stages <= _max_texture_stages && _num_active_texture_stages <= _max_texture_stages); @@ -6237,8 +6302,8 @@ update_standard_texture_bindings() { int last_stage = -1; int i; for (i = 0; i < num_stages; i++) { - TextureStage *stage = _effective_texture->get_on_ff_stage(i); - Texture *texture = _effective_texture->get_on_texture(stage); + TextureStage *stage = _target_texture->get_on_ff_stage(i); + Texture *texture = _target_texture->get_on_texture(stage); nassertv(texture != (Texture *)NULL); // Issue the texture on stage i. @@ -6450,12 +6515,14 @@ do_issue_tex_matrix() { nassertv(_num_active_texture_stages <= _max_texture_stages); for (int i = 0; i < _num_active_texture_stages; i++) { - TextureStage *stage = _effective_texture->get_on_ff_stage(i); + TextureStage *stage = _target_texture->get_on_ff_stage(i); _glActiveTexture(GL_TEXTURE0 + i); GLP(MatrixMode)(GL_TEXTURE); - if (_target._tex_matrix->has_stage(stage)) { - GLP(LoadMatrixf)(_target._tex_matrix->get_mat(stage).get_data()); + + const TexMatrixAttrib *target_tex_matrix = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot())); + if (target_tex_matrix->has_stage(stage)) { + GLP(LoadMatrixf)(target_tex_matrix->get_mat(stage).get_data()); } else { GLP(LoadIdentity)(); @@ -6497,7 +6564,7 @@ do_issue_tex_gen() { bool got_point_sprites = false; for (int i = 0; i < _num_active_texture_stages; i++) { - TextureStage *stage = _effective_texture->get_on_ff_stage(i); + TextureStage *stage = _target_texture->get_on_ff_stage(i); _glActiveTexture(GL_TEXTURE0 + i); GLP(Disable)(GL_TEXTURE_GEN_S); GLP(Disable)(GL_TEXTURE_GEN_T); @@ -6507,7 +6574,7 @@ do_issue_tex_gen() { GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE); } - TexGenAttrib::Mode mode = _effective_tex_gen->get_mode(stage); + TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage); switch (mode) { case TexGenAttrib::M_off: case TexGenAttrib::M_light_vector: @@ -6695,7 +6762,7 @@ do_issue_tex_gen() { // flattens the vertex position to zero and then adds our // desired value. { - const TexCoord3f &v = _effective_tex_gen->get_constant_value(stage); + const TexCoord3f &v = _target_tex_gen->get_constant_value(stage); GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); @@ -8149,10 +8216,9 @@ void gl_set_stencil_functions (StencilRenderStates *stencil_render_states) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_stencil() { - const StencilAttrib *stencil; - StencilRenderStates *stencil_render_states; + const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib_def(StencilAttrib::get_class_slot())); - stencil = _target._stencil; + StencilRenderStates *stencil_render_states; stencil_render_states = this -> _stencil_render_states; if (stencil && stencil_render_states) { @@ -8226,7 +8292,8 @@ do_issue_stencil() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: do_issue_scissor() { - const LVecBase4f &frame = _target._scissor->get_frame(); + const ScissorAttrib *target_scissor = DCAST(ScissorAttrib, _target_rs->get_attrib_def(ScissorAttrib::get_class_slot())); + const LVecBase4f &frame = target_scissor->get_frame(); int x = (int)(_viewport_x + _viewport_width * frame[0] + 0.5f); int y = (int)(_viewport_y + _viewport_height * frame[2] + 0.5f); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 8257e1bd03..3fdbcd77ab 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -27,6 +27,7 @@ #include "textureStage.h" #include "antialiasAttrib.h" #include "renderModeAttrib.h" +#include "colorBlendAttrib.h" #include "pointerToArray.h" #include "fog.h" #include "graphicsWindow.h" diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index c57f98c746..de623563ea 100755 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -258,8 +258,8 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, if (p == 0) continue; InternalName *name = _shader->_var_spec[i]._name; int texslot = _shader->_var_spec[i]._append_uv; - if (texslot >= 0 && texslot < gsg->_state._texture->get_num_on_stages()) { - TextureStage *stage = gsg->_state._texture->get_on_stage(texslot); + if (texslot >= 0 && texslot < gsg->_state_texture->get_num_on_stages()) { + TextureStage *stage = gsg->_state_texture->get_on_stage(texslot); InternalName *texname = stage->get_texcoord_name(); if (name == InternalName::get_texcoord()) { name = texname; @@ -351,14 +351,14 @@ update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg) { Texture *tex = 0; InternalName *id = _shader->_tex_spec[i]._name; if (id != 0) { - const ShaderInput *input = gsg->_target._shader->get_shader_input(id); + const ShaderInput *input = gsg->_target_shader->get_shader_input(id); tex = input->get_texture(); } else { - if (_shader->_tex_spec[i]._stage >= gsg->_target._texture->get_num_on_stages()) { + if (_shader->_tex_spec[i]._stage >= gsg->_target_texture->get_num_on_stages()) { continue; } - TextureStage *stage = gsg->_target._texture->get_on_stage(_shader->_tex_spec[i]._stage); - tex = gsg->_target._texture->get_on_texture(stage); + TextureStage *stage = gsg->_target_texture->get_on_stage(_shader->_tex_spec[i]._stage); + tex = gsg->_target_texture->get_on_texture(stage); } if (_shader->_tex_spec[i]._suffix != 0) { // The suffix feature is inefficient. It is a temporary hack. diff --git a/panda/src/grutil/multitexReducer.cxx b/panda/src/grutil/multitexReducer.cxx index ddc3e07160..f1a928184d 100644 --- a/panda/src/grutil/multitexReducer.cxx +++ b/panda/src/grutil/multitexReducer.cxx @@ -29,6 +29,7 @@ #include "colorAttrib.h" #include "colorScaleAttrib.h" #include "colorBlendAttrib.h" +#include "alphaTestAttrib.h" #include "textureAttrib.h" #include "config_grutil.h" #include "config_gobj.h" @@ -99,7 +100,7 @@ scan(PandaNode *node, const RenderState *state, const TransformState *transform) // operation, since the flattened texture will be applied to the // Geoms after the flatten() operation, and we don't want to still // have a multitexture specified. - node->set_state(node->get_state()->remove_attrib(TextureAttrib::get_class_type())); + node->set_state(node->get_state()->remove_attrib(TextureAttrib::get_class_slot())); if (node->is_geom_node()) { scan_geom_node(DCAST(GeomNode, node), next_state, next_transform); @@ -376,7 +377,7 @@ flatten(GraphicsOutput *window) { CPT(RenderState) geom_state = geom_info._geom_node->get_geom_state(geom_info._index); - int override = geom_info._geom_net_state->get_override(TextureAttrib::get_class_type()); + int override = geom_info._geom_net_state->get_override(TextureAttrib::get_class_slot()); geom_state = geom_state->add_attrib(new_ta, override); if (bake_in_color) { @@ -389,7 +390,7 @@ flatten(GraphicsOutput *window) { // thing as a ColorScaleAttrib::make_off(), since that would // prohibit any future changes to the color scale. const RenderAttrib *attrib = - geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_type()); + geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { geom_state = geom_state->add_attrib @@ -400,7 +401,7 @@ flatten(GraphicsOutput *window) { // Determine what tex matrix should be on the Geom. CPT(TransformState) tex_mat = TransformState::make_identity(); - const RenderAttrib *ra = geom_info._state->get_attrib(TexMatrixAttrib::get_class_type()); + const RenderAttrib *ra = geom_info._state->get_attrib(TexMatrixAttrib::get_class_slot()); if (ra != (const RenderAttrib *)NULL) { // There is a texture matrix inherited from above; put an // inverse matrix on the Geom to compensate. @@ -415,7 +416,7 @@ flatten(GraphicsOutput *window) { if (tex_mat->is_identity()) { // There should be no texture matrix on the Geom. - geom_state = geom_state->remove_attrib(TexMatrixAttrib::get_class_type()); + geom_state = geom_state->remove_attrib(TexMatrixAttrib::get_class_slot()); } else { // The texture matrix should be as computed. CPT(RenderAttrib) new_tma = TexMatrixAttrib::make @@ -437,7 +438,7 @@ flatten(GraphicsOutput *window) { const GeomNodeInfo &geom_node_info = (*gni); AccumulatedAttribs attribs; attribs._texture = - geom_node_info._state->get_attrib(TextureAttrib::get_class_type()); + geom_node_info._state->get_attrib(TextureAttrib::get_class_slot()); geom_node_info._geom_node->apply_attribs_to_vertices (attribs, SceneGraphReducer::TT_tex_matrix, transformer); } @@ -475,7 +476,7 @@ scan_geom_node(GeomNode *node, const RenderState *state, const RenderAttrib *attrib; const TextureAttrib *ta = NULL; - attrib = geom_net_state->get_attrib(TextureAttrib::get_class_type()); + attrib = geom_net_state->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { ta = DCAST(TextureAttrib, attrib); } @@ -483,14 +484,14 @@ scan_geom_node(GeomNode *node, const RenderState *state, if (ta == (TextureAttrib *)NULL) { // No texture should be on the Geom. CPT(RenderState) geom_state = node->get_geom_state(gi); - geom_state = geom_state->remove_attrib(TextureAttrib::get_class_type()); + geom_state = geom_state->remove_attrib(TextureAttrib::get_class_slot()); node->set_geom_state(gi, geom_state); } else if (ta->get_num_on_stages() < 2) { // Just a single texture on the Geom; we don't really need to do // anything to flatten the textures, then. But we should ensure // that the correct TextureAttrib is applied to the Geom. - int override = geom_net_state->get_override(TextureAttrib::get_class_type()); + int override = geom_net_state->get_override(TextureAttrib::get_class_slot()); CPT(RenderState) geom_state = node->get_geom_state(gi); geom_state = geom_state->add_attrib(ta, override); node->set_geom_state(gi, geom_state); @@ -498,7 +499,7 @@ scan_geom_node(GeomNode *node, const RenderState *state, } else { // Ok, we have multitexture. Record the Geom. CPT(TexMatrixAttrib) tma = DCAST(TexMatrixAttrib, TexMatrixAttrib::make()); - attrib = geom_net_state->get_attrib(TexMatrixAttrib::get_class_type()); + attrib = geom_net_state->get_attrib(TexMatrixAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { tma = DCAST(TexMatrixAttrib, attrib); } @@ -963,11 +964,11 @@ transfer_geom(GeomNode *geom_node, const InternalName *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()); + const RenderAttrib *ca = geom_info._geom_net_state->get_attrib(ColorAttrib::get_class_slot()); 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()); + const RenderAttrib *csa = geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_slot()); if (csa != (const RenderAttrib *)NULL) { geom_state = geom_state->add_attrib(csa); } @@ -1002,7 +1003,7 @@ scan_color(const MultitexReducer::GeomList &geom_list, Colorf &geom_color, bool has_vertex_color = false; Colorf color_scale(1.0f, 1.0f, 1.0f, 1.0f); - const RenderAttrib *csa = geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_type()); + const RenderAttrib *csa = geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_slot()); if (csa != (const RenderAttrib *)NULL) { const ColorScaleAttrib *a = DCAST(ColorScaleAttrib, csa); if (a->has_scale()) { @@ -1011,7 +1012,7 @@ scan_color(const MultitexReducer::GeomList &geom_list, Colorf &geom_color, } ColorAttrib::Type color_type = ColorAttrib::T_vertex; - const RenderAttrib *ca = geom_info._geom_net_state->get_attrib(ColorAttrib::get_class_type()); + const RenderAttrib *ca = geom_info._geom_net_state->get_attrib(ColorAttrib::get_class_slot()); if (ca != (const RenderAttrib *)NULL) { color_type = DCAST(ColorAttrib, ca)->get_color_type(); } diff --git a/panda/src/grutil/pipeOcclusionCullTraverser.cxx b/panda/src/grutil/pipeOcclusionCullTraverser.cxx index 84374b3b72..e64f983b69 100644 --- a/panda/src/grutil/pipeOcclusionCullTraverser.cxx +++ b/panda/src/grutil/pipeOcclusionCullTraverser.cxx @@ -22,6 +22,10 @@ #include "geomTristrips.h" #include "geomTriangles.h" #include "pStatTimer.h" +#include "depthWriteAttrib.h" +#include "depthTestAttrib.h" +#include "colorWriteAttrib.h" +#include "colorAttrib.h" #include "cullBinManager.h" #include "configVariableInt.h" #include "config_grutil.h" diff --git a/panda/src/osxdisplay/Sources.pp b/panda/src/osxdisplay/Sources.pp index db152ef4c7..427cdbf9b5 100644 --- a/panda/src/osxdisplay/Sources.pp +++ b/panda/src/osxdisplay/Sources.pp @@ -1,4 +1,4 @@ -#define BUILD_DIRECTORY $[IS_OSX] +#define BUILD_DIRECTORY $[and $[IS_OSX],$[HAVE_GL]] #define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \ dtoolutil:c dtoolbase:c dtool:m prc:c diff --git a/panda/src/osxdisplay/osxGraphicsStateGuardian.cxx b/panda/src/osxdisplay/osxGraphicsStateGuardian.cxx index 4ab31cc266..c3e957855a 100644 --- a/panda/src/osxdisplay/osxGraphicsStateGuardian.cxx +++ b/panda/src/osxdisplay/osxGraphicsStateGuardian.cxx @@ -13,6 +13,9 @@ #include "osxGraphicsBuffer.h" #include "string_utils.h" #include "config_osxdisplay.h" +#include "depthWriteAttrib.h" +#include "depthTestAttrib.h" +#include "textureAttrib.h" #include "pnmImage.h" #include diff --git a/panda/src/pgraph/Sources.pp b/panda/src/pgraph/Sources.pp index 046d4e2386..f03859c19d 100644 --- a/panda/src/pgraph/Sources.pp +++ b/panda/src/pgraph/Sources.pp @@ -17,7 +17,6 @@ alphaTestAttrib.I alphaTestAttrib.h \ antialiasAttrib.I antialiasAttrib.h \ attribNodeRegistry.I attribNodeRegistry.h \ - attribSlots.h attribSlots.I \ audioVolumeAttrib.I audioVolumeAttrib.h \ auxSceneData.I auxSceneData.h \ auxBitplaneAttrib.I auxBitplaneAttrib.h \ @@ -47,7 +46,6 @@ depthOffsetAttrib.I depthOffsetAttrib.h \ depthTestAttrib.I depthTestAttrib.h \ depthWriteAttrib.I depthWriteAttrib.h \ - drawMaskAttrib.I drawMaskAttrib.h \ eventStorePandaNode.I eventStorePandaNode.h \ fadeLodNode.I fadeLodNode.h \ fadeLodNodeData.h \ @@ -87,6 +85,7 @@ portalNode.I portalNode.h \ portalClipper.I portalClipper.h \ renderAttrib.I renderAttrib.h \ + renderAttribRegistry.I renderAttribRegistry.h \ renderEffect.I renderEffect.h \ renderEffects.I renderEffects.h \ renderModeAttrib.I renderModeAttrib.h \ @@ -124,7 +123,6 @@ alphaTestAttrib.cxx \ antialiasAttrib.cxx \ attribNodeRegistry.cxx \ - attribSlots.cxx \ audioVolumeAttrib.cxx \ auxSceneData.cxx \ bamFile.cxx \ @@ -152,7 +150,6 @@ depthOffsetAttrib.cxx \ depthTestAttrib.cxx \ depthWriteAttrib.cxx \ - drawMaskAttrib.cxx \ eventStorePandaNode.cxx \ fadeLodNode.cxx \ fadeLodNodeData.cxx \ @@ -191,6 +188,7 @@ portalNode.cxx \ portalClipper.cxx \ renderAttrib.cxx \ + renderAttribRegistry.cxx \ renderEffect.cxx \ renderEffects.cxx \ renderModeAttrib.cxx \ @@ -225,7 +223,6 @@ alphaTestAttrib.I alphaTestAttrib.h \ antialiasAttrib.I antialiasAttrib.h \ attribNodeRegistry.I attribNodeRegistry.h \ - attribSlots.h attribSlots.I \ audioVolumeAttrib.I audioVolumeAttrib.h \ auxSceneData.I auxSceneData.h \ auxBitplaneAttrib.I auxBitplaneAttrib.h \ @@ -255,7 +252,6 @@ depthOffsetAttrib.I depthOffsetAttrib.h \ depthTestAttrib.I depthTestAttrib.h \ depthWriteAttrib.I depthWriteAttrib.h \ - drawMaskAttrib.I drawMaskAttrib.h \ eventStorePandaNode.I eventStorePandaNode.h \ fadeLodNode.I fadeLodNode.h \ fadeLodNodeData.h \ @@ -293,6 +289,7 @@ portalNode.I portalNode.h \ portalClipper.I portalClipper.h \ renderAttrib.I renderAttrib.h \ + renderAttribRegistry.I renderAttribRegistry.h \ renderEffect.I renderEffect.h \ renderEffects.I renderEffects.h \ renderModeAttrib.I renderModeAttrib.h \ diff --git a/panda/src/pgraph/accumulatedAttribs.cxx b/panda/src/pgraph/accumulatedAttribs.cxx index fa36a7d259..7dc153665b 100644 --- a/panda/src/pgraph/accumulatedAttribs.cxx +++ b/panda/src/pgraph/accumulatedAttribs.cxx @@ -172,9 +172,9 @@ collect(const RenderState *state, int attrib_types) { if ((attrib_types & SceneGraphReducer::TT_color) != 0) { const RenderAttrib *node_attrib = - new_state->get_attrib(ColorAttrib::get_class_type()); + new_state->get_attrib(ColorAttrib::get_class_slot()); if (node_attrib != (const RenderAttrib *)NULL) { - int color_override = new_state->get_override(ColorAttrib::get_class_type()); + int color_override = new_state->get_override(ColorAttrib::get_class_slot()); if (color_override >= _color_override || _color == (const RenderAttrib *)NULL) { // The node has a color attribute; apply it. @@ -185,15 +185,15 @@ collect(const RenderState *state, int attrib_types) { } _color_override = color_override; } - new_state = new_state->remove_attrib(ColorAttrib::get_class_type()); + new_state = new_state->remove_attrib(ColorAttrib::get_class_slot()); } } if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) { const RenderAttrib *node_attrib = - new_state->get_attrib(ColorScaleAttrib::get_class_type()); + new_state->get_attrib(ColorScaleAttrib::get_class_slot()); if (node_attrib != (const RenderAttrib *)NULL) { - int color_scale_override = new_state->get_override(ColorScaleAttrib::get_class_type()); + int color_scale_override = new_state->get_override(ColorScaleAttrib::get_class_slot()); if (color_scale_override >= _color_scale_override || _color_scale == (const RenderAttrib *)NULL) { if (_color_scale == (const RenderAttrib *)NULL) { @@ -203,15 +203,15 @@ collect(const RenderState *state, int attrib_types) { } _color_scale_override = color_scale_override; } - new_state = new_state->remove_attrib(ColorScaleAttrib::get_class_type()); + new_state = new_state->remove_attrib(ColorScaleAttrib::get_class_slot()); } } if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) { const RenderAttrib *node_attrib = - new_state->get_attrib(TexMatrixAttrib::get_class_type()); + new_state->get_attrib(TexMatrixAttrib::get_class_slot()); if (node_attrib != (const RenderAttrib *)NULL) { - int tex_matrix_override = new_state->get_override(TexMatrixAttrib::get_class_type()); + int tex_matrix_override = new_state->get_override(TexMatrixAttrib::get_class_slot()); if (tex_matrix_override >= _tex_matrix_override || _tex_matrix == (const RenderAttrib *)NULL) { if (_tex_matrix == (const RenderAttrib *)NULL) { @@ -221,15 +221,15 @@ collect(const RenderState *state, int attrib_types) { } _tex_matrix_override = tex_matrix_override; } - new_state = new_state->remove_attrib(TexMatrixAttrib::get_class_type()); + new_state = new_state->remove_attrib(TexMatrixAttrib::get_class_slot()); } // We also need to accumulate the texture state if we are // accumulating texture matrix. const RenderAttrib *tex_attrib = - new_state->get_attrib(TextureAttrib::get_class_type()); + new_state->get_attrib(TextureAttrib::get_class_slot()); if (tex_attrib != (const RenderAttrib *)NULL) { - int texture_override = new_state->get_override(TextureAttrib::get_class_type()); + int texture_override = new_state->get_override(TextureAttrib::get_class_slot()); if (texture_override >= _texture_override || _texture == (const RenderAttrib *)NULL) { if (_texture == (const RenderAttrib *)NULL) { @@ -248,9 +248,9 @@ collect(const RenderState *state, int attrib_types) { if ((attrib_types & SceneGraphReducer::TT_clip_plane) != 0) { const RenderAttrib *node_attrib = - new_state->get_attrib(ClipPlaneAttrib::get_class_type()); + new_state->get_attrib(ClipPlaneAttrib::get_class_slot()); if (node_attrib != (const RenderAttrib *)NULL) { - int clip_plane_override = new_state->get_override(ClipPlaneAttrib::get_class_type()); + int clip_plane_override = new_state->get_override(ClipPlaneAttrib::get_class_slot()); if (clip_plane_override >= _clip_plane_override || _clip_plane == (const RenderAttrib *)NULL) { if (_clip_plane == (const RenderAttrib *)NULL) { @@ -260,15 +260,15 @@ collect(const RenderState *state, int attrib_types) { } _clip_plane_override = clip_plane_override; } - new_state = new_state->remove_attrib(ClipPlaneAttrib::get_class_type()); + new_state = new_state->remove_attrib(ClipPlaneAttrib::get_class_slot()); } } if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) { const RenderAttrib *node_attrib = - new_state->get_attrib(CullFaceAttrib::get_class_type()); + new_state->get_attrib(CullFaceAttrib::get_class_slot()); if (node_attrib != (const RenderAttrib *)NULL) { - int cull_face_override = new_state->get_override(CullFaceAttrib::get_class_type()); + int cull_face_override = new_state->get_override(CullFaceAttrib::get_class_slot()); if (cull_face_override >= _cull_face_override || _cull_face == (const RenderAttrib *)NULL) { if (_cull_face == (const RenderAttrib *)NULL) { @@ -278,7 +278,7 @@ collect(const RenderState *state, int attrib_types) { } _cull_face_override = cull_face_override; } - new_state = new_state->remove_attrib(CullFaceAttrib::get_class_type()); + new_state = new_state->remove_attrib(CullFaceAttrib::get_class_slot()); } } @@ -312,7 +312,7 @@ apply_to_node(PandaNode *node, int attrib_types) { if ((attrib_types & SceneGraphReducer::TT_color) != 0) { if (_color != (RenderAttrib *)NULL) { const RenderAttrib *node_attrib = - node->get_attrib(ColorAttrib::get_class_type()); + node->get_attrib(ColorAttrib::get_class_slot()); if (node_attrib != (RenderAttrib *)NULL) { node->set_attrib(_color->compose(node_attrib)); } else { @@ -325,7 +325,7 @@ apply_to_node(PandaNode *node, int attrib_types) { if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) { if (_color_scale != (RenderAttrib *)NULL) { const RenderAttrib *node_attrib = - node->get_attrib(ColorScaleAttrib::get_class_type()); + node->get_attrib(ColorScaleAttrib::get_class_slot()); if (node_attrib != (RenderAttrib *)NULL) { node->set_attrib(_color_scale->compose(node_attrib)); } else { @@ -338,7 +338,7 @@ apply_to_node(PandaNode *node, int attrib_types) { if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) { if (_tex_matrix != (RenderAttrib *)NULL) { const RenderAttrib *node_attrib = - node->get_attrib(TexMatrixAttrib::get_class_type()); + node->get_attrib(TexMatrixAttrib::get_class_slot()); if (node_attrib != (RenderAttrib *)NULL) { node->set_attrib(_tex_matrix->compose(node_attrib)); } else { @@ -351,7 +351,7 @@ apply_to_node(PandaNode *node, int attrib_types) { if ((attrib_types & SceneGraphReducer::TT_clip_plane) != 0) { if (_clip_plane != (RenderAttrib *)NULL) { const RenderAttrib *node_attrib = - node->get_attrib(ClipPlaneAttrib::get_class_type()); + node->get_attrib(ClipPlaneAttrib::get_class_slot()); if (node_attrib != (RenderAttrib *)NULL) { node->set_attrib(_clip_plane->compose(node_attrib)); } else { @@ -364,7 +364,7 @@ apply_to_node(PandaNode *node, int attrib_types) { if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) { if (_cull_face != (RenderAttrib *)NULL) { const RenderAttrib *node_attrib = - node->get_attrib(CullFaceAttrib::get_class_type()); + node->get_attrib(CullFaceAttrib::get_class_slot()); if (node_attrib != (RenderAttrib *)NULL) { node->set_attrib(_cull_face->compose(node_attrib)); } else { diff --git a/panda/src/pgraph/alphaTestAttrib.cxx b/panda/src/pgraph/alphaTestAttrib.cxx index e990ecea02..0c629a2326 100644 --- a/panda/src/pgraph/alphaTestAttrib.cxx +++ b/panda/src/pgraph/alphaTestAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "alphaTestAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle AlphaTestAttrib::_type_handle; +int AlphaTestAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: AlphaTestAttrib::make @@ -35,6 +35,18 @@ make(PandaCompareFunc mode, float reference_value) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: AlphaTestAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AlphaTestAttrib:: +make_default() { + return return_new(new AlphaTestAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: AlphaTestAttrib::output // Access: Public, Virtual @@ -74,33 +86,6 @@ compare_to_impl(const RenderAttrib *other) const { } } -//////////////////////////////////////////////////////////////////// -// Function: AlphaTestAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived AlphaTestAttrib -// types to specify what the default property for a -// AlphaTestAttrib of this type should be. -// -// This should return a newly-allocated AlphaTestAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of AlphaTestAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *AlphaTestAttrib:: -make_default_impl() const { - return new AlphaTestAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: AlphaTestAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void AlphaTestAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_alpha_test = this; -} - //////////////////////////////////////////////////////////////////// // Function: AlphaTestAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/alphaTestAttrib.h b/panda/src/pgraph/alphaTestAttrib.h index 0a8c707570..646b1870eb 100644 --- a/panda/src/pgraph/alphaTestAttrib.h +++ b/panda/src/pgraph/alphaTestAttrib.h @@ -33,21 +33,29 @@ private: PUBLISHED: static CPT(RenderAttrib) make(PandaCompareFunc mode, float reference_alpha); + static CPT(RenderAttrib) make_default(); + INLINE float get_reference_alpha() const; INLINE PandaCompareFunc get_mode() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: PandaCompareFunc _mode; float _reference_alpha; // should be in range [0.0-1.0] +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -64,6 +72,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "AlphaTestAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -72,6 +81,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "alphaTestAttrib.I" diff --git a/panda/src/pgraph/antialiasAttrib.cxx b/panda/src/pgraph/antialiasAttrib.cxx index 696fc7103f..d6e9908abb 100644 --- a/panda/src/pgraph/antialiasAttrib.cxx +++ b/panda/src/pgraph/antialiasAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "antialiasAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle AntialiasAttrib::_type_handle; +int AntialiasAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: AntialiasAttrib::make @@ -65,6 +65,18 @@ make(unsigned short mode) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: AntialiasAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AntialiasAttrib:: +make_default() { + return return_new(new AntialiasAttrib(M_none)); +} + //////////////////////////////////////////////////////////////////// // Function: AntialiasAttrib::output // Access: Public, Virtual @@ -186,33 +198,6 @@ compose_impl(const RenderAttrib *other) const { return make(mode_type | mode_quality); } -//////////////////////////////////////////////////////////////////// -// Function: AntialiasAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived AntialiasAttrib -// types to specify what the default property for a -// AntialiasAttrib of this type should be. -// -// This should return a newly-allocated AntialiasAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of AntialiasAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *AntialiasAttrib:: -make_default_impl() const { - return new AntialiasAttrib(M_none); -} - -//////////////////////////////////////////////////////////////////// -// Function: AntialiasAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void AntialiasAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_antialias = this; -} - //////////////////////////////////////////////////////////////////// // Function: AntialiasAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/antialiasAttrib.h b/panda/src/pgraph/antialiasAttrib.h index 3927fa499a..af0b915e13 100644 --- a/panda/src/pgraph/antialiasAttrib.h +++ b/panda/src/pgraph/antialiasAttrib.h @@ -48,6 +48,7 @@ private: PUBLISHED: static CPT(RenderAttrib) make(unsigned short mode); + static CPT(RenderAttrib) make_default(); INLINE unsigned short get_mode() const; INLINE unsigned short get_mode_type() const; @@ -55,16 +56,22 @@ PUBLISHED: public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: unsigned short _mode; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -81,6 +88,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "AntialiasAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -89,6 +97,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "antialiasAttrib.I" diff --git a/panda/src/pgraph/attribSlots.I b/panda/src/pgraph/attribSlots.I deleted file mode 100644 index 9f82e5f6fa..0000000000 --- a/panda/src/pgraph/attribSlots.I +++ /dev/null @@ -1,74 +0,0 @@ -// Filename: attribSlots.I -// Created by: jyelon (01Sep05) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////////////// -// Function: AttribSlots::clear_to_zero -// Access: Private -// Description: clears all values to zero. -//////////////////////////////////////////////////////////////////// -INLINE void AttribSlots:: -clear_to_zero() { - _alpha_test = NULL; - _antialias = NULL; - _audio_volume = NULL; - _aux_bitplane = NULL; - _clip_plane = NULL; - _color = NULL; - _color_blend = NULL; - _color_scale = NULL; - _color_write = NULL; - _cull_bin = NULL; - _cull_face = NULL; - _depth_offset = NULL; - _depth_test = NULL; - _depth_write = NULL; - _fog = NULL; - _light = NULL; - _material = NULL; - _render_mode = NULL; - _rescale_normal = NULL; - _shade_model = NULL; - _shader = NULL; - _stencil = NULL; - _tex_gen = NULL; - _tex_matrix = NULL; - _texture = NULL; - _transparency = NULL; - _scissor = NULL; -} - -//////////////////////////////////////////////////////////////////// -// Function: AttribSlots::get_defaults -// Access: Public -// Description: Returns a set of slots containing all the default -// attribute values, as defined by make_default_impl. -//////////////////////////////////////////////////////////////////// -INLINE const AttribSlots &AttribSlots:: -get_defaults() { - if (_defvals._alpha_test == 0) { - initialize_defvals(); - } - return _defvals; -} - -//////////////////////////////////////////////////////////////////// -// Function: AttribSlots::clear_to_defaults -// Access: Private -// Description: clears all values to their default values. -//////////////////////////////////////////////////////////////////// -INLINE void AttribSlots:: -clear_to_defaults() { - (*this) = get_defaults(); -} diff --git a/panda/src/pgraph/attribSlots.cxx b/panda/src/pgraph/attribSlots.cxx deleted file mode 100644 index 6fd0543ba0..0000000000 --- a/panda/src/pgraph/attribSlots.cxx +++ /dev/null @@ -1,217 +0,0 @@ -// Filename: attribSlots.h -// Created by: jyelon (01Sep05) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - -#include "attribSlots.h" -#include "renderAttrib.h" - -AttribSlots AttribSlots::_defvals; - -//////////////////////////////////////////////////////////////////// -// Function: AttribSlots::clear_to_defaults -// Access: Private -// Description: clears all values to their initial defaults. -//////////////////////////////////////////////////////////////////// -void AttribSlots:: -initialize_defvals() { - - // Step one. Fill slots with any object of right type. - // the actual value is totally irrelevant. - - _defvals._alpha_test = DCAST(AlphaTestAttrib,AlphaTestAttrib::make(AlphaTestAttrib::M_none, 0.0)); - _defvals._antialias = DCAST(AntialiasAttrib,AntialiasAttrib::make(AntialiasAttrib::M_none)); - _defvals._audio_volume = DCAST(AudioVolumeAttrib,AudioVolumeAttrib::make_identity()); - _defvals._aux_bitplane = DCAST(AuxBitplaneAttrib,AuxBitplaneAttrib::make()); - _defvals._clip_plane = DCAST(ClipPlaneAttrib,ClipPlaneAttrib::make_all_off()); - _defvals._color = DCAST(ColorAttrib,ColorAttrib::make_off()); - _defvals._color_blend = DCAST(ColorBlendAttrib,ColorBlendAttrib::make_off()); - _defvals._color_scale = DCAST(ColorScaleAttrib,ColorScaleAttrib::make_off()); - _defvals._color_write = DCAST(ColorWriteAttrib,ColorWriteAttrib::make(ColorWriteAttrib::C_all)); - _defvals._cull_bin = DCAST(CullBinAttrib,CullBinAttrib::make("",0)); - _defvals._cull_face = DCAST(CullFaceAttrib,CullFaceAttrib::make(CullFaceAttrib::M_cull_counter_clockwise)); - _defvals._depth_offset = DCAST(DepthOffsetAttrib,DepthOffsetAttrib::make(0)); - _defvals._depth_test = DCAST(DepthTestAttrib,DepthTestAttrib::make(DepthTestAttrib::M_none)); - _defvals._depth_write = DCAST(DepthWriteAttrib,DepthWriteAttrib::make(DepthWriteAttrib::M_on)); - _defvals._fog = DCAST(FogAttrib,FogAttrib::make_off()); - _defvals._light = DCAST(LightAttrib,LightAttrib::make_all_off()); - _defvals._light_ramp = DCAST(LightRampAttrib,LightRampAttrib::make_identity()); - _defvals._material = DCAST(MaterialAttrib,MaterialAttrib::make_off()); - _defvals._render_mode = DCAST(RenderModeAttrib,RenderModeAttrib::make(RenderModeAttrib::M_unchanged)); - _defvals._rescale_normal = DCAST(RescaleNormalAttrib,RescaleNormalAttrib::make_default()); - _defvals._shade_model = DCAST(ShadeModelAttrib,ShadeModelAttrib::make(ShadeModelAttrib::M_smooth)); - _defvals._shader = DCAST(ShaderAttrib,ShaderAttrib::make_off()); - _defvals._stencil = DCAST(StencilAttrib,StencilAttrib::make_off()); - _defvals._tex_gen = DCAST(TexGenAttrib,TexGenAttrib::make()); - _defvals._tex_matrix = DCAST(TexMatrixAttrib,TexMatrixAttrib::make()); - _defvals._texture = DCAST(TextureAttrib,TextureAttrib::make_all_off()); - _defvals._transparency = DCAST(TransparencyAttrib,TransparencyAttrib::make(TransparencyAttrib::M_none)); - _defvals._scissor = DCAST(ScissorAttrib, ScissorAttrib::make_off()); - - // Step two. Replace each with make_default_impl. - - _defvals._alpha_test = DCAST(AlphaTestAttrib,_defvals._alpha_test->make_default()); - _defvals._antialias = DCAST(AntialiasAttrib,_defvals._antialias->make_default()); - _defvals._audio_volume = DCAST(AudioVolumeAttrib,_defvals._audio_volume->make_default()); - _defvals._aux_bitplane = DCAST(AuxBitplaneAttrib,_defvals._aux_bitplane->make_default()); - _defvals._clip_plane = DCAST(ClipPlaneAttrib,_defvals._clip_plane->make_default()); - _defvals._color = DCAST(ColorAttrib,_defvals._color->make_default()); - _defvals._color_blend = DCAST(ColorBlendAttrib,_defvals._color_blend->make_default()); - _defvals._color_scale = DCAST(ColorScaleAttrib,_defvals._color_scale->make_default()); - _defvals._color_write = DCAST(ColorWriteAttrib,_defvals._color_write->make_default()); - _defvals._cull_bin = DCAST(CullBinAttrib,_defvals._cull_bin->make_default()); - _defvals._cull_face = DCAST(CullFaceAttrib,_defvals._cull_face->make_default()); - _defvals._depth_offset = DCAST(DepthOffsetAttrib,_defvals._depth_offset->make_default()); - _defvals._depth_test = DCAST(DepthTestAttrib,_defvals._depth_test->make_default()); - _defvals._depth_write = DCAST(DepthWriteAttrib,_defvals._depth_write->make_default()); - _defvals._fog = DCAST(FogAttrib,_defvals._fog->make_default()); - _defvals._light = DCAST(LightAttrib,_defvals._light->make_default()); - _defvals._light_ramp = DCAST(LightRampAttrib,_defvals._light_ramp->make_default()); - _defvals._material = DCAST(MaterialAttrib,_defvals._material->make_default()); - _defvals._render_mode = DCAST(RenderModeAttrib,_defvals._render_mode->make_default()); - _defvals._rescale_normal = DCAST(RescaleNormalAttrib,_defvals._rescale_normal->make_default()); - _defvals._shade_model = DCAST(ShadeModelAttrib,_defvals._shade_model->make_default()); - _defvals._shader = DCAST(ShaderAttrib,_defvals._shader->make_default()); - _defvals._stencil = DCAST(StencilAttrib,_defvals._stencil->make_default()); - _defvals._tex_gen = DCAST(TexGenAttrib,_defvals._tex_gen->make_default()); - _defvals._tex_matrix = DCAST(TexMatrixAttrib,_defvals._tex_matrix->make_default()); - _defvals._texture = DCAST(TextureAttrib,_defvals._texture->make_default()); - _defvals._transparency = DCAST(TransparencyAttrib,_defvals._transparency->make_default()); - _defvals._scissor = DCAST(ScissorAttrib,_defvals._scissor->make_default()); -} - -//////////////////////////////////////////////////////////////////// -// Function: AttribSlots::Default Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -AttribSlots:: -AttribSlots() { -} - -//////////////////////////////////////////////////////////////////// -// Function: AttribSlots::Copy Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -AttribSlots:: -AttribSlots(const AttribSlots ©) : - _alpha_test(copy._alpha_test), - _antialias(copy._antialias), - _audio_volume(copy._audio_volume), - _aux_bitplane(copy._aux_bitplane), - _clip_plane(copy._clip_plane), - _color(copy._color), - _color_blend(copy._color_blend), - _color_scale(copy._color_scale), - _color_write(copy._color_write), - _cull_bin(copy._cull_bin), - _cull_face(copy._cull_face), - _depth_offset(copy._depth_offset), - _depth_test(copy._depth_test), - _depth_write(copy._depth_write), - _fog(copy._fog), - _light(copy._light), - _light_ramp(copy._light_ramp), - _material(copy._material), - _render_mode(copy._render_mode), - _rescale_normal(copy._rescale_normal), - _shade_model(copy._shade_model), - _shader(copy._shader), - _stencil(copy._stencil), - _tex_gen(copy._tex_gen), - _tex_matrix(copy._tex_matrix), - _texture(copy._texture), - _transparency(copy._transparency), - _scissor(copy._scissor) -{ -} - -//////////////////////////////////////////////////////////////////// -// Function: AttribSlots::Copy Assignment Operator -// Access: Public -// Description: copy all the slots from source. -//////////////////////////////////////////////////////////////////// -void AttribSlots:: -operator =(const AttribSlots &src) { - _alpha_test = src._alpha_test; - _antialias = src._antialias; - _audio_volume = src._audio_volume; - _aux_bitplane = src._aux_bitplane; - _clip_plane = src._clip_plane; - _color = src._color; - _color_blend = src._color_blend; - _color_scale = src._color_scale; - _color_write = src._color_write; - _cull_bin = src._cull_bin; - _cull_face = src._cull_face; - _depth_offset = src._depth_offset; - _depth_test = src._depth_test; - _depth_write = src._depth_write; - _fog = src._fog; - _light = src._light; - _light_ramp = src._light_ramp; - _material = src._material; - _render_mode = src._render_mode; - _rescale_normal = src._rescale_normal; - _shade_model = src._shade_model; - _shader = src._shader; - _stencil = src._stencil; - _tex_gen = src._tex_gen; - _tex_matrix = src._tex_matrix; - _texture = src._texture; - _transparency = src._transparency; - _scissor = src._scissor; -} - -//////////////////////////////////////////////////////////////////// -// Function: AttribSlots::get_slot -// Access: Public -// Description: fetch the contents of the nth slot. -//////////////////////////////////////////////////////////////////// -const RenderAttrib *AttribSlots:: -get_slot(int n) const { - switch(n) { - case 0: return _alpha_test; - case 1: return _antialias; - case 2: return _audio_volume; - case 3: return _aux_bitplane; - case 4: return _clip_plane; - case 5: return _color; - case 6: return _color_blend; - case 7: return _color_scale; - case 8: return _color_write; - case 9: return _cull_bin; - case 10: return _cull_face; - case 11: return _depth_offset; - case 12: return _depth_test; - case 13: return _depth_write; - case 14: return _fog; - case 15: return _light; - case 16: return _light_ramp; - case 17: return _material; - case 18: return _render_mode; - case 19: return _rescale_normal; - case 20: return _shade_model; - case 21: return _shader; - case 22: return _stencil; - case 23: return _tex_gen; - case 24: return _tex_matrix; - case 25: return _texture; - case 26: return _transparency; - case 27: return _scissor; - default: - nassertr(false, NULL); - return NULL; - } -} - diff --git a/panda/src/pgraph/attribSlots.h b/panda/src/pgraph/attribSlots.h deleted file mode 100644 index 5932cdb461..0000000000 --- a/panda/src/pgraph/attribSlots.h +++ /dev/null @@ -1,109 +0,0 @@ -// Filename: attribSlots.h -// Created by: jyelon (01Sep05) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - -#ifndef ATTRIBSLOTS_H -#define ATTRIBSLOTS_H - -#include "pandabase.h" -#include "typedWritableReferenceCount.h" -#include "pointerTo.h" - -#include "renderAttrib.h" -#include "alphaTestAttrib.h" -#include "antialiasAttrib.h" -#include "audioVolumeAttrib.h" -#include "auxBitplaneAttrib.h" -#include "clipPlaneAttrib.h" -#include "colorAttrib.h" -#include "colorBlendAttrib.h" -#include "colorScaleAttrib.h" -#include "colorWriteAttrib.h" -#include "cullBinAttrib.h" -#include "cullFaceAttrib.h" -#include "depthOffsetAttrib.h" -#include "depthTestAttrib.h" -#include "depthWriteAttrib.h" -#include "fogAttrib.h" -#include "lightAttrib.h" -#include "lightRampAttrib.h" -#include "materialAttrib.h" -#include "renderModeAttrib.h" -#include "rescaleNormalAttrib.h" -#include "scissorAttrib.h" -#include "shadeModelAttrib.h" -#include "shaderAttrib.h" -#include "stencilAttrib.h" -#include "texMatrixAttrib.h" -#include "texGenAttrib.h" -#include "textureAttrib.h" -#include "transparencyAttrib.h" - -//////////////////////////////////////////////////////////////////// -// Class : AttribSlots -// Description : This is a very simple class: an object full of -// render attributes, one per attrib type. -//////////////////////////////////////////////////////////////////// - -class EXPCL_PANDA_PGRAPH AttribSlots -{ - public: - CPT(AlphaTestAttrib) _alpha_test; - CPT(AntialiasAttrib) _antialias; - CPT(AudioVolumeAttrib) _audio_volume; - CPT(AuxBitplaneAttrib) _aux_bitplane; - CPT(ClipPlaneAttrib) _clip_plane; - CPT(ColorAttrib) _color; - CPT(ColorBlendAttrib) _color_blend; - CPT(ColorScaleAttrib) _color_scale; - CPT(ColorWriteAttrib) _color_write; - CPT(CullBinAttrib) _cull_bin; - CPT(CullFaceAttrib) _cull_face; - CPT(DepthOffsetAttrib) _depth_offset; - CPT(DepthTestAttrib) _depth_test; - CPT(DepthWriteAttrib) _depth_write; - CPT(FogAttrib) _fog; - CPT(LightAttrib) _light; - CPT(LightRampAttrib) _light_ramp; - CPT(MaterialAttrib) _material; - CPT(RenderModeAttrib) _render_mode; - CPT(RescaleNormalAttrib) _rescale_normal; - CPT(ShadeModelAttrib) _shade_model; - CPT(ShaderAttrib) _shader; - CPT(StencilAttrib) _stencil; - CPT(TexGenAttrib) _tex_gen; - CPT(TexMatrixAttrib) _tex_matrix; - CPT(TextureAttrib) _texture; - CPT(TransparencyAttrib) _transparency; - CPT(ScissorAttrib) _scissor; - - public: - AttribSlots(); - AttribSlots(const AttribSlots ©); - INLINE void clear_to_zero(); - INLINE void clear_to_defaults(); - void operator =(const AttribSlots &src); - INLINE static const AttribSlots &get_defaults(); - - public: - enum { slot_count=28 }; - const RenderAttrib *get_slot(int n) const; - - private: - static AttribSlots _defvals; - static void initialize_defvals(); -}; - -#include "attribSlots.I" - -#endif /* ATTRIBSLOTS_H */ diff --git a/panda/src/pgraph/audioVolumeAttrib.cxx b/panda/src/pgraph/audioVolumeAttrib.cxx index 17044bf858..e2aea521df 100755 --- a/panda/src/pgraph/audioVolumeAttrib.cxx +++ b/panda/src/pgraph/audioVolumeAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "audioVolumeAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,8 +21,9 @@ #include "datagramIterator.h" #include "config_pgraph.h" -TypeHandle AudioVolumeAttrib::_type_handle; CPT(RenderAttrib) AudioVolumeAttrib::_identity_attrib; +TypeHandle AudioVolumeAttrib::_type_handle; +int AudioVolumeAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: AudioVolumeAttrib::Constructor @@ -84,6 +84,18 @@ make_off() { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: AudioVolumeAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AudioVolumeAttrib:: +make_default() { + return return_new(new AudioVolumeAttrib(false, 1.0f)); +} + //////////////////////////////////////////////////////////////////// // Function: AudioVolumeAttrib::set_volume // Access: Published @@ -210,33 +222,6 @@ invert_compose_impl(const RenderAttrib *other) const { return return_new(attrib); } -//////////////////////////////////////////////////////////////////// -// Function: AudioVolumeAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived AudioVolumeAttrib -// types to specify what the default property for a -// AudioVolumeAttrib of this type should be. -// -// This should return a newly-allocated AudioVolumeAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of AudioVolumeAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *AudioVolumeAttrib:: -make_default_impl() const { - return new AudioVolumeAttrib(false, 1.0f); -} - -//////////////////////////////////////////////////////////////////// -// Function: AudioVolumeAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void AudioVolumeAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_audio_volume = this; -} - //////////////////////////////////////////////////////////////////// // Function: AudioVolumeAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/audioVolumeAttrib.h b/panda/src/pgraph/audioVolumeAttrib.h index 3855a07311..ecae4bc767 100755 --- a/panda/src/pgraph/audioVolumeAttrib.h +++ b/panda/src/pgraph/audioVolumeAttrib.h @@ -36,6 +36,7 @@ PUBLISHED: static CPT(RenderAttrib) make_identity(); static CPT(RenderAttrib) make(float volume); static CPT(RenderAttrib) make_off(); + static CPT(RenderAttrib) make_default(); INLINE bool is_off() const; INLINE bool has_volume() const; @@ -44,13 +45,11 @@ PUBLISHED: public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: bool _off; @@ -58,6 +57,14 @@ private: float _volume; static CPT(RenderAttrib) _identity_attrib; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -74,6 +81,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "AudioVolumeAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -82,6 +90,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "audioVolumeAttrib.I" diff --git a/panda/src/pgraph/auxBitplaneAttrib.cxx b/panda/src/pgraph/auxBitplaneAttrib.cxx index 8eefb268d5..20ab5e1d25 100644 --- a/panda/src/pgraph/auxBitplaneAttrib.cxx +++ b/panda/src/pgraph/auxBitplaneAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "auxBitplaneAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle AuxBitplaneAttrib::_type_handle; +int AuxBitplaneAttrib::_attrib_slot; CPT(RenderAttrib) AuxBitplaneAttrib::_default; //////////////////////////////////////////////////////////////////// @@ -49,6 +49,18 @@ make(int outputs) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: AuxBitplaneAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AuxBitplaneAttrib:: +make_default() { + return return_new(new AuxBitplaneAttrib(0)); +} + //////////////////////////////////////////////////////////////////// // Function: AuxBitplaneAttrib::output // Access: Public, Virtual @@ -85,33 +97,6 @@ compare_to_impl(const RenderAttrib *other) const { return 0; } -//////////////////////////////////////////////////////////////////// -// Function: AuxBitplaneAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived AuxBitplaneAttrib -// types to specify what the default property for a -// AuxBitplaneAttrib of this type should be. -// -// This should return a newly-allocated AuxBitplaneAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of AuxBitplaneAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *AuxBitplaneAttrib:: -make_default_impl() const { - return new AuxBitplaneAttrib(0); -} - -//////////////////////////////////////////////////////////////////// -// Function: AuxBitplaneAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void AuxBitplaneAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_aux_bitplane = this; -} - //////////////////////////////////////////////////////////////////// // Function: AuxBitplaneAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/auxBitplaneAttrib.h b/panda/src/pgraph/auxBitplaneAttrib.h index d029163021..98398ea663 100644 --- a/panda/src/pgraph/auxBitplaneAttrib.h +++ b/panda/src/pgraph/auxBitplaneAttrib.h @@ -67,22 +67,29 @@ PUBLISHED: }; static CPT(RenderAttrib) make(); static CPT(RenderAttrib) make(int outputs); + static CPT(RenderAttrib) make_default(); INLINE int get_outputs() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: int _outputs; static CPT(RenderAttrib) _default; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -99,6 +106,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "AuxBitplaneAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -107,6 +115,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "auxBitplaneAttrib.I" diff --git a/panda/src/pgraph/clipPlaneAttrib.cxx b/panda/src/pgraph/clipPlaneAttrib.cxx index daa86e240b..9df143af08 100644 --- a/panda/src/pgraph/clipPlaneAttrib.cxx +++ b/panda/src/pgraph/clipPlaneAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "clipPlaneAttrib.h" -#include "attribSlots.h" #include "pandaNode.h" #include "graphicsStateGuardianBase.h" #include "bamReader.h" @@ -26,6 +25,7 @@ CPT(RenderAttrib) ClipPlaneAttrib::_empty_attrib; CPT(RenderAttrib) ClipPlaneAttrib::_all_off_attrib; TypeHandle ClipPlaneAttrib::_type_handle; +int ClipPlaneAttrib::_attrib_slot; // This STL Function object is used in filter_to_max(), below, to sort // a list of PlaneNodes in reverse order by priority. @@ -209,6 +209,18 @@ make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2, return make(); } +//////////////////////////////////////////////////////////////////// +// Function: ClipPlaneAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ClipPlaneAttrib:: +make_default() { + return return_new(new ClipPlaneAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: ClipPlaneAttrib::get_operation // Access: Published @@ -863,33 +875,6 @@ invert_compose_impl(const RenderAttrib *other) const { return other; } -//////////////////////////////////////////////////////////////////// -// Function: ClipPlaneAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived ClipPlaneAttrib -// types to specify what the default property for a -// ClipPlaneAttrib of this type should be. -// -// This should return a newly-allocated ClipPlaneAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of ClipPlaneAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *ClipPlaneAttrib:: -make_default_impl() const { - return new ClipPlaneAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: ClipPlaneAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void ClipPlaneAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_clip_plane = this; -} - //////////////////////////////////////////////////////////////////// // Function: ClipPlaneAttrib::sort_on_planes // Access: Private diff --git a/panda/src/pgraph/clipPlaneAttrib.h b/panda/src/pgraph/clipPlaneAttrib.h index bbada85694..7fd3473a79 100644 --- a/panda/src/pgraph/clipPlaneAttrib.h +++ b/panda/src/pgraph/clipPlaneAttrib.h @@ -57,6 +57,7 @@ PUBLISHED: static CPT(RenderAttrib) make(Operation op, PlaneNode *plane1, PlaneNode *plane2, PlaneNode *plane3, PlaneNode *plane4); + static CPT(RenderAttrib) make_default(); Operation get_operation() const; @@ -96,13 +97,11 @@ PUBLISHED: public: CPT(RenderAttrib) compose_off(const RenderAttrib *other) const; virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: INLINE void check_filtered() const; @@ -121,6 +120,14 @@ private: static CPT(RenderAttrib) _empty_attrib; static CPT(RenderAttrib) _all_off_attrib; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -139,6 +146,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "ClipPlaneAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -147,6 +155,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "clipPlaneAttrib.I" diff --git a/panda/src/pgraph/colorAttrib.cxx b/panda/src/pgraph/colorAttrib.cxx index 5714917f6d..06cee28ca3 100644 --- a/panda/src/pgraph/colorAttrib.cxx +++ b/panda/src/pgraph/colorAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "colorAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle ColorAttrib::_type_handle; +int ColorAttrib::_attrib_slot; CPT(RenderAttrib) ColorAttrib::_off; CPT(RenderAttrib) ColorAttrib::_vertex; @@ -71,6 +71,18 @@ make_off() { return _off; } +//////////////////////////////////////////////////////////////////// +// Function: ColorAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ColorAttrib:: +make_default() { + return return_new(new ColorAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: ColorAttrib::output // Access: Public, Virtual @@ -122,33 +134,6 @@ compare_to_impl(const RenderAttrib *other) const { return 0; } -//////////////////////////////////////////////////////////////////// -// Function: ColorAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived ColorAttrib -// types to specify what the default property for a -// ColorAttrib of this type should be. -// -// This should return a newly-allocated ColorAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of ColorAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *ColorAttrib:: -make_default_impl() const { - return new ColorAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: ColorAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void ColorAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_color = this; -} - //////////////////////////////////////////////////////////////////// // Function: ColorAttrib::quantize_color // Access: Private diff --git a/panda/src/pgraph/colorAttrib.h b/panda/src/pgraph/colorAttrib.h index c3e90baf9a..df895f7985 100644 --- a/panda/src/pgraph/colorAttrib.h +++ b/panda/src/pgraph/colorAttrib.h @@ -41,17 +41,16 @@ PUBLISHED: static CPT(RenderAttrib) make_vertex(); static CPT(RenderAttrib) make_flat(const Colorf &color); static CPT(RenderAttrib) make_off(); + static CPT(RenderAttrib) make_default(); INLINE Type get_color_type() const; INLINE const Colorf &get_color() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: void quantize_color(); @@ -62,6 +61,14 @@ private: static CPT(RenderAttrib) _off; static CPT(RenderAttrib) _vertex; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -78,6 +85,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "ColorAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -86,6 +94,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "colorAttrib.I" diff --git a/panda/src/pgraph/colorBlendAttrib.cxx b/panda/src/pgraph/colorBlendAttrib.cxx index ccfd2ff8df..f8729e17b5 100644 --- a/panda/src/pgraph/colorBlendAttrib.cxx +++ b/panda/src/pgraph/colorBlendAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "colorBlendAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle ColorBlendAttrib::_type_handle; +int ColorBlendAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: ColorBlendAttrib::make_off @@ -65,6 +65,18 @@ make(ColorBlendAttrib::Mode mode, return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: ColorBlendAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ColorBlendAttrib:: +make_default() { + return return_new(new ColorBlendAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: ColorBlendAttrib::output // Access: Public, Virtual @@ -119,33 +131,6 @@ compare_to_impl(const RenderAttrib *other) const { return _color.compare_to(ta->_color); } -//////////////////////////////////////////////////////////////////// -// Function: ColorBlendAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived ColorBlendAttrib -// types to specify what the default property for a -// ColorBlendAttrib of this type should be. -// -// This should return a newly-allocated ColorBlendAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of ColorBlendAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *ColorBlendAttrib:: -make_default_impl() const { - return new ColorBlendAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: ColorBlendAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void ColorBlendAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_color_blend = this; -} - //////////////////////////////////////////////////////////////////// // Function: ColorBlendAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/colorBlendAttrib.h b/panda/src/pgraph/colorBlendAttrib.h index 655329c0ec..1d81d4b42d 100644 --- a/panda/src/pgraph/colorBlendAttrib.h +++ b/panda/src/pgraph/colorBlendAttrib.h @@ -77,6 +77,7 @@ PUBLISHED: static CPT(RenderAttrib) make(Mode mode); static CPT(RenderAttrib) make(Mode mode, Operand a, Operand b, const Colorf &color = Colorf::zero()); + static CPT(RenderAttrib) make_default(); INLINE Mode get_mode() const; INLINE Operand get_operand_a() const; @@ -91,11 +92,9 @@ PUBLISHED: public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: Mode _mode; @@ -104,6 +103,14 @@ private: bool _involves_constant_color; bool _involves_color_scale; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -120,6 +127,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "ColorBlendAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -128,6 +136,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; ostream &operator << (ostream &out, ColorBlendAttrib::Mode mode); diff --git a/panda/src/pgraph/colorScaleAttrib.cxx b/panda/src/pgraph/colorScaleAttrib.cxx index 8ac20f381b..5f6a6fbc20 100644 --- a/panda/src/pgraph/colorScaleAttrib.cxx +++ b/panda/src/pgraph/colorScaleAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "colorScaleAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -23,6 +22,7 @@ #include "config_pgraph.h" TypeHandle ColorScaleAttrib::_type_handle; +int ColorScaleAttrib::_attrib_slot; CPT(RenderAttrib) ColorScaleAttrib::_identity_attrib; //////////////////////////////////////////////////////////////////// @@ -86,6 +86,18 @@ make_off() { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: ColorScaleAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ColorScaleAttrib:: +make_default() { + return return_new(new ColorScaleAttrib(false, LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f))); +} + //////////////////////////////////////////////////////////////////// // Function: ColorScaleAttrib::set_scale // Access: Published @@ -256,33 +268,6 @@ invert_compose_impl(const RenderAttrib *other) const { return return_new(attrib); } -//////////////////////////////////////////////////////////////////// -// Function: ColorScaleAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived ColorScaleAttrib -// types to specify what the default property for a -// ColorScaleAttrib of this type should be. -// -// This should return a newly-allocated ColorScaleAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of ColorScaleAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *ColorScaleAttrib:: -make_default_impl() const { - return new ColorScaleAttrib(false, LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f)); -} - -//////////////////////////////////////////////////////////////////// -// Function: ColorScaleAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void ColorScaleAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_color_scale = this; -} - //////////////////////////////////////////////////////////////////// // Function: ColorScaleAttrib::quantize_scale // Access: Private diff --git a/panda/src/pgraph/colorScaleAttrib.h b/panda/src/pgraph/colorScaleAttrib.h index 7a1133d864..a7afc99bd8 100644 --- a/panda/src/pgraph/colorScaleAttrib.h +++ b/panda/src/pgraph/colorScaleAttrib.h @@ -36,6 +36,7 @@ PUBLISHED: static CPT(RenderAttrib) make_identity(); static CPT(RenderAttrib) make(const LVecBase4f &scale); static CPT(RenderAttrib) make_off(); + static CPT(RenderAttrib) make_default(); INLINE bool is_off() const; INLINE bool is_identity() const; @@ -48,13 +49,11 @@ PUBLISHED: public: virtual bool lower_attrib_can_override() const; virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: void quantize_scale(); @@ -67,6 +66,14 @@ private: LVecBase4f _scale; static CPT(RenderAttrib) _identity_attrib; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -83,6 +90,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "ColorScaleAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -91,6 +99,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "colorScaleAttrib.I" diff --git a/panda/src/pgraph/colorWriteAttrib.cxx b/panda/src/pgraph/colorWriteAttrib.cxx index b1acc9f7b5..ef6459a817 100644 --- a/panda/src/pgraph/colorWriteAttrib.cxx +++ b/panda/src/pgraph/colorWriteAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "colorWriteAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle ColorWriteAttrib::_type_handle; +int ColorWriteAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: ColorWriteAttrib::make @@ -34,6 +34,18 @@ make(unsigned int channels) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: ColorWriteAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ColorWriteAttrib:: +make_default() { + return return_new(new ColorWriteAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: ColorWriteAttrib::output // Access: Public, Virtual @@ -82,33 +94,6 @@ compare_to_impl(const RenderAttrib *other) const { return (int)_channels - (int)ta->_channels; } -//////////////////////////////////////////////////////////////////// -// Function: ColorWriteAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived ColorWriteAttrib -// types to specify what the default property for a -// ColorWriteAttrib of this type should be. -// -// This should return a newly-allocated ColorWriteAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of ColorWriteAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *ColorWriteAttrib:: -make_default_impl() const { - return new ColorWriteAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: ColorWriteAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void ColorWriteAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_color_write = this; -} - //////////////////////////////////////////////////////////////////// // Function: ColorWriteAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/colorWriteAttrib.h b/panda/src/pgraph/colorWriteAttrib.h index 9b41d92c2a..8a7c8d5003 100644 --- a/panda/src/pgraph/colorWriteAttrib.h +++ b/panda/src/pgraph/colorWriteAttrib.h @@ -47,16 +47,15 @@ private: PUBLISHED: static CPT(RenderAttrib) make(unsigned int channels); + static CPT(RenderAttrib) make_default(); INLINE unsigned int get_channels() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: int _channels; @@ -68,6 +67,14 @@ public: protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); void fillin(DatagramIterator &scan, BamReader *manager); + +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } public: static TypeHandle get_class_type() { @@ -77,6 +84,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "ColorWriteAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -85,6 +93,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "colorWriteAttrib.I" diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index 1a56c53fe9..4182210849 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.cxx @@ -36,7 +36,6 @@ #include "depthOffsetAttrib.h" #include "depthTestAttrib.h" #include "depthWriteAttrib.h" -#include "drawMaskAttrib.h" #include "eventStorePandaNode.h" #include "findApproxLevelEntry.h" #include "fadeLodNode.h" @@ -391,7 +390,6 @@ init_libpgraph() { DepthOffsetAttrib::init_type(); DepthTestAttrib::init_type(); DepthWriteAttrib::init_type(); - DrawMaskAttrib::init_type(); EventStorePandaNode::init_type(); FadeLODNode::init_type(); FadeLODNodeData::init_type(); @@ -470,7 +468,6 @@ init_libpgraph() { DepthOffsetAttrib::register_with_read_factory(); DepthTestAttrib::register_with_read_factory(); DepthWriteAttrib::register_with_read_factory(); - DrawMaskAttrib::register_with_read_factory(); FadeLODNode::register_with_read_factory(); Fog::register_with_read_factory(); FogAttrib::register_with_read_factory(); diff --git a/panda/src/pgraph/cullBinAttrib.cxx b/panda/src/pgraph/cullBinAttrib.cxx index b8a8244d24..aa6aa63e5a 100644 --- a/panda/src/pgraph/cullBinAttrib.cxx +++ b/panda/src/pgraph/cullBinAttrib.cxx @@ -13,13 +13,13 @@ //////////////////////////////////////////////////////////////////// #include "cullBinAttrib.h" -#include "attribSlots.h" #include "bamReader.h" #include "bamWriter.h" #include "datagram.h" #include "datagramIterator.h" TypeHandle CullBinAttrib::_type_handle; +int CullBinAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: CullBinAttrib::make @@ -40,6 +40,18 @@ make(const string &bin_name, int draw_order) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: CullBinAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) CullBinAttrib:: +make_default() { + return return_new(new CullBinAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: CullBinAttrib::output // Access: Public, Virtual @@ -80,33 +92,6 @@ compare_to_impl(const RenderAttrib *other) const { return strcmp(_bin_name.c_str(), ta->_bin_name.c_str()); } -//////////////////////////////////////////////////////////////////// -// Function: CullBinAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived CullBinAttrib -// types to specify what the default property for a -// CullBinAttrib of this type should be. -// -// This should return a newly-allocated CullBinAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of CullBinAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *CullBinAttrib:: -make_default_impl() const { - return new CullBinAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: CullBinAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void CullBinAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_cull_bin = this; -} - //////////////////////////////////////////////////////////////////// // Function: CullBinAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/cullBinAttrib.h b/panda/src/pgraph/cullBinAttrib.h index f5b14017c7..98bcf72e0c 100644 --- a/panda/src/pgraph/cullBinAttrib.h +++ b/panda/src/pgraph/cullBinAttrib.h @@ -33,22 +33,29 @@ private: PUBLISHED: static CPT(RenderAttrib) make(const string &bin_name, int draw_order); + static CPT(RenderAttrib) make_default(); INLINE const string &get_bin_name() const; INLINE int get_draw_order() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: string _bin_name; int _draw_order; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -65,6 +72,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "CullBinAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -73,6 +81,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "cullBinAttrib.I" diff --git a/panda/src/pgraph/cullFaceAttrib.cxx b/panda/src/pgraph/cullFaceAttrib.cxx index 6d140867a4..32b6933287 100644 --- a/panda/src/pgraph/cullFaceAttrib.cxx +++ b/panda/src/pgraph/cullFaceAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "cullFaceAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle CullFaceAttrib::_type_handle; +int CullFaceAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: CullFaceAttrib::make @@ -51,8 +51,6 @@ make(CullFaceAttrib::Mode mode) { // the scene graph. M_cull_clockwise will be treated as // M_cull_counter_clockwise, and vice-versa. // M_cull_none is unchanged. - - //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) CullFaceAttrib:: make_reverse() { @@ -60,6 +58,18 @@ make_reverse() { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: CullFaceAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) CullFaceAttrib:: +make_default() { + return return_new(new CullFaceAttrib(M_cull_clockwise, false)); +} + //////////////////////////////////////////////////////////////////// // Function: CullFaceAttrib::get_effective_mode // Access: Published @@ -223,33 +233,6 @@ invert_compose_impl(const RenderAttrib *other) const { return return_new(attrib); } -//////////////////////////////////////////////////////////////////// -// Function: CullFaceAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived CullFaceAttrib -// types to specify what the default property for a -// CullFaceAttrib of this type should be. -// -// This should return a newly-allocated CullFaceAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of CullFaceAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *CullFaceAttrib:: -make_default_impl() const { - return new CullFaceAttrib(M_cull_clockwise, false); -} - -//////////////////////////////////////////////////////////////////// -// Function: CullFaceAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void CullFaceAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_cull_face = this; -} - //////////////////////////////////////////////////////////////////// // Function: CullFaceAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/cullFaceAttrib.h b/panda/src/pgraph/cullFaceAttrib.h index ae60206db0..306065a85d 100644 --- a/panda/src/pgraph/cullFaceAttrib.h +++ b/panda/src/pgraph/cullFaceAttrib.h @@ -41,6 +41,7 @@ private: PUBLISHED: static CPT(RenderAttrib) make(Mode mode = M_cull_clockwise); static CPT(RenderAttrib) make_reverse(); + static CPT(RenderAttrib) make_default(); INLINE Mode get_actual_mode() const; INLINE bool get_reverse() const; @@ -48,18 +49,24 @@ PUBLISHED: public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: Mode _mode; bool _reverse; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -76,6 +83,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "CullFaceAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -84,6 +92,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "cullFaceAttrib.I" diff --git a/panda/src/pgraph/cullPlanes.cxx b/panda/src/pgraph/cullPlanes.cxx index f68f4c135a..31befcdbfe 100644 --- a/panda/src/pgraph/cullPlanes.cxx +++ b/panda/src/pgraph/cullPlanes.cxx @@ -136,7 +136,7 @@ do_cull(int &result, CPT(RenderState) &state, result = BoundingVolume::IF_all | BoundingVolume::IF_possible | BoundingVolume::IF_some; - CPT(ClipPlaneAttrib) orig_cpa = state->get_clip_plane(); + CPT(ClipPlaneAttrib) orig_cpa = DCAST(ClipPlaneAttrib, state->get_attrib(ClipPlaneAttrib::get_class_slot())); // If there are no clip planes in the state, the node is completely // in front of all zero of the clip planes. (This can happen if @@ -172,7 +172,7 @@ do_cull(int &result, CPT(RenderState) &state, if (new_cpa != orig_cpa) { if (new_cpa->is_identity()) { - state = state->remove_attrib(ClipPlaneAttrib::get_class_type()); + state = state->remove_attrib(ClipPlaneAttrib::get_class_slot()); } else { state = state->add_attrib(new_cpa); } diff --git a/panda/src/pgraph/cullResult.cxx b/panda/src/pgraph/cullResult.cxx index 811ab8f75d..ca8cc78ed7 100644 --- a/panda/src/pgraph/cullResult.cxx +++ b/panda/src/pgraph/cullResult.cxx @@ -114,7 +114,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) { const RenderState *state = object->_state; nassertv(state != (const RenderState *)NULL); - const TransparencyAttrib *trans = state->get_transparency(); + const TransparencyAttrib *trans = DCAST(TransparencyAttrib, state->get_attrib(TransparencyAttrib::get_class_slot())); if (trans != (const TransparencyAttrib *)NULL) { switch (trans->get_mode()) { case TransparencyAttrib::M_alpha: @@ -163,7 +163,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) { // explicit bin already applied; otherwise, M_dual falls back // to M_alpha. { - const CullBinAttrib *bin_attrib = state->get_bin(); + const CullBinAttrib *bin_attrib = DCAST(CullBinAttrib, state->get_attrib(CullBinAttrib::get_class_slot())); if (bin_attrib == (CullBinAttrib *)NULL || bin_attrib->get_bin_name().empty()) { // We make a copy of the object to draw the transparent part @@ -397,10 +397,10 @@ check_flash_bin(CPT(RenderState) &state, CullBin *bin) { if (bin->has_flash_color()) { int cycle = (int)(ClockObject::get_global_clock()->get_frame_time() * bin_color_flash_rate); if ((cycle & 1) == 0) { - state = state->remove_attrib(TextureAttrib::get_class_type()); - state = state->remove_attrib(LightAttrib::get_class_type()); - state = state->remove_attrib(ColorScaleAttrib::get_class_type()); - state = state->remove_attrib(FogAttrib::get_class_type()); + state = state->remove_attrib(TextureAttrib::get_class_slot()); + state = state->remove_attrib(LightAttrib::get_class_slot()); + state = state->remove_attrib(ColorScaleAttrib::get_class_slot()); + state = state->remove_attrib(FogAttrib::get_class_slot()); state = state->add_attrib(ColorAttrib::make_flat(bin->get_flash_color()), RenderState::get_max_priority()); } @@ -419,10 +419,10 @@ check_flash_transparency(CPT(RenderState) &state, const Colorf &transparency) { if (show_transparency) { int cycle = (int)(ClockObject::get_global_clock()->get_frame_time() * bin_color_flash_rate); if ((cycle & 1) == 0) { - state = state->remove_attrib(TextureAttrib::get_class_type()); - state = state->remove_attrib(LightAttrib::get_class_type()); - state = state->remove_attrib(ColorScaleAttrib::get_class_type()); - state = state->remove_attrib(FogAttrib::get_class_type()); + state = state->remove_attrib(TextureAttrib::get_class_slot()); + state = state->remove_attrib(LightAttrib::get_class_slot()); + state = state->remove_attrib(ColorScaleAttrib::get_class_slot()); + state = state->remove_attrib(FogAttrib::get_class_slot()); state = state->add_attrib(ColorAttrib::make_flat(transparency), RenderState::get_max_priority()); } diff --git a/panda/src/pgraph/cullTraverser.cxx b/panda/src/pgraph/cullTraverser.cxx index 3a5f38d509..fdccb36a8b 100644 --- a/panda/src/pgraph/cullTraverser.cxx +++ b/panda/src/pgraph/cullTraverser.cxx @@ -198,7 +198,7 @@ traverse(CullTraverserData &data) { data.apply_transform_and_state(this); - const FogAttrib *fog = node_reader->get_state()->get_fog(); + const FogAttrib *fog = DCAST(FogAttrib, node_reader->get_state()->get_attrib(FogAttrib::get_class_slot())); if (fog != (const FogAttrib *)NULL && fog->get_fog() != (Fog *)NULL) { // If we just introduced a FogAttrib here, call adjust_to_camera() // now. This maybe isn't the perfect time to call it, but it's diff --git a/panda/src/pgraph/cullTraverserData.cxx b/panda/src/pgraph/cullTraverserData.cxx index 24d0f13c0b..c6f38b6236 100644 --- a/panda/src/pgraph/cullTraverserData.cxx +++ b/panda/src/pgraph/cullTraverserData.cxx @@ -116,7 +116,7 @@ apply_transform_and_state(CullTraverser *trav, if (clip_plane_cull) { _cull_planes = _cull_planes->apply_state(trav, this, - node_state->get_clip_plane(), + DCAST(ClipPlaneAttrib, node_state->get_attrib(ClipPlaneAttrib::get_class_slot())), DCAST(ClipPlaneAttrib, off_clip_planes)); } } diff --git a/panda/src/pgraph/cullableObject.cxx b/panda/src/pgraph/cullableObject.cxx index 47d6972912..4760be99e3 100644 --- a/panda/src/pgraph/cullableObject.cxx +++ b/panda/src/pgraph/cullableObject.cxx @@ -238,7 +238,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { bool has_aspect_ratio = (aspect_ratio.has_column()); bool sprite_texcoord = false; - const TexGenAttrib *tex_gen = _state->get_tex_gen(); + const TexGenAttrib *tex_gen = DCAST(TexGenAttrib, _state->get_attrib(TexGenAttrib::get_class_slot())); if (tex_gen != (TexGenAttrib *)NULL) { if (tex_gen->get_mode(TextureStage::get_default()) == TexGenAttrib::M_point_sprite) { sprite_texcoord = true; @@ -250,7 +250,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { float point_size = 1.0f; bool perspective = false; - const RenderModeAttrib *render_mode = _state->get_render_mode(); + const RenderModeAttrib *render_mode = DCAST(RenderModeAttrib, _state->get_attrib(RenderModeAttrib::get_class_slot())); if (render_mode != (RenderModeAttrib *)NULL) { point_size = render_mode->get_thickness(); perspective = render_mode->get_perspective(); @@ -604,7 +604,7 @@ munge_texcoord_light_vector(const CullTraverser *traverser, bool force) { return true; } - CPT(TexGenAttrib) tex_gen = _state->get_tex_gen(); + CPT(TexGenAttrib) tex_gen = DCAST(TexGenAttrib, _state->get_attrib(TexGenAttrib::get_class_slot())); nassertr(tex_gen != (TexGenAttrib *)NULL, false); const TexGenAttrib::LightVectors &light_vectors = tex_gen->get_light_vectors(); @@ -617,7 +617,7 @@ munge_texcoord_light_vector(const CullTraverser *traverser, bool force) { if (light.is_empty()) { // If a particular light isn't specified in the TexGenAttrib, // use the most important light in the current state. - CPT(RenderAttrib) attrib = _state->get_attrib(LightAttrib::get_class_type()); + CPT(RenderAttrib) attrib = _state->get_attrib(LightAttrib::get_class_slot()); if (attrib != (RenderAttrib *)NULL) { CPT(LightAttrib) la = DCAST(LightAttrib, attrib); light = la->get_most_important_light(); diff --git a/panda/src/pgraph/depthOffsetAttrib.cxx b/panda/src/pgraph/depthOffsetAttrib.cxx index 72ce85ed8c..7630d8824a 100644 --- a/panda/src/pgraph/depthOffsetAttrib.cxx +++ b/panda/src/pgraph/depthOffsetAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "depthOffsetAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle DepthOffsetAttrib::_type_handle; +int DepthOffsetAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: DepthOffsetAttrib::make @@ -36,6 +36,18 @@ make(int offset) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: DepthOffsetAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) DepthOffsetAttrib:: +make_default() { + return return_new(new DepthOffsetAttrib(0)); +} + //////////////////////////////////////////////////////////////////// // Function: DepthOffsetAttrib::output // Access: Public, Virtual @@ -114,33 +126,6 @@ invert_compose_impl(const RenderAttrib *other) const { return return_new(attrib); } -//////////////////////////////////////////////////////////////////// -// Function: DepthOffsetAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived DepthOffsetAttrib -// types to specify what the default property for a -// DepthOffsetAttrib of this type should be. -// -// This should return a newly-allocated DepthOffsetAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of DepthOffsetAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *DepthOffsetAttrib:: -make_default_impl() const { - return new DepthOffsetAttrib(0); -} - -//////////////////////////////////////////////////////////////////// -// Function: DepthOffsetAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void DepthOffsetAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_depth_offset = this; -} - //////////////////////////////////////////////////////////////////// // Function: DepthOffsetAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/depthOffsetAttrib.h b/panda/src/pgraph/depthOffsetAttrib.h index 2346447870..542241a1b5 100644 --- a/panda/src/pgraph/depthOffsetAttrib.h +++ b/panda/src/pgraph/depthOffsetAttrib.h @@ -56,22 +56,29 @@ private: PUBLISHED: static CPT(RenderAttrib) make(int offset = 1); + static CPT(RenderAttrib) make_default(); INLINE int get_offset() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: int _offset; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -88,6 +95,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "DepthOffsetAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -96,6 +104,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "depthOffsetAttrib.I" diff --git a/panda/src/pgraph/depthTestAttrib.cxx b/panda/src/pgraph/depthTestAttrib.cxx index db12397a2d..2efbdbe20e 100644 --- a/panda/src/pgraph/depthTestAttrib.cxx +++ b/panda/src/pgraph/depthTestAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "depthTestAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle DepthTestAttrib::_type_handle; +int DepthTestAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: DepthTestAttrib::make @@ -34,6 +34,18 @@ make(DepthTestAttrib::PandaCompareFunc mode) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: DepthTestAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) DepthTestAttrib:: +make_default() { + return return_new(new DepthTestAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: DepthTestAttrib::output // Access: Public, Virtual @@ -67,33 +79,6 @@ compare_to_impl(const RenderAttrib *other) const { return (int)_mode - (int)ta->_mode; } -//////////////////////////////////////////////////////////////////// -// Function: DepthTestAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived DepthTestAttrib -// types to specify what the default property for a -// DepthTestAttrib of this type should be. -// -// This should return a newly-allocated DepthTestAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of DepthTestAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *DepthTestAttrib:: -make_default_impl() const { - return new DepthTestAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: DepthTestAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void DepthTestAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_depth_test = this; -} - //////////////////////////////////////////////////////////////////// // Function: DepthTestAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/depthTestAttrib.h b/panda/src/pgraph/depthTestAttrib.h index 92acc36888..2553543579 100644 --- a/panda/src/pgraph/depthTestAttrib.h +++ b/panda/src/pgraph/depthTestAttrib.h @@ -31,20 +31,27 @@ private: PUBLISHED: static CPT(RenderAttrib) make(PandaCompareFunc mode); + static CPT(RenderAttrib) make_default(); INLINE PandaCompareFunc get_mode() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: PandaCompareFunc _mode; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -61,6 +68,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "DepthTestAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -69,6 +77,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "depthTestAttrib.I" diff --git a/panda/src/pgraph/depthWriteAttrib.cxx b/panda/src/pgraph/depthWriteAttrib.cxx index 3cbae1d719..113b469b5e 100644 --- a/panda/src/pgraph/depthWriteAttrib.cxx +++ b/panda/src/pgraph/depthWriteAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "depthWriteAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle DepthWriteAttrib::_type_handle; +int DepthWriteAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: DepthWriteAttrib::make @@ -34,6 +34,18 @@ make(DepthWriteAttrib::Mode mode) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: DepthWriteAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) DepthWriteAttrib:: +make_default() { + return return_new(new DepthWriteAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: DepthWriteAttrib::output // Access: Public, Virtual @@ -74,33 +86,6 @@ compare_to_impl(const RenderAttrib *other) const { return (int)_mode - (int)ta->_mode; } -//////////////////////////////////////////////////////////////////// -// Function: DepthWriteAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived DepthWriteAttrib -// types to specify what the default property for a -// DepthWriteAttrib of this type should be. -// -// This should return a newly-allocated DepthWriteAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of DepthWriteAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *DepthWriteAttrib:: -make_default_impl() const { - return new DepthWriteAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: DepthWriteAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void DepthWriteAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_depth_write = this; -} - //////////////////////////////////////////////////////////////////// // Function: DepthWriteAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/depthWriteAttrib.h b/panda/src/pgraph/depthWriteAttrib.h index 5fb37cc872..a500bee583 100644 --- a/panda/src/pgraph/depthWriteAttrib.h +++ b/panda/src/pgraph/depthWriteAttrib.h @@ -37,20 +37,27 @@ private: PUBLISHED: static CPT(RenderAttrib) make(Mode mode); + static CPT(RenderAttrib) make_default(); INLINE Mode get_mode() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: Mode _mode; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -67,6 +74,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "DepthWriteAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -75,6 +83,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "depthWriteAttrib.I" diff --git a/panda/src/pgraph/drawMaskAttrib.I b/panda/src/pgraph/drawMaskAttrib.I deleted file mode 100644 index 4ed6bf23a3..0000000000 --- a/panda/src/pgraph/drawMaskAttrib.I +++ /dev/null @@ -1,92 +0,0 @@ -// Filename: drawMaskAttrib.I -// Created by: drose (28Sep05) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::Constructor -// Access: Protected -// Description: Use DrawMaskAttrib::make() to construct a new -// DrawMaskAttrib object. -//////////////////////////////////////////////////////////////////// -INLINE DrawMaskAttrib:: -DrawMaskAttrib(DrawMask new_mask, DrawMask bits_to_change) : - _new_mask(new_mask & bits_to_change), - _bits_to_change(bits_to_change) -{ -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::Copy Constructor -// Access: Protected -// Description: Use DrawMaskAttrib::make() to construct a new -// DrawMaskAttrib object. -//////////////////////////////////////////////////////////////////// -INLINE DrawMaskAttrib:: -DrawMaskAttrib(const DrawMaskAttrib ©) : - _new_mask(copy._new_mask), - _bits_to_change(copy._bits_to_change) -{ -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::make_hide -// Access: Published, Static -// Description: Constructs a new DrawMaskAttrib that removes the -// indicated draw bits from the visibility mask. That -// is, it makes any nodes invisible to cameras that have -// any bits in common with draw_mask. This is similar -// to (but not quite identical to) -// NodePath.hide(draw_mask). -//////////////////////////////////////////////////////////////////// -INLINE CPT(RenderAttrib) DrawMaskAttrib:: -make_hide(DrawMask draw_mask) { - return make(DrawMask::all_off(), draw_mask); -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::make_show -// Access: Published, Static -// Description: Constructs a new DrawMaskAttrib that adds the -// indicated draw bits to the visibility mask. That -// is, it makes any nodes visible to cameras that have -// any bits in common with draw_mask. This is similar -// to (but not quite identical to) -// NodePath.show(draw_mask). -//////////////////////////////////////////////////////////////////// -INLINE CPT(RenderAttrib) DrawMaskAttrib:: -make_show(DrawMask draw_mask) { - return make(draw_mask, draw_mask); -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::get_new_mask -// Access: Published -// Description: Returns the new DrawMask that will be set after the -// attrib has been applied. -//////////////////////////////////////////////////////////////////// -INLINE DrawMask DrawMaskAttrib:: -get_new_mask() const { - return _new_mask; -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::get_bits_to_change -// Access: Published -// Description: Returns the set of bits that will be allowed to be -// changed by this DrawMaskAttrib. -//////////////////////////////////////////////////////////////////// -INLINE DrawMask DrawMaskAttrib:: -get_bits_to_change() const { - return _bits_to_change; -} diff --git a/panda/src/pgraph/drawMaskAttrib.cxx b/panda/src/pgraph/drawMaskAttrib.cxx deleted file mode 100644 index cbcf0cf498..0000000000 --- a/panda/src/pgraph/drawMaskAttrib.cxx +++ /dev/null @@ -1,226 +0,0 @@ -// Filename: drawMaskAttrib.cxx -// Created by: drose (28Sep05) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - -#include "drawMaskAttrib.h" -#include "dcast.h" -#include "bamReader.h" -#include "bamWriter.h" -#include "datagram.h" -#include "datagramIterator.h" -#include "cullTraverser.h" -#include "config_pgraph.h" - -TypeHandle DrawMaskAttrib::_type_handle; - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::make -// Access: Published, Static -// Description: Constructs a new DrawMaskAttrib that changes the -// bits_to_change bits in the current DrawMask to the -// values of the corresponding bits in new_mask. Only -// those bits in common with bits_to_change are -// affected. -//////////////////////////////////////////////////////////////////// -CPT(RenderAttrib) DrawMaskAttrib:: -make(DrawMask new_mask, DrawMask bits_to_change) { - DrawMaskAttrib *attrib = new DrawMaskAttrib(new_mask, bits_to_change); - return return_new(attrib); -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::output -// Access: Public, Virtual -// Description: -//////////////////////////////////////////////////////////////////// -void DrawMaskAttrib:: -output(ostream &out) const { - out << get_type() << ":" << get_new_mask() << "/" << get_bits_to_change(); -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::compare_to_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived DrawMaskAttrib -// types to return a unique number indicating whether -// this DrawMaskAttrib is equivalent to the other one. -// -// This should return 0 if the two DrawMaskAttrib objects -// are equivalent, a number less than zero if this one -// should be sorted before the other one, and a number -// greater than zero otherwise. -// -// This will only be called with two DrawMaskAttrib -// objects whose get_type() functions return the same. -//////////////////////////////////////////////////////////////////// -int DrawMaskAttrib:: -compare_to_impl(const RenderAttrib *other) const { - const DrawMaskAttrib *ta; - DCAST_INTO_R(ta, other, 0); - - int compare = get_new_mask().compare_to(ta->get_new_mask()); - if (compare != 0) { - return compare; - } - compare = get_bits_to_change().compare_to(ta->get_bits_to_change()); - return compare; -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::compose_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived RenderAttrib -// types to specify how two consecutive RenderAttrib -// objects of the same type interact. -// -// This should return the result of applying the other -// RenderAttrib to a node in the scene graph below this -// RenderAttrib, which was already applied. In most -// cases, the result is the same as the other -// RenderAttrib (that is, a subsequent RenderAttrib -// completely replaces the preceding one). On the other -// hand, some kinds of RenderAttrib (for instance, -// ColorTransformAttrib) might combine in meaningful -// ways. -//////////////////////////////////////////////////////////////////// -CPT(RenderAttrib) DrawMaskAttrib:: -compose_impl(const RenderAttrib *other) const { - const DrawMaskAttrib *ta; - DCAST_INTO_R(ta, other, 0); - - DrawMask mask = get_new_mask(); - mask = (mask & ~ta->get_bits_to_change()) | ta->get_new_mask(); - - DrawMaskAttrib *attrib = new DrawMaskAttrib(mask, DrawMask::all_on()); - return return_new(attrib); -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived DrawMaskAttrib -// types to specify what the default property for a -// DrawMaskAttrib of this type should be. -// -// This should return a newly-allocated DrawMaskAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of DrawMaskAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *DrawMaskAttrib:: -make_default_impl() const { - return new DrawMaskAttrib(DrawMask::all_on(), DrawMask::all_on()); -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void DrawMaskAttrib:: -store_into_slot(AttribSlots *) const { - // There's no need to store a DrawMaskAttrib at the moment, since it - // doesn't actually change any rendering state. -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::has_cull_callback -// Access: Public, Virtual -// Description: Should be overridden by derived classes to return -// true if cull_callback() has been defined. Otherwise, -// returns false to indicate cull_callback() does not -// need to be called for this node during the cull -// traversal. -//////////////////////////////////////////////////////////////////// -bool DrawMaskAttrib:: -has_cull_callback() const { - return (_new_mask != DrawMask::all_on()); -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::cull_callback -// Access: Public, Virtual -// Description: If has_cull_callback() returns true, this function -// will be called during the cull traversal to perform -// any additional operations that should be performed at -// cull time. -// -// This is called each time the RenderAttrib is -// discovered applied to a Geom in the traversal. It -// should return true if the Geom is visible, false if -// it should be omitted. -//////////////////////////////////////////////////////////////////// -bool DrawMaskAttrib:: -cull_callback(CullTraverser *trav, const CullTraverserData &) const { - return (trav->get_camera_mask() & _new_mask) != 0; -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::register_with_read_factory -// Access: Public, Static -// Description: Tells the BamReader how to create objects of type -// DrawMaskAttrib. -//////////////////////////////////////////////////////////////////// -void DrawMaskAttrib:: -register_with_read_factory() { - BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::write_datagram -// Access: Public, Virtual -// Description: Writes the contents of this object to the datagram -// for shipping out to a Bam file. -//////////////////////////////////////////////////////////////////// -void DrawMaskAttrib:: -write_datagram(BamWriter *manager, Datagram &dg) { - RenderAttrib::write_datagram(manager, dg); - - dg.add_uint32(_new_mask.get_word()); - dg.add_uint32(_bits_to_change.get_word()); -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::make_from_bam -// Access: Protected, Static -// Description: This function is called by the BamReader's factory -// when a new object of type DrawMaskAttrib is encountered -// in the Bam file. It should create the DrawMaskAttrib -// and extract its information from the file. -//////////////////////////////////////////////////////////////////// -TypedWritable *DrawMaskAttrib:: -make_from_bam(const FactoryParams ¶ms) { - DrawMaskAttrib *attrib = new DrawMaskAttrib(0, 0); - DatagramIterator scan; - BamReader *manager; - - parse_params(params, scan, manager); - attrib->fillin(scan, manager); - - return attrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: DrawMaskAttrib::fillin -// Access: Protected -// Description: This internal function is called by make_from_bam to -// read in all of the relevant data from the BamFile for -// the new DrawMaskAttrib. -//////////////////////////////////////////////////////////////////// -void DrawMaskAttrib:: -fillin(DatagramIterator &scan, BamReader *manager) { - RenderAttrib::fillin(scan, manager); - - _new_mask.set_word(scan.get_uint32()); - _bits_to_change.set_word(scan.get_uint32()); -} diff --git a/panda/src/pgraph/drawMaskAttrib.h b/panda/src/pgraph/drawMaskAttrib.h deleted file mode 100644 index ce225f495c..0000000000 --- a/panda/src/pgraph/drawMaskAttrib.h +++ /dev/null @@ -1,98 +0,0 @@ -// Filename: drawMaskAttrib.h -// Created by: drose (28Sep05) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - -#ifndef DRAWMASKATTRIB_H -#define DRAWMASKATTRIB_H - -#include "pandabase.h" - -#include "renderAttrib.h" -#include "drawMask.h" - -class FactoryParams; - -//////////////////////////////////////////////////////////////////// -// Class : DrawMaskAttrib -// Description : This attrib can be used to control the visibility of -// certain Geoms from certain cameras. It is similar in -// principle to the PandaNode::set_draw_mask() -// interface, except it does not cause an early prune in -// the cull traversal; thus, it can be used to show a -// node even though its parent has been hidden (if the -// parent was hidden using the same interface). -// -// It is mainly useful for unusual circumstances in -// which the visibility of a node is not easy to -// determine from examining the static hierarchy of the -// graph. -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDA_PGRAPH DrawMaskAttrib : public RenderAttrib { -protected: - INLINE DrawMaskAttrib(DrawMask new_mask, DrawMask bits_to_change); - INLINE DrawMaskAttrib(const DrawMaskAttrib ©); - -PUBLISHED: - INLINE static CPT(RenderAttrib) make_hide(DrawMask draw_mask = DrawMask::all_on()); - INLINE static CPT(RenderAttrib) make_show(DrawMask draw_mask = DrawMask::all_on()); - static CPT(RenderAttrib) make(DrawMask new_mask, DrawMask bits_to_change); - - INLINE DrawMask get_new_mask() const; - INLINE DrawMask get_bits_to_change() const; - -public: - virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; - - virtual bool has_cull_callback() const; - virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const; - -protected: - virtual int compare_to_impl(const RenderAttrib *other) const; - virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; - -private: - DrawMask _new_mask; - DrawMask _bits_to_change; - -public: - static void register_with_read_factory(); - virtual void write_datagram(BamWriter *manager, Datagram &dg); - -protected: - static TypedWritable *make_from_bam(const FactoryParams ¶ms); - void fillin(DatagramIterator &scan, BamReader *manager); - -public: - static TypeHandle get_class_type() { - return _type_handle; - } - static void init_type() { - RenderAttrib::init_type(); - register_type(_type_handle, "DrawMaskAttrib", - RenderAttrib::get_class_type()); - } - virtual TypeHandle get_type() const { - return get_class_type(); - } - virtual TypeHandle force_init_type() {init_type(); return get_class_type();} - -private: - static TypeHandle _type_handle; -}; - -#include "drawMaskAttrib.I" - -#endif - diff --git a/panda/src/pgraph/fogAttrib.cxx b/panda/src/pgraph/fogAttrib.cxx index 1848bf6e1a..175d0e6c31 100644 --- a/panda/src/pgraph/fogAttrib.cxx +++ b/panda/src/pgraph/fogAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "fogAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "bamReader.h" #include "bamWriter.h" @@ -21,6 +20,7 @@ #include "datagramIterator.h" TypeHandle FogAttrib::_type_handle; +int FogAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: FogAttrib::make @@ -35,6 +35,18 @@ make(Fog *fog) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: FogAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) FogAttrib:: +make_default() { + return return_new(new FogAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: FogAttrib::make_off // Access: Published, Static @@ -91,33 +103,6 @@ compare_to_impl(const RenderAttrib *other) const { return 0; } -//////////////////////////////////////////////////////////////////// -// Function: FogAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived FogAttrib -// types to specify what the default property for a -// FogAttrib of this type should be. -// -// This should return a newly-allocated FogAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of FogAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *FogAttrib:: -make_default_impl() const { - return new FogAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: FogAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void FogAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_fog = this; -} - //////////////////////////////////////////////////////////////////// // Function: FogAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/fogAttrib.h b/panda/src/pgraph/fogAttrib.h index 4baca8e970..ab25fe15d8 100644 --- a/panda/src/pgraph/fogAttrib.h +++ b/panda/src/pgraph/fogAttrib.h @@ -31,21 +31,28 @@ private: PUBLISHED: static CPT(RenderAttrib) make(Fog *fog); static CPT(RenderAttrib) make_off(); + static CPT(RenderAttrib) make_default(); INLINE bool is_off() const; INLINE Fog *get_fog() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: PT(Fog) _fog; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -63,6 +70,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "FogAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -71,6 +79,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "fogAttrib.I" diff --git a/panda/src/pgraph/geomNode.cxx b/panda/src/pgraph/geomNode.cxx index b89005d033..7166efc117 100644 --- a/panda/src/pgraph/geomNode.cxx +++ b/panda/src/pgraph/geomNode.cxx @@ -144,7 +144,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types, } entry._state = entry._state->add_attrib(ra, override); - ra = entry._state->get_attrib(ColorAttrib::get_class_type()); + ra = entry._state->get_attrib(ColorAttrib::get_class_slot()); const ColorAttrib *ca = DCAST(ColorAttrib, ra); if (ca->get_color_type() != ColorAttrib::T_vertex) { if (transformer.remove_column(new_geom, InternalName::get_color())) { @@ -160,7 +160,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types, // Now, if we have an "off" or "flat" color attribute, we // simply modify the color attribute, and leave the // vertices alone. - const RenderAttrib *ra = entry._state->get_attrib(ColorAttrib::get_class_type()); + const RenderAttrib *ra = entry._state->get_attrib(ColorAttrib::get_class_slot()); if (ra != (const RenderAttrib *)NULL) { const ColorAttrib *ca = DCAST(ColorAttrib, ra); if (ca->get_color_type() == ColorAttrib::T_off) { @@ -374,7 +374,7 @@ r_prepare_scene(const RenderState *state, for (gi = geoms->begin(); gi != geoms->end(); ++gi) { CPT(RenderState) geom_state = state->compose((*gi)._state); const RenderAttrib *attrib = - geom_state->get_attrib(TextureAttrib::get_class_type()); + geom_state->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta; DCAST_INTO_V(ta, attrib); @@ -767,25 +767,19 @@ output(ostream &out) const { pset attrib_types; GeomList::const_iterator gi; + CPT(RenderState) common = RenderState::make_empty(); + CPT(GeomList) geoms = cdata->get_geoms(); for (gi = geoms->begin(); gi != geoms->end(); ++gi) { const GeomEntry &entry = (*gi); - int num_attribs = entry._state->get_num_attribs(); - for (int i = 0; i < num_attribs; i++) { - const RenderAttrib *attrib = entry._state->get_attrib(i); - attrib_types.insert(attrib->get_type()); - } + common = common->compose(entry._state); } PandaNode::output(out); out << " (" << geoms->size() << " geoms"; - if (!attrib_types.empty()) { - out << ":"; - pset::const_iterator ai; - for (ai = attrib_types.begin(); ai != attrib_types.end(); ++ai) { - out << " " << (*ai); - } + if (!common->is_empty()) { + out << ": " << *common; } out << ")"; @@ -964,7 +958,7 @@ finalize(BamReader *manager) { } if (vdata->has_column(color) && - entry._state->get_color() == (ColorAttrib *)NULL) { + !entry._state->has_attrib(ColorAttrib::get_class_slot())) { // We'll be reassigning the RenderState. Therefore, save it // temporarily to increment its reference count. PT(BamAuxData) aux_data = new BamAuxData; diff --git a/panda/src/pgraph/geomTransformer.cxx b/panda/src/pgraph/geomTransformer.cxx index e82d43ea03..bc07c95b6c 100644 --- a/panda/src/pgraph/geomTransformer.cxx +++ b/panda/src/pgraph/geomTransformer.cxx @@ -653,15 +653,15 @@ apply_texture_colors(GeomNode *node, const RenderState *state) { GeomNode::GeomEntry &entry = (*gi); CPT(RenderState) geom_state = state->compose(entry._state); - const TextureAttrib *ta = geom_state->get_texture(); + const TextureAttrib *ta = DCAST(TextureAttrib, geom_state->get_attrib(TextureAttrib::get_class_slot())); if (ta != (TextureAttrib *)NULL) { CPT(TextureAttrib) ta2 = ta->filter_to_max(1); if (ta2->get_num_on_stages() > 0) { TextureStage *ts = ta2->get_on_stage(0); Texture *tex = ta2->get_on_texture(ts); - const TexMatrixAttrib *tma = geom_state->get_tex_matrix(); + const TexMatrixAttrib *tma = DCAST(TexMatrixAttrib, geom_state->get_attrib(TexMatrixAttrib::get_class_slot())); - const ColorAttrib *ca = geom_state->get_color(); + const ColorAttrib *ca = DCAST(ColorAttrib, geom_state->get_attrib(ColorAttrib::get_class_slot())); Colorf base_color(1.0f, 1.0f, 1.0f, 1.0f); bool keep_vertex_color = true; if (ca != (ColorAttrib *)NULL && ca->get_color_type() == ColorAttrib::T_flat) { @@ -685,7 +685,7 @@ apply_texture_colors(GeomNode *node, const RenderState *state) { } // Also remove any texture references from the GeomState. - CPT(RenderState) no_tex_state = entry._state->remove_attrib(TextureAttrib::get_class_type()); + CPT(RenderState) no_tex_state = entry._state->remove_attrib(TextureAttrib::get_class_slot()); if (entry._state != no_tex_state) { entry._state = no_tex_state; any_changed = true; @@ -889,7 +889,7 @@ make_compatible_state(GeomNode *node) { const RenderState *canon_state = (*si).first; for (int i = 0; i < (int)indices.size(); i++) { GeomNode::GeomEntry &entry = geoms[indices[i]]; - const RenderAttrib *ra = entry._state->get_attrib(ColorAttrib::get_class_type()); + const RenderAttrib *ra = entry._state->get_attrib(ColorAttrib::get_class_slot()); if (ra == (RenderAttrib *)NULL) { ra = ColorAttrib::make_off(); } diff --git a/panda/src/pgraph/lightAttrib.cxx b/panda/src/pgraph/lightAttrib.cxx index 8aa5a2324a..b7c01a89e6 100644 --- a/panda/src/pgraph/lightAttrib.cxx +++ b/panda/src/pgraph/lightAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "lightAttrib.h" -#include "attribSlots.h" #include "pandaNode.h" #include "nodePath.h" #include "graphicsStateGuardianBase.h" @@ -25,6 +24,7 @@ #include "attribNodeRegistry.h" CPT(RenderAttrib) LightAttrib::_empty_attrib; +int LightAttrib::_attrib_slot; CPT(RenderAttrib) LightAttrib::_all_off_attrib; TypeHandle LightAttrib::_type_handle; @@ -214,6 +214,18 @@ make(LightAttrib::Operation op, Light *light1, Light *light2, return make(); } +//////////////////////////////////////////////////////////////////// +// Function: LightAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) LightAttrib:: +make_default() { + return return_new(new LightAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: LightAttrib::get_operation // Access: Published @@ -843,33 +855,6 @@ invert_compose_impl(const RenderAttrib *other) const { return other; } -//////////////////////////////////////////////////////////////////// -// Function: LightAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived LightAttrib -// types to specify what the default property for a -// LightAttrib of this type should be. -// -// This should return a newly-allocated LightAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of LightAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *LightAttrib:: -make_default_impl() const { - return new LightAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: LightAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void LightAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_light = this; -} - //////////////////////////////////////////////////////////////////// // Function: LightAttrib::sort_on_lights // Access: Private diff --git a/panda/src/pgraph/lightAttrib.h b/panda/src/pgraph/lightAttrib.h index c6ad400c4c..6fea963be7 100644 --- a/panda/src/pgraph/lightAttrib.h +++ b/panda/src/pgraph/lightAttrib.h @@ -55,6 +55,7 @@ PUBLISHED: static CPT(RenderAttrib) make(Operation op, Light *light1, Light *light2, Light *light3, Light *light4); + static CPT(RenderAttrib) make_default(); Operation get_operation() const; @@ -94,13 +95,11 @@ PUBLISHED: public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: INLINE void check_filtered() const; @@ -119,6 +118,14 @@ private: static CPT(RenderAttrib) _empty_attrib; static CPT(RenderAttrib) _all_off_attrib; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -137,6 +144,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "LightAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 20, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -145,6 +153,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "lightAttrib.I" diff --git a/panda/src/pgraph/lightRampAttrib.cxx b/panda/src/pgraph/lightRampAttrib.cxx index 3f4aebf494..704839393d 100644 --- a/panda/src/pgraph/lightRampAttrib.cxx +++ b/panda/src/pgraph/lightRampAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "lightRampAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle LightRampAttrib::_type_handle; +int LightRampAttrib::_attrib_slot; CPT(RenderAttrib) LightRampAttrib::_default; //////////////////////////////////////////////////////////////////// @@ -248,33 +248,6 @@ compare_to_impl(const RenderAttrib *other) const { return 0; } -//////////////////////////////////////////////////////////////////// -// Function: LightRampAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived LightRampAttrib -// types to specify what the default property for a -// LightRampAttrib of this type should be. -// -// This should return a newly-allocated LightRampAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of LightRampAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *LightRampAttrib:: -make_default_impl() const { - return new LightRampAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: LightRampAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void LightRampAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_light_ramp = this; -} - //////////////////////////////////////////////////////////////////// // Function: LightRampAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/lightRampAttrib.h b/panda/src/pgraph/lightRampAttrib.h index 9ddc4a7c9e..5f78aaeeff 100644 --- a/panda/src/pgraph/lightRampAttrib.h +++ b/panda/src/pgraph/lightRampAttrib.h @@ -58,11 +58,9 @@ PUBLISHED: public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: LightRampMode _mode; @@ -71,6 +69,14 @@ private: static CPT(RenderAttrib) _default; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -87,6 +93,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "LightRampAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -95,6 +102,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "lightRampAttrib.I" diff --git a/panda/src/pgraph/materialAttrib.cxx b/panda/src/pgraph/materialAttrib.cxx index 8c9bba4b48..a5f2f5d532 100644 --- a/panda/src/pgraph/materialAttrib.cxx +++ b/panda/src/pgraph/materialAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "materialAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "bamReader.h" #include "bamWriter.h" @@ -21,6 +20,7 @@ #include "datagramIterator.h" TypeHandle MaterialAttrib::_type_handle; +int MaterialAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: MaterialAttrib::make @@ -48,6 +48,18 @@ make_off() { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: MaterialAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) MaterialAttrib:: +make_default() { + return return_new(new MaterialAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: MaterialAttrib::output // Access: Public, Virtual @@ -92,33 +104,6 @@ compare_to_impl(const RenderAttrib *other) const { return 0; } -//////////////////////////////////////////////////////////////////// -// Function: MaterialAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived MaterialAttrib -// types to specify what the default property for a -// MaterialAttrib of this type should be. -// -// This should return a newly-allocated MaterialAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of MaterialAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *MaterialAttrib:: -make_default_impl() const { - return new MaterialAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: MaterialAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void MaterialAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_material = this; -} - //////////////////////////////////////////////////////////////////// // Function: MaterialAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/materialAttrib.h b/panda/src/pgraph/materialAttrib.h index 422b02145c..17498b4391 100644 --- a/panda/src/pgraph/materialAttrib.h +++ b/panda/src/pgraph/materialAttrib.h @@ -34,21 +34,28 @@ private: PUBLISHED: static CPT(RenderAttrib) make(Material *material); static CPT(RenderAttrib) make_off(); + static CPT(RenderAttrib) make_default(); INLINE bool is_off() const; INLINE Material *get_material() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: PT(Material) _material; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -66,6 +73,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "MaterialAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -74,6 +82,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "materialAttrib.I" diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index e545358967..1ff9cd6409 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -2142,7 +2142,7 @@ set_color_off(int priority) { void NodePath:: clear_color() { nassertv_always(!is_empty()); - node()->clear_attrib(ColorAttrib::get_class_type()); + node()->clear_attrib(ColorAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -2154,7 +2154,7 @@ clear_color() { bool NodePath:: has_color() const { nassertr_always(!is_empty(), false); - return node()->has_attrib(ColorAttrib::get_class_type()); + return node()->has_attrib(ColorAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -2167,7 +2167,7 @@ Colorf NodePath:: get_color() const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(ColorAttrib::get_class_type()); + node()->get_attrib(ColorAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const ColorAttrib *ca = DCAST(ColorAttrib, attrib); if (ca->get_color_type() == ColorAttrib::T_flat) { @@ -2192,7 +2192,7 @@ get_color() const { bool NodePath:: has_color_scale() const { nassertr_always(!is_empty(), false); - return node()->has_attrib(ColorScaleAttrib::get_class_type()); + return node()->has_attrib(ColorScaleAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -2207,7 +2207,7 @@ has_color_scale() const { void NodePath:: clear_color_scale() { nassertv_always(!is_empty()); - node()->clear_attrib(ColorScaleAttrib::get_class_type()); + node()->clear_attrib(ColorScaleAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -2222,10 +2222,10 @@ compose_color_scale(const LVecBase4f &scale, int priority) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(ColorScaleAttrib::get_class_type()); + node()->get_attrib(ColorScaleAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(ColorScaleAttrib::get_class_type())); + node()->get_state()->get_override(ColorScaleAttrib::get_class_slot())); const ColorScaleAttrib *csa = DCAST(ColorScaleAttrib, attrib); // Modify the existing ColorScaleAttrib by multiplying with the @@ -2254,10 +2254,10 @@ set_color_scale(const LVecBase4f &scale, int priority) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(ColorScaleAttrib::get_class_type()); + node()->get_attrib(ColorScaleAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(ColorScaleAttrib::get_class_type())); + node()->get_state()->get_override(ColorScaleAttrib::get_class_slot())); const ColorScaleAttrib *csa = DCAST(ColorScaleAttrib, attrib); // Modify the existing ColorScaleAttrib to add the indicated @@ -2305,10 +2305,10 @@ set_alpha_scale(float scale, int priority) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(ColorScaleAttrib::get_class_type()); + node()->get_attrib(ColorScaleAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(ColorScaleAttrib::get_class_type())); + node()->get_state()->get_override(ColorScaleAttrib::get_class_slot())); const ColorScaleAttrib *csa = DCAST(ColorScaleAttrib, attrib); // Modify the existing ColorScaleAttrib to add the indicated @@ -2335,10 +2335,10 @@ set_all_color_scale(float scale, int priority) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(ColorScaleAttrib::get_class_type()); + node()->get_attrib(ColorScaleAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(ColorScaleAttrib::get_class_type())); + node()->get_state()->get_override(ColorScaleAttrib::get_class_slot())); const ColorScaleAttrib *csa = DCAST(ColorScaleAttrib, attrib); // Modify the existing ColorScaleAttrib to add the indicated @@ -2366,7 +2366,7 @@ get_color_scale() const { static const LVecBase4f ident_scale(1.0f, 1.0f, 1.0f, 1.0f); nassertr_always(!is_empty(), ident_scale); const RenderAttrib *attrib = - node()->get_attrib(ColorScaleAttrib::get_class_type()); + node()->get_attrib(ColorScaleAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const ColorScaleAttrib *csa = DCAST(ColorScaleAttrib, attrib); return csa->get_scale(); @@ -2393,10 +2393,10 @@ set_light(const NodePath &light, int priority) { if (light_obj != (Light *)NULL) { // It's an actual Light object. const RenderAttrib *attrib = - node()->get_attrib(LightAttrib::get_class_type()); + node()->get_attrib(LightAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(LightAttrib::get_class_type())); + node()->get_state()->get_override(LightAttrib::get_class_slot())); const LightAttrib *la = DCAST(LightAttrib, attrib); // Modify the existing LightAttrib to add the indicated @@ -2481,10 +2481,10 @@ set_light_off(const NodePath &light, int priority) { Light *light_obj = light.node()->as_light(); if (light_obj != (Light *)NULL) { const RenderAttrib *attrib = - node()->get_attrib(LightAttrib::get_class_type()); + node()->get_attrib(LightAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(LightAttrib::get_class_type())); + node()->get_state()->get_override(LightAttrib::get_class_slot())); const LightAttrib *la = DCAST(LightAttrib, attrib); // Modify the existing LightAttrib to add the indicated light @@ -2514,7 +2514,7 @@ set_light_off(const NodePath &light, int priority) { void NodePath:: clear_light() { nassertv_always(!is_empty()); - node()->clear_attrib(LightAttrib::get_class_type()); + node()->clear_attrib(LightAttrib::get_class_slot()); node()->clear_effect(PolylightEffect::get_class_type()); } @@ -2532,17 +2532,17 @@ clear_light(const NodePath &light) { Light *light_obj = light.node()->as_light(); if (light_obj != (Light *)NULL) { const RenderAttrib *attrib = - node()->get_attrib(LightAttrib::get_class_type()); + node()->get_attrib(LightAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { CPT(LightAttrib) la = DCAST(LightAttrib, attrib); la = DCAST(LightAttrib, la->remove_on_light(light)); la = DCAST(LightAttrib, la->remove_off_light(light)); if (la->is_identity()) { - node()->clear_attrib(LightAttrib::get_class_type()); + node()->clear_attrib(LightAttrib::get_class_slot()); } else { - int priority = node()->get_state()->get_override(LightAttrib::get_class_type()); + int priority = node()->get_state()->get_override(LightAttrib::get_class_slot()); node()->set_attrib(la, priority); } } @@ -2578,7 +2578,7 @@ has_light(const NodePath &light) const { Light *light_obj = light.node()->as_light(); if (light_obj != (Light *)NULL) { const RenderAttrib *attrib = - node()->get_attrib(LightAttrib::get_class_type()); + node()->get_attrib(LightAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const LightAttrib *la = DCAST(LightAttrib, attrib); return la->has_on_light(light); @@ -2612,7 +2612,7 @@ has_light_off() const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(LightAttrib::get_class_type()); + node()->get_attrib(LightAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const LightAttrib *la = DCAST(LightAttrib, attrib); return la->has_all_off(); @@ -2639,7 +2639,7 @@ has_light_off(const NodePath &light) const { Light *light_obj = light.node()->as_light(); if (light_obj != (Light *)NULL) { const RenderAttrib *attrib = - node()->get_attrib(LightAttrib::get_class_type()); + node()->get_attrib(LightAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const LightAttrib *la = DCAST(LightAttrib, attrib); return la->has_off_light(light); @@ -2665,10 +2665,10 @@ set_clip_plane(const NodePath &clip_plane, int priority) { nassertv_always(!is_empty()); if (!clip_plane.is_empty() && clip_plane.node()->is_of_type(PlaneNode::get_class_type())) { const RenderAttrib *attrib = - node()->get_attrib(ClipPlaneAttrib::get_class_type()); + node()->get_attrib(ClipPlaneAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(ClipPlaneAttrib::get_class_type())); + node()->get_state()->get_override(ClipPlaneAttrib::get_class_slot())); const ClipPlaneAttrib *la = DCAST(ClipPlaneAttrib, attrib); // Modify the existing ClipPlaneAttrib to add the indicated @@ -2722,10 +2722,10 @@ set_clip_plane_off(const NodePath &clip_plane, int priority) { if (!clip_plane.is_empty() && clip_plane.node()->is_of_type(PlaneNode::get_class_type())) { const RenderAttrib *attrib = - node()->get_attrib(ClipPlaneAttrib::get_class_type()); + node()->get_attrib(ClipPlaneAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(ClipPlaneAttrib::get_class_type())); + node()->get_state()->get_override(ClipPlaneAttrib::get_class_slot())); const ClipPlaneAttrib *la = DCAST(ClipPlaneAttrib, attrib); // Modify the existing ClipPlaneAttrib to add the indicated clip_plane @@ -2754,7 +2754,7 @@ set_clip_plane_off(const NodePath &clip_plane, int priority) { void NodePath:: clear_clip_plane() { nassertv_always(!is_empty()); - node()->clear_attrib(ClipPlaneAttrib::get_class_type()); + node()->clear_attrib(ClipPlaneAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -2769,17 +2769,17 @@ clear_clip_plane(const NodePath &clip_plane) { if (!clip_plane.is_empty() && clip_plane.node()->is_of_type(PlaneNode::get_class_type())) { const RenderAttrib *attrib = - node()->get_attrib(ClipPlaneAttrib::get_class_type()); + node()->get_attrib(ClipPlaneAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { CPT(ClipPlaneAttrib) la = DCAST(ClipPlaneAttrib, attrib); la = DCAST(ClipPlaneAttrib, la->remove_on_plane(clip_plane)); la = DCAST(ClipPlaneAttrib, la->remove_off_plane(clip_plane)); if (la->is_identity()) { - node()->clear_attrib(ClipPlaneAttrib::get_class_type()); + node()->clear_attrib(ClipPlaneAttrib::get_class_slot()); } else { - int priority = node()->get_state()->get_override(ClipPlaneAttrib::get_class_type()); + int priority = node()->get_state()->get_override(ClipPlaneAttrib::get_class_slot()); node()->set_attrib(la, priority); } } @@ -2802,7 +2802,7 @@ has_clip_plane(const NodePath &clip_plane) const { if (!clip_plane.is_empty() && clip_plane.node()->is_of_type(PlaneNode::get_class_type())) { const RenderAttrib *attrib = - node()->get_attrib(ClipPlaneAttrib::get_class_type()); + node()->get_attrib(ClipPlaneAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const ClipPlaneAttrib *la = DCAST(ClipPlaneAttrib, attrib); return la->has_on_plane(clip_plane); @@ -2826,7 +2826,7 @@ has_clip_plane_off() const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(ClipPlaneAttrib::get_class_type()); + node()->get_attrib(ClipPlaneAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const ClipPlaneAttrib *la = DCAST(ClipPlaneAttrib, attrib); return la->has_all_off(); @@ -2848,7 +2848,7 @@ has_clip_plane_off(const NodePath &clip_plane) const { nassertr_always(!is_empty(), false); if (!clip_plane.is_empty() && clip_plane.node()->is_of_type(PlaneNode::get_class_type())) { const RenderAttrib *attrib = - node()->get_attrib(ClipPlaneAttrib::get_class_type()); + node()->get_attrib(ClipPlaneAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const ClipPlaneAttrib *la = DCAST(ClipPlaneAttrib, attrib); return la->has_off_plane(clip_plane); @@ -3004,7 +3004,7 @@ set_bin(const string &bin_name, int draw_order, int priority) { void NodePath:: clear_bin() { nassertv_always(!is_empty()); - node()->clear_attrib(CullBinAttrib::get_class_type()); + node()->clear_attrib(CullBinAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -3017,7 +3017,7 @@ clear_bin() { bool NodePath:: has_bin() const { nassertr_always(!is_empty(), false); - return node()->has_attrib(CullBinAttrib::get_class_type()); + return node()->has_attrib(CullBinAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -3031,7 +3031,7 @@ string NodePath:: get_bin_name() const { nassertr_always(!is_empty(), string()); const RenderAttrib *attrib = - node()->get_attrib(CullBinAttrib::get_class_type()); + node()->get_attrib(CullBinAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const CullBinAttrib *ba = DCAST(CullBinAttrib, attrib); return ba->get_bin_name(); @@ -3052,7 +3052,7 @@ int NodePath:: get_bin_draw_order() const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(CullBinAttrib::get_class_type()); + node()->get_attrib(CullBinAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const CullBinAttrib *ba = DCAST(CullBinAttrib, attrib); return ba->get_draw_order(); @@ -3096,10 +3096,10 @@ set_texture(TextureStage *stage, Texture *tex, int priority) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(TextureAttrib::get_class_type()); + node()->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(TextureAttrib::get_class_type())); + node()->get_state()->get_override(TextureAttrib::get_class_slot())); const TextureAttrib *tsa = DCAST(TextureAttrib, attrib); // Modify the existing TextureAttrib to add the indicated @@ -3144,10 +3144,10 @@ set_texture_off(TextureStage *stage, int priority) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(TextureAttrib::get_class_type()); + node()->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(TextureAttrib::get_class_type())); + node()->get_state()->get_override(TextureAttrib::get_class_slot())); const TextureAttrib *tsa = DCAST(TextureAttrib, attrib); // Modify the existing TextureAttrib to add the indicated texture @@ -3175,7 +3175,7 @@ set_texture_off(TextureStage *stage, int priority) { void NodePath:: clear_texture() { nassertv_always(!is_empty()); - node()->clear_attrib(TextureAttrib::get_class_type()); + node()->clear_attrib(TextureAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -3189,17 +3189,17 @@ clear_texture(TextureStage *stage) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(TextureAttrib::get_class_type()); + node()->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { CPT(TextureAttrib) tsa = DCAST(TextureAttrib, attrib); tsa = DCAST(TextureAttrib, tsa->remove_on_stage(stage)); tsa = DCAST(TextureAttrib, tsa->remove_off_stage(stage)); if (tsa->is_identity()) { - node()->clear_attrib(TextureAttrib::get_class_type()); + node()->clear_attrib(TextureAttrib::get_class_slot()); } else { - int priority = node()->get_state()->get_override(TextureAttrib::get_class_type()); + int priority = node()->get_state()->get_override(TextureAttrib::get_class_slot()); node()->set_attrib(tsa, priority); } } @@ -3235,7 +3235,7 @@ has_texture(TextureStage *stage) const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(TextureAttrib::get_class_type()); + node()->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); return ta->has_on_stage(stage); @@ -3258,7 +3258,7 @@ bool NodePath:: has_texture_off() const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(TextureAttrib::get_class_type()); + node()->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); return ta->has_all_off(); @@ -3282,7 +3282,7 @@ has_texture_off(TextureStage *stage) const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(TextureAttrib::get_class_type()); + node()->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); return ta->has_off_stage(stage); @@ -3307,7 +3307,7 @@ Texture *NodePath:: get_texture() const { nassertr_always(!is_empty(), NULL); const RenderAttrib *attrib = - node()->get_attrib(TextureAttrib::get_class_type()); + node()->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); return ta->get_texture(); @@ -3327,7 +3327,7 @@ Texture *NodePath:: get_texture(TextureStage *stage) const { nassertr_always(!is_empty(), NULL); const RenderAttrib *attrib = - node()->get_attrib(TextureAttrib::get_class_type()); + node()->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); return ta->get_on_texture(stage); @@ -3346,10 +3346,10 @@ set_shader(const Shader *sha, int priority) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(ShaderAttrib::get_class_type()); + node()->get_attrib(ShaderAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(ShaderAttrib::get_class_type())); + node()->get_state()->get_override(ShaderAttrib::get_class_slot())); const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib); node()->set_attrib(sa->set_shader(sha, priority)); } else { @@ -3379,10 +3379,10 @@ set_shader_auto(int priority) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(ShaderAttrib::get_class_type()); + node()->get_attrib(ShaderAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(ShaderAttrib::get_class_type())); + node()->get_state()->get_override(ShaderAttrib::get_class_slot())); const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib); node()->set_attrib(sa->set_shader_auto(priority)); } else { @@ -3402,7 +3402,7 @@ clear_shader() { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(ShaderAttrib::get_class_type()); + node()->get_attrib(ShaderAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib); node()->set_attrib(sa->clear_shader()); @@ -3418,7 +3418,7 @@ const Shader *NodePath:: get_shader() const { nassertr_always(!is_empty(), NULL); const RenderAttrib *attrib = - node()->get_attrib(ShaderAttrib::get_class_type()); + node()->get_attrib(ShaderAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib); return sa->get_shader(); @@ -3436,7 +3436,7 @@ set_shader_input(const ShaderInput *inp) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(ShaderAttrib::get_class_type()); + node()->get_attrib(ShaderAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib); node()->set_attrib(sa->set_shader_input(inp)); @@ -3457,7 +3457,7 @@ get_shader_input(InternalName *id) const { nassertr_always(!is_empty(), NULL); const RenderAttrib *attrib = - node()->get_attrib(ShaderAttrib::get_class_type()); + node()->get_attrib(ShaderAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib); return sa->get_shader_input(id); @@ -3475,7 +3475,7 @@ clear_shader_input(InternalName *id) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(ShaderAttrib::get_class_type()); + node()->get_attrib(ShaderAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib); node()->set_attrib(sa->clear_shader_input(id)); @@ -3593,7 +3593,7 @@ set_tex_transform(TextureStage *stage, const TransformState *transform) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(TexMatrixAttrib::get_class_type()); + node()->get_attrib(TexMatrixAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TexMatrixAttrib *tma = DCAST(TexMatrixAttrib, attrib); @@ -3615,7 +3615,7 @@ set_tex_transform(TextureStage *stage, const TransformState *transform) { void NodePath:: clear_tex_transform() { nassertv_always(!is_empty()); - node()->clear_attrib(TexMatrixAttrib::get_class_type()); + node()->clear_attrib(TexMatrixAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -3629,13 +3629,13 @@ clear_tex_transform(TextureStage *stage) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(TexMatrixAttrib::get_class_type()); + node()->get_attrib(TexMatrixAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { CPT(TexMatrixAttrib) tma = DCAST(TexMatrixAttrib, attrib); tma = DCAST(TexMatrixAttrib, tma->remove_stage(stage)); if (tma->is_empty()) { - node()->clear_attrib(TexMatrixAttrib::get_class_type()); + node()->clear_attrib(TexMatrixAttrib::get_class_slot()); } else { node()->set_attrib(tma); @@ -3654,7 +3654,7 @@ has_tex_transform(TextureStage *stage) const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(TexMatrixAttrib::get_class_type()); + node()->get_attrib(TexMatrixAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TexMatrixAttrib *tma = DCAST(TexMatrixAttrib, attrib); return tma->has_stage(stage); @@ -3675,7 +3675,7 @@ get_tex_transform(TextureStage *stage) const { nassertr_always(!is_empty(), NULL); const RenderAttrib *attrib = - node()->get_attrib(TexMatrixAttrib::get_class_type()); + node()->get_attrib(TexMatrixAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TexMatrixAttrib *tma = DCAST(TexMatrixAttrib, attrib); return tma->get_transform(stage); @@ -3697,7 +3697,7 @@ set_tex_transform(const NodePath &other, TextureStage *stage, const TransformSta CPT(RenderState) state = get_state(other); const RenderAttrib *attrib = - state->get_attrib(TexMatrixAttrib::get_class_type()); + state->get_attrib(TexMatrixAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TexMatrixAttrib *tma = DCAST(TexMatrixAttrib, attrib); @@ -3721,7 +3721,7 @@ set_tex_transform(const NodePath &other, TextureStage *stage, const TransformSta // And apply only the TexMatrixAttrib to the current node, leaving // the others unchanged. - node()->set_attrib(new_state->get_attrib(TexMatrixAttrib::get_class_type())); + node()->set_attrib(new_state->get_attrib(TexMatrixAttrib::get_class_slot())); } //////////////////////////////////////////////////////////////////// @@ -3736,7 +3736,7 @@ get_tex_transform(const NodePath &other, TextureStage *stage) const { CPT(RenderState) state = get_state(other); const RenderAttrib *attrib = - state->get_attrib(TexMatrixAttrib::get_class_type()); + state->get_attrib(TexMatrixAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TexMatrixAttrib *tma = DCAST(TexMatrixAttrib, attrib); return tma->get_transform(stage); @@ -3756,13 +3756,13 @@ set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode, int priority) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(TexGenAttrib::get_class_type()); + node()->get_attrib(TexGenAttrib::get_class_slot()); CPT(TexGenAttrib) tga; if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(TextureAttrib::get_class_type())); + node()->get_state()->get_override(TextureAttrib::get_class_slot())); tga = DCAST(TexGenAttrib, attrib); } else { @@ -3788,13 +3788,13 @@ set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode, nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(TexGenAttrib::get_class_type()); + node()->get_attrib(TexGenAttrib::get_class_slot()); CPT(TexGenAttrib) tga; if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(TextureAttrib::get_class_type())); + node()->get_state()->get_override(TextureAttrib::get_class_slot())); tga = DCAST(TexGenAttrib, attrib); } else { @@ -3818,13 +3818,13 @@ set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode, nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(TexGenAttrib::get_class_type()); + node()->get_attrib(TexGenAttrib::get_class_slot()); CPT(TexGenAttrib) tga; if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(TextureAttrib::get_class_type())); + node()->get_state()->get_override(TextureAttrib::get_class_slot())); tga = DCAST(TexGenAttrib, attrib); } else { @@ -3843,7 +3843,7 @@ set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode, void NodePath:: clear_tex_gen() { nassertv_always(!is_empty()); - node()->clear_attrib(TexGenAttrib::get_class_type()); + node()->clear_attrib(TexGenAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -3857,13 +3857,13 @@ clear_tex_gen(TextureStage *stage) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(TexGenAttrib::get_class_type()); + node()->get_attrib(TexGenAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { CPT(TexGenAttrib) tga = DCAST(TexGenAttrib, attrib); tga = DCAST(TexGenAttrib, tga->remove_stage(stage)); if (tga->is_empty()) { - node()->clear_attrib(TexGenAttrib::get_class_type()); + node()->clear_attrib(TexGenAttrib::get_class_slot()); } else { node()->set_attrib(tga); @@ -3883,7 +3883,7 @@ has_tex_gen(TextureStage *stage) const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(TexGenAttrib::get_class_type()); + node()->get_attrib(TexGenAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TexGenAttrib *tga = DCAST(TexGenAttrib, attrib); return tga->has_stage(stage); @@ -3904,7 +3904,7 @@ get_tex_gen(TextureStage *stage) const { nassertr_always(!is_empty(), TexGenAttrib::M_off); const RenderAttrib *attrib = - node()->get_attrib(TexGenAttrib::get_class_type()); + node()->get_attrib(TexGenAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TexGenAttrib *tga = DCAST(TexGenAttrib, attrib); return tga->get_mode(stage); @@ -3926,7 +3926,7 @@ get_tex_gen_light(TextureStage *stage) const { nassertr_always(!is_empty(), NodePath::fail()); const RenderAttrib *attrib = - node()->get_attrib(TexGenAttrib::get_class_type()); + node()->get_attrib(TexGenAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TexGenAttrib *tga = DCAST(TexGenAttrib, attrib); return tga->get_light(stage); @@ -4158,7 +4158,7 @@ clear_normal_map() { // set_normal_map(), remove it from the state. CPT(RenderAttrib) attrib = - get_state()->get_attrib(TextureAttrib::get_class_type()); + get_state()->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); for (int i = 0; i < ta->get_num_on_stages(); i++) { @@ -4580,7 +4580,7 @@ set_material_off(int priority) { void NodePath:: clear_material() { nassertv_always(!is_empty()); - node()->clear_attrib(MaterialAttrib::get_class_type()); + node()->clear_attrib(MaterialAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -4593,7 +4593,7 @@ bool NodePath:: has_material() const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(MaterialAttrib::get_class_type()); + node()->get_attrib(MaterialAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const MaterialAttrib *ma = DCAST(MaterialAttrib, attrib); return !ma->is_off(); @@ -4618,7 +4618,7 @@ PT(Material) NodePath:: get_material() const { nassertr_always(!is_empty(), NULL); const RenderAttrib *attrib = - node()->get_attrib(MaterialAttrib::get_class_type()); + node()->get_attrib(MaterialAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const MaterialAttrib *ma = DCAST(MaterialAttrib, attrib); return ma->get_material(); @@ -4667,7 +4667,7 @@ set_fog_off(int priority) { void NodePath:: clear_fog() { nassertv_always(!is_empty()); - node()->clear_attrib(FogAttrib::get_class_type()); + node()->clear_attrib(FogAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -4684,7 +4684,7 @@ bool NodePath:: has_fog() const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(FogAttrib::get_class_type()); + node()->get_attrib(FogAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const FogAttrib *fa = DCAST(FogAttrib, attrib); return !fa->is_off(); @@ -4707,7 +4707,7 @@ bool NodePath:: has_fog_off() const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(FogAttrib::get_class_type()); + node()->get_attrib(FogAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const FogAttrib *fa = DCAST(FogAttrib, attrib); return fa->is_off(); @@ -4730,7 +4730,7 @@ Fog *NodePath:: get_fog() const { nassertr_always(!is_empty(), NULL); const RenderAttrib *attrib = - node()->get_attrib(FogAttrib::get_class_type()); + node()->get_attrib(FogAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const FogAttrib *fa = DCAST(FogAttrib, attrib); return fa->get_fog(); @@ -4837,7 +4837,7 @@ set_render_mode(RenderModeAttrib::Mode mode, float thickness, int priority) { void NodePath:: clear_render_mode() { nassertv_always(!is_empty()); - node()->clear_attrib(RenderModeAttrib::get_class_type()); + node()->clear_attrib(RenderModeAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -4851,7 +4851,7 @@ clear_render_mode() { bool NodePath:: has_render_mode() const { nassertr_always(!is_empty(), false); - return node()->has_attrib(RenderModeAttrib::get_class_type()); + return node()->has_attrib(RenderModeAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -4865,7 +4865,7 @@ RenderModeAttrib::Mode NodePath:: get_render_mode() const { nassertr_always(!is_empty(), RenderModeAttrib::M_unchanged); const RenderAttrib *attrib = - node()->get_attrib(RenderModeAttrib::get_class_type()); + node()->get_attrib(RenderModeAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const RenderModeAttrib *ta = DCAST(RenderModeAttrib, attrib); return ta->get_mode(); @@ -4885,7 +4885,7 @@ float NodePath:: get_render_mode_thickness() const { nassertr_always(!is_empty(), 0.0f); const RenderAttrib *attrib = - node()->get_attrib(RenderModeAttrib::get_class_type()); + node()->get_attrib(RenderModeAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const RenderModeAttrib *ta = DCAST(RenderModeAttrib, attrib); return ta->get_thickness(); @@ -4905,7 +4905,7 @@ bool NodePath:: get_render_mode_perspective() const { nassertr_always(!is_empty(), 0.0f); const RenderAttrib *attrib = - node()->get_attrib(RenderModeAttrib::get_class_type()); + node()->get_attrib(RenderModeAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const RenderModeAttrib *ta = DCAST(RenderModeAttrib, attrib); return ta->get_perspective(); @@ -4949,7 +4949,7 @@ set_two_sided(bool two_sided, int priority) { void NodePath:: clear_two_sided() { nassertv_always(!is_empty()); - node()->clear_attrib(CullFaceAttrib::get_class_type()); + node()->clear_attrib(CullFaceAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -4964,7 +4964,7 @@ clear_two_sided() { bool NodePath:: has_two_sided() const { nassertr_always(!is_empty(), false); - return node()->has_attrib(CullFaceAttrib::get_class_type()); + return node()->has_attrib(CullFaceAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -4982,7 +4982,7 @@ bool NodePath:: get_two_sided() const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(CullFaceAttrib::get_class_type()); + node()->get_attrib(CullFaceAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const CullFaceAttrib *cfa = DCAST(CullFaceAttrib, attrib); return (cfa->get_actual_mode() == CullFaceAttrib::M_cull_none); @@ -5021,7 +5021,7 @@ set_depth_test(bool depth_test, int priority) { void NodePath:: clear_depth_test() { nassertv_always(!is_empty()); - node()->clear_attrib(DepthTestAttrib::get_class_type()); + node()->clear_attrib(DepthTestAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -5036,7 +5036,7 @@ clear_depth_test() { bool NodePath:: has_depth_test() const { nassertr_always(!is_empty(), false); - return node()->has_attrib(DepthTestAttrib::get_class_type()); + return node()->has_attrib(DepthTestAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -5052,7 +5052,7 @@ bool NodePath:: get_depth_test() const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(DepthTestAttrib::get_class_type()); + node()->get_attrib(DepthTestAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const DepthTestAttrib *dta = DCAST(DepthTestAttrib, attrib); return (dta->get_mode() != DepthTestAttrib::M_none); @@ -5091,7 +5091,7 @@ set_depth_write(bool depth_write, int priority) { void NodePath:: clear_depth_write() { nassertv_always(!is_empty()); - node()->clear_attrib(DepthWriteAttrib::get_class_type()); + node()->clear_attrib(DepthWriteAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -5106,7 +5106,7 @@ clear_depth_write() { bool NodePath:: has_depth_write() const { nassertr_always(!is_empty(), false); - return node()->has_attrib(DepthWriteAttrib::get_class_type()); + return node()->has_attrib(DepthWriteAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -5122,7 +5122,7 @@ bool NodePath:: get_depth_write() const { nassertr_always(!is_empty(), false); const RenderAttrib *attrib = - node()->get_attrib(DepthWriteAttrib::get_class_type()); + node()->get_attrib(DepthWriteAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const DepthWriteAttrib *dta = DCAST(DepthWriteAttrib, attrib); return (dta->get_mode() != DepthWriteAttrib::M_off); @@ -5366,7 +5366,7 @@ set_transparency(TransparencyAttrib::Mode mode, int priority) { void NodePath:: clear_transparency() { nassertv_always(!is_empty()); - node()->clear_attrib(TransparencyAttrib::get_class_type()); + node()->clear_attrib(TransparencyAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -5382,7 +5382,7 @@ clear_transparency() { bool NodePath:: has_transparency() const { nassertr_always(!is_empty(), false); - return node()->has_attrib(TransparencyAttrib::get_class_type()); + return node()->has_attrib(TransparencyAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -5400,7 +5400,7 @@ TransparencyAttrib::Mode NodePath:: get_transparency() const { nassertr_always(!is_empty(), TransparencyAttrib::M_none); const RenderAttrib *attrib = - node()->get_attrib(TransparencyAttrib::get_class_type()); + node()->get_attrib(TransparencyAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TransparencyAttrib *ta = DCAST(TransparencyAttrib, attrib); return ta->get_mode(); @@ -5431,7 +5431,7 @@ set_antialias(unsigned short mode, int priority) { void NodePath:: clear_antialias() { nassertv_always(!is_empty()); - node()->clear_attrib(AntialiasAttrib::get_class_type()); + node()->clear_attrib(AntialiasAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -5446,7 +5446,7 @@ clear_antialias() { bool NodePath:: has_antialias() const { nassertr_always(!is_empty(), false); - return node()->has_attrib(AntialiasAttrib::get_class_type()); + return node()->has_attrib(AntialiasAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -5460,7 +5460,7 @@ unsigned short NodePath:: get_antialias() const { nassertr_always(!is_empty(), AntialiasAttrib::M_none); const RenderAttrib *attrib = - node()->get_attrib(AntialiasAttrib::get_class_type()); + node()->get_attrib(AntialiasAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const AntialiasAttrib *ta = DCAST(AntialiasAttrib, attrib); return ta->get_mode(); @@ -5480,7 +5480,7 @@ get_antialias() const { bool NodePath:: has_audio_volume() const { nassertr_always(!is_empty(), false); - return node()->has_attrib(AudioVolumeAttrib::get_class_type()); + return node()->has_attrib(AudioVolumeAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -5495,7 +5495,7 @@ has_audio_volume() const { void NodePath:: clear_audio_volume() { nassertv_always(!is_empty()); - node()->clear_attrib(AudioVolumeAttrib::get_class_type()); + node()->clear_attrib(AudioVolumeAttrib::get_class_slot()); } //////////////////////////////////////////////////////////////////// @@ -5508,10 +5508,10 @@ set_audio_volume(float volume, int priority) { nassertv_always(!is_empty()); const RenderAttrib *attrib = - node()->get_attrib(AudioVolumeAttrib::get_class_type()); + node()->get_attrib(AudioVolumeAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { priority = max(priority, - node()->get_state()->get_override(AudioVolumeAttrib::get_class_type())); + node()->get_state()->get_override(AudioVolumeAttrib::get_class_slot())); CPT(AudioVolumeAttrib) ava = DCAST(AudioVolumeAttrib, attrib); // Modify the existing AudioVolumeAttrib to add the indicated @@ -5555,7 +5555,7 @@ set_audio_volume_off(int priority) { float NodePath:: get_audio_volume() const { const RenderAttrib *attrib = - node()->get_attrib(AudioVolumeAttrib::get_class_type()); + node()->get_attrib(AudioVolumeAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const AudioVolumeAttrib *ava = DCAST(AudioVolumeAttrib, attrib); return ava->get_volume(); @@ -5573,7 +5573,7 @@ get_audio_volume() const { float NodePath:: get_net_audio_volume() const { CPT(RenderState) net_state = get_net_state(); - const RenderAttrib *attrib = net_state->get_audio_volume(); + const RenderAttrib *attrib = net_state->get_attrib(AudioVolumeAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const AudioVolumeAttrib *ava = DCAST(AudioVolumeAttrib, attrib); if (ava != (const AudioVolumeAttrib *)NULL) { @@ -6693,7 +6693,7 @@ r_find_texture(PandaNode *node, const RenderState *state, // Look for a TextureAttrib on the state. const RenderAttrib *attrib = - geom_state->get_attrib(TextureAttrib::get_class_type()); + geom_state->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); for (int i = 0; i < ta->get_num_on_stages(); i++) { @@ -6743,7 +6743,7 @@ r_find_all_textures(PandaNode *node, const RenderState *state, // Look for a TextureAttrib on the state. const RenderAttrib *attrib = - geom_state->get_attrib(TextureAttrib::get_class_type()); + geom_state->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); for (int i = 0; i < ta->get_num_on_stages(); i++) { @@ -6775,7 +6775,7 @@ Texture * NodePath:: r_find_texture(PandaNode *node, TextureStage *stage) const { // Look for a TextureAttrib on the node. const RenderAttrib *attrib = - node->get_attrib(TextureAttrib::get_class_type()); + node->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); if (ta->has_on_stage(stage)) { @@ -6793,7 +6793,7 @@ r_find_texture(PandaNode *node, TextureStage *stage) const { // Look for a TextureAttrib on the state. const RenderAttrib *attrib = - geom_state->get_attrib(TextureAttrib::get_class_type()); + geom_state->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); if (ta->has_on_stage(stage)) { @@ -6828,7 +6828,7 @@ r_find_all_textures(PandaNode *node, TextureStage *stage, NodePath::Textures &textures) const { // Look for a TextureAttrib on the node. const RenderAttrib *attrib = - node->get_attrib(TextureAttrib::get_class_type()); + node->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); if (ta->has_on_stage(stage)) { @@ -6846,7 +6846,7 @@ r_find_all_textures(PandaNode *node, TextureStage *stage, // Look for a TextureAttrib on the state. const RenderAttrib *attrib = - geom_state->get_attrib(TextureAttrib::get_class_type()); + geom_state->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); if (ta->has_on_stage(stage)) { @@ -6884,7 +6884,7 @@ r_find_texture_stage(PandaNode *node, const RenderState *state, // Look for a TextureAttrib on the state. const RenderAttrib *attrib = - geom_state->get_attrib(TextureAttrib::get_class_type()); + geom_state->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); for (int i = 0; i < ta->get_num_on_stages(); i++) { @@ -6934,7 +6934,7 @@ r_find_all_texture_stages(PandaNode *node, const RenderState *state, // Look for a TextureAttrib on the state. const RenderAttrib *attrib = - geom_state->get_attrib(TextureAttrib::get_class_type()); + geom_state->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); for (int i = 0; i < ta->get_num_on_stages(); i++) { @@ -6966,7 +6966,7 @@ void NodePath:: r_unify_texture_stages(PandaNode *node, TextureStage *stage) { // Look for a TextureAttrib on the state. const RenderAttrib *attrib = - node->get_attrib(TextureAttrib::get_class_type()); + node->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); CPT(RenderAttrib) new_attrib = ta->unify_texture_stages(stage); @@ -6985,7 +6985,7 @@ r_unify_texture_stages(PandaNode *node, TextureStage *stage) { // Look for a TextureAttrib on the state. const RenderAttrib *attrib = - state->get_attrib(TextureAttrib::get_class_type()); + state->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); CPT(RenderAttrib) new_attrib = ta->unify_texture_stages(stage); @@ -7025,7 +7025,7 @@ r_find_material(PandaNode *node, const RenderState *state, // Look for a MaterialAttrib on the state. const RenderAttrib *attrib = - geom_state->get_attrib(MaterialAttrib::get_class_type()); + geom_state->get_attrib(MaterialAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const MaterialAttrib *ta = DCAST(MaterialAttrib, attrib); if (!ta->is_off()) { @@ -7073,7 +7073,7 @@ r_find_all_materials(PandaNode *node, const RenderState *state, // Look for a MaterialAttrib on the state. const RenderAttrib *attrib = - geom_state->get_attrib(MaterialAttrib::get_class_type()); + geom_state->get_attrib(MaterialAttrib::get_class_slot()); if (attrib != (const RenderAttrib *)NULL) { const MaterialAttrib *ta = DCAST(MaterialAttrib, attrib); if (!ta->is_off()) { diff --git a/panda/src/pgraph/pandaNode.I b/panda/src/pgraph/pandaNode.I index 6b9806ac11..2f6e503502 100644 --- a/panda/src/pgraph/pandaNode.I +++ b/panda/src/pgraph/pandaNode.I @@ -235,11 +235,22 @@ find_stashed(PandaNode *node, Thread *current_thread) const { INLINE const RenderAttrib *PandaNode:: get_attrib(TypeHandle type) const { CDReader cdata(_cycler); - int index = cdata->_state->find_attrib(type); - if (index >= 0) { - return cdata->_state->get_attrib(index); - } - return NULL; + return cdata->_state->get_attrib(type); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::get_attrib +// Access: Published +// Description: Returns the render attribute of the indicated type, +// if it is defined on the node, or NULL if it is not. +// This checks only what is set on this particular node +// level, and has nothing to do with what render +// attributes may be inherited from parent nodes. +//////////////////////////////////////////////////////////////////// +INLINE const RenderAttrib *PandaNode:: +get_attrib(int slot) const { + CDReader cdata(_cycler); + return cdata->_state->get_attrib(slot); } //////////////////////////////////////////////////////////////////// @@ -252,8 +263,35 @@ get_attrib(TypeHandle type) const { INLINE bool PandaNode:: has_attrib(TypeHandle type) const { CDReader cdata(_cycler); - int index = cdata->_state->find_attrib(type); - return (index >= 0); + return cdata->_state->has_attrib(type); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::has_attrib +// Access: Published +// Description: Returns true if there is a render attribute of the +// indicated type defined on this node, or false if +// there is not. +//////////////////////////////////////////////////////////////////// +INLINE bool PandaNode:: +has_attrib(int slot) const { + CDReader cdata(_cycler); + return cdata->_state->has_attrib(slot); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::clear_attrib +// Access: Published +// Description: Removes the render attribute of the given type from +// this node. This node, and the subgraph below, will +// now inherit the indicated render attribute from the +// nodes above this one. +//////////////////////////////////////////////////////////////////// +INLINE void PandaNode:: +clear_attrib(TypeHandle type) { + RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr(); + int slot = reg->get_slot(type); + clear_attrib(slot); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/pandaNode.cxx b/panda/src/pgraph/pandaNode.cxx index 9d8970fc72..3ffa9c2282 100644 --- a/panda/src/pgraph/pandaNode.cxx +++ b/panda/src/pgraph/pandaNode.cxx @@ -1090,14 +1090,14 @@ set_attrib(const RenderAttrib *attrib, int override) { // nodes above this one. //////////////////////////////////////////////////////////////////// void PandaNode:: -clear_attrib(TypeHandle type) { +clear_attrib(int slot) { bool any_changed = false; Thread *current_thread = Thread::get_current_thread(); OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { CDStageWriter cdata(_cycler, pipeline_stage, current_thread); - CPT(RenderState) new_state = cdata->_state->remove_attrib(type); + CPT(RenderState) new_state = cdata->_state->remove_attrib(slot); if (cdata->_state != new_state) { cdata->_state = new_state; cdata->set_fancy_bit(FB_state, !new_state->is_empty()); @@ -3644,7 +3644,7 @@ update_bounds(int pipeline_stage, PandaNode::CDLockedStageReader &cdata) { << "\nnet_draw_show_mask = " << net_draw_show_mask << "\n"; } - CPT(RenderAttrib) off_clip_planes = cdata->_state->get_clip_plane(); + CPT(RenderAttrib) off_clip_planes = cdata->_state->get_attrib(ClipPlaneAttrib::get_class_slot()); if (off_clip_planes == (RenderAttrib *)NULL) { off_clip_planes = ClipPlaneAttrib::make(); } diff --git a/panda/src/pgraph/pandaNode.h b/panda/src/pgraph/pandaNode.h index c2802045d8..ddc2dab31d 100644 --- a/panda/src/pgraph/pandaNode.h +++ b/panda/src/pgraph/pandaNode.h @@ -157,8 +157,11 @@ PUBLISHED: void set_attrib(const RenderAttrib *attrib, int override = 0); INLINE const RenderAttrib *get_attrib(TypeHandle type) const; + INLINE const RenderAttrib *get_attrib(int slot) const; INLINE bool has_attrib(TypeHandle type) const; - void clear_attrib(TypeHandle type); + INLINE bool has_attrib(int slot) const; + INLINE void clear_attrib(TypeHandle type); + void clear_attrib(int slot); void set_effect(const RenderEffect *effect); INLINE const RenderEffect *get_effect(TypeHandle type) const; diff --git a/panda/src/pgraph/pgraph_composite1.cxx b/panda/src/pgraph/pgraph_composite1.cxx index aff97112b3..1998c66703 100644 --- a/panda/src/pgraph/pgraph_composite1.cxx +++ b/panda/src/pgraph/pgraph_composite1.cxx @@ -4,7 +4,6 @@ #include "audioVolumeAttrib.cxx" #include "auxBitplaneAttrib.cxx" #include "auxSceneData.cxx" -#include "attribSlots.cxx" #include "bamFile.cxx" #include "billboardEffect.cxx" #include "cacheStats.cxx" diff --git a/panda/src/pgraph/pgraph_composite2.cxx b/panda/src/pgraph/pgraph_composite2.cxx index 2d9ce24203..81502e0107 100644 --- a/panda/src/pgraph/pgraph_composite2.cxx +++ b/panda/src/pgraph/pgraph_composite2.cxx @@ -13,7 +13,6 @@ #include "depthTestAttrib.cxx" #include "depthWriteAttrib.cxx" #include "alphaTestAttrib.cxx" -#include "drawMaskAttrib.cxx" #include "eventStorePandaNode.cxx" #include "fadeLodNode.cxx" #include "fadeLodNodeData.cxx" diff --git a/panda/src/pgraph/pgraph_composite4.cxx b/panda/src/pgraph/pgraph_composite4.cxx index 8f83815608..532ba1c14c 100644 --- a/panda/src/pgraph/pgraph_composite4.cxx +++ b/panda/src/pgraph/pgraph_composite4.cxx @@ -1,4 +1,5 @@ #include "renderAttrib.cxx" +#include "renderAttribRegistry.cxx" #include "renderEffect.cxx" #include "renderEffects.cxx" #include "renderModeAttrib.cxx" diff --git a/panda/src/pgraph/renderAttrib.I b/panda/src/pgraph/renderAttrib.I index 4cf45c8bf3..a4262b6e30 100644 --- a/panda/src/pgraph/renderAttrib.I +++ b/panda/src/pgraph/renderAttrib.I @@ -49,20 +49,6 @@ invert_compose(const RenderAttrib *other) const { return invert_compose_impl(other); } -//////////////////////////////////////////////////////////////////// -// Function: RenderAttrib::make_default -// Access: Public -// Description: Returns a different (or possibly the same) -// RenderAttrib pointer of the same type as this one -// that corresponds to whatever the standard default -// properties for render attributes of this type ought -// to be. -//////////////////////////////////////////////////////////////////// -INLINE CPT(RenderAttrib) RenderAttrib:: -make_default() const { - return return_new(make_default_impl()); -} - //////////////////////////////////////////////////////////////////// // Function: RenderAttrib::always_reissue // Access: Public @@ -102,3 +88,17 @@ compare_to(const RenderAttrib &other) const { // We only call compare_to_impl() if they have the same type. return compare_to_impl(&other); } + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttrib::register_slot +// Access: Public, Static +// Description: Adds the indicated TypeHandle to the registry, if it +// is not there already, and returns a unique slot +// number. See RenderAttribRegistry. +//////////////////////////////////////////////////////////////////// +INLINE int RenderAttrib:: +register_slot(TypeHandle type_handle, int sort, + RenderAttribRegistry::MakeDefaultFunc *make_default_func) { + RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr(); + return reg->register_slot(type_handle, sort, make_default_func); +} diff --git a/panda/src/pgraph/renderAttrib.cxx b/panda/src/pgraph/renderAttrib.cxx index fcfc639511..b74193c454 100644 --- a/panda/src/pgraph/renderAttrib.cxx +++ b/panda/src/pgraph/renderAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "renderAttrib.h" -#include "attribSlots.h" #include "bamReader.h" #include "indent.h" #include "config_pgraph.h" @@ -461,22 +460,6 @@ release_new() { } } -//////////////////////////////////////////////////////////////////// -// Function: RenderAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived RenderAttrib -// types to specify what the default property for a -// RenderAttrib of this type should be. -// -// This should return a newly-allocated RenderAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of RenderAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *RenderAttrib:: -make_default_impl() const { - return (RenderAttrib *)NULL; -} - //////////////////////////////////////////////////////////////////// // Function: RenderAttrib::init_attribs // Access: Public, Static diff --git a/panda/src/pgraph/renderAttrib.h b/panda/src/pgraph/renderAttrib.h index 0f84a3ce02..c8f8e01b0a 100644 --- a/panda/src/pgraph/renderAttrib.h +++ b/panda/src/pgraph/renderAttrib.h @@ -18,6 +18,7 @@ #include "pandabase.h" #include "typedWritableReferenceCount.h" +#include "renderAttribRegistry.h" #include "pointerTo.h" #include "pset.h" #include "lightReMutex.h" @@ -66,11 +67,9 @@ public: INLINE CPT(RenderAttrib) compose(const RenderAttrib *other) const; INLINE CPT(RenderAttrib) invert_compose(const RenderAttrib *other) const; - INLINE CPT(RenderAttrib) make_default() const; virtual bool lower_attrib_can_override() const; INLINE bool always_reissue() const; - virtual void store_into_slot(AttribSlots *slots) const=0; virtual bool has_cull_callback() const; virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const; @@ -87,6 +86,8 @@ PUBLISHED: static void list_attribs(ostream &out); static bool validate_attribs(); + virtual int get_slot() const=0; + enum PandaCompareFunc { // intentionally defined to match D3DCMPFUNC M_none=0, // alpha-test disabled (always-draw) M_never, // Never draw. @@ -176,9 +177,12 @@ protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const=0; void output_comparefunc(ostream &out, PandaCompareFunc fn) const; +public: + INLINE static int register_slot(TypeHandle type_handle, int sort, + RenderAttribRegistry::MakeDefaultFunc *make_default_func); + private: void release_new(); diff --git a/panda/src/pgraph/renderAttribRegistry.I b/panda/src/pgraph/renderAttribRegistry.I new file mode 100644 index 0000000000..ba8da15691 --- /dev/null +++ b/panda/src/pgraph/renderAttribRegistry.I @@ -0,0 +1,162 @@ +// Filename: renderAttribRegistry.I +// Created by: drose (13Nov08) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::get_slot +// Access: Published +// Description: Returns the slot number assigned to the indicated +// TypeHandle, or 0 if no slot number has been assigned. +//////////////////////////////////////////////////////////////////// +INLINE int RenderAttribRegistry:: +get_slot(TypeHandle type_handle) const { + int type_index = type_handle.get_index(); + if (type_index >= (int)_slots_by_type.size()) { + return 0; + } + return _slots_by_type[type_index]; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::get_max_slots +// Access: Published +// Description: Returns the maximum number that any slot number is +// allowed to grow. Actually, this number will be one +// higher than the highest possible slot number. This +// puts an upper bound on the number of RenderAttrib +// slots that may be allocated, and allows other code to +// define an array of slots. +// +// This number will not change during the lifetime of +// the application. +//////////////////////////////////////////////////////////////////// +INLINE int RenderAttribRegistry:: +get_max_slots() const { + return _max_slots; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::get_num_slots +// Access: Published +// Description: Returns the number of RenderAttrib slots that have +// been allocated. This is one more than the highest +// slot number in use. +//////////////////////////////////////////////////////////////////// +INLINE int RenderAttribRegistry:: +get_num_slots() const { + return _registry.size(); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::get_slot_type +// Access: Published +// Description: Returns the TypeHandle associated with slot n. +//////////////////////////////////////////////////////////////////// +INLINE TypeHandle RenderAttribRegistry:: +get_slot_type(int slot) const { + nassertr(slot >= 0 && slot < (int)_registry.size(), TypeHandle::none()); + return _registry[slot]._type; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::get_slot_sort +// Access: Published +// Description: Returns the sort number associated with slot n. +//////////////////////////////////////////////////////////////////// +INLINE int RenderAttribRegistry:: +get_slot_sort(int slot) const { + nassertr(slot >= 0 && slot < (int)_registry.size(), 0); + return _registry[slot]._sort; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::get_num_sorted_slots +// Access: Published +// Description: Returns the number of entries in the sorted_slots +// list. +//////////////////////////////////////////////////////////////////// +INLINE int RenderAttribRegistry:: +get_num_sorted_slots() const { + return _sorted_slots.size(); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::get_sorted_slot +// Access: Published +// Description: Returns the nth slot in sorted order. By traversing +// this list, you will retrieve all the slot numbers in +// order according to their registered sort value. +//////////////////////////////////////////////////////////////////// +INLINE int RenderAttribRegistry:: +get_sorted_slot(int n) const { + nassertr(n >= 0 && n < (int)_sorted_slots.size(), 0); + return _sorted_slots[n]; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::get_array_chain +// Access: Published +// Description: Returns the DeletedBufferChain object that may be +// used to allocated appropriately-sized arrays of +// RenderState::Attribute objects. +//////////////////////////////////////////////////////////////////// +INLINE DeletedBufferChain *RenderAttribRegistry:: +get_array_chain() const { + return _array_chain; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::get_global_ptr +// Access: Published, Static +// Description: +//////////////////////////////////////////////////////////////////// +INLINE RenderAttribRegistry *RenderAttribRegistry:: +get_global_ptr() { + if (_global_ptr == (RenderAttribRegistry *)NULL) { + init_global_ptr(); + } + return _global_ptr; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::quick_get_global_ptr +// Access: Public, Static +// Description: Returns the global_ptr without first ensuring it has +// been initialized. Only safe for code that knows it +// has already been initialized. +//////////////////////////////////////////////////////////////////// +INLINE RenderAttribRegistry *RenderAttribRegistry:: +quick_get_global_ptr() { + return _global_ptr; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::SortSlots::Constructor +// Access: Public +// Description: This is an STL function object for sorting the +// _sorted_slots list into order by slot sort number. +//////////////////////////////////////////////////////////////////// +INLINE RenderAttribRegistry::SortSlots:: +SortSlots(RenderAttribRegistry *reg) : _reg(reg) { +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::SortSlots::operator () +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool RenderAttribRegistry::SortSlots:: +operator () (int a, int b) const { + return _reg->get_slot_sort(a) < _reg->get_slot_sort(b); +} diff --git a/panda/src/pgraph/renderAttribRegistry.cxx b/panda/src/pgraph/renderAttribRegistry.cxx new file mode 100644 index 0000000000..7dd633fb0e --- /dev/null +++ b/panda/src/pgraph/renderAttribRegistry.cxx @@ -0,0 +1,175 @@ +// Filename: renderAttribRegistry.cxx +// Created by: drose (13Nov08) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "renderAttribRegistry.h" +#include "renderAttrib.h" +#include "renderState.h" +#include "deletedChain.h" + +RenderAttribRegistry *RenderAttribRegistry::_global_ptr; + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::Constructor +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +RenderAttribRegistry:: +RenderAttribRegistry() { + ConfigVariableInt max_attribs + ("max-attribs", SlotMask::get_max_num_bits(), + PRC_DESC("This specifies the maximum number of different RenderAttrib " + "types that may be defined at runtime. Normally you should " + "never need to change this, but if the default value is too " + "low for the number of attribs that Panda actually defines, " + "you may need to raise this number.")); + + // Assign this number once, at startup, and never change it again. + _max_slots = max((int)max_attribs, 1); + if (_max_slots > SlotMask::get_max_num_bits()) { + pgraph_cat->warning() + << "Value for max-attribs too large: cannot exceed " + << SlotMask::get_max_num_bits() + << " in this build. To raise this limit, change the typedef " + << "for SlotMask in renderAttribRegistry.h and recompile.\n"; + + _max_slots = SlotMask::get_max_num_bits(); + } + + // Get a DeletedBufferChain to manage the arrays of RenderAttribs that are + // allocated within each RenderState object. + init_memory_hook(); + _array_chain = memory_hook->get_deleted_chain(_max_slots * sizeof(RenderState::Attribute)); + + // Reserve slot 0 for TypeHandle::none(), and for types that exceed + // max_slots. + RegistryNode node; + node._sort = 0; + node._make_default_func = NULL; + _registry.push_back(node); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::Destructor +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +RenderAttribRegistry:: +~RenderAttribRegistry() { +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::register_slot +// Access: Public +// Description: Adds the indicated TypeHandle to the registry, if it +// is not there already, and returns a unique slot +// number in the range 0 < slot < get_max_slots(). +// +// The sort value is an arbitrary integer. In general, +// the RenderAttribs will be sorted in order from lowest +// sort value to highest sort value, when they are +// traversed via the get_num_sorted_slots() / +// get_sorted_slot() methods. This will be used to sort +// render states, so that heavier RenderAttribs are +// changed less frequently. In general, you should +// choose sort values such that the heavier +// RenderAttribs (that is, those which are more +// expensive to change) have lower sort values. +// +// The make_default_func pointer is a function that may +// be called to generate a default RenderAttrib to apply +// in the absence of any other attrib of this type. +// +// register_slot() is intended to be called at +// application start for each different RenderAttrib +// type in the system, to assign a different integer +// slot number to each one. +//////////////////////////////////////////////////////////////////// +int RenderAttribRegistry:: +register_slot(TypeHandle type_handle, int sort, + RenderAttribRegistry::MakeDefaultFunc *make_default_func) { + int type_index = type_handle.get_index(); + while (type_index >= (int)_slots_by_type.size()) { + _slots_by_type.push_back(0); + } + + if (_slots_by_type[type_index] != 0) { + // This type has already been registered. + return _slots_by_type[type_index]; + } + + int slot = (int)_registry.size(); + if (slot >= _max_slots) { + pgraph_cat->error() + << "Too many registered RenderAttribs; not registering " + << type_handle << "\n"; + nassertr(false, 0); + return 0; + } + + _slots_by_type[type_index] = slot; + + RegistryNode node; + node._type = type_handle; + node._sort = sort; + node._make_default_func = make_default_func; + _registry.push_back(node); + + _sorted_slots.push_back(slot); + ::sort(_sorted_slots.begin(), _sorted_slots.end(), SortSlots(this)); + + return slot; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::set_slot_sort +// Access: Published +// Description: Changes the sort number associated with slot n. +//////////////////////////////////////////////////////////////////// +void RenderAttribRegistry:: +set_slot_sort(int slot, int sort) { + nassertv(slot >= 0 && slot < (int)_registry.size()); + _registry[slot]._sort = sort; + + // Re-sort the slot list. + _sorted_slots.clear(); + _sorted_slots.reserve(_registry.size() - 1); + for (int i = 1; i < (int)_registry.size(); ++i) { + _sorted_slots.push_back(i); + } + ::sort(_sorted_slots.begin(), _sorted_slots.end(), SortSlots(this)); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::get_slot_default +// Access: Published +// Description: Returns the default RenderAttrib object associated +// with slot n. This is the attrib that should be +// applied in the absence of any other attrib of this +// type. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) RenderAttribRegistry:: +get_slot_default(int slot) const { + nassertr(slot >= 0 && slot < (int)_registry.size(), 0); + return (*_registry[slot]._make_default_func)(); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderAttribRegistry::init_global_ptr +// Access: Private, Static +// Description: +//////////////////////////////////////////////////////////////////// +void RenderAttribRegistry:: +init_global_ptr() { + _global_ptr = new RenderAttribRegistry; +} diff --git a/panda/src/pgraph/renderAttribRegistry.h b/panda/src/pgraph/renderAttribRegistry.h new file mode 100644 index 0000000000..207171c505 --- /dev/null +++ b/panda/src/pgraph/renderAttribRegistry.h @@ -0,0 +1,107 @@ +// Filename: renderAttribRegistry.h +// Created by: drose (13Nov08) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef RENDERATTRIBREGISTRY_H +#define RENDERATTRIBREGISTRY_H + +#include "pandabase.h" +#include "typeHandle.h" +#include "vector_int.h" +#include "pointerTo.h" +#include "bitMask.h" + +class RenderAttrib; +class DeletedBufferChain; + +//////////////////////////////////////////////////////////////////// +// Class : RenderAttribRegistry +// Description : This class is used to associate each RenderAttrib +// with a different slot index at runtime, so we can +// store a list of RenderAttribs in the RenderState +// object, and very quickly look them up by type. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA_PGRAPH RenderAttribRegistry { +private: + RenderAttribRegistry(); + ~RenderAttribRegistry(); + +public: + typedef CPT(RenderAttrib) MakeDefaultFunc(); + + // This typedef defines the native bitmask type for indicating which + // slots are present in a RenderState. It must be wide enough to + // allow room for all of the possible RenderAttribs that might + // register themselves. Presently, 32 bits is wide enough, but only + // barely; when we exceed this limit, we will need to go to a 64-bit + // type instead. It will be interesting to see whether a BitMask64 + // or a DoubleBitMask will be faster on a 32-bit machine. + typedef BitMask32 SlotMask; + + int register_slot(TypeHandle type_handle, int sort, + MakeDefaultFunc *make_default_func); + +PUBLISHED: + INLINE int get_slot(TypeHandle type_handle) const; + INLINE int get_max_slots() const; + + INLINE int get_num_slots() const; + INLINE TypeHandle get_slot_type(int slot) const; + INLINE int get_slot_sort(int slot) const; + void set_slot_sort(int slot, int sort); + CPT(RenderAttrib) get_slot_default(int slot) const; + + INLINE int get_num_sorted_slots() const; + INLINE int get_sorted_slot(int n) const; + + INLINE DeletedBufferChain *get_array_chain() const; + + INLINE static RenderAttribRegistry *get_global_ptr(); + +public: + INLINE static RenderAttribRegistry *quick_get_global_ptr(); + +private: + static void init_global_ptr(); + +private: + int _max_slots; + + class SortSlots { + public: + INLINE SortSlots(RenderAttribRegistry *reg); + INLINE bool operator () (int a, int b) const; + RenderAttribRegistry *_reg; + }; + + class RegistryNode { + public: + TypeHandle _type; + int _sort; + MakeDefaultFunc *_make_default_func; + }; + typedef pvector Registry; + Registry _registry; + + vector_int _slots_by_type; + vector_int _sorted_slots; + + DeletedBufferChain *_array_chain; + + static RenderAttribRegistry *_global_ptr; +}; + +#include "renderAttribRegistry.I" + +#endif + diff --git a/panda/src/pgraph/renderModeAttrib.cxx b/panda/src/pgraph/renderModeAttrib.cxx index c15af4c6e1..38bd658a93 100644 --- a/panda/src/pgraph/renderModeAttrib.cxx +++ b/panda/src/pgraph/renderModeAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "renderModeAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle RenderModeAttrib::_type_handle; +int RenderModeAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: RenderModeAttrib::make @@ -51,6 +51,18 @@ make(RenderModeAttrib::Mode mode, float thickness, bool perspective) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: RenderModeAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) RenderModeAttrib:: +make_default() { + return return_new(new RenderModeAttrib(M_filled, 1.0f, false)); +} + //////////////////////////////////////////////////////////////////// // Function: RenderModeAttrib::output // Access: Public, Virtual @@ -148,33 +160,6 @@ compose_impl(const RenderAttrib *other) const { return make(mode, ta->get_thickness(), ta->get_perspective()); } -//////////////////////////////////////////////////////////////////// -// Function: RenderModeAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived RenderModeAttrib -// types to specify what the default property for a -// RenderModeAttrib of this type should be. -// -// This should return a newly-allocated RenderModeAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of RenderModeAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *RenderModeAttrib:: -make_default_impl() const { - return new RenderModeAttrib(M_filled, 1.0f, false); -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderModeAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void RenderModeAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_render_mode = this; -} - //////////////////////////////////////////////////////////////////// // Function: RenderModeAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/renderModeAttrib.h b/panda/src/pgraph/renderModeAttrib.h index d2f5c749c1..5187ea2a66 100644 --- a/panda/src/pgraph/renderModeAttrib.h +++ b/panda/src/pgraph/renderModeAttrib.h @@ -53,6 +53,7 @@ private: PUBLISHED: static CPT(RenderAttrib) make(Mode mode, float thickness = 1.0f, bool perspective = false); + static CPT(RenderAttrib) make_default(); INLINE Mode get_mode() const; INLINE float get_thickness() const; @@ -62,18 +63,24 @@ PUBLISHED: public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: Mode _mode; float _thickness; bool _perspective; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -90,6 +97,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "RenderModeAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -98,6 +106,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "renderModeAttrib.I" diff --git a/panda/src/pgraph/renderState.I b/panda/src/pgraph/renderState.I index ff89310c16..aab6733e5d 100644 --- a/panda/src/pgraph/renderState.I +++ b/panda/src/pgraph/renderState.I @@ -20,41 +20,7 @@ //////////////////////////////////////////////////////////////////// INLINE bool RenderState:: is_empty() const { - return _attributes.empty(); -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_num_attribs -// Access: Published -// Description: Returns the number of separate attributes indicated -// in the state. -//////////////////////////////////////////////////////////////////// -INLINE int RenderState:: -get_num_attribs() const { - return _attributes.size(); -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_attrib -// Access: Published -// Description: Returns the nth attribute in the state. -//////////////////////////////////////////////////////////////////// -INLINE const RenderAttrib *RenderState:: -get_attrib(int n) const { - nassertr(n >= 0 && n < (int)_attributes.size(), NULL); - return _attributes[n]._attrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_override -// Access: Published -// Description: Returns the override associated with the nth -// attribute in the state. -//////////////////////////////////////////////////////////////////// -INLINE int RenderState:: -get_override(int n) const { - nassertr(n >= 0 && n < (int)_attributes.size(), 0); - return _attributes[n]._override; + return _filled_slots.is_zero(); } //////////////////////////////////////////////////////////////////// @@ -74,6 +40,109 @@ has_cull_callback() const { return (_flags & F_has_cull_callback) != 0; } +//////////////////////////////////////////////////////////////////// +// Function: RenderState::remove_attrib +// Access: Published +// Description: Returns a new RenderState object that represents the +// same as the source state, with the indicated +// RenderAttrib removed. +//////////////////////////////////////////////////////////////////// +INLINE CPT(RenderState) RenderState:: +remove_attrib(TypeHandle type) const { + RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr(); + int slot = reg->get_slot(type); + return remove_attrib(slot); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::has_attrib +// Access: Published +// Description: Returns true if an attrib of the indicated type is +// present, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool RenderState:: +has_attrib(TypeHandle type) const { + return get_attrib(type) != (RenderAttrib *)NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::has_attrib +// Access: Published +// Description: Returns true if an attrib of the indicated type is +// present, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool RenderState:: +has_attrib(int slot) const { + return get_attrib(slot) != (RenderAttrib *)NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::get_attrib +// Access: Published +// Description: Looks for a RenderAttrib of the indicated type in the +// state, and returns it if it is found, or NULL if it +// is not. +//////////////////////////////////////////////////////////////////// +INLINE const RenderAttrib *RenderState:: +get_attrib(TypeHandle type) const { + RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr(); + int slot = reg->get_slot(type); + return _attributes[slot]._attrib; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::get_attrib +// Access: Published +// Description: Returns the RenderAttrib with the indicated slot +// index, or NULL if there is no such RenderAttrib in +// the state. +//////////////////////////////////////////////////////////////////// +INLINE const RenderAttrib *RenderState:: +get_attrib(int slot) const { + return _attributes[slot]._attrib; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::get_attrib_def +// Access: Published +// Description: Returns the RenderAttrib with the indicated slot +// index, or the default attrib for that slot if there +// is no such RenderAttrib in the state. +//////////////////////////////////////////////////////////////////// +INLINE const RenderAttrib *RenderState:: +get_attrib_def(int slot) const { + if (_attributes[slot]._attrib != (RenderAttrib *)NULL) { + return _attributes[slot]._attrib; + } + return make_full_default()->get_attrib(slot); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::get_override +// Access: Published +// Description: Looks for a RenderAttrib of the indicated type in the +// state, and returns its override value if it is found, +// or 0 if it is not. +//////////////////////////////////////////////////////////////////// +INLINE int RenderState:: +get_override(TypeHandle type) const { + RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr(); + int slot = reg->get_slot(type); + return _attributes[slot]._override; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::get_override +// Access: Published +// Description: Looks for a RenderAttrib of the indicated type in the +// state, and returns its override value if it is found, +// or 0 if it is not. +//////////////////////////////////////////////////////////////////// +INLINE int RenderState:: +get_override(int slot) const { + return _attributes[slot]._override; +} + //////////////////////////////////////////////////////////////////// // Function: RenderState::cache_ref // Access: Published @@ -157,63 +226,6 @@ get_draw_order() const { return _draw_order; } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_fog -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a FogAttrib on this state. It returns a -// pointer to the FogAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const FogAttrib *RenderState:: -get_fog() const { - if ((_flags & F_checked_fog) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal fog cache. - ((RenderState *)this)->determine_fog(); - } - return _fog; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_bin -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a BinAttrib on this state. It returns a -// pointer to the BinAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const CullBinAttrib *RenderState:: -get_bin() const { - if ((_flags & F_checked_bin) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal bin cache. - ((RenderState *)this)->determine_bin(); - } - return _bin; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_transparency -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a TransparencyAttrib on this state. It returns a -// pointer to the TransparencyAttrib, if there is one, -// or NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const TransparencyAttrib *RenderState:: -get_transparency() const { - if ((_flags & F_checked_transparency) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal transparency cache. - ((RenderState *)this)->determine_transparency(); - } - return _transparency; -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::get_bin_index // Access: Published @@ -233,218 +245,6 @@ get_bin_index() const { return _bin_index; } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_color -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a ColorAttrib on this state. It returns a -// pointer to the ColorAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const ColorAttrib *RenderState:: -get_color() const { - if ((_flags & F_checked_color) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal color cache. - ((RenderState *)this)->determine_color(); - } - return _color; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_color_scale -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a ColorScaleAttrib on this state. It returns a -// pointer to the ColorScaleAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const ColorScaleAttrib *RenderState:: -get_color_scale() const { - if ((_flags & F_checked_color_scale) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal color_scale cache. - ((RenderState *)this)->determine_color_scale(); - } - return _color_scale; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_texture -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a TextureAttrib on this state. It returns a -// pointer to the TextureAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const TextureAttrib *RenderState:: -get_texture() const { - if ((_flags & F_checked_texture) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal texture cache. - ((RenderState *)this)->determine_texture(); - } - return _texture; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_tex_gen -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a TexGenAttrib on this state. It returns a -// pointer to the TexGenAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const TexGenAttrib *RenderState:: -get_tex_gen() const { - if ((_flags & F_checked_tex_gen) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal tex_gen cache. - ((RenderState *)this)->determine_tex_gen(); - } - return _tex_gen; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_tex_matrix -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a TexMatrixAttrib on this state. It returns a -// pointer to the TexMatrixAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const TexMatrixAttrib *RenderState:: -get_tex_matrix() const { - if ((_flags & F_checked_tex_matrix) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal tex_matrix cache. - ((RenderState *)this)->determine_tex_matrix(); - } - return _tex_matrix; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_render_mode -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a RenderModeAttrib on this state. It returns a -// pointer to the RenderModeAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const RenderModeAttrib *RenderState:: -get_render_mode() const { - if ((_flags & F_checked_render_mode) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal render_mode cache. - ((RenderState *)this)->determine_render_mode(); - } - return _render_mode; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_clip_plane -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a ClipPlaneAttrib on this state. It returns a -// pointer to the ClipPlaneAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const ClipPlaneAttrib *RenderState:: -get_clip_plane() const { - if ((_flags & F_checked_clip_plane) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal clip_plane cache. - ((RenderState *)this)->determine_clip_plane(); - } - return _clip_plane; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_scissor -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a ScissorAttrib on this state. It returns a -// pointer to the ScissorAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const ScissorAttrib *RenderState:: -get_scissor() const { - if ((_flags & F_checked_scissor) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal scissor cache. - ((RenderState *)this)->determine_scissor(); - } - return _scissor; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_shader -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a ShaderAttrib on this state. It returns a -// pointer to the ShaderAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const ShaderAttrib *RenderState:: -get_shader() const { - if ((_flags & F_checked_shader) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal shader cache. - ((RenderState *)this)->determine_shader(); - } - return _shader; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_audio_volume -// Access: Published -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of an AudioVolumeAttrib on this state. It returns a -// pointer to the AudioVolumeAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const AudioVolumeAttrib *RenderState:: -get_audio_volume() const { - if ((_flags & F_checked_audio_volume) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal audio_volume cache. - ((RenderState *)this)->determine_audio_volume(); - } - return _audio_volume; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_bin -// Access: Private -// Description: This is the private implementation of get_bin(). -//////////////////////////////////////////////////////////////////// -INLINE void RenderState:: -determine_bin() { - LightMutexHolder holder(_lock); - do_determine_bin(); -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_transparency -// Access: Private -// Description: This is the private implementation of get_transparency(). -//////////////////////////////////////////////////////////////////// -INLINE void RenderState:: -determine_transparency() { - LightMutexHolder holder(_lock); - do_determine_transparency(); -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::set_destructing // Access: Private @@ -522,7 +322,6 @@ Composition(const RenderState::Composition ©) : //////////////////////////////////////////////////////////////////// INLINE RenderState::Attribute:: Attribute(const RenderAttrib *attrib, int override) : - _type(attrib->get_type()), _attrib(attrib), _override(override) { @@ -531,9 +330,7 @@ Attribute(const RenderAttrib *attrib, int override) : //////////////////////////////////////////////////////////////////// // Function: RenderState::Attribute::Constructor // Access: Public -// Description: This constructor is only used when reading the -// RenderState from a bam file. At this point, the -// attribute pointer is unknown. +// Description: //////////////////////////////////////////////////////////////////// INLINE RenderState::Attribute:: Attribute(int override) : @@ -541,22 +338,6 @@ Attribute(int override) : { } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::Attribute::Constructor -// Access: Public -// Description: This constructor makes an invalid Attribute with no -// RenderAttrib pointer; its purpose is just to make an -// object we can use to look up a particular type in the -// Attribute set. -//////////////////////////////////////////////////////////////////// -INLINE RenderState::Attribute:: -Attribute(TypeHandle type) : - _type(type), - _attrib(NULL), - _override(0) -{ -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::Attribute::Copy Constructor // Access: Public @@ -564,7 +345,6 @@ Attribute(TypeHandle type) : //////////////////////////////////////////////////////////////////// INLINE RenderState::Attribute:: Attribute(const Attribute ©) : - _type(copy._type), _attrib(copy._attrib), _override(copy._override) { @@ -577,45 +357,37 @@ Attribute(const Attribute ©) : //////////////////////////////////////////////////////////////////// INLINE void RenderState::Attribute:: operator = (const Attribute ©) { - _type = copy._type; _attrib = copy._attrib; _override = copy._override; } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::Attribute::operator < -// Access: Public -// Description: This is used by the Attributes set to uniquify -// RenderAttributes by type. Only one RenderAttrib of a -// given type is allowed in the set. This ordering must -// also match the ordering reported by compare_to(). -//////////////////////////////////////////////////////////////////// -INLINE bool RenderState::Attribute:: -operator < (const Attribute &other) const { - return _type < other._type; -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::Attribute::compare_to // Access: Public // Description: Provides an indication of whether a particular // attribute is equivalent to another one, for purposes // of generating unique RenderStates. This should -// compare all properties of the Attribute, but it is -// important that the type is compared first, to be -// consistent with the ordering defined by operator <. +// compare all properties of the Attribute. //////////////////////////////////////////////////////////////////// INLINE int RenderState::Attribute:: compare_to(const Attribute &other) const { - if (_type != other._type) { - return _type.get_index() - other._type.get_index(); - } if (_attrib != other._attrib) { return _attrib < other._attrib ? -1 : 1; } return _override - other._override; } +//////////////////////////////////////////////////////////////////// +// Function: RenderState::Attribute::set +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void RenderState::Attribute:: +set(const RenderAttrib *attrib, int override) { + _attrib = attrib; + _override = override; +} + //////////////////////////////////////////////////////////////////// // Function: RenderState::flush_level // Access: Public, Static diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 01a2b71dbb..d082aaf389 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -35,12 +35,13 @@ #include "lightReMutexHolder.h" #include "lightMutexHolder.h" #include "thread.h" -#include "attribSlots.h" #include "shaderGeneratorBase.h" +#include "renderAttribRegistry.h" LightReMutex *RenderState::_states_lock = NULL; RenderState::States *RenderState::_states = NULL; CPT(RenderState) RenderState::_empty_state; +CPT(RenderState) RenderState::_full_default_state; UpdateSeq RenderState::_last_cycle_detect; PStatCollector RenderState::_cache_update_pcollector("*:State Cache:Update"); @@ -62,24 +63,52 @@ TypeHandle RenderState::_type_handle; // spurious warning if all constructors are private. //////////////////////////////////////////////////////////////////// RenderState:: -RenderState() : _lock("RenderState") { +RenderState() : + _lock("RenderState"), + _flags(0) +{ + // Allocate the _attributes array. + RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr(); + _attributes = (Attribute *)reg->get_array_chain()->allocate(reg->get_max_slots() * sizeof(Attribute), get_class_type()); + + // Also make sure each element gets initialized. + for (int i = 0; i < reg->get_max_slots(); ++i) { + new(&_attributes[i]) Attribute(); + } + if (_states == (States *)NULL) { init_states(); } _saved_entry = _states->end(); - _flags = 0; _last_mi = _mungers.end(); _cache_stats.add_num_states(1); + _read_overrides = NULL; } //////////////////////////////////////////////////////////////////// // Function: RenderState::Copy Constructor // Access: Private -// Description: RenderStates are not meant to be copied. +// Description: RenderStates are only meant to be copied internally. //////////////////////////////////////////////////////////////////// RenderState:: -RenderState(const RenderState &) { - nassertv(false); +RenderState(const RenderState ©) : + _lock("RenderState"), + _filled_slots(copy._filled_slots), + _flags(0) +{ + // Allocate the _attributes array. + RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr(); + _attributes = (Attribute *)reg->get_array_chain()->allocate(reg->get_max_slots() * sizeof(Attribute), get_class_type()); + + // Also make sure each element gets initialized, as a copy. + for (int i = 0; i < reg->get_max_slots(); ++i) { + new(&_attributes[i]) Attribute(copy._attributes[i]); + } + + _saved_entry = _states->end(); + _last_mi = _mungers.end(); + _cache_stats.add_num_states(1); + _read_overrides = NULL; } //////////////////////////////////////////////////////////////////// @@ -114,6 +143,14 @@ RenderState:: // longer true now, probably we've been double-deleted. nassertv(get_ref_count() == 0); _cache_stats.add_num_states(-1); + + // Free the _attributes array. + RenderAttribRegistry *reg = RenderAttribRegistry::get_global_ptr(); + for (int i = 0; i < reg->get_max_slots(); ++i) { + _attributes[i].~Attribute(); + } + reg->get_array_chain()->deallocate(_attributes, get_class_type()); + _attributes = NULL; } //////////////////////////////////////////////////////////////////// @@ -130,11 +167,52 @@ RenderState:: //////////////////////////////////////////////////////////////////// bool RenderState:: operator < (const RenderState &other) const { - // We must compare all the properties of the attributes, not just - // the type; thus, we compare them one at a time using compare_to(). - return lexicographical_compare(_attributes.begin(), _attributes.end(), - other._attributes.begin(), other._attributes.end(), - CompareTo()); + RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr(); + SlotMask mask = _filled_slots | other._filled_slots; + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + int result = _attributes[slot].compare_to(other._attributes[slot]); + if (result != 0) { + return result < 0; + } + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); + } + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::compare_sort +// Access: Published +// Description: Returns -1, 0, or 1 according to the relative sorting +// of these two RenderStates, with regards to rendering +// performance, so that "heavier" RenderAttribs (as +// defined by RenderAttribRegistry::get_slot_sort()) are +// more likely to be grouped together. This is not +// related to the sorting order defined by operator <. +//////////////////////////////////////////////////////////////////// +int RenderState:: +compare_sort(const RenderState &other) const { + if (this == &other) { + // Trivial case. + return 0; + } + + RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr(); + int num_sorted_slots = reg->get_num_sorted_slots(); + for (int n = 0; n < num_sorted_slots; ++n) { + int slot = reg->get_sorted_slot(n); + nassertr((_attributes[slot]._attrib != NULL) == _filled_slots.get_bit(slot), 0); + + const RenderAttrib *a = _attributes[slot]._attrib; + const RenderAttrib *b = other._attributes[slot]._attrib; + if (a != b) { + return a < b ? -1 : 1; + } + } + + return 0; } //////////////////////////////////////////////////////////////////// @@ -146,12 +224,16 @@ size_t RenderState:: get_hash() const { size_t hash = 0; - // hash = sequence_hash::add_hash(hash, _attributes); - Attributes::const_iterator ai; - for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) { - const Attribute &attrib = *ai; - hash = pointer_hash::add_hash(hash, attrib._attrib); - hash = int_hash::add_hash(hash, attrib._override); + SlotMask mask = _filled_slots; + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + const Attribute &attrib = _attributes[slot]; + if (attrib._attrib != (RenderAttrib *)NULL) { + hash = pointer_hash::add_hash(hash, attrib._attrib); + hash = int_hash::add_hash(hash, attrib._override); + } + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); } return hash; @@ -167,33 +249,22 @@ get_hash() const { //////////////////////////////////////////////////////////////////// bool RenderState:: cull_callback(CullTraverser *trav, const CullTraverserData &data) const { - Attributes::const_iterator ai; - for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) { - const Attribute &attrib = *ai; + SlotMask mask = _filled_slots; + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + const Attribute &attrib = _attributes[slot]; + nassertr(attrib._attrib != NULL, false); if (!attrib._attrib->cull_callback(trav, data)) { return false; } + + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); } return true; } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::find_attrib -// Access: Published -// Description: Searches for an attribute with the indicated type in -// the state, and returns its index if it is found, or -// -1 if it is not. -//////////////////////////////////////////////////////////////////// -int RenderState:: -find_attrib(TypeHandle type) const { - Attributes::const_iterator ai = _attributes.find(Attribute(type)); - if (ai == _attributes.end()) { - return -1; - } - return ai - _attributes.begin(); -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::make_empty // Access: Published, Static @@ -211,6 +282,25 @@ make_empty() { return _empty_state; } +//////////////////////////////////////////////////////////////////// +// Function: RenderState::make_full_default +// Access: Published, Static +// Description: Returns a RenderState with all possible attributes +// set to their default value. +//////////////////////////////////////////////////////////////////// +CPT(RenderState) RenderState:: +make_full_default() { + // The empty state is asked for so often, we make it a special case + // and store a pointer forever once we find it the first time. + if (_full_default_state == (RenderState *)NULL) { + RenderState *state = new RenderState; + state->fill_default(); + _full_default_state = return_new(state); + } + + return _full_default_state; +} + //////////////////////////////////////////////////////////////////// // Function: RenderState::make // Access: Published, Static @@ -219,8 +309,9 @@ make_empty() { CPT(RenderState) RenderState:: make(const RenderAttrib *attrib, int override) { RenderState *state = new RenderState; - state->_attributes.reserve(1); - state->_attributes.insert(Attribute(attrib, override)); + int slot = attrib->get_slot(); + state->_attributes[slot].set(attrib, override); + state->_filled_slots.set_bit(slot); return return_new(state); } @@ -233,10 +324,10 @@ CPT(RenderState) RenderState:: make(const RenderAttrib *attrib1, const RenderAttrib *attrib2, int override) { RenderState *state = new RenderState; - state->_attributes.reserve(2); - state->_attributes.push_back(Attribute(attrib1, override)); - state->_attributes.push_back(Attribute(attrib2, override)); - state->_attributes.sort(); + state->_attributes[attrib1->get_slot()].set(attrib1, override); + state->_attributes[attrib2->get_slot()].set(attrib2, override); + state->_filled_slots.set_bit(attrib1->get_slot()); + state->_filled_slots.set_bit(attrib2->get_slot()); return return_new(state); } @@ -250,11 +341,12 @@ make(const RenderAttrib *attrib1, const RenderAttrib *attrib2, const RenderAttrib *attrib3, int override) { RenderState *state = new RenderState; - state->_attributes.reserve(3); - state->_attributes.push_back(Attribute(attrib1, override)); - state->_attributes.push_back(Attribute(attrib2, override)); - state->_attributes.push_back(Attribute(attrib3, override)); - state->_attributes.sort(); + state->_attributes[attrib1->get_slot()].set(attrib1, override); + state->_attributes[attrib2->get_slot()].set(attrib2, override); + state->_attributes[attrib3->get_slot()].set(attrib3, override); + state->_filled_slots.set_bit(attrib1->get_slot()); + state->_filled_slots.set_bit(attrib2->get_slot()); + state->_filled_slots.set_bit(attrib3->get_slot()); return return_new(state); } @@ -269,12 +361,14 @@ make(const RenderAttrib *attrib1, const RenderAttrib *attrib3, const RenderAttrib *attrib4, int override) { RenderState *state = new RenderState; - state->_attributes.reserve(4); - state->_attributes.push_back(Attribute(attrib1, override)); - state->_attributes.push_back(Attribute(attrib2, override)); - state->_attributes.push_back(Attribute(attrib3, override)); - state->_attributes.push_back(Attribute(attrib4, override)); - state->_attributes.sort(); + state->_attributes[attrib1->get_slot()].set(attrib1, override); + state->_attributes[attrib2->get_slot()].set(attrib2, override); + state->_attributes[attrib3->get_slot()].set(attrib3, override); + state->_attributes[attrib4->get_slot()].set(attrib4, override); + state->_filled_slots.set_bit(attrib1->get_slot()); + state->_filled_slots.set_bit(attrib2->get_slot()); + state->_filled_slots.set_bit(attrib3->get_slot()); + state->_filled_slots.set_bit(attrib4->get_slot()); return return_new(state); } @@ -285,33 +379,18 @@ make(const RenderAttrib *attrib1, //////////////////////////////////////////////////////////////////// CPT(RenderState) RenderState:: make(const RenderAttrib * const *attrib, int num_attribs, int override) { + if (num_attribs == 0) { + return make_empty(); + } RenderState *state = new RenderState; - state->_attributes.reserve(num_attribs); for (int i = 0; i < num_attribs; i++) { - state->_attributes.push_back(Attribute(attrib[i], override)); + int slot = attrib[i]->get_slot(); + state->_attributes[slot].set(attrib[i], override); + state->_filled_slots.set_bit(slot); } return return_new(state); } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::make -// Access: Published, Static -// Description: Returns a RenderState made from the specified slots. -//////////////////////////////////////////////////////////////////// -CPT(RenderState) RenderState:: -make(const AttribSlots *slots, int override) { - RenderState *state = new RenderState; - for (int i = 0; i < AttribSlots::slot_count; i++) { - const RenderAttrib *attrib = slots->get_slot(i); - if (attrib != 0) { - state->_attributes.push_back(Attribute(attrib, override)); - } - } - state->_attributes.reserve(state->_attributes.size()); - state->_attributes.sort(); - return return_new(state); -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::compose // Access: Published @@ -512,50 +591,17 @@ invert_compose(const RenderState *other) const { //////////////////////////////////////////////////////////////////// CPT(RenderState) RenderState:: add_attrib(const RenderAttrib *attrib, int override) const { - RenderState *new_state = new RenderState; - back_insert_iterator result = - back_inserter(new_state->_attributes); - - Attribute new_attribute(attrib, override); - Attributes::const_iterator ai = _attributes.begin(); - - while (ai != _attributes.end() && (*ai) < new_attribute) { - *result = *ai; - ++ai; - ++result; - } - - if (ai != _attributes.end() && !(new_attribute < (*ai))) { - // At this point we know: !((*ai) < new_attribute) && - // !(new_attribute < (*ai)) which means (*ai) == new_attribute, so - // there is another attribute of the same type already in the - // state. - - if ((*ai)._override > override) { - // The existing attribute overrides. - *result = *ai; - ++ai; - } else { - // The new attribute overrides. - *result = new_attribute; - ++ai; - ++result; - } - - } else { - // There is not another attribute of the same type already in the - // state. - *result = new_attribute; - ++result; - } - - - while (ai != _attributes.end()) { - *result = *ai; - ++ai; - ++result; + int slot = attrib->get_slot(); + if (_attributes[slot]._attrib != (RenderAttrib *)NULL && + _attributes[slot]._override > override) { + // The existing attribute overrides. + return this; } + // The new attribute replaces. + RenderState *new_state = new RenderState(*this); + new_state->_attributes[slot].set(attrib, override); + new_state->_filled_slots.set_bit(slot); return return_new(new_state); } @@ -570,43 +616,10 @@ add_attrib(const RenderAttrib *attrib, int override) const { //////////////////////////////////////////////////////////////////// CPT(RenderState) RenderState:: set_attrib(const RenderAttrib *attrib) const { - RenderState *new_state = new RenderState; - back_insert_iterator result = - back_inserter(new_state->_attributes); - - Attribute new_attribute(attrib, 0); - Attributes::const_iterator ai = _attributes.begin(); - - while (ai != _attributes.end() && (*ai) < new_attribute) { - *result = *ai; - ++ai; - ++result; - } - - if (ai != _attributes.end() && !(new_attribute < (*ai))) { - // At this point we know: !((*ai) < new_attribute) && - // !(new_attribute < (*ai)) which means (*ai) == new_attribute, so - // there is another attribute of the same type already in the - // state. - - (*result) = Attribute(attrib, (*ai)._override); - ++ai; - ++result; - - } else { - // There is not another attribute of the same type already in the - // state. - *result = new_attribute; - ++result; - } - - - while (ai != _attributes.end()) { - *result = *ai; - ++ai; - ++result; - } - + RenderState *new_state = new RenderState(*this); + int slot = attrib->get_slot(); + new_state->_attributes[slot]._attrib = attrib; + new_state->_filled_slots.set_bit(slot); return return_new(new_state); } @@ -621,43 +634,10 @@ set_attrib(const RenderAttrib *attrib) const { //////////////////////////////////////////////////////////////////// CPT(RenderState) RenderState:: set_attrib(const RenderAttrib *attrib, int override) const { - RenderState *new_state = new RenderState; - back_insert_iterator result = - back_inserter(new_state->_attributes); - - Attribute new_attribute(attrib, override); - Attributes::const_iterator ai = _attributes.begin(); - - while (ai != _attributes.end() && (*ai) < new_attribute) { - *result = *ai; - ++ai; - ++result; - } - - if (ai != _attributes.end() && !(new_attribute < (*ai))) { - // At this point we know: !((*ai) < new_attribute) && - // !(new_attribute < (*ai)) which means (*ai) == new_attribute, so - // there is another attribute of the same type already in the - // state. - - (*result) = Attribute(attrib, override); - ++ai; - ++result; - - } else { - // There is not another attribute of the same type already in the - // state. - *result = new_attribute; - ++result; - } - - - while (ai != _attributes.end()) { - *result = *ai; - ++ai; - ++result; - } - + RenderState *new_state = new RenderState(*this); + int slot = attrib->get_slot(); + new_state->_attributes[slot].set(attrib, override); + new_state->_filled_slots.set_bit(slot); return return_new(new_state); } @@ -669,26 +649,25 @@ set_attrib(const RenderAttrib *attrib, int override) const { // RenderAttrib removed. //////////////////////////////////////////////////////////////////// CPT(RenderState) RenderState:: -remove_attrib(TypeHandle type) const { - RenderState *new_state = new RenderState; - back_insert_iterator result = - back_inserter(new_state->_attributes); - - Attributes::const_iterator ai = _attributes.begin(); - - while (ai != _attributes.end()) { - if ((*ai)._type != type) { - *result = *ai; - ++result; - } - ++ai; +remove_attrib(int slot) const { + if (_attributes[slot]._attrib == NULL) { + // Already removed. + return this; } + // Will this bring us down to the empty state? + if (_filled_slots.get_num_on_bits() == 1) { + return make_empty(); + } + + RenderState *new_state = new RenderState(*this); + new_state->_attributes[slot].set(NULL, 0); + new_state->_filled_slots.clear_bit(slot); return return_new(new_state); } //////////////////////////////////////////////////////////////////// -// Function: RenderState::remove_attrib +// Function: RenderState::adjust_all_priorities // Access: Published // Description: Returns a new RenderState object that represents the // same as the source state, with all attributes' @@ -699,52 +678,22 @@ remove_attrib(TypeHandle type) const { CPT(RenderState) RenderState:: adjust_all_priorities(int adjustment) const { RenderState *new_state = new RenderState; - new_state->_attributes.reserve(_attributes.size()); - Attributes::const_iterator ai; - for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) { - Attribute attrib = *ai; - attrib._override = max(attrib._override + adjustment, 0); - new_state->_attributes.push_back(attrib); + SlotMask mask = _filled_slots; + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + Attribute &attrib = new_state->_attributes[slot]; + if (attrib._attrib != (RenderAttrib *)NULL) { + attrib._override = max(attrib._override + adjustment, 0); + } + + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); } return return_new(new_state); } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_attrib -// Access: Published, Virtual -// Description: Looks for a RenderAttrib of the indicated type in the -// state, and returns it if it is found, or NULL if it -// is not. -//////////////////////////////////////////////////////////////////// -const RenderAttrib *RenderState:: -get_attrib(TypeHandle type) const { - Attributes::const_iterator ai; - ai = _attributes.find(Attribute(type)); - if (ai != _attributes.end()) { - return (*ai)._attrib; - } - return NULL; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_override -// Access: Published, Virtual -// Description: Looks for a RenderAttrib of the indicated type in the -// state, and returns its override value if it is found, -// or 0 if it is not. -//////////////////////////////////////////////////////////////////// -int RenderState:: -get_override(TypeHandle type) const { - Attributes::const_iterator ai; - ai = _attributes.find(Attribute(type)); - if (ai != _attributes.end()) { - return (*ai)._override; - } - return 0; -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::unref // Access: Published @@ -812,16 +761,23 @@ unref() const { void RenderState:: output(ostream &out) const { out << "S:"; - if (_attributes.empty()) { + if (is_empty()) { out << "(empty)"; } else { - Attributes::const_iterator ai = _attributes.begin(); - out << "(" << (*ai)._type; - ++ai; - while (ai != _attributes.end()) { - out << " " << (*ai)._type; - ++ai; + out << "("; + const char *sep = ""; + + SlotMask mask = _filled_slots; + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + const Attribute &attrib = _attributes[slot]; + nassertv(attrib._attrib != (RenderAttrib *)NULL); + out << sep << attrib._attrib->get_type(); + sep = " "; + + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); } out << ")"; } @@ -834,14 +790,21 @@ output(ostream &out) const { //////////////////////////////////////////////////////////////////// void RenderState:: write(ostream &out, int indent_level) const { - indent(out, indent_level) << _attributes.size() << " attribs:\n"; - Attributes::const_iterator ai; - for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) { - const Attribute &attribute = (*ai); - attribute._attrib->write(out, indent_level + 2); + if (is_empty()) { + indent(out, indent_level) + << "(empty)\n"; + } + + SlotMask mask = _filled_slots; + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + const Attribute &attrib = _attributes[slot]; + nassertv(attrib._attrib != (RenderAttrib *)NULL); + attrib._attrib->write(out, indent_level); + + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); } - // indent(out, indent_level + 2) << _composition_cache << "\n"; - // indent(out, indent_level + 2) << _invert_composition_cache << "\n"; } //////////////////////////////////////////////////////////////////// @@ -1192,6 +1155,7 @@ validate_states() { States::const_iterator snext = si; ++snext; nassertr((*si)->get_ref_count() > 0, false); + nassertr((*si)->validate_filled_slots(), false); while (snext != _states->end()) { if (!(*(*si) < *(*snext))) { pgraph_cat.error() @@ -1214,6 +1178,7 @@ validate_states() { si = snext; ++snext; nassertr((*si)->get_ref_count() > 0, false); + nassertr((*si)->validate_filled_slots(), false); } return true; @@ -1229,14 +1194,18 @@ validate_states() { //////////////////////////////////////////////////////////////////// int RenderState:: get_geom_rendering(int geom_rendering) const { - if (get_render_mode() != (const RenderModeAttrib *)NULL) { - geom_rendering = _render_mode->get_geom_rendering(geom_rendering); + const RenderModeAttrib *render_mode = DCAST(RenderModeAttrib, get_attrib(RenderModeAttrib::get_class_slot())); + const TexGenAttrib *tex_gen = DCAST(TexGenAttrib, get_attrib(TexGenAttrib::get_class_slot())); + const TexMatrixAttrib *tex_matrix = DCAST(TexMatrixAttrib, get_attrib(TexMatrixAttrib::get_class_slot())); + + if (render_mode != (const RenderModeAttrib *)NULL) { + geom_rendering = render_mode->get_geom_rendering(geom_rendering); } - if (get_tex_gen() != (const TexGenAttrib *)NULL) { - geom_rendering = _tex_gen->get_geom_rendering(geom_rendering); + if (tex_gen != (const TexGenAttrib *)NULL) { + geom_rendering = tex_gen->get_geom_rendering(geom_rendering); } - if (get_tex_matrix() != (const TexMatrixAttrib *)NULL) { - geom_rendering = _tex_matrix->get_geom_rendering(geom_rendering); + if (tex_matrix != (const TexMatrixAttrib *)NULL) { + geom_rendering = tex_matrix->get_geom_rendering(geom_rendering); } return geom_rendering; @@ -1265,19 +1234,6 @@ get_generated_shader() const { } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::store_into_slots -// Access: Public -// Description: Convert the attribute list into an AttribSlots. -//////////////////////////////////////////////////////////////////// -void RenderState:: -store_into_slots(AttribSlots *output) const { - Attributes::const_iterator ai; - for (ai = _attributes.begin(); ai != _attributes.end(); ai++) { - (*ai)._attrib->store_into_slot(output); - } -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::bin_removed // Access: Public, Static @@ -1291,6 +1247,49 @@ bin_removed(int bin_index) { // Do something here. nassertv(false); } + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::determine_filled_slots +// Access: Private +// Description: Examines all of the slots to determine the +// appropriate bitmask to put in _filled_slots. +//////////////////////////////////////////////////////////////////// +void RenderState:: +determine_filled_slots() { + _filled_slots.clear(); + RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr(); + int max_slots = reg->get_max_slots(); + for (int slot = 1; slot < max_slots; ++slot) { + const Attribute &attribute = _attributes[slot]; + if (attribute._attrib != (RenderAttrib *)NULL) { + _filled_slots.set_bit(slot); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::validate_filled_slots +// Access: Private +// Description: Returns true if the _filled_slots bitmask is +// consistent with the table of RenderAttrib pointers, +// false otherwise. +//////////////////////////////////////////////////////////////////// +bool RenderState:: +validate_filled_slots() const { + SlotMask mask; + + RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr(); + int max_slots = reg->get_max_slots(); + for (int slot = 1; slot < max_slots; ++slot) { + const Attribute &attribute = _attributes[slot]; + if (attribute._attrib != (RenderAttrib *)NULL) { + mask.set_bit(slot); + } + } + + return (mask == _filled_slots); +} + //////////////////////////////////////////////////////////////////// // Function: RenderState::return_new @@ -1307,6 +1306,36 @@ bin_removed(int bin_index) { CPT(RenderState) RenderState:: return_new(RenderState *state) { nassertr(state != (RenderState *)NULL, state); + + // Make sure we don't have anything in the 0 slot. If we did, that + // would indicate an uninitialized slot number. +#ifndef NDEBUG + if (state->_attributes[0]._attrib != (RenderAttrib *)NULL) { + const RenderAttrib *attrib = state->_attributes[0]._attrib; + if (attrib->get_type() == TypeHandle::none()) { + ((RenderAttrib *)attrib)->force_init_type(); + pgraph_cat->error() + << "Uninitialized RenderAttrib type: " << attrib->get_type() + << "\n"; + + } else { + static pset already_reported; + if (already_reported.insert(attrib->get_type()).second) { + pgraph_cat->error() + << attrib->get_type() << " did not initialize its slot number.\n"; + } + } + } +#endif + state->_attributes[0]._attrib = NULL; + state->_filled_slots.clear_bit(0); + +#ifndef NDEBUG + nassertd(state->validate_filled_slots()) { + state->determine_filled_slots(); + } +#endif + static ConfigVariableBool uniquify_states("uniquify-states", true); if (!uniquify_states && !state->is_empty()) { return state; @@ -1359,69 +1388,41 @@ CPT(RenderState) RenderState:: do_compose(const RenderState *other) const { PStatTimer timer(_state_compose_pcollector); - // First, build a new Attributes member that represents the union of - // this one and that one. - Attributes::const_iterator ai = _attributes.begin(); - Attributes::const_iterator bi = other->_attributes.begin(); - - // Create a new RenderState that will hold the result. RenderState *new_state = new RenderState; - back_insert_iterator result = - back_inserter(new_state->_attributes); - while (ai != _attributes.end() && bi != other->_attributes.end()) { - if ((*ai) < (*bi)) { - // Here is an attribute that we have in the original, which is - // not present in the secondary. - *result = *ai; - ++ai; - ++result; - } else if ((*bi) < (*ai)) { - // Here is a new attribute we have in the secondary, that was - // not present in the original. - *result = *bi; - ++bi; - ++result; + SlotMask mask = _filled_slots | other->_filled_slots; + new_state->_filled_slots = mask; + + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + const Attribute &a = _attributes[slot]; + const Attribute &b = other->_attributes[slot]; + Attribute &result = new_state->_attributes[slot]; + + if (a._attrib == NULL) { + nassertr(b._attrib != NULL, this); + // B wins. + result = b; + + } else if (b._attrib == NULL) { + // A wins. + result = a; + + } else if (a._override < b._override) { + // B overrides. + result = b; + + } else if (b._override < a._override) { + // A overrides. + result = a; + } else { - // Here is an attribute we have in both. Does A override B? - const Attribute &a = (*ai); - const Attribute &b = (*bi); - if (b._override < a._override) { - // A, the higher RenderAttrib, overrides. - *result = *ai; - - } else if (a._override < b._override && - a._attrib->lower_attrib_can_override()) { - // B, the lower RenderAttrib, overrides. This is a special - // case; normally, a lower RenderAttrib does not override a - // higher one, even if it has a higher override value. But - // certain kinds of RenderAttribs redefine - // lower_attrib_can_override() to return true, allowing this - // override. - *result = *bi; - - } else { - // Either they have the same override value, or B is higher. - // In either case, the result is the composition of the two, - // with B's override value. - *result = Attribute(a._attrib->compose(b._attrib), b._override); - } - ++ai; - ++bi; - ++result; + // Both attribs compose. + result.set(a._attrib->compose(b._attrib), a._override); } - } - - while (ai != _attributes.end()) { - *result = *ai; - ++ai; - ++result; - } - - while (bi != other->_attributes.end()) { - *result = *bi; - ++bi; - ++result; + + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); } return return_new(new_state); @@ -1436,49 +1437,37 @@ CPT(RenderState) RenderState:: do_invert_compose(const RenderState *other) const { PStatTimer timer(_state_invert_pcollector); - Attributes::const_iterator ai = _attributes.begin(); - Attributes::const_iterator bi = other->_attributes.begin(); - - // Create a new RenderState that will hold the result. RenderState *new_state = new RenderState; - back_insert_iterator result = - back_inserter(new_state->_attributes); - while (ai != _attributes.end() && bi != other->_attributes.end()) { - if ((*ai) < (*bi)) { - // Here is an attribute that we have in the original, which is - // not present in the secondary. - *result = Attribute((*ai)._attrib->invert_compose((*ai)._attrib->make_default()), 0); - ++ai; - ++result; - } else if ((*bi) < (*ai)) { - // Here is a new attribute we have in the secondary, that was - // not present in the original. - *result = *bi; - ++bi; - ++result; + SlotMask mask = _filled_slots | other->_filled_slots; + new_state->_filled_slots = mask; + + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + const Attribute &a = _attributes[slot]; + const Attribute &b = other->_attributes[slot]; + Attribute &result = new_state->_attributes[slot]; + + if (a._attrib == NULL) { + nassertr(b._attrib != NULL, this); + // B wins. + result = b; + + } else if (b._attrib == NULL) { + // A wins. Invert it. + CPT(RenderState) full_default = make_full_default(); + CPT(RenderAttrib) default_attrib = full_default->get_attrib(slot); + result.set(a._attrib->invert_compose(default_attrib), 0); + } else { - // Here is an attribute we have in both. In this case, override - // is meaningless. - *result = Attribute((*ai)._attrib->invert_compose((*bi)._attrib), (*bi)._override); - ++ai; - ++bi; - ++result; + // Both are good. (Overrides are not used in invert_compose.) + // Compose. + result.set(a._attrib->invert_compose(b._attrib), 0); } + + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); } - - while (ai != _attributes.end()) { - *result = Attribute((*ai)._attrib->invert_compose((*ai)._attrib->make_default()), 0); - ++ai; - ++result; - } - - while (bi != other->_attributes.end()) { - *result = *bi; - ++bi; - ++result; - } - return return_new(new_state); } @@ -1718,13 +1707,10 @@ determine_bin_index() { string bin_name; _draw_order = 0; - if ((_flags & F_checked_bin) == 0) { - do_determine_bin(); - } - - if (_bin != (const CullBinAttrib *)NULL) { - bin_name = _bin->get_bin_name(); - _draw_order = _bin->get_draw_order(); + const CullBinAttrib *bin = DCAST(CullBinAttrib, get_attrib(CullBinAttrib::get_class_slot())); + if (bin != (const CullBinAttrib *)NULL) { + bin_name = bin->get_bin_name(); + _draw_order = bin->get_draw_order(); } if (bin_name.empty()) { @@ -1733,12 +1719,9 @@ determine_bin_index() { // setting. bin_name = "opaque"; - if ((_flags & F_checked_transparency) == 0) { - do_determine_transparency(); - } - - if (_transparency != (const TransparencyAttrib *)NULL) { - switch (_transparency->get_mode()) { + const TransparencyAttrib *transparency = DCAST(TransparencyAttrib, get_attrib(TransparencyAttrib::get_class_slot())); + if (transparency != (const TransparencyAttrib *)NULL) { + switch (transparency->get_mode()) { case TransparencyAttrib::M_alpha: case TransparencyAttrib::M_dual: // These transparency modes require special back-to-front sorting. @@ -1750,7 +1733,7 @@ determine_bin_index() { } } } - + CullBinManager *bin_manager = CullBinManager::get_global_ptr(); _bin_index = bin_manager->find_bin(bin_name); if (_bin_index == -1) { @@ -1761,260 +1744,6 @@ determine_bin_index() { _flags |= F_checked_bin_index; } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_fog -// Access: Private -// Description: This is the private implementation of get_fog(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_fog() { - LightMutexHolder holder(_lock); - if ((_flags & F_checked_fog) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = get_attrib(FogAttrib::get_class_type()); - _fog = (const FogAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _fog = DCAST(FogAttrib, attrib); - } - _flags |= F_checked_fog; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::do_determine_bin -// Access: Private -// Description: This is the implementation of determine_bin(); it -// assumes the lock is already held. -//////////////////////////////////////////////////////////////////// -void RenderState:: -do_determine_bin() { - if ((_flags & F_checked_bin) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = get_attrib(CullBinAttrib::get_class_type()); - _bin = (const CullBinAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _bin = DCAST(CullBinAttrib, attrib); - } - _flags |= F_checked_bin; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::do_determine_transparency -// Access: Private -// Description: This is the implementation of -// determine_transparency(); it assumes the lock is -// already held. -//////////////////////////////////////////////////////////////////// -void RenderState:: -do_determine_transparency() { - if ((_flags & F_checked_transparency) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = - get_attrib(TransparencyAttrib::get_class_type()); - _transparency = (const TransparencyAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _transparency = DCAST(TransparencyAttrib, attrib); - } - _flags |= F_checked_transparency; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_color -// Access: Private -// Description: This is the private implementation of get_color(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_color() { - LightMutexHolder holder(_lock); - if ((_flags & F_checked_color) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = get_attrib(ColorAttrib::get_class_type()); - _color = (const ColorAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _color = DCAST(ColorAttrib, attrib); - } - _flags |= F_checked_color; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_color_scale -// Access: Private -// Description: This is the private implementation of get_color_scale(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_color_scale() { - LightMutexHolder holder(_lock); - if ((_flags & F_checked_color_scale) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = get_attrib(ColorScaleAttrib::get_class_type()); - _color_scale = (const ColorScaleAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _color_scale = DCAST(ColorScaleAttrib, attrib); - } - _flags |= F_checked_color_scale; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_texture -// Access: Private -// Description: This is the private implementation of get_texture(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_texture() { - LightMutexHolder holder(_lock); - if ((_flags & F_checked_texture) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = get_attrib(TextureAttrib::get_class_type()); - _texture = (const TextureAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _texture = DCAST(TextureAttrib, attrib); - } - _flags |= F_checked_texture; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_tex_gen -// Access: Private -// Description: This is the private implementation of get_tex_gen(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_tex_gen() { - LightMutexHolder holder(_lock); - if ((_flags & F_checked_tex_gen) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = get_attrib(TexGenAttrib::get_class_type()); - _tex_gen = (const TexGenAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _tex_gen = DCAST(TexGenAttrib, attrib); - } - _flags |= F_checked_tex_gen; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_tex_matrix -// Access: Private -// Description: This is the private implementation of get_tex_matrix(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_tex_matrix() { - LightMutexHolder holder(_lock); - if ((_flags & F_checked_tex_matrix) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = get_attrib(TexMatrixAttrib::get_class_type()); - _tex_matrix = (const TexMatrixAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _tex_matrix = DCAST(TexMatrixAttrib, attrib); - } - _flags |= F_checked_tex_matrix; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_render_mode -// Access: Private -// Description: This is the private implementation of get_render_mode(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_render_mode() { - LightMutexHolder holder(_lock); - if ((_flags & F_checked_render_mode) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = get_attrib(RenderModeAttrib::get_class_type()); - _render_mode = (const RenderModeAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _render_mode = DCAST(RenderModeAttrib, attrib); - } - _flags |= F_checked_render_mode; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_clip_plane -// Access: Private -// Description: This is the private implementation of get_clip_plane(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_clip_plane() { - LightMutexHolder holder(_lock); - if ((_flags & F_checked_clip_plane) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = get_attrib(ClipPlaneAttrib::get_class_type()); - _clip_plane = (const ClipPlaneAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _clip_plane = DCAST(ClipPlaneAttrib, attrib); - } - _flags |= F_checked_clip_plane; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_scissor -// Access: Private -// Description: This is the private implementation of get_scissor(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_scissor() { - LightMutexHolder holder(_lock); - if ((_flags & F_checked_scissor) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = get_attrib(ScissorAttrib::get_class_type()); - _scissor = (const ScissorAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _scissor = DCAST(ScissorAttrib, attrib); - } - _flags |= F_checked_scissor; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_shader -// Access: Private -// Description: This is the private implementation of get_shader(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_shader() { - LightMutexHolder holder(_lock); - if ((_flags & F_checked_shader) != 0) { - // Someone else checked it first. - return; - } - - const RenderAttrib *attrib = get_attrib(ShaderAttrib::get_class_type()); - _shader = (const ShaderAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _shader = DCAST(ShaderAttrib, attrib); - } - _flags |= F_checked_shader; -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::determine_cull_callback // Access: Private @@ -2028,37 +1757,36 @@ determine_cull_callback() { return; } - Attributes::const_iterator ai; - for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) { - const Attribute &attrib = *ai; - if (attrib._attrib->has_cull_callback()) { + SlotMask mask = _filled_slots; + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + const Attribute &attrib = _attributes[slot]; + if (attrib._attrib != (RenderAttrib *)NULL && + attrib._attrib->has_cull_callback()) { _flags |= F_has_cull_callback; break; } + + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); } _flags |= F_checked_cull_callback; } //////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_audio_volume +// Function: RenderState::fill_default // Access: Private -// Description: This is the private implementation of has_audio_volume(). +// Description: Fills up the state with all of the default attribs. //////////////////////////////////////////////////////////////////// void RenderState:: -determine_audio_volume() { - LightMutexHolder holder(_lock); - if ((_flags & F_checked_audio_volume) != 0) { - // Someone else checked it first. - return; +fill_default() { + RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr(); + int num_slots = reg->get_num_slots(); + for (int slot = 1; slot < num_slots; ++slot) { + _attributes[slot].set(reg->get_slot_default(slot), 0); + _filled_slots.set_bit(slot); } - - const RenderAttrib *attrib = get_attrib(AudioVolumeAttrib::get_class_type()); - _audio_volume = (const AudioVolumeAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _audio_volume = DCAST(AudioVolumeAttrib, attrib); - } - _flags |= F_checked_audio_volume; } //////////////////////////////////////////////////////////////////// @@ -2131,18 +1859,22 @@ void RenderState:: write_datagram(BamWriter *manager, Datagram &dg) { TypedWritable::write_datagram(manager, dg); - int num_attribs = _attributes.size(); + int num_attribs = _filled_slots.get_num_on_bits(); nassertv(num_attribs == (int)(PN_uint16)num_attribs); dg.add_uint16(num_attribs); // **** We should smarten up the writing of the override // number--most of the time these will all be zero. - Attributes::const_iterator ai; - for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) { - const Attribute &attribute = (*ai); - - manager->write_pointer(dg, attribute._attrib); - dg.add_int32(attribute._override); + SlotMask mask = _filled_slots; + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + const Attribute &attrib = _attributes[slot]; + nassertv(attrib._attrib != (RenderAttrib *)NULL); + manager->write_pointer(dg, attrib._attrib); + dg.add_int32(attrib._override); + + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); } } @@ -2157,28 +1889,25 @@ int RenderState:: complete_pointers(TypedWritable **p_list, BamReader *manager) { int pi = TypedWritable::complete_pointers(p_list, manager); - // Get the attribute pointers. - for (size_t i = 0; i < _attributes.size(); ++i) { - Attribute &attribute = _attributes[i]; + int num_attribs = 0; - TypedWritable *ptr = p_list[pi++]; - while (ptr == NULL && i < _attributes.size()) { - // This is an attribute that we weren't able to load from the - // bam file. Remove it. - _attributes.pop_back(); - ptr = p_list[pi++]; - } - if (i < _attributes.size()) { - attribute._attrib = DCAST(RenderAttrib, ptr); - attribute._type = attribute._attrib->get_type(); + RenderAttribRegistry *reg = RenderAttribRegistry::quick_get_global_ptr(); + for (size_t i = 0; i < (*_read_overrides).size(); ++i) { + int override = (*_read_overrides)[i]; + + RenderAttrib *attrib = DCAST(RenderAttrib, p_list[pi++]); + if (attrib != (RenderAttrib *)NULL) { + int slot = attrib->get_slot(); + if (slot > 0 && slot < reg->get_max_slots()) { + _attributes[slot].set(attrib, override); + _filled_slots.set_bit(slot); + ++num_attribs; + } } } - // Now make sure the array is properly sorted. (It won't - // necessarily preserve its correct sort after being read from bam, - // because the sort is based on TypeHandle indices and raw pointers, - // both of which can change from session to session.) - _attributes.sort(); + delete _read_overrides; + _read_overrides = NULL; return pi; } @@ -2268,14 +1997,13 @@ fillin(DatagramIterator &scan, BamReader *manager) { TypedWritable::fillin(scan, manager); int num_attribs = scan.get_uint16(); + _read_overrides = new vector_int; + (*_read_overrides).reserve(num_attribs); - // Push back a NULL pointer for each attribute for now, until we get - // the actual list of pointers later in complete_pointers(). - _attributes.reserve(num_attribs); - for (int i = 0; i < num_attribs; i++) { + for (int i = 0; i < num_attribs; ++i) { manager->read_pointer(scan); int override = scan.get_int32(); - _attributes.push_back(Attribute(override)); + (*_read_overrides).push_back(override); } } diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index 8e9b364881..755451c8e9 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -20,7 +20,7 @@ #include "renderAttrib.h" #include "nodeCachedReferenceCount.h" #include "pointerTo.h" -#include "ordered_vector.h" +#include "pvector.h" #include "updateSeq.h" #include "pStatCollector.h" #include "renderModeAttrib.h" @@ -32,20 +32,11 @@ #include "deletedChain.h" #include "simpleHashMap.h" #include "cacheStats.h" +#include "renderAttribRegistry.h" class GraphicsStateGuardianBase; -class FogAttrib; -class CullBinAttrib; -class TransparencyAttrib; -class ColorAttrib; -class ColorScaleAttrib; -class TextureAttrib; -class TexGenAttrib; -class ClipPlaneAttrib; -class ScissorAttrib; -class ShaderAttrib; class FactoryParams; -class AudioVolumeAttrib; +class ShaderAttrib; //////////////////////////////////////////////////////////////////// // Class : RenderState @@ -71,21 +62,20 @@ public: virtual ~RenderState(); ALLOC_DELETED_CHAIN(RenderState); + typedef RenderAttribRegistry::SlotMask SlotMask; + PUBLISHED: bool operator < (const RenderState &other) const; + int compare_sort(const RenderState &other) const; size_t get_hash() const; INLINE bool is_empty() const; - INLINE int get_num_attribs() const; - INLINE const RenderAttrib *get_attrib(int n) const; - INLINE int get_override(int n) const; INLINE bool has_cull_callback() const; bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const; - int find_attrib(TypeHandle type) const; - static CPT(RenderState) make_empty(); + static CPT(RenderState) make_full_default(); static CPT(RenderState) make(const RenderAttrib *attrib, int override = 0); static CPT(RenderState) make(const RenderAttrib *attrib1, const RenderAttrib *attrib2, int override = 0); @@ -98,7 +88,6 @@ PUBLISHED: const RenderAttrib *attrib4, int override = 0); static CPT(RenderState) make(const RenderAttrib * const *attrib, int num_attribs, int override = 0); - static CPT(RenderState) make(const AttribSlots *slots, int override = 0); CPT(RenderState) compose(const RenderState *other) const; CPT(RenderState) invert_compose(const RenderState *other) const; @@ -106,12 +95,18 @@ PUBLISHED: CPT(RenderState) add_attrib(const RenderAttrib *attrib, int override = 0) const; CPT(RenderState) set_attrib(const RenderAttrib *attrib) const; CPT(RenderState) set_attrib(const RenderAttrib *attrib, int override) const; - CPT(RenderState) remove_attrib(TypeHandle type) const; + INLINE CPT(RenderState) remove_attrib(TypeHandle type) const; + CPT(RenderState) remove_attrib(int slot) const; CPT(RenderState) adjust_all_priorities(int adjustment) const; - const RenderAttrib *get_attrib(TypeHandle type) const; - int get_override(TypeHandle type) const; + INLINE bool has_attrib(TypeHandle type) const; + INLINE bool has_attrib(int slot) const; + INLINE const RenderAttrib *get_attrib(TypeHandle type) const; + INLINE const RenderAttrib *get_attrib(int slot) const; + INLINE const RenderAttrib *get_attrib_def(int slot) const; + INLINE int get_override(TypeHandle type) const; + INLINE int get_override(int slot) const; bool unref() const; @@ -137,33 +132,18 @@ PUBLISHED: // These methods are intended for use by low-level code, but they're // also handy enough to expose to high-level users. INLINE int get_draw_order() const; - INLINE const FogAttrib *get_fog() const; - INLINE const CullBinAttrib *get_bin() const; - INLINE const TransparencyAttrib *get_transparency() const; INLINE int get_bin_index() const; - INLINE const ColorAttrib *get_color() const; - INLINE const ColorScaleAttrib *get_color_scale() const; - INLINE const TextureAttrib *get_texture() const; - INLINE const TexGenAttrib *get_tex_gen() const; - INLINE const TexMatrixAttrib *get_tex_matrix() const; - INLINE const RenderModeAttrib *get_render_mode() const; - INLINE const ClipPlaneAttrib *get_clip_plane() const; - INLINE const ScissorAttrib *get_scissor() const; - INLINE const ShaderAttrib *get_shader() const; - INLINE const AudioVolumeAttrib *get_audio_volume() const; - int get_geom_rendering(int geom_rendering) const; - const ShaderAttrib *get_generated_shader() const; public: - void store_into_slots(AttribSlots *slots) const; - static void bin_removed(int bin_index); INLINE static void flush_level(); private: + void determine_filled_slots(); + bool validate_filled_slots() const; INLINE bool do_cache_unref() const; INLINE bool do_node_unref() const; @@ -191,22 +171,8 @@ private: void remove_cache_pointers(); void determine_bin_index(); - void determine_fog(); - INLINE void determine_bin(); - void do_determine_bin(); - INLINE void determine_transparency(); - void do_determine_transparency(); - void determine_color(); - void determine_color_scale(); - void determine_texture(); - void determine_tex_gen(); - void determine_tex_matrix(); - void determine_render_mode(); - void determine_clip_plane(); - void determine_scissor(); - void determine_shader(); void determine_cull_callback(); - void determine_audio_volume(); + void fill_default(); INLINE void set_destructing(); INLINE bool is_destructing() const; @@ -225,6 +191,7 @@ private: typedef phash_set > States; static States *_states; static CPT(RenderState) _empty_state; + static CPT(RenderState) _full_default_state; // This iterator records the entry corresponding to this RenderState // object in the above global set. We keep the iterator around so @@ -277,23 +244,24 @@ private: private: // This is the actual data within the RenderState: a set of - // RenderAttribs. + // max_slots RenderAttribs. class Attribute { public: INLINE Attribute(const RenderAttrib *attrib, int override); - INLINE Attribute(int override); - INLINE Attribute(TypeHandle type); + INLINE Attribute(int override = 0); INLINE Attribute(const Attribute ©); INLINE void operator = (const Attribute ©); - INLINE bool operator < (const Attribute &other) const; + INLINE void set(const RenderAttrib *attrib, int override); INLINE int compare_to(const Attribute &other) const; - TypeHandle _type; CPT(RenderAttrib) _attrib; int _override; }; - typedef ov_set Attributes; - Attributes _attributes; + Attribute *_attributes; + + // We also store a bitmask of the non-NULL attributes in the above + // array. This is redundant, but it is a useful cache. + SlotMask _filled_slots; // We cache the index to the associated CullBin, if there happens to // be a CullBinAttrib in the state. @@ -305,44 +273,17 @@ private: // I can't declare this as a ShaderAttrib because that would create // a circular include-file dependency problem. Aaargh. CPT(RenderAttrib) _generated_shader; - - // We also cache the pointer to some critical attribs stored in the - // state, if they exist. - const FogAttrib *_fog; - const CullBinAttrib *_bin; - const TransparencyAttrib *_transparency; - const ColorAttrib *_color; - const ColorScaleAttrib *_color_scale; - const TextureAttrib *_texture; - const TexGenAttrib *_tex_gen; - const TexMatrixAttrib *_tex_matrix; - const RenderModeAttrib *_render_mode; - const ClipPlaneAttrib *_clip_plane; - const ScissorAttrib *_scissor; - const ShaderAttrib *_shader; - const AudioVolumeAttrib *_audio_volume; - + enum Flags { F_checked_bin_index = 0x000001, - F_checked_fog = 0x000002, - F_checked_bin = 0x000004, - F_checked_transparency = 0x000008, - F_checked_color = 0x000010, - F_checked_color_scale = 0x000020, - F_checked_texture = 0x000040, - F_checked_tex_gen = 0x000080, - F_checked_tex_matrix = 0x000100, - F_checked_render_mode = 0x000200, - F_checked_clip_plane = 0x000400, - F_checked_shader = 0x000800, - F_checked_cull_callback = 0x001000, - F_checked_audio_volume = 0x002000, - F_has_cull_callback = 0x004000, - F_is_destructing = 0x008000, - F_checked_scissor = 0x010000, + F_checked_cull_callback = 0x000002, + F_has_cull_callback = 0x000004, + F_is_destructing = 0x000008, }; unsigned int _flags; + vector_int *_read_overrides; // Only used during bam reading. + // This mutex protects _flags, and all of the above computed values. LightMutex _lock; @@ -377,6 +318,7 @@ private: static TypeHandle _type_handle; friend class GraphicsStateGuardian; + friend class RenderAttribRegistry; }; INLINE ostream &operator << (ostream &out, const RenderState &state) { diff --git a/panda/src/pgraph/rescaleNormalAttrib.cxx b/panda/src/pgraph/rescaleNormalAttrib.cxx index af998904c7..fc9d18aaea 100644 --- a/panda/src/pgraph/rescaleNormalAttrib.cxx +++ b/panda/src/pgraph/rescaleNormalAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "rescaleNormalAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "string_utils.h" #include "dcast.h" @@ -24,6 +23,7 @@ #include "configVariableEnum.h" TypeHandle RescaleNormalAttrib::_type_handle; +int RescaleNormalAttrib::_attrib_slot; // This variable is defined here instead of in config_pgraph.cxx, // because it depends on rescaleNormalAttrib.h having already been @@ -96,33 +96,6 @@ compare_to_impl(const RenderAttrib *other) const { return (int)_mode - (int)ta->_mode; } -//////////////////////////////////////////////////////////////////// -// Function: RescaleNormalAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived RescaleNormalAttrib -// types to specify what the default property for a -// RescaleNormalAttrib of this type should be. -// -// This should return a newly-allocated RescaleNormalAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of RescaleNormalAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *RescaleNormalAttrib:: -make_default_impl() const { - return new RescaleNormalAttrib(M_none); -} - -//////////////////////////////////////////////////////////////////// -// Function: RescaleNormalAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void RescaleNormalAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_rescale_normal = this; -} - //////////////////////////////////////////////////////////////////// // Function: RescaleNormalAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/rescaleNormalAttrib.h b/panda/src/pgraph/rescaleNormalAttrib.h index b435addf2c..24cce8542d 100644 --- a/panda/src/pgraph/rescaleNormalAttrib.h +++ b/panda/src/pgraph/rescaleNormalAttrib.h @@ -55,15 +55,21 @@ PUBLISHED: public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: Mode _mode; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -80,6 +86,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "RescaleNormalAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -88,6 +95,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; EXPCL_PANDA_PGRAPH ostream &operator << (ostream &out, RescaleNormalAttrib::Mode mode); diff --git a/panda/src/pgraph/sceneGraphAnalyzer.cxx b/panda/src/pgraph/sceneGraphAnalyzer.cxx index d1f834786e..693aa99591 100644 --- a/panda/src/pgraph/sceneGraphAnalyzer.cxx +++ b/panda/src/pgraph/sceneGraphAnalyzer.cxx @@ -280,7 +280,7 @@ collect_statistics(PandaNode *node, bool under_instance) { if (!node->get_state()->is_empty()) { _num_nodes_with_attribs++; const RenderAttrib *attrib = - node->get_attrib(TextureAttrib::get_class_type()); + node->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); for (int i = 0; i < ta->get_num_on_stages(); i++) { @@ -350,7 +350,7 @@ collect_statistics(GeomNode *geom_node) { const RenderState *geom_state = geom_node->get_geom_state(i); const RenderAttrib *attrib = - geom_state->get_attrib(TextureAttrib::get_class_type()); + geom_state->get_attrib(TextureAttrib::get_class_slot()); if (attrib != (RenderAttrib *)NULL) { const TextureAttrib *ta = DCAST(TextureAttrib, attrib); for (int i = 0; i < ta->get_num_on_stages(); i++) { diff --git a/panda/src/pgraph/sceneSetup.h b/panda/src/pgraph/sceneSetup.h index 515880f99b..5d6c73fa58 100644 --- a/panda/src/pgraph/sceneSetup.h +++ b/panda/src/pgraph/sceneSetup.h @@ -24,6 +24,8 @@ #include "lens.h" #include "pointerTo.h" +class DisplayRegion; + //////////////////////////////////////////////////////////////////// // Class : SceneSetup // Description : This object holds the camera position, etc., and diff --git a/panda/src/pgraph/scissorAttrib.cxx b/panda/src/pgraph/scissorAttrib.cxx index 09fc6a7400..14c12c718a 100644 --- a/panda/src/pgraph/scissorAttrib.cxx +++ b/panda/src/pgraph/scissorAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "scissorAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle ScissorAttrib::_type_handle; +int ScissorAttrib::_attrib_slot; CPT(RenderAttrib) ScissorAttrib::_off; //////////////////////////////////////////////////////////////////// @@ -71,6 +71,18 @@ make(const LVecBase4f &frame) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: ScissorAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ScissorAttrib:: +make_default() { + return return_new(new ScissorAttrib(LVecBase4f(0.0f, 1.0f, 0.0f, 1.0f))); +} + //////////////////////////////////////////////////////////////////// // Function: ScissorAttrib::output // Access: Public, Virtual @@ -134,33 +146,6 @@ compose_impl(const RenderAttrib *other) const { return return_new(attrib); } -//////////////////////////////////////////////////////////////////// -// Function: ScissorAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived ScissorAttrib -// types to specify what the default property for a -// ScissorAttrib of this type should be. -// -// This should return a newly-allocated ScissorAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of ScissorAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *ScissorAttrib:: -make_default_impl() const { - return new ScissorAttrib(LVecBase4f(0.0f, 1.0f, 0.0f, 1.0f)); -} - -//////////////////////////////////////////////////////////////////// -// Function: ScissorAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void ScissorAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_scissor = this; -} - //////////////////////////////////////////////////////////////////// // Function: ScissorAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/scissorAttrib.h b/panda/src/pgraph/scissorAttrib.h index df550e722b..7b79575b29 100644 --- a/panda/src/pgraph/scissorAttrib.h +++ b/panda/src/pgraph/scissorAttrib.h @@ -46,22 +46,29 @@ PUBLISHED: static CPT(RenderAttrib) make_off(); INLINE static CPT(RenderAttrib) make(float left, float right, float bottom, float top); static CPT(RenderAttrib) make(const LVecBase4f &frame); + static CPT(RenderAttrib) make_default(); INLINE const LVecBase4f &get_frame() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: LVecBase4f _frame; static CPT(RenderAttrib) _off; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -78,6 +85,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "ScissorAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -86,6 +94,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "scissorAttrib.I" diff --git a/panda/src/pgraph/shadeModelAttrib.cxx b/panda/src/pgraph/shadeModelAttrib.cxx index 5c076607c6..0486c15965 100644 --- a/panda/src/pgraph/shadeModelAttrib.cxx +++ b/panda/src/pgraph/shadeModelAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "shadeModelAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle ShadeModelAttrib::_type_handle; +int ShadeModelAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: ShadeModelAttrib::make @@ -36,6 +36,18 @@ make(ShadeModelAttrib::Mode mode) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: ShadeModelAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ShadeModelAttrib:: +make_default() { + return return_new(new ShadeModelAttrib(M_smooth)); +} + //////////////////////////////////////////////////////////////////// // Function: ShadeModelAttrib::output // Access: Public, Virtual @@ -103,33 +115,6 @@ compose_impl(const RenderAttrib *other) const { return make(mode); } -//////////////////////////////////////////////////////////////////// -// Function: ShadeModelAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived ShadeModelAttrib -// types to specify what the default property for a -// ShadeModelAttrib of this type should be. -// -// This should return a newly-allocated ShadeModelAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of ShadeModelAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *ShadeModelAttrib:: -make_default_impl() const { - return new ShadeModelAttrib(M_smooth); -} - -//////////////////////////////////////////////////////////////////// -// Function: ShadeModelAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void ShadeModelAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_shade_model = this; -} - //////////////////////////////////////////////////////////////////// // Function: ShadeModelAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/shadeModelAttrib.h b/panda/src/pgraph/shadeModelAttrib.h index 233f872479..25456849a5 100644 --- a/panda/src/pgraph/shadeModelAttrib.h +++ b/panda/src/pgraph/shadeModelAttrib.h @@ -38,21 +38,28 @@ private: PUBLISHED: static CPT(RenderAttrib) make(Mode mode); + static CPT(RenderAttrib) make_default(); INLINE Mode get_mode() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: Mode _mode; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -69,6 +76,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "ShadeModelAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -77,6 +85,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "shadeModelAttrib.I" diff --git a/panda/src/pgraph/shaderAttrib.cxx b/panda/src/pgraph/shaderAttrib.cxx index 06b5860827..af0c3f6ac7 100755 --- a/panda/src/pgraph/shaderAttrib.cxx +++ b/panda/src/pgraph/shaderAttrib.cxx @@ -14,7 +14,6 @@ #include "pandabase.h" #include "shaderAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "bamReader.h" #include "bamWriter.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle ShaderAttrib::_type_handle; +int ShaderAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: ShaderAttrib::make_off @@ -58,6 +58,18 @@ make() { return _null_attrib; } +//////////////////////////////////////////////////////////////////// +// Function: ShaderAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ShaderAttrib:: +make_default() { + return return_new(new ShaderAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: ShaderAttrib::set_shader // Access: Published @@ -394,33 +406,6 @@ get_shader() const { return _shader; } -//////////////////////////////////////////////////////////////////// -// Function: ShaderAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived ShaderAttrib -// types to specify what the default property for a -// ShaderAttrib of this type should be. -// -// This should return a newly-allocated ShaderAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of ShaderAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *ShaderAttrib:: -make_default_impl() const { - return new ShaderAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: ShaderAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void ShaderAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_shader = this; -} - //////////////////////////////////////////////////////////////////// // Function: ShaderAttrib::compare_to_impl // Access: Protected, Virtual diff --git a/panda/src/pgraph/shaderAttrib.h b/panda/src/pgraph/shaderAttrib.h index 9de22b422e..658a7c8faa 100755 --- a/panda/src/pgraph/shaderAttrib.h +++ b/panda/src/pgraph/shaderAttrib.h @@ -35,6 +35,7 @@ private: PUBLISHED: static CPT(RenderAttrib) make(); static CPT(RenderAttrib) make_off(); + static CPT(RenderAttrib) make_default(); enum { F_disable_alpha_write = 0, // Suppress writes to color buffer alpha channel. @@ -80,10 +81,8 @@ PUBLISHED: static void register_with_read_factory(); public: - virtual void store_into_slot(AttribSlots *slots) const; protected: - virtual RenderAttrib *make_default_impl() const; virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; @@ -98,6 +97,14 @@ private: typedef pmap < CPT(InternalName), CPT(ShaderInput) > Inputs; Inputs _inputs; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static TypeHandle get_class_type() { return _type_handle; @@ -106,6 +113,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "ShaderAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 10, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -114,6 +122,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; diff --git a/panda/src/pgraph/stencilAttrib.cxx b/panda/src/pgraph/stencilAttrib.cxx index d7c539ea64..418a234fad 100644 --- a/panda/src/pgraph/stencilAttrib.cxx +++ b/panda/src/pgraph/stencilAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "stencilAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle StencilAttrib::_type_handle; +int StencilAttrib::_attrib_slot; char *StencilAttrib:: stencil_render_state_name_array [StencilAttrib::SRS_total] = @@ -91,6 +91,18 @@ make_off() return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: StencilAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) StencilAttrib:: +make_default() { + return return_new(new StencilAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: StencilAttrib::make // Access: Published, Static @@ -316,33 +328,6 @@ compare_to_impl(const RenderAttrib *other) const { return compare_result; } -//////////////////////////////////////////////////////////////////// -// Function: StencilAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived StencilAttrib -// types to specify what the default property for a -// StencilAttrib of this type should be. -// -// This should return a newly-allocated StencilAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of StencilAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *StencilAttrib:: -make_default_impl() const { - return new StencilAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: StencilAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void StencilAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_stencil = this; -} - //////////////////////////////////////////////////////////////////// // Function: StencilAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/stencilAttrib.h b/panda/src/pgraph/stencilAttrib.h index d1774ab32a..42918e40c5 100644 --- a/panda/src/pgraph/stencilAttrib.h +++ b/panda/src/pgraph/stencilAttrib.h @@ -94,6 +94,7 @@ PUBLISHED: }; static CPT(RenderAttrib) make_off(); + static CPT(RenderAttrib) make_default(); static CPT(RenderAttrib) make( unsigned int front_enable, @@ -155,15 +156,21 @@ public: static char *stencil_render_state_name_array [SRS_total]; virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: unsigned int _stencil_render_states [SRS_total]; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -180,6 +187,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "StencilAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -188,6 +196,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "stencilAttrib.I" diff --git a/panda/src/pgraph/texGenAttrib.cxx b/panda/src/pgraph/texGenAttrib.cxx index 99294b0ea1..c73fafe3a1 100755 --- a/panda/src/pgraph/texGenAttrib.cxx +++ b/panda/src/pgraph/texGenAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "texGenAttrib.h" -#include "attribSlots.h" #include "texturePool.h" #include "graphicsStateGuardianBase.h" #include "bamReader.h" @@ -24,6 +23,7 @@ CPT(RenderAttrib) TexGenAttrib::_empty_attrib; TypeHandle TexGenAttrib::_type_handle; +int TexGenAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: TexGenAttrib::Destructor @@ -62,6 +62,18 @@ make(TextureStage *stage, TexGenAttrib::Mode mode) { return DCAST(TexGenAttrib, make())->add_stage(stage, mode); } +//////////////////////////////////////////////////////////////////// +// Function: TexGenAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) TexGenAttrib:: +make_default() { + return return_new(new TexGenAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: TexGenAttrib::add_stage // Access: Published, Static @@ -523,22 +535,6 @@ invert_compose_impl(const RenderAttrib *other) const { return return_new(attrib); } -//////////////////////////////////////////////////////////////////// -// Function: TexGenAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived TexGenAttrib -// types to specify what the default property for a -// TexGenAttrib of this type should be. -// -// This should return a newly-allocated TexGenAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of TexGenAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *TexGenAttrib:: -make_default_impl() const { - return new TexGenAttrib; -} - //////////////////////////////////////////////////////////////////// // Function: TexGenAttrib::filled_stages // Access: Private @@ -602,17 +598,6 @@ record_stage(TextureStage *stage, TexGenAttrib::ModeDef &mode_def) { } } -//////////////////////////////////////////////////////////////////// -// Function: TexGenAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void TexGenAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_tex_gen = this; -} - //////////////////////////////////////////////////////////////////// // Function: TexGenAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/texGenAttrib.h b/panda/src/pgraph/texGenAttrib.h index c0289b9c90..730e8524a0 100755 --- a/panda/src/pgraph/texGenAttrib.h +++ b/panda/src/pgraph/texGenAttrib.h @@ -51,6 +51,7 @@ public: PUBLISHED: static CPT(RenderAttrib) make(); static CPT(RenderAttrib) make(TextureStage *stage, Mode mode); + static CPT(RenderAttrib) make_default(); CPT(RenderAttrib) add_stage(TextureStage *stage, Mode mode) const; CPT(RenderAttrib) add_stage(TextureStage *stage, Mode mode, const string &source_name, const NodePath &light) const; @@ -72,13 +73,11 @@ public: INLINE const LightVectors &get_light_vectors() const; virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: class ModeDef; @@ -124,6 +123,14 @@ private: static CPT(RenderAttrib) _empty_attrib; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -141,6 +148,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "TexGenAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -149,6 +157,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "texGenAttrib.I" diff --git a/panda/src/pgraph/texMatrixAttrib.cxx b/panda/src/pgraph/texMatrixAttrib.cxx index b9931f3d39..6a2809a8a8 100644 --- a/panda/src/pgraph/texMatrixAttrib.cxx +++ b/panda/src/pgraph/texMatrixAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "texMatrixAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -23,6 +22,7 @@ CPT(RenderAttrib) TexMatrixAttrib::_empty_attrib; TypeHandle TexMatrixAttrib::_type_handle; +int TexMatrixAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: TexMatrixAttrib::Destructor @@ -84,6 +84,18 @@ make(TextureStage *stage, const TransformState *transform) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: TexMatrixAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) TexMatrixAttrib:: +make_default() { + return return_new(new TexMatrixAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: TexMatrixAttrib::add_stage // Access: Published, Static @@ -406,33 +418,6 @@ invert_compose_impl(const RenderAttrib *other) const { return return_new(attrib); } -//////////////////////////////////////////////////////////////////// -// Function: TexMatrixAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived TexMatrixAttrib -// types to specify what the default property for a -// TexMatrixAttrib of this type should be. -// -// This should return a newly-allocated TexMatrixAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of TexMatrixAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *TexMatrixAttrib:: -make_default_impl() const { - return new TexMatrixAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: TexMatrixAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void TexMatrixAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_tex_matrix = this; -} - //////////////////////////////////////////////////////////////////// // Function: TexMatrixAttrib::rebuild_stage_list // Access: Private diff --git a/panda/src/pgraph/texMatrixAttrib.h b/panda/src/pgraph/texMatrixAttrib.h index e096de81cf..9a3cc4df6d 100644 --- a/panda/src/pgraph/texMatrixAttrib.h +++ b/panda/src/pgraph/texMatrixAttrib.h @@ -42,6 +42,7 @@ PUBLISHED: static CPT(RenderAttrib) make(); static CPT(RenderAttrib) make(const LMatrix4f &mat); static CPT(RenderAttrib) make(TextureStage *stage, const TransformState *transform); + static CPT(RenderAttrib) make_default(); CPT(RenderAttrib) add_stage(TextureStage *stage, const TransformState *transform) const; CPT(RenderAttrib) remove_stage(TextureStage *stage) const; @@ -62,13 +63,11 @@ PUBLISHED: public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: INLINE void check_stage_list() const; @@ -87,6 +86,14 @@ private: static CPT(RenderAttrib) _empty_attrib; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -104,6 +111,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "TexMatrixAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -112,6 +120,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "texMatrixAttrib.I" diff --git a/panda/src/pgraph/textureAttrib.cxx b/panda/src/pgraph/textureAttrib.cxx index bc945bd65d..4778d309cf 100644 --- a/panda/src/pgraph/textureAttrib.cxx +++ b/panda/src/pgraph/textureAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "textureAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "internalName.h" #include "bamReader.h" @@ -25,6 +24,7 @@ CPT(RenderAttrib) TextureAttrib::_empty_attrib; CPT(RenderAttrib) TextureAttrib::_all_off_attrib; TypeHandle TextureAttrib::_type_handle; +int TextureAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// @@ -86,6 +86,18 @@ make_all_off() { return _all_off_attrib; } +//////////////////////////////////////////////////////////////////// +// Function: TextureAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) TextureAttrib:: +make_default() { + return return_new(new TextureAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: TextureAttrib::find_on_stage @@ -760,33 +772,6 @@ invert_compose_impl(const RenderAttrib *other) const { return other; } -//////////////////////////////////////////////////////////////////// -// Function: TextureAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived TextureAttrib -// types to specify what the default property for a -// TextureAttrib of this type should be. -// -// This should return a newly-allocated TextureAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of TextureAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *TextureAttrib:: -make_default_impl() const { - return new TextureAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: TextureAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void TextureAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_texture = this; -} - //////////////////////////////////////////////////////////////////// // Function: TextureAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/textureAttrib.h b/panda/src/pgraph/textureAttrib.h index 15ff22510a..8068c194c8 100644 --- a/panda/src/pgraph/textureAttrib.h +++ b/panda/src/pgraph/textureAttrib.h @@ -40,6 +40,7 @@ PUBLISHED: // For multitexture, use the multitexture interfaces, further below. static CPT(RenderAttrib) make(Texture *tex); static CPT(RenderAttrib) make_off(); + static CPT(RenderAttrib) make_default(); INLINE bool is_off() const; INLINE Texture *get_texture() const; @@ -81,7 +82,6 @@ public: CPT(TextureAttrib) filter_to_max(int max_texture_stages) const; virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; virtual bool has_cull_callback() const; virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const; @@ -90,7 +90,6 @@ protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: INLINE void check_sorted() const; @@ -143,6 +142,14 @@ private: static CPT(RenderAttrib) _empty_attrib; static CPT(RenderAttrib) _all_off_attrib; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -160,6 +167,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "TextureAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 30, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -168,6 +176,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "textureAttrib.I" diff --git a/panda/src/pgraph/transparencyAttrib.cxx b/panda/src/pgraph/transparencyAttrib.cxx index b5c9fa5c21..511fa6535c 100644 --- a/panda/src/pgraph/transparencyAttrib.cxx +++ b/panda/src/pgraph/transparencyAttrib.cxx @@ -13,7 +13,6 @@ //////////////////////////////////////////////////////////////////// #include "transparencyAttrib.h" -#include "attribSlots.h" #include "graphicsStateGuardianBase.h" #include "dcast.h" #include "bamReader.h" @@ -22,6 +21,7 @@ #include "datagramIterator.h" TypeHandle TransparencyAttrib::_type_handle; +int TransparencyAttrib::_attrib_slot; //////////////////////////////////////////////////////////////////// // Function: TransparencyAttrib::make @@ -34,6 +34,18 @@ make(TransparencyAttrib::Mode mode) { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: TransparencyAttrib::make_default +// Access: Published, Static +// Description: Returns a RenderAttrib that corresponds to whatever +// the standard default properties for render attributes +// of this type ought to be. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) TransparencyAttrib:: +make_default() { + return return_new(new TransparencyAttrib); +} + //////////////////////////////////////////////////////////////////// // Function: TransparencyAttrib::output // Access: Public, Virtual @@ -94,33 +106,6 @@ compare_to_impl(const RenderAttrib *other) const { return (int)_mode - (int)ta->_mode; } -//////////////////////////////////////////////////////////////////// -// Function: TransparencyAttrib::make_default_impl -// Access: Protected, Virtual -// Description: Intended to be overridden by derived TransparencyAttrib -// types to specify what the default property for a -// TransparencyAttrib of this type should be. -// -// This should return a newly-allocated TransparencyAttrib of -// the same type that corresponds to whatever the -// standard default for this kind of TransparencyAttrib is. -//////////////////////////////////////////////////////////////////// -RenderAttrib *TransparencyAttrib:: -make_default_impl() const { - return new TransparencyAttrib; -} - -//////////////////////////////////////////////////////////////////// -// Function: TransparencyAttrib::store_into_slot -// Access: Public, Virtual -// Description: Stores this attrib into the appropriate slot of -// an object of class AttribSlots. -//////////////////////////////////////////////////////////////////// -void TransparencyAttrib:: -store_into_slot(AttribSlots *slots) const { - slots->_transparency = this; -} - //////////////////////////////////////////////////////////////////// // Function: TransparencyAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/transparencyAttrib.h b/panda/src/pgraph/transparencyAttrib.h index faae85896e..8c95c70dbd 100644 --- a/panda/src/pgraph/transparencyAttrib.h +++ b/panda/src/pgraph/transparencyAttrib.h @@ -53,20 +53,27 @@ private: PUBLISHED: static CPT(RenderAttrib) make(Mode mode); + static CPT(RenderAttrib) make_default(); INLINE Mode get_mode() const; public: virtual void output(ostream &out) const; - virtual void store_into_slot(AttribSlots *slots) const; protected: virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; private: Mode _mode; +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -83,6 +90,7 @@ public: RenderAttrib::init_type(); register_type(_type_handle, "TransparencyAttrib", RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, make_default); } virtual TypeHandle get_type() const { return get_class_type(); @@ -91,6 +99,7 @@ public: private: static TypeHandle _type_handle; + static int _attrib_slot; }; #include "transparencyAttrib.I" diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index 3163c80139..05fa18c67b 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -12,10 +12,23 @@ // //////////////////////////////////////////////////////////////////// - +#include "shaderGenerator.h" #include "renderState.h" #include "shaderAttrib.h" -#include "shaderGenerator.h" +#include "auxBitplaneAttrib.h" +#include "alphaTestAttrib.h" +#include "colorBlendAttrib.h" +#include "transparencyAttrib.h" +#include "textureAttrib.h" +#include "colorAttrib.h" +#include "lightAttrib.h" +#include "materialAttrib.h" +#include "lightRampAttrib.h" +#include "texMatrixAttrib.h" +#include "texGenAttrib.h" +#include "colorScaleAttrib.h" +#include "fogAttrib.h" +#include "texture.h" #include "ambientLight.h" #include "directionalLight.h" #include "pointLight.h" @@ -117,21 +130,24 @@ analyze_renderstate(const RenderState *rs) { clear_analysis(); // verify_enforce_attrib_lock(); - - rs->store_into_slots(&_attribs); - int outputs = _attribs._aux_bitplane->get_outputs(); + _state = rs; + const AuxBitplaneAttrib *aux_bitplane = DCAST(AuxBitplaneAttrib, rs->get_attrib_def(AuxBitplaneAttrib::get_class_slot())); + int outputs = aux_bitplane->get_outputs(); // Decide whether or not we need alpha testing or alpha blending. - if ((_attribs._alpha_test->get_mode() != RenderAttrib::M_none)&& - (_attribs._alpha_test->get_mode() != RenderAttrib::M_always)) { + const AlphaTestAttrib *alpha_test = DCAST(AlphaTestAttrib, rs->get_attrib_def(AlphaTestAttrib::get_class_slot())); + if ((alpha_test->get_mode() != RenderAttrib::M_none)&& + (alpha_test->get_mode() != RenderAttrib::M_always)) { _have_alpha_test = true; } - if (_attribs._color_blend->get_mode() != ColorBlendAttrib::M_none) { + const ColorBlendAttrib *color_blend = DCAST(ColorBlendAttrib, rs->get_attrib_def(ColorBlendAttrib::get_class_slot())); + if (color_blend->get_mode() != ColorBlendAttrib::M_none) { _have_alpha_blend = true; } - if ((_attribs._transparency->get_mode() == TransparencyAttrib::M_alpha)|| - (_attribs._transparency->get_mode() == TransparencyAttrib::M_dual)) { + const TransparencyAttrib *transparency = DCAST(TransparencyAttrib, rs->get_attrib_def(TransparencyAttrib::get_class_slot())); + if ((transparency->get_mode() == TransparencyAttrib::M_alpha)|| + (transparency->get_mode() == TransparencyAttrib::M_dual)) { _have_alpha_blend = true; } @@ -164,22 +180,21 @@ analyze_renderstate(const RenderState *rs) { // Count number of textures. - _num_textures = 0; - if (_attribs._texture) { - _num_textures = _attribs._texture->get_num_on_stages(); - } + const TextureAttrib *texture = DCAST(TextureAttrib, rs->get_attrib_def(TextureAttrib::get_class_slot())); + _num_textures = texture->get_num_on_stages(); // Determine whether or not vertex colors or flat colors are present. - if (_attribs._color->get_color_type() == ColorAttrib::T_vertex) { + const ColorAttrib *color = DCAST(ColorAttrib, rs->get_attrib_def(ColorAttrib::get_class_slot())); + if (color->get_color_type() == ColorAttrib::T_vertex) { _vertex_colors = true; - } else if (_attribs._color->get_color_type() == ColorAttrib::T_flat) { + } else if (color->get_color_type() == ColorAttrib::T_flat) { _flat_colors = true; } // Break out the lights by type. - const LightAttrib *la = _attribs._light; + const LightAttrib *la = DCAST(LightAttrib, rs->get_attrib_def(LightAttrib::get_class_slot())); for (int i=0; iget_num_on_lights(); i++) { NodePath light = la->get_on_light(i); nassertv(!light.is_empty()); @@ -207,7 +222,7 @@ analyze_renderstate(const RenderState *rs) { // See if there is a normal map, height map, gloss map, or glow map. for (int i=0; i<_num_textures; i++) { - TextureStage *stage = _attribs._texture->get_on_stage(i); + TextureStage *stage = texture->get_on_stage(i); TextureStage::Mode mode = stage->get_mode(); if ((mode == TextureStage::M_normal)||(mode == TextureStage::M_normal_height)) { _map_index_normal = i; @@ -225,14 +240,16 @@ analyze_renderstate(const RenderState *rs) { // Determine whether lighting is needed. - if (_attribs._light->get_num_on_lights() > 0) { + if (la->get_num_on_lights() > 0) { _lighting = true; } // Find the material. - if (!_attribs._material->is_off()) { - _material = _attribs._material->get_material(); + const MaterialAttrib *material = DCAST(MaterialAttrib, rs->get_attrib_def(MaterialAttrib::get_class_slot())); + + if (!material->is_off()) { + _material = material->get_material(); } else { _material = Material::get_default(); } @@ -297,8 +314,9 @@ analyze_renderstate(const RenderState *rs) { } } + const LightRampAttrib *light_ramp = DCAST(LightRampAttrib, rs->get_attrib_def(LightRampAttrib::get_class_slot())); if (_lighting && - (_attribs._light_ramp->get_mode() != LightRampAttrib::LRT_identity)) { + (light_ramp->get_mode() != LightRampAttrib::LRT_identity)) { _separate_ambient_diffuse = true; } @@ -312,16 +330,20 @@ analyze_renderstate(const RenderState *rs) { // Check for unimplemented features and issue warnings. - if (!_attribs._tex_matrix->is_empty()) { + const TexMatrixAttrib *tex_matrix = DCAST(TexMatrixAttrib, rs->get_attrib_def(TexMatrixAttrib::get_class_slot())); + if (!tex_matrix->is_empty()) { pgraph_cat.error() << "Shader Generator does not support TexMatrix yet.\n"; } - if (!_attribs._tex_gen->is_empty()) { + const TexGenAttrib *tex_gen = DCAST(TexGenAttrib, rs->get_attrib_def(TexGenAttrib::get_class_slot())); + if (!tex_gen->is_empty()) { pgraph_cat.error() << "Shader Generator does not support TexGen yet.\n"; } - if (!_attribs._color_scale->is_identity()) { + const ColorScaleAttrib *color_scale = DCAST(ColorScaleAttrib, rs->get_attrib_def(ColorScaleAttrib::get_class_slot())); + if (!color_scale->is_identity()) { pgraph_cat.error() << "Shader Generator does not support ColorScale yet.\n"; } - if (!_attribs._fog->is_off()) { + const FogAttrib *fog = DCAST(FogAttrib, rs->get_attrib_def(FogAttrib::get_class_slot())); + if (!fog->is_off()) { pgraph_cat.error() << "Shader Generator does not support Fog yet.\n"; } } @@ -358,7 +380,6 @@ clear_analysis() { _out_aux_normal = false; _out_aux_glow = false; _out_aux_any = false; - _attribs.clear_to_defaults(); _material = (Material*)NULL; _need_material_props = false; _alights.clear(); @@ -700,11 +721,13 @@ synthesize_shader(const RenderState *rs) { text << "\t tot_specular += lspec;\n"; } } - switch (_attribs._light_ramp->get_mode()) { + + const LightRampAttrib *light_ramp = DCAST(LightRampAttrib, rs->get_attrib_def(LightRampAttrib::get_class_slot())); + switch (light_ramp->get_mode()) { case LightRampAttrib::LRT_single_threshold: { - float t = _attribs._light_ramp->get_threshold(0); - float l0 = _attribs._light_ramp->get_level(0); + float t = light_ramp->get_threshold(0); + float l0 = light_ramp->get_level(0); text << "\t // Single-threshold light ramp\n"; text << "\t float lr_in = dot(tot_diffuse.rgb, float3(0.33,0.34,0.33));\n"; text << "\t float lr_scale = (lr_in < " << t << ") ? 0.0 : (" << l0 << "/lr_in);\n"; @@ -713,11 +736,11 @@ synthesize_shader(const RenderState *rs) { } case LightRampAttrib::LRT_double_threshold: { - float t0 = _attribs._light_ramp->get_threshold(0); - float t1 = _attribs._light_ramp->get_threshold(1); - float l0 = _attribs._light_ramp->get_level(0); - float l1 = _attribs._light_ramp->get_level(1); - float l2 = _attribs._light_ramp->get_level(2); + float t0 = light_ramp->get_threshold(0); + float t1 = light_ramp->get_threshold(1); + float l0 = light_ramp->get_level(0); + float l1 = light_ramp->get_level(1); + float l2 = light_ramp->get_level(2); text << "\t // Double-threshold light ramp\n"; text << "\t float lr_in = dot(tot_diffuse.rgb, float3(0.33,0.34,0.33));\n"; text << "\t float lr_out = " << l0 << "\n"; @@ -763,7 +786,7 @@ synthesize_shader(const RenderState *rs) { text << "\t result += tot_diffuse;\n"; } } - if (_attribs._light_ramp->get_mode() == LightRampAttrib::LRT_default) { + if (light_ramp->get_mode() == LightRampAttrib::LRT_default) { text << "\t result = saturate(result);\n"; } text << "\t // End view-space light calculations\n"; @@ -789,8 +812,9 @@ synthesize_shader(const RenderState *rs) { } } + const TextureAttrib *texture = DCAST(TextureAttrib, rs->get_attrib_def(TextureAttrib::get_class_slot())); for (int i=0; i<_num_textures; i++) { - TextureStage *stage = _attribs._texture->get_on_stage(i); + TextureStage *stage = texture->get_on_stage(i); switch (stage->get_mode()) { case TextureStage::M_modulate: case TextureStage::M_modulate_glow: @@ -824,9 +848,10 @@ synthesize_shader(const RenderState *rs) { } if (_subsume_alpha_test) { + const AlphaTestAttrib *alpha_test = DCAST(AlphaTestAttrib, rs->get_attrib_def(AlphaTestAttrib::get_class_slot())); text << "\t // Shader includes alpha test:\n"; - double ref = _attribs._alpha_test->get_reference_alpha(); - switch (_attribs._alpha_test->get_mode()) { + double ref = alpha_test->get_reference_alpha(); + switch (alpha_test->get_mode()) { case RenderAttrib::M_never: text<<"\t discard;\n"; case RenderAttrib::M_less: text<<"\t if (result.a >= "<get_mode()) { + const LightRampAttrib *light_ramp = DCAST(LightRampAttrib, rs->get_attrib_def(LightRampAttrib::get_class_slot())); + switch (light_ramp->get_mode()) { case LightRampAttrib::LRT_hdr0: text << "\t result.rgb = (result*result*result + result*result + result) / (result*result*result + result*result + result + 1);\n"; break; diff --git a/panda/src/pgraphnodes/shaderGenerator.h b/panda/src/pgraphnodes/shaderGenerator.h index fb0f2955b4..3f09f405e6 100644 --- a/panda/src/pgraphnodes/shaderGenerator.h +++ b/panda/src/pgraphnodes/shaderGenerator.h @@ -17,7 +17,6 @@ #include "pandabase.h" #include "shaderGeneratorBase.h" -#include "attribSlots.h" #include "nodePath.h" class AmbientLight; @@ -81,7 +80,7 @@ protected: // RenderState analysis information. Created by analyze_renderstate: - AttribSlots _attribs; + CPT(RenderState) _state; Material *_material; int _num_textures; diff --git a/panda/src/pgraphnodes/spotlight.h b/panda/src/pgraphnodes/spotlight.h index 4a995c587a..18a393f7a1 100644 --- a/panda/src/pgraphnodes/spotlight.h +++ b/panda/src/pgraphnodes/spotlight.h @@ -18,8 +18,7 @@ #include "pandabase.h" #include "lightLensNode.h" - -class Texture; +#include "texture.h" //////////////////////////////////////////////////////////////////// // Class : Spotlight diff --git a/panda/src/pgui/pgItem.cxx b/panda/src/pgui/pgItem.cxx index c3227632ad..26bab3fc9c 100644 --- a/panda/src/pgui/pgItem.cxx +++ b/panda/src/pgui/pgItem.cxx @@ -258,8 +258,9 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { // which only provides one. sort = (bin_sort << 16) | ((sort + 0x8000) & 0xffff); - if (activate_region(transform, sort, data._state->get_clip_plane(), - data._state->get_scissor())) { + if (activate_region(transform, sort, + DCAST(ClipPlaneAttrib, data._state->get_attrib(ClipPlaneAttrib::get_class_slot())), + DCAST(ScissorAttrib, data._state->get_attrib(ScissorAttrib::get_class_slot())))) { pg_trav->_top->add_region(get_region()); } } diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx index 5ebd622e94..fe6dcf4dc1 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx @@ -22,6 +22,16 @@ #include "pointLight.h" #include "directionalLight.h" #include "spotlight.h" +#include "depthWriteAttrib.h" +#include "colorWriteAttrib.h" +#include "alphaTestAttrib.h" +#include "depthTestAttrib.h" +#include "shadeModelAttrib.h" +#include "cullFaceAttrib.h" +#include "rescaleNormalAttrib.h" +#include "materialAttrib.h" +#include "lightAttrib.h" +#include "scissorAttrib.h" #include "bitMask.h" #include "zgl.h" #include "zmath.h" @@ -589,17 +599,20 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, bool needs_texmat = false; LMatrix4f texmat; const InternalName *texcoord_name = InternalName::get_texcoord(); - int max_stage_index = _effective_texture->get_num_on_ff_stages(); + int max_stage_index = _target_texture->get_num_on_ff_stages(); if (max_stage_index > 0) { - TextureStage *stage = _effective_texture->get_on_ff_stage(0); + TextureStage *stage = _target_texture->get_on_ff_stage(0); rtexcoord = GeomVertexReader(data_reader, stage->get_texcoord_name(), force); rtexcoord.set_row(_min_vertex); needs_texcoord = rtexcoord.has_column(); - if (needs_texcoord && _target._tex_matrix->has_stage(stage)) { - needs_texmat = true; - texmat = _target._tex_matrix->get_mat(stage); + if (needs_texcoord) { + const TexMatrixAttrib *target_tex_matrix = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot())); + if (target_tex_matrix->has_stage(stage)) { + needs_texmat = true; + texmat = target_tex_matrix->get_mat(stage); + } } } @@ -723,12 +736,14 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, // according to the current state. int depth_write_state = 0; // zon - if (_target._depth_write->get_mode() != DepthWriteAttrib::M_on) { + const DepthWriteAttrib *target_depth_write = DCAST(DepthWriteAttrib, _target_rs->get_attrib_def(DepthWriteAttrib::get_class_slot())); + if (target_depth_write->get_mode() != DepthWriteAttrib::M_on) { depth_write_state = 1; // zoff } int color_write_state = 0; // cstore - switch (_target._transparency->get_mode()) { + const TransparencyAttrib *target_transparency = DCAST(TransparencyAttrib, _target_rs->get_attrib_def(TransparencyAttrib::get_class_slot())); + switch (target_transparency->get_mode()) { case TransparencyAttrib::M_alpha: case TransparencyAttrib::M_dual: color_write_state = 1; // cblend @@ -738,13 +753,14 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, break; } - if (_target._color_blend->get_mode() == ColorBlendAttrib::M_add) { + const ColorBlendAttrib *target_color_blend = DCAST(ColorBlendAttrib, _target_rs->get_attrib_def(ColorBlendAttrib::get_class_slot())); + if (target_color_blend->get_mode() == ColorBlendAttrib::M_add) { // If we have a color blend set that we can support, it overrides // the transparency set. - int op_a = get_color_blend_op(_target._color_blend->get_operand_a()); - int op_b = get_color_blend_op(_target._color_blend->get_operand_b()); + int op_a = get_color_blend_op(target_color_blend->get_operand_a()); + int op_b = get_color_blend_op(target_color_blend->get_operand_b()); _c->zb->store_pix_func = store_pixel_funcs[op_a][op_b]; - Colorf c = _target._color_blend->get_color(); + Colorf c = target_color_blend->get_color(); _c->zb->blend_r = (int)(c[0] * ZB_POINT_RED_MAX); _c->zb->blend_g = (int)(c[1] * ZB_POINT_GREEN_MAX); _c->zb->blend_b = (int)(c[2] * ZB_POINT_BLUE_MAX); @@ -753,14 +769,16 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, color_write_state = 2; // cgeneral } + const ColorWriteAttrib *target_color_write = DCAST(ColorWriteAttrib, _target_rs->get_attrib_def(ColorWriteAttrib::get_class_slot())); unsigned int color_channels = - _target._color_write->get_channels() & _color_write_mask; + target_color_write->get_channels() & _color_write_mask; if (color_channels == ColorWriteAttrib::C_off) { color_write_state = 3; // coff } int alpha_test_state = 0; // anone - switch (_target._alpha_test->get_mode()) { + const AlphaTestAttrib *target_alpha_test = DCAST(AlphaTestAttrib, _target_rs->get_attrib_def(AlphaTestAttrib::get_class_slot())); + switch (target_alpha_test->get_mode()) { case AlphaTestAttrib::M_none: case AlphaTestAttrib::M_never: case AlphaTestAttrib::M_always: @@ -772,24 +790,26 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, case AlphaTestAttrib::M_less: case AlphaTestAttrib::M_less_equal: alpha_test_state = 1; // aless - _c->zb->reference_alpha = (int)(_target._alpha_test->get_reference_alpha() * ZB_POINT_ALPHA_MAX); + _c->zb->reference_alpha = (int)(target_alpha_test->get_reference_alpha() * ZB_POINT_ALPHA_MAX); break; case AlphaTestAttrib::M_greater: case AlphaTestAttrib::M_greater_equal: alpha_test_state = 2; // amore - _c->zb->reference_alpha = (int)(_target._alpha_test->get_reference_alpha() * ZB_POINT_ALPHA_MAX); + _c->zb->reference_alpha = (int)(target_alpha_test->get_reference_alpha() * ZB_POINT_ALPHA_MAX); break; } int depth_test_state = 1; // zless _c->depth_test = 1; // set this for ZB_line - if (_target._depth_test->get_mode() == DepthTestAttrib::M_none) { + const DepthTestAttrib *target_depth_test = DCAST(DepthTestAttrib, _target_rs->get_attrib_def(DepthTestAttrib::get_class_slot())); + if (target_depth_test->get_mode() == DepthTestAttrib::M_none) { depth_test_state = 0; // zless _c->depth_test = 0; } - ShadeModelAttrib::Mode shade_model = _target._shade_model->get_mode(); + const ShadeModelAttrib *target_shade_model = DCAST(ShadeModelAttrib, _target_rs->get_attrib_def(ShadeModelAttrib::get_class_slot())); + ShadeModelAttrib::Mode shade_model = target_shade_model->get_mode(); if (!needs_normal && !needs_color) { // With no per-vertex lighting, and no per-vertex colors, we might // as well use the flat shading model. @@ -1387,60 +1407,75 @@ set_state_and_transform(const RenderState *target, return; } _target_rs = target; - _target.clear_to_defaults(); - target->store_into_slots(&_target); - _state_rs = 0; - if (_target._color != _state._color || - _target._color_scale != _state._color_scale) { + int color_slot = ColorAttrib::get_class_slot(); + int color_scale_slot = ColorScaleAttrib::get_class_slot(); + if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) || + _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) || + !_state_mask.get_bit(color_slot) || + !_state_mask.get_bit(color_scale_slot)) { PStatTimer timer(_draw_set_state_color_pcollector); do_issue_color(); do_issue_color_scale(); - _state._color = _target._color; - _state._color_scale = _target._color_scale; + _state_mask.set_bit(color_slot); + _state_mask.set_bit(color_scale_slot); } - if (_target._cull_face != _state._cull_face) { + int cull_face_slot = CullFaceAttrib::get_class_slot(); + if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) || + !_state_mask.get_bit(cull_face_slot)) { PStatTimer timer(_draw_set_state_cull_face_pcollector); do_issue_cull_face(); - _state._cull_face = _target._cull_face; + _state_mask.set_bit(cull_face_slot); } - - if (_target._rescale_normal != _state._rescale_normal) { + + int rescale_normal_slot = RescaleNormalAttrib::get_class_slot(); + if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) || + !_state_mask.get_bit(rescale_normal_slot)) { PStatTimer timer(_draw_set_state_rescale_normal_pcollector); do_issue_rescale_normal(); - _state._rescale_normal = _target._rescale_normal; + _state_mask.set_bit(rescale_normal_slot); } - if (_target._render_mode != _state._render_mode) { + int render_mode_slot = RenderModeAttrib::get_class_slot(); + if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) || + !_state_mask.get_bit(render_mode_slot)) { PStatTimer timer(_draw_set_state_render_mode_pcollector); do_issue_render_mode(); - _state._render_mode = _target._render_mode; + _state_mask.set_bit(render_mode_slot); } - if (_target._texture != _state._texture) { + int texture_slot = TextureAttrib::get_class_slot(); + if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) || + !_state_mask.get_bit(texture_slot)) { PStatTimer timer(_draw_set_state_texture_pcollector); - determine_effective_texture(); + determine_target_texture(); do_issue_texture(); - _state._texture = _target._texture; + _state_mask.set_bit(texture_slot); } - - if (_target._material != _state._material) { + + int material_slot = MaterialAttrib::get_class_slot(); + if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) || + !_state_mask.get_bit(material_slot)) { PStatTimer timer(_draw_set_state_material_pcollector); do_issue_material(); - _state._material = _target._material; + _state_mask.set_bit(material_slot); } - if (_target._light != _state._light) { + int light_slot = LightAttrib::get_class_slot(); + if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) || + !_state_mask.get_bit(light_slot)) { PStatTimer timer(_draw_set_state_light_pcollector); do_issue_light(); - _state._light = _target._light; + _state_mask.set_bit(light_slot); } - if (_target._scissor != _state._scissor) { + int scissor_slot = ScissorAttrib::get_class_slot(); + if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) || + !_state_mask.get_bit(scissor_slot)) { PStatTimer timer(_draw_set_state_scissor_pcollector); do_issue_scissor(); - _state._scissor = _target._scissor; + _state_mask.set_bit(scissor_slot); } _state_rs = _target_rs; @@ -1573,17 +1608,18 @@ do_issue_light() { int num_enabled = 0; int num_on_lights = 0; + const LightAttrib *target_light = DCAST(LightAttrib, _target_rs->get_attrib_def(LightAttrib::get_class_slot())); if (display_cat.is_spam()) { display_cat.spam() - << "do_issue_light: " << _target._light << "\n"; + << "do_issue_light: " << target_light << "\n"; } // First, release all of the previously-assigned lights. clear_light_state(); // Now, assign new lights. - if (_target._light != (LightAttrib *)NULL) { - CPT(LightAttrib) new_light = _target._light->filter_to_max(_max_lights); + if (target_light != (LightAttrib *)NULL) { + CPT(LightAttrib) new_light = target_light->filter_to_max(_max_lights); if (display_cat.is_spam()) { new_light->write(display_cat.spam(false), 2); } @@ -1841,11 +1877,11 @@ do_issue_transform() { //////////////////////////////////////////////////////////////////// void TinyGraphicsStateGuardian:: do_issue_render_mode() { - const RenderModeAttrib *attrib = _target._render_mode; + const RenderModeAttrib *target_render_mode = DCAST(RenderModeAttrib, _target_rs->get_attrib_def(RenderModeAttrib::get_class_slot())); _filled_flat = false; - switch (attrib->get_mode()) { + switch (target_render_mode->get_mode()) { case RenderModeAttrib::M_unchanged: case RenderModeAttrib::M_filled: _c->draw_triangle_front = gl_draw_triangle_fill; @@ -1870,7 +1906,7 @@ do_issue_render_mode() { default: tinydisplay_cat.error() - << "Unknown render mode " << (int)attrib->get_mode() << endl; + << "Unknown render mode " << (int)target_render_mode->get_mode() << endl; } } @@ -1881,8 +1917,8 @@ do_issue_render_mode() { //////////////////////////////////////////////////////////////////// void TinyGraphicsStateGuardian:: do_issue_rescale_normal() { - const RescaleNormalAttrib *attrib = _target._rescale_normal; - RescaleNormalAttrib::Mode mode = attrib->get_mode(); + const RescaleNormalAttrib *target_rescale_normal = DCAST(RescaleNormalAttrib, _target_rs->get_attrib_def(RescaleNormalAttrib::get_class_slot())); + RescaleNormalAttrib::Mode mode = target_rescale_normal->get_mode(); _auto_rescale_normal = false; @@ -1916,8 +1952,8 @@ do_issue_rescale_normal() { //////////////////////////////////////////////////////////////////// void TinyGraphicsStateGuardian:: do_issue_cull_face() { - const CullFaceAttrib *attrib = _target._cull_face; - CullFaceAttrib::Mode mode = attrib->get_effective_mode(); + const CullFaceAttrib *target_cull_face = DCAST(CullFaceAttrib, _target_rs->get_attrib_def(CullFaceAttrib::get_class_slot())); + CullFaceAttrib::Mode mode = target_cull_face->get_effective_mode(); switch (mode) { case CullFaceAttrib::M_cull_none: @@ -1946,12 +1982,15 @@ do_issue_cull_face() { void TinyGraphicsStateGuardian:: do_issue_material() { static Material empty; + + const MaterialAttrib *target_material = DCAST(MaterialAttrib, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot())); + const Material *material; - if (_target._material == (MaterialAttrib *)NULL || - _target._material->is_off()) { + if (target_material == (MaterialAttrib *)NULL || + target_material->is_off()) { material = ∅ } else { - material = _target._material->get_material(); + material = target_material->get_material(); } // Apply the material parameters to the front face. @@ -1976,15 +2015,15 @@ do_issue_texture() { _texturing_state = 0; // untextured _c->texture_2d_enabled = false; - int num_stages = _effective_texture->get_num_on_ff_stages(); + int num_stages = _target_texture->get_num_on_ff_stages(); if (num_stages == 0) { // No texturing. return; } nassertv(num_stages == 1); - TextureStage *stage = _effective_texture->get_on_ff_stage(0); - Texture *texture = _effective_texture->get_on_texture(stage); + TextureStage *stage = _target_texture->get_on_ff_stage(0); + Texture *texture = _target_texture->get_on_texture(stage); nassertv(texture != (Texture *)NULL); TextureContext *tc = texture->prepare_now(_prepared_objects, this); @@ -2058,7 +2097,8 @@ do_issue_texture() { //////////////////////////////////////////////////////////////////// void TinyGraphicsStateGuardian:: do_issue_scissor() { - const LVecBase4f &frame = _target._scissor->get_frame(); + const ScissorAttrib *target_scissor = DCAST(ScissorAttrib, _target_rs->get_attrib_def(ScissorAttrib::get_class_slot())); + const LVecBase4f &frame = target_scissor->get_frame(); set_scissor(frame[0], frame[1], frame[2], frame[3]); }