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.
// Set the GSG to the initial state.
gsg->clear_before_callback();
gsg->set_state_and_transform(RenderState::make_empty(), TransformState::make_identity());
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
// Access: Public, Virtual

View File

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

View File

@ -1537,6 +1537,20 @@ prepare_display_region(DisplayRegionPipelineReader *dr,
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
// 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
// buffers are unbound, or the nVidia drivers may crash.
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;
}
unbind_buffers();
GeomContext *gc = ((Geom *)geom_reader->get_object())->prepare_now(get_prepared_objects(), this);
nassertr(gc != (GeomContext *)NULL, false);
@ -2303,6 +2302,35 @@ update_standard_vertex_arrays(bool force) {
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
// Access: Protected

View File

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

View File

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

View File

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