fix vertex-buffer problem in callbacks

This commit is contained in:
David Rose 2009-03-15 00:01:05 +00:00
parent 77bb94535c
commit eee0f7321b
7 changed files with 63 additions and 16 deletions

View File

@ -1763,6 +1763,7 @@ do_draw(CullResult *cull_result, SceneSetup *scene_setup,
// Issue the draw callback on this DisplayRegion. // Issue the draw callback on this DisplayRegion.
// Set the GSG to the initial state. // Set the GSG to the initial state.
gsg->clear_before_callback();
gsg->set_state_and_transform(RenderState::make_empty(), TransformState::make_identity()); gsg->set_state_and_transform(RenderState::make_empty(), TransformState::make_identity());
DisplayRegionDrawCallbackData cbdata(cull_result, scene_setup); DisplayRegionDrawCallbackData cbdata(cull_result, scene_setup);

View File

@ -1239,6 +1239,19 @@ prepare_display_region(DisplayRegionPipelineReader *dr,
} }
} }
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::clear_before_callback
// Access: Public, Virtual
// Description: Resets any non-standard graphics state that might
// give a callback apoplexy. Some drivers require that
// the graphics state be restored to neutral before
// performing certain operations. In OpenGL, for
// instance, this closes any open vertex buffers.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
clear_before_callback() {
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::clear_state_and_transform // Function: GraphicsStateGuardian::clear_state_and_transform
// Access: Public, Virtual // Access: Public, Virtual

View File

@ -225,6 +225,7 @@ public:
virtual void prepare_display_region(DisplayRegionPipelineReader *dr, virtual void prepare_display_region(DisplayRegionPipelineReader *dr,
Lens::StereoChannel stereo_channel); Lens::StereoChannel stereo_channel);
virtual void clear_before_callback();
virtual void clear_state_and_transform(); virtual void clear_state_and_transform();
virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual CPT(TransformState) calc_projection_mat(const Lens *lens);

View File

@ -1537,6 +1537,20 @@ prepare_display_region(DisplayRegionPipelineReader *dr,
do_point_size(); do_point_size();
} }
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::clear_before_callback
// Access: Public, Virtual
// Description: Resets any non-standard graphics state that might
// give a callback apoplexy. Some drivers require that
// the graphics state be restored to neutral before
// performing certain operations. In OpenGL, for
// instance, this closes any open vertex buffers.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
clear_before_callback() {
unbind_buffers();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::calc_projection_mat // Function: GLGraphicsStateGuardian::calc_projection_mat
// Access: Public, Virtual // Access: Public, Virtual
@ -1955,22 +1969,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
// Before we compile or call a display list, make sure the current // Before we compile or call a display list, make sure the current
// buffers are unbound, or the nVidia drivers may crash. // buffers are unbound, or the nVidia drivers may crash.
if (_current_vbuffer_index != 0) { unbind_buffers();
if (GLCAT.is_debug() && CLP(debug_buffers)) {
GLCAT.debug()
<< "unbinding vertex buffer\n";
}
_glBindBuffer(GL_ARRAY_BUFFER, 0);
_current_vbuffer_index = 0;
}
if (_current_ibuffer_index != 0) {
if (GLCAT.is_debug() && CLP(debug_buffers)) {
GLCAT.debug()
<< "unbinding index buffer\n";
}
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
_current_ibuffer_index = 0;
}
GeomContext *gc = ((Geom *)geom_reader->get_object())->prepare_now(get_prepared_objects(), this); GeomContext *gc = ((Geom *)geom_reader->get_object())->prepare_now(get_prepared_objects(), this);
nassertr(gc != (GeomContext *)NULL, false); nassertr(gc != (GeomContext *)NULL, false);
@ -2303,6 +2302,35 @@ update_standard_vertex_arrays(bool force) {
return true; return true;
} }
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::unbind_buffers
// Access: Protected
// Description: Ensures the vertex and array buffers are no longer
// bound. Some graphics drivers crash if these are left
// bound indiscriminantly.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
unbind_buffers() {
if (_current_vbuffer_index != 0) {
if (GLCAT.is_debug() && CLP(debug_buffers)) {
GLCAT.debug()
<< "unbinding vertex buffer\n";
}
_glBindBuffer(GL_ARRAY_BUFFER, 0);
_current_vbuffer_index = 0;
}
if (_current_ibuffer_index != 0) {
if (GLCAT.is_debug() && CLP(debug_buffers)) {
GLCAT.debug()
<< "unbinding index buffer\n";
}
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
_current_ibuffer_index = 0;
}
disable_standard_vertex_arrays();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::disable_standard_vertex_arrays // Function: GLGraphicsStateGuardian::disable_standard_vertex_arrays
// Access: Protected // Access: Protected

View File

@ -115,6 +115,7 @@ public:
virtual void prepare_display_region(DisplayRegionPipelineReader *dr, virtual void prepare_display_region(DisplayRegionPipelineReader *dr,
Lens::StereoChannel stereo_channel); Lens::StereoChannel stereo_channel);
virtual void clear_before_callback();
virtual CPT(TransformState) calc_projection_mat(const Lens *lens); virtual CPT(TransformState) calc_projection_mat(const Lens *lens);
virtual bool prepare_lens(); virtual bool prepare_lens();
@ -319,6 +320,7 @@ protected:
static GLenum get_blend_func(ColorBlendAttrib::Operand operand); static GLenum get_blend_func(ColorBlendAttrib::Operand operand);
static GLenum get_usage(Geom::UsageHint usage_hint); static GLenum get_usage(Geom::UsageHint usage_hint);
void unbind_buffers();
void disable_standard_vertex_arrays(); void disable_standard_vertex_arrays();
bool update_standard_vertex_arrays(bool force); bool update_standard_vertex_arrays(bool force);
void disable_standard_texture_bindings(); void disable_standard_texture_bindings();

View File

@ -128,6 +128,7 @@ public:
// that display depends on. // that display depends on.
virtual SceneSetup *get_scene() const=0; virtual SceneSetup *get_scene() const=0;
virtual void clear_before_callback()=0;
virtual void clear_state_and_transform()=0; virtual void clear_state_and_transform()=0;
#ifndef CPPPARSER #ifndef CPPPARSER

View File

@ -782,6 +782,7 @@ draw_fancy(GraphicsStateGuardianBase *gsg, bool force,
nassertv(_fancy); nassertv(_fancy);
if (_draw_callback != (CallbackObject *)NULL) { if (_draw_callback != (CallbackObject *)NULL) {
// It has a callback associated. // It has a callback associated.
gsg->clear_before_callback();
gsg->set_state_and_transform(_state, _internal_transform); gsg->set_state_and_transform(_state, _internal_transform);
GeomDrawCallbackData cbdata(this, gsg, force); GeomDrawCallbackData cbdata(this, gsg, force);
_draw_callback->do_callback(&cbdata); _draw_callback->do_callback(&cbdata);