simpler do_issue_clip_plane() and do_issue_light(); more pstats calipers

This commit is contained in:
David Rose 2007-07-19 16:16:41 +00:00
parent 8824ef8a0a
commit 93f85f9ef9
8 changed files with 204 additions and 340 deletions

View File

@ -17,29 +17,6 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::LightInfo::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GraphicsStateGuardian::LightInfo::
LightInfo() {
_enabled = false;
_next_enabled = false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::ClipPlaneInfo::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GraphicsStateGuardian::ClipPlaneInfo::
ClipPlaneInfo() {
_enabled = false;
_next_enabled = false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::release_all
// Access: Public
@ -759,30 +736,6 @@ get_inv_cs_transform() const {
return _inv_cs_transform;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_light
// Access: Protected
// Description: Returns the Light object that is bound to the
// indicated id, or empty NodePath if no Light is bound.
////////////////////////////////////////////////////////////////////
INLINE NodePath GraphicsStateGuardian::
get_light(int light_id) const {
nassertr(light_id >= 0 && light_id < (int)_light_info.size(), NodePath::fail());
return _light_info[light_id]._light;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_clip_plane
// Access: Protected
// Description: Returns the PlaneNode object that is bound to the
// indicated id, or NULL if no PlaneNode is bound.
////////////////////////////////////////////////////////////////////
INLINE NodePath GraphicsStateGuardian::
get_clip_plane(int plane_id) const {
nassertr(plane_id >= 0 && plane_id < (int)_clip_plane_info.size(), NodePath::fail());
return _clip_plane_info[plane_id]._plane;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::set_current_properties
// Access: Protected

View File

@ -74,6 +74,29 @@ PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush");
PStatCollector GraphicsStateGuardian::_wait_occlusion_pcollector("Wait:Occlusion");
PStatCollector GraphicsStateGuardian::_draw_set_state_transform_pcollector("Draw:Set State:Transform");
PStatCollector GraphicsStateGuardian::_draw_set_state_alpha_test_pcollector("Draw:Set State:Alpha test");
PStatCollector GraphicsStateGuardian::_draw_set_state_antialias_pcollector("Draw:Set State:Antialias");
PStatCollector GraphicsStateGuardian::_draw_set_state_clip_plane_pcollector("Draw:Set State:Clip plane");
PStatCollector GraphicsStateGuardian::_draw_set_state_color_pcollector("Draw:Set State:Color");
PStatCollector GraphicsStateGuardian::_draw_set_state_cull_face_pcollector("Draw:Set State:Cull face");
PStatCollector GraphicsStateGuardian::_draw_set_state_depth_offset_pcollector("Draw:Set State:Depth offset");
PStatCollector GraphicsStateGuardian::_draw_set_state_depth_test_pcollector("Draw:Set State:Depth test");
PStatCollector GraphicsStateGuardian::_draw_set_state_depth_write_pcollector("Draw:Set State:Depth write");
PStatCollector GraphicsStateGuardian::_draw_set_state_render_mode_pcollector("Draw:Set State:Render mode");
PStatCollector GraphicsStateGuardian::_draw_set_state_rescale_normal_pcollector("Draw:Set State:Rescale normal");
PStatCollector GraphicsStateGuardian::_draw_set_state_shade_model_pcollector("Draw:Set State:Shade model");
PStatCollector GraphicsStateGuardian::_draw_set_state_blending_pcollector("Draw:Set State:Blending");
PStatCollector GraphicsStateGuardian::_draw_set_state_shader_pcollector("Draw:Set State:Shader");
PStatCollector GraphicsStateGuardian::_draw_set_state_texture_pcollector("Draw:Set State:Texture");
PStatCollector GraphicsStateGuardian::_draw_set_state_tex_matrix_pcollector("Draw:Set State:Tex matrix");
PStatCollector GraphicsStateGuardian::_draw_set_state_tex_gen_pcollector("Draw:Set State:Tex gen");
PStatCollector GraphicsStateGuardian::_draw_set_state_material_pcollector("Draw:Set State:Material");
PStatCollector GraphicsStateGuardian::_draw_set_state_light_pcollector("Draw:Set State:Light");
PStatCollector GraphicsStateGuardian::_draw_set_state_stencil_pcollector("Draw:Set State:Stencil");
PStatCollector GraphicsStateGuardian::_draw_set_state_fog_pcollector("Draw:Set State:Fog");
PT(TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage = NULL;
TypeHandle GraphicsStateGuardian::_type_handle;
@ -315,10 +338,8 @@ reset() {
_texture_involves_color_scale = false;
_vertex_colors_enabled = true;
_lighting_enabled = false;
_lighting_enabled_this_frame = false;
_clip_planes_enabled = false;
_clip_planes_enabled_this_frame = false;
_num_lights_enabled = 0;
_num_clip_planes_enabled = 0;
_color_scale_enabled = false;
_current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
@ -1132,37 +1153,17 @@ end_scene() {
// Undo any lighting we had enabled last scene, to force the lights
// to be reissued, in case their parameters or positions have
// changed between scenes.
if (_lighting_enabled_this_frame) {
for (int i = 0; i < (int)_light_info.size(); i++) {
if (_light_info[i]._enabled) {
enable_light(i, false);
_light_info[i]._enabled = false;
}
_light_info[i]._light = NodePath();
}
// Also force the lighting state to unlit, so that issue_light()
// will be guaranteed to be called next frame even if we have the
// same set of light pointers we had this frame.
// modify_state(get_unlit_state());
_lighting_enabled_this_frame = false;
int i;
for (i = 0; i < _num_lights_enabled; ++i) {
enable_light(i, false);
}
_num_lights_enabled = 0;
// Ditto for the clipping planes.
if (_clip_planes_enabled_this_frame) {
for (int i = 0; i < (int)_clip_plane_info.size(); i++) {
if (_clip_plane_info[i]._enabled) {
enable_clip_plane(i, false);
_clip_plane_info[i]._enabled = false;
}
_clip_plane_info[i]._plane = (PlaneNode *)NULL;
}
// modify_state(get_unclipped_state());
_clip_planes_enabled_this_frame = false;
for (i = 0; i < _num_clip_planes_enabled; ++i) {
enable_clip_plane(i, false);
}
_num_clip_planes_enabled = 0;
// Put the state into the 'unknown' state, forcing a reload.
_state_rs = 0;
@ -1417,114 +1418,49 @@ get_cs_transform() const {
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
do_issue_clip_plane() {
const ClipPlaneAttrib *attrib = _target._clip_plane;
int i;
int cur_max_planes = (int)_clip_plane_info.size();
for (i = 0; i < cur_max_planes; i++) {
_clip_plane_info[i]._next_enabled = false;
}
CPT(ClipPlaneAttrib) new_attrib = attrib->filter_to_max(_max_clip_planes);
bool any_bound = false;
int num_enabled = 0;
int num_on_planes = new_attrib->get_num_on_planes();
for (int li = 0; li < num_on_planes; li++) {
NodePath plane = new_attrib->get_on_plane(li);
nassertv(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()));
PlaneNode *plane_node = (PlaneNode *)plane.node();
if ((plane_node->get_clip_effect() & PlaneNode::CE_visible) != 0) {
num_enabled++;
int num_on_planes = 0;
// Clipping should be enabled before we apply any planes.
enable_clip_planes(true);
_clip_planes_enabled = true;
_clip_planes_enabled_this_frame = true;
// Check to see if this plane has already been bound to an id
int cur_plane_id = -1;
for (i = 0; i < cur_max_planes; i++) {
if (_clip_plane_info[i]._plane == plane) {
// Plane has already been bound to an id, we only need to
// enable the plane, not reapply it.
cur_plane_id = -2;
enable_clip_plane(i, true);
_clip_plane_info[i]._enabled = true;
_clip_plane_info[i]._next_enabled = true;
break;
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++) {
NodePath plane = new_plane->get_on_plane(li);
nassertv(!plane.is_empty());
PlaneNode *plane_node;
DCAST_INTO_V(plane_node, plane.node());
if ((plane_node->get_clip_effect() & PlaneNode::CE_visible) != 0) {
// Clipping should be enabled before we apply any planes.
if (!_clip_planes_enabled) {
enable_clip_planes(true);
_clip_planes_enabled = true;
}
}
// See if there are any unbound plane ids
if (cur_plane_id == -1) {
for (i = 0; i < cur_max_planes; i++) {
if (_clip_plane_info[i]._plane.is_empty()) {
_clip_plane_info[i]._plane = plane;
cur_plane_id = i;
break;
}
}
}
// If there were no unbound plane ids, see if we can replace
// a currently unused but previously bound id
if (cur_plane_id == -1) {
for (i = 0; i < cur_max_planes; i++) {
if (!new_attrib->has_on_plane(_clip_plane_info[i]._plane)) {
_clip_plane_info[i]._plane = plane;
cur_plane_id = i;
break;
}
}
}
// If we *still* don't have a plane id, slot a new one.
if (cur_plane_id == -1) {
if (_max_clip_planes < 0 || cur_max_planes < _max_clip_planes) {
cur_plane_id = cur_max_planes;
_clip_plane_info.push_back(ClipPlaneInfo());
cur_max_planes++;
nassertv(cur_max_planes == (int)_clip_plane_info.size());
}
}
if (cur_plane_id >= 0) {
enable_clip_plane(cur_plane_id, true);
_clip_plane_info[cur_plane_id]._enabled = true;
_clip_plane_info[cur_plane_id]._next_enabled = true;
if (!any_bound) {
enable_clip_plane(num_enabled, true);
if (num_enabled == 0) {
begin_bind_clip_planes();
any_bound = true;
}
// This is the first time this frame that this plane has been
// bound to this particular id.
bind_clip_plane(plane, cur_plane_id);
} else if (cur_plane_id == -1) {
gsg_cat.warning()
<< "Failed to bind " << plane << " to id.\n";
bind_clip_plane(plane, num_enabled);
num_enabled++;
}
}
}
// Disable all unused planes
for (i = 0; i < cur_max_planes; i++) {
if (!_clip_plane_info[i]._next_enabled) {
enable_clip_plane(i, false);
_clip_plane_info[i]._enabled = false;
}
int i;
for (i = num_enabled; i < _num_clip_planes_enabled; ++i) {
enable_clip_plane(i, false);
}
_num_clip_planes_enabled = num_enabled;
// If no planes were enabled, disable clip planes in general.
// If no planes were set, disable clipping
if (num_enabled == 0) {
enable_clip_planes(false);
_clip_planes_enabled = false;
}
if (any_bound) {
if (_clip_planes_enabled) {
enable_clip_planes(false);
_clip_planes_enabled = false;
}
} else {
end_bind_clip_planes();
}
}
@ -1649,29 +1585,32 @@ do_issue_light() {
// light list
Colorf cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
int i;
int cur_max_lights = (int)_light_info.size();
for (i = 0; i < cur_max_lights; i++) {
_light_info[i]._next_enabled = false;
}
bool any_bound = false;
int num_enabled = 0;
int num_on_lights = 0;
if (display_cat.is_debug()) {
display_cat.debug()
<< "do_issue_light: " << _target._light << "\n";
}
if (_target._light != (LightAttrib *)NULL) {
CPT(LightAttrib) new_light = _target._light->filter_to_max(_max_lights);
if (display_cat.is_debug()) {
new_light->write(display_cat.debug(false), 2);
}
int num_on_lights = new_light->get_num_on_lights();
num_on_lights = new_light->get_num_on_lights();
for (int li = 0; li < num_on_lights; li++) {
NodePath light = new_light->get_on_light(li);
nassertv(!light.is_empty() && light.node()->as_light() != (Light *)NULL);
nassertv(!light.is_empty());
Light *light_obj = light.node()->as_light();
num_enabled++;
nassertv(light_obj != (Light *)NULL);
// Lighting should be enabled before we apply any lights.
enable_lighting(true);
_lighting_enabled = true;
_lighting_enabled_this_frame = true;
if (!_lighting_enabled) {
enable_lighting(true);
_lighting_enabled = true;
}
if (light_obj->get_type() == AmbientLight::get_class_type()) {
// Ambient lights don't require specific light ids; simply add
@ -1679,108 +1618,45 @@ do_issue_light() {
cur_ambient_light += light_obj->get_color();
} else {
// Check to see if this light has already been bound to an id
int cur_light_id = -1;
for (i = 0; i < cur_max_lights; i++) {
if (_light_info[i]._light == light) {
// Light has already been bound to an id; reuse the same id.
cur_light_id = -2;
enable_light(i, true);
_light_info[i]._enabled = true;
_light_info[i]._next_enabled = true;
if (!any_bound) {
begin_bind_lights();
any_bound = true;
}
light_obj->bind(this, light, i);
break;
}
enable_light(num_enabled, true);
if (num_enabled == 0) {
begin_bind_lights();
}
// See if there are any unbound light ids
if (cur_light_id == -1) {
for (i = 0; i < cur_max_lights; i++) {
if (_light_info[i]._light.is_empty()) {
_light_info[i]._light = light;
cur_light_id = i;
break;
}
}
}
// If there were no unbound light ids, see if we can replace
// a currently unused but previously bound id
if (cur_light_id == -1) {
for (i = 0; i < cur_max_lights; i++) {
if (!new_light->has_on_light(_light_info[i]._light)) {
_light_info[i]._light = light;
cur_light_id = i;
break;
}
}
}
// If we *still* don't have a light id, slot a new one.
if (cur_light_id == -1) {
if (_max_lights < 0 || cur_max_lights < _max_lights) {
cur_light_id = cur_max_lights;
_light_info.push_back(LightInfo());
cur_max_lights++;
nassertv(cur_max_lights == (int)_light_info.size());
}
}
if (cur_light_id >= 0) {
enable_light(cur_light_id, true);
_light_info[cur_light_id]._enabled = true;
_light_info[cur_light_id]._next_enabled = true;
if (!any_bound) {
begin_bind_lights();
any_bound = true;
}
// This is the first time this frame that this light has been
// bound to this particular id.
light_obj->bind(this, light, cur_light_id);
} else if (cur_light_id == -1) {
gsg_cat.warning()
<< "Failed to bind " << light << " to id.\n";
}
light_obj->bind(this, light, num_enabled);
num_enabled++;
}
}
}
// Disable all unused lights
for (i = 0; i < cur_max_lights; i++) {
if (!_light_info[i]._next_enabled) {
enable_light(i, false);
_light_info[i]._enabled = false;
}
for (i = num_enabled; i < _num_lights_enabled; ++i) {
enable_light(i, false);
}
_num_lights_enabled = num_enabled;
// If no lights were enabled, disable lighting
if (num_enabled == 0) {
// If no lights were set, disable lighting
if (num_on_lights == 0) {
if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale != LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f))) {
// Unless we need lighting anyway to apply a color or color
// scale.
enable_lighting(true);
_lighting_enabled = true;
_lighting_enabled_this_frame = true;
if (!_lighting_enabled) {
enable_lighting(true);
_lighting_enabled = true;
}
set_ambient_light(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
} else {
enable_lighting(false);
_lighting_enabled = false;
if (_lighting_enabled) {
enable_lighting(false);
_lighting_enabled = false;
}
}
} else {
set_ambient_light(cur_ambient_light);
}
if (any_bound) {
if (num_enabled != 0) {
end_bind_lights();
}
}

View File

@ -267,14 +267,12 @@ public:
#endif
protected:
INLINE NodePath get_light(int light_id) const;
virtual void enable_lighting(bool enable);
virtual void set_ambient_light(const Colorf &color);
virtual void enable_light(int light_id, bool enable);
virtual void begin_bind_lights();
virtual void end_bind_lights();
INLINE NodePath get_clip_plane(int plane_id) const;
virtual void enable_clip_planes(bool enable);
virtual void enable_clip_plane(int plane_id, bool enable);
virtual void begin_bind_clip_planes();
@ -447,28 +445,33 @@ public:
static PStatCollector _flush_pcollector;
static PStatCollector _wait_occlusion_pcollector;
// A whole slew of collectors to measure the cost of individual
// state changes. These are disabled by default.
static PStatCollector _draw_set_state_transform_pcollector;
static PStatCollector _draw_set_state_alpha_test_pcollector;
static PStatCollector _draw_set_state_antialias_pcollector;
static PStatCollector _draw_set_state_clip_plane_pcollector;
static PStatCollector _draw_set_state_color_pcollector;
static PStatCollector _draw_set_state_cull_face_pcollector;
static PStatCollector _draw_set_state_depth_offset_pcollector;
static PStatCollector _draw_set_state_depth_test_pcollector;
static PStatCollector _draw_set_state_depth_write_pcollector;
static PStatCollector _draw_set_state_render_mode_pcollector;
static PStatCollector _draw_set_state_rescale_normal_pcollector;
static PStatCollector _draw_set_state_shade_model_pcollector;
static PStatCollector _draw_set_state_blending_pcollector;
static PStatCollector _draw_set_state_shader_pcollector;
static PStatCollector _draw_set_state_texture_pcollector;
static PStatCollector _draw_set_state_tex_matrix_pcollector;
static PStatCollector _draw_set_state_tex_gen_pcollector;
static PStatCollector _draw_set_state_material_pcollector;
static PStatCollector _draw_set_state_light_pcollector;
static PStatCollector _draw_set_state_stencil_pcollector;
static PStatCollector _draw_set_state_fog_pcollector;
private:
class LightInfo {
public:
INLINE LightInfo();
NodePath _light;
bool _enabled;
bool _next_enabled;
};
pvector<LightInfo> _light_info;
bool _lighting_enabled_this_frame;
class ClipPlaneInfo {
public:
INLINE ClipPlaneInfo();
NodePath _plane;
bool _enabled;
bool _next_enabled;
};
pvector<ClipPlaneInfo> _clip_plane_info;
bool _clip_planes_enabled_this_frame;
int _num_lights_enabled;
int _num_clip_planes_enabled;
PT(GraphicsPipe) _pipe;
GraphicsEngine *_engine;

View File

@ -4036,10 +4036,14 @@ 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);
float light_color[4];
GLenum id = get_light_id(light_id);
static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
GLP(Lightfv)(id, GL_AMBIENT, black.get_data());
GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_obj));
GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_color, light_obj));
GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data());
// Position needs to specify x, y, z, and w
@ -4076,10 +4080,14 @@ 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);
float light_color[4];
GLenum id = get_light_id( light_id );
static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
GLP(Lightfv)(id, GL_AMBIENT, black.get_data());
GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_obj));
GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_color, light_obj));
GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data());
// Position needs to specify x, y, z, and w.
@ -4117,13 +4125,17 @@ 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);
Lens *lens = light_obj->get_lens();
nassertv(lens != (Lens *)NULL);
float light_color[4];
GLenum id = get_light_id(light_id);
static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
GLP(Lightfv)(id, GL_AMBIENT, black.get_data());
GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_obj));
GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_color, light_obj));
GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data());
// Position needs to specify x, y, z, and w
@ -5564,20 +5576,22 @@ print_gfx_visual() {
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::get_light_color
// Access: Public
// Description: Returns the array of four floats that should be
// issued as the light's color, as scaled by the current
// value of _light_color_scale, in the case of
// color_scale_via_lighting.
// Description: Fills the array of four floats with the values that
// that should be issued as the light's color, as scaled
// by the current value of _light_color_scale, in the
// case of color_scale_via_lighting. Returns
// light_color.
////////////////////////////////////////////////////////////////////
const float *CLP(GraphicsStateGuardian)::
get_light_color(Light *light) const {
static Colorf c;
c = light->get_color();
c.set(c[0] * _light_color_scale[0],
c[1] * _light_color_scale[1],
c[2] * _light_color_scale[2],
c[3] * _light_color_scale[3]);
return c.get_data();
float *CLP(GraphicsStateGuardian)::
get_light_color(float light_color[4], Light *light) const {
const Colorf &c = light->get_color();
light_color[0] = c[0] * _light_color_scale[0];
light_color[1] = c[1] * _light_color_scale[1];
light_color[2] = c[2] * _light_color_scale[2];
light_color[3] = c[3] * _light_color_scale[3];
return light_color;
}
////////////////////////////////////////////////////////////////////
@ -5590,6 +5604,9 @@ get_light_color(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);
if (enable) {
GLP(Enable)(GL_LIGHTING);
} else {
@ -5607,6 +5624,9 @@ 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);
Colorf c = color;
c.set(c[0] * _light_color_scale[0],
c[1] * _light_color_scale[1],
@ -5624,6 +5644,9 @@ 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);
if (enable) {
GLP(Enable)(get_light_id(light_id));
} else {
@ -5645,6 +5668,9 @@ 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);
// 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
// root. (Alternatively, we could leave the current transform where
@ -5671,6 +5697,9 @@ 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);
GLP(MatrixMode)(GL_MODELVIEW);
GLP(PopMatrix)();
}
@ -5787,9 +5816,10 @@ set_state_and_transform(const RenderState *target,
#endif
_state_pcollector.add_level(1);
PStatTimer timer(_draw_set_state_pcollector);
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();
@ -5804,22 +5834,26 @@ set_state_and_transform(const RenderState *target,
_state_rs = 0;
if (_target._alpha_test != _state._alpha_test) {
PStatTimer timer(_draw_set_state_alpha_test_pcollector);
do_issue_alpha_test();
_state._alpha_test = _target._alpha_test;
}
if (_target._antialias != _state._antialias) {
PStatTimer timer(_draw_set_state_antialias_pcollector);
do_issue_antialias();
_state._antialias = _target._antialias;
}
if (_target._clip_plane != _state._clip_plane) {
PStatTimer timer(_draw_set_state_clip_plane_pcollector);
do_issue_clip_plane();
_state._clip_plane = _target._clip_plane;
}
if (_target._color != _state._color ||
_target._color_scale != _state._color_scale) {
PStatTimer timer(_draw_set_state_color_pcollector);
do_issue_color();
do_issue_color_scale();
_state._color = _target._color;
@ -5827,36 +5861,43 @@ set_state_and_transform(const RenderState *target,
}
if (_target._cull_face != _state._cull_face) {
PStatTimer timer(_draw_set_state_cull_face_pcollector);
do_issue_cull_face();
_state._cull_face = _target._cull_face;
}
if (_target._depth_offset != _state._depth_offset) {
PStatTimer timer(_draw_set_state_depth_offset_pcollector);
do_issue_depth_offset();
_state._depth_offset = _target._depth_offset;
}
if (_target._depth_test != _state._depth_test) {
PStatTimer timer(_draw_set_state_depth_test_pcollector);
do_issue_depth_test();
_state._depth_test = _target._depth_test;
}
if (_target._depth_write != _state._depth_write) {
PStatTimer timer(_draw_set_state_depth_write_pcollector);
do_issue_depth_write();
_state._depth_write = _target._depth_write;
}
if (_target._render_mode != _state._render_mode) {
PStatTimer timer(_draw_set_state_render_mode_pcollector);
do_issue_render_mode();
_state._render_mode = _target._render_mode;
}
if (_target._rescale_normal != _state._rescale_normal) {
PStatTimer timer(_draw_set_state_rescale_normal_pcollector);
do_issue_rescale_normal();
_state._rescale_normal = _target._rescale_normal;
}
if (_target._shade_model != _state._shade_model) {
PStatTimer timer(_draw_set_state_shade_model_pcollector);
do_issue_shade_model();
_state._shade_model = _target._shade_model;
}
@ -5864,6 +5905,7 @@ set_state_and_transform(const RenderState *target,
if ((_target._transparency != _state._transparency)||
(_target._color_write != _state._color_write)||
(_target._color_blend != _state._color_blend)) {
PStatTimer timer(_draw_set_state_blending_pcollector);
do_issue_blending();
_state._transparency = _target._transparency;
_state._color_write = _target._color_write;
@ -5871,12 +5913,14 @@ set_state_and_transform(const RenderState *target,
}
if (_target._shader != _state._shader) {
PStatTimer timer(_draw_set_state_shader_pcollector);
do_issue_shader();
_state._shader = _target._shader;
_state._texture = 0;
}
if (_target._texture != _state._texture) {
PStatTimer timer(_draw_set_state_texture_pcollector);
determine_effective_texture();
int prev_active = _num_active_texture_stages;
do_issue_texture();
@ -5902,32 +5946,38 @@ set_state_and_transform(const RenderState *target,
}
if (_target._tex_matrix != _state._tex_matrix) {
PStatTimer timer(_draw_set_state_tex_matrix_pcollector);
do_issue_tex_matrix();
_state._tex_matrix = _target._tex_matrix;
}
if (_effective_tex_gen != _state._tex_gen) {
PStatTimer timer(_draw_set_state_tex_gen_pcollector);
do_issue_tex_gen();
_state._tex_gen = _effective_tex_gen;
}
if (_target._material != _state._material) {
PStatTimer timer(_draw_set_state_material_pcollector);
do_issue_material();
_state._material = _target._material;
}
if (_target._light != _state._light) {
PStatTimer timer(_draw_set_state_light_pcollector);
do_issue_light();
_state._light = _target._light;
}
if (_target._stencil != _state._stencil) {
PStatTimer timer(_draw_set_state_stencil_pcollector);
do_issue_stencil();
_state._stencil = _target._stencil;
}
if (_current_shader_context == 0) {
if (_target._fog != _state._fog) {
PStatTimer timer(_draw_set_state_fog_pcollector);
do_issue_fog();
_state._fog = _target._fog;
}

View File

@ -179,11 +179,7 @@ public:
void print_gfx_visual();
//For those interested in what the guardian thinks is the current
//enabled/disable GL State compared to what GL says it is
void dump_state();
const float *get_light_color(Light *light) const;
float *get_light_color(float light_color[4], Light *light) const;
#ifdef SUPPORT_IMMEDIATE_MODE
void draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode);

View File

@ -66,6 +66,8 @@
#include "bamFile.h"
#include "preparedGraphicsObjects.h"
#include "dcast.h"
#include "pStatCollector.h"
#include "pStatTimer.h"
// stack seems to overflow on Intel C++ at 7000. If we need more than
// 7000, need to increase stack size.
@ -706,6 +708,8 @@ get_transform(Thread *current_thread) const {
CPT(TransformState) NodePath::
get_transform(const NodePath &other, Thread *current_thread) const {
nassertr(_error_type == ET_ok && other._error_type == ET_ok, TransformState::make_identity());
static PStatCollector _get_transform_pcollector("*:NodePath:get_transform");
PStatTimer timer(_get_transform_pcollector);
if (other.is_empty()) {
return get_net_transform(current_thread);
@ -713,7 +717,7 @@ get_transform(const NodePath &other, Thread *current_thread) const {
if (is_empty()) {
return other.get_net_transform(current_thread)->invert_compose(TransformState::make_identity());
}
nassertr(verify_complete(current_thread), TransformState::make_identity());
nassertr(other.verify_complete(current_thread), TransformState::make_identity());
@ -744,6 +748,7 @@ get_transform(const NodePath &other, Thread *current_thread) const {
a_transform = r_get_net_transform(_head, current_thread);
b_transform = r_get_net_transform(other._head, current_thread);
}
return b_transform->invert_compose(a_transform);
}
@ -5523,7 +5528,7 @@ verify_complete(Thread *current_thread) const {
}
#ifdef HAVE_THREADS
if (Thread::is_threading_supported()) {
if (Thread::is_true_threads()) {
// In a threaded environment, we can't reliably test this, since a
// sub-thread may be mucking with the NodePath's ancestry as we
// try to validate it. NodePaths are inherently not thread-safe,
@ -5532,6 +5537,9 @@ verify_complete(Thread *current_thread) const {
}
#endif // HAVE_THREADS
static PStatCollector _verify_complete_pcollector("*:NodePath:verify_complete");
PStatTimer timer(_verify_complete_pcollector);
const NodePathComponent *comp = _head;
nassertr(comp != (const NodePathComponent *)NULL, false);

View File

@ -193,32 +193,9 @@ bool RenderEffects::
operator < (const RenderEffects &other) const {
// We must compare all the properties of the effects, not just
// the type; thus, we compare them one at a time using compare_to().
// We could use STL's lexicographical_compare() function here, but
// it seems to generate aberrant behavior on OSX and Linux. We
// suspect a compiler bug in gcc. Instead, we implement the
// comparison by hand.
Effects::const_iterator ai = _effects.begin();
Effects::const_iterator bi = other._effects.begin();
while (ai != _effects.end() && bi != other._effects.end()) {
int compare = (*ai).compare_to(*bi);
if (compare != 0) {
return compare < 0;
}
++ai;
++bi;
}
if (ai != _effects.end()) {
// bi ran out first..
return false;
}
if (bi != other._effects.end()) {
// ai ran out first.
return true;
}
// Lists are equivalent.
return false;
return lexicographical_compare(_effects.begin(), _effects.end(),
other._effects.begin(), other._effects.end(),
CompareTo<Effect>());
}

View File

@ -142,6 +142,7 @@ static TimeCollectorProperties time_properties[] = {
{ 1, "*:Animation", { 1.0, 0.0, 1.0 } },
{ 0, "*:Flatten", { 0.0, 0.7, 0.4 } },
{ 0, "*:State Cache", { 0.4, 0.7, 0.7 } },
{ 0, "*:NodePath", { 0.1, 0.6, 0.8 } },
{ 1, "Draw", { 0.83, 0.02, 0.01 }, 1.0 / 30.0 },
{ 1, "Draw:Make current", { 0.4, 0.2, 0.6 } },
{ 1, "Draw:Copy texture", { 0.2, 0.6, 0.4 } },