diff --git a/panda/src/cull/cullBinBackToFront.cxx b/panda/src/cull/cullBinBackToFront.cxx index 25a6ff70f5..0992571840 100644 --- a/panda/src/cull/cullBinBackToFront.cxx +++ b/panda/src/cull/cullBinBackToFront.cxx @@ -101,12 +101,12 @@ finish_cull(SceneSetup *, Thread *current_thread) { // order. //////////////////////////////////////////////////////////////////// void CullBinBackToFront:: -draw(Thread *current_thread) { +draw(bool force, Thread *current_thread) { PStatTimer timer(_draw_this_pcollector, current_thread); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; - CullHandler::draw(object, _gsg, current_thread); + CullHandler::draw(object, _gsg, force, current_thread); } } diff --git a/panda/src/cull/cullBinBackToFront.h b/panda/src/cull/cullBinBackToFront.h index 006dfdf721..2b22a755cf 100644 --- a/panda/src/cull/cullBinBackToFront.h +++ b/panda/src/cull/cullBinBackToFront.h @@ -49,7 +49,7 @@ public: virtual void add_object(CullableObject *object, Thread *current_thread); virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread); - virtual void draw(Thread *current_thread); + virtual void draw(bool force, Thread *current_thread); private: class ObjectData { diff --git a/panda/src/cull/cullBinFixed.cxx b/panda/src/cull/cullBinFixed.cxx index c315a3d20c..7c1f260c21 100644 --- a/panda/src/cull/cullBinFixed.cxx +++ b/panda/src/cull/cullBinFixed.cxx @@ -87,12 +87,12 @@ finish_cull(SceneSetup *, Thread *current_thread) { // order. //////////////////////////////////////////////////////////////////// void CullBinFixed:: -draw(Thread *current_thread) { +draw(bool force, Thread *current_thread) { PStatTimer timer(_draw_this_pcollector, current_thread); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; - CullHandler::draw(object, _gsg, current_thread); + CullHandler::draw(object, _gsg, force, current_thread); } } diff --git a/panda/src/cull/cullBinFixed.h b/panda/src/cull/cullBinFixed.h index 6af207fa57..4b0e2f6828 100644 --- a/panda/src/cull/cullBinFixed.h +++ b/panda/src/cull/cullBinFixed.h @@ -51,7 +51,7 @@ public: virtual void add_object(CullableObject *object, Thread *current_thread); virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread); - virtual void draw(Thread *current_thread); + virtual void draw(bool force, Thread *current_thread); private: class ObjectData { diff --git a/panda/src/cull/cullBinFrontToBack.cxx b/panda/src/cull/cullBinFrontToBack.cxx index d8a09e515c..a4313ede52 100644 --- a/panda/src/cull/cullBinFrontToBack.cxx +++ b/panda/src/cull/cullBinFrontToBack.cxx @@ -101,12 +101,12 @@ finish_cull(SceneSetup *, Thread *current_thread) { // order. //////////////////////////////////////////////////////////////////// void CullBinFrontToBack:: -draw(Thread *current_thread) { +draw(bool force, Thread *current_thread) { PStatTimer timer(_draw_this_pcollector, current_thread); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; - CullHandler::draw(object, _gsg, current_thread); + CullHandler::draw(object, _gsg, force, current_thread); } } diff --git a/panda/src/cull/cullBinFrontToBack.h b/panda/src/cull/cullBinFrontToBack.h index 52953a4551..68d8cf2728 100644 --- a/panda/src/cull/cullBinFrontToBack.h +++ b/panda/src/cull/cullBinFrontToBack.h @@ -49,7 +49,7 @@ public: virtual void add_object(CullableObject *object, Thread *current_thread); virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread); - virtual void draw(Thread *current_thread); + virtual void draw(bool force, Thread *current_thread); private: class ObjectData { diff --git a/panda/src/cull/cullBinStateSorted.cxx b/panda/src/cull/cullBinStateSorted.cxx index 353afa6953..c19ea2cac6 100644 --- a/panda/src/cull/cullBinStateSorted.cxx +++ b/panda/src/cull/cullBinStateSorted.cxx @@ -86,12 +86,12 @@ finish_cull(SceneSetup *, Thread *current_thread) { // order. //////////////////////////////////////////////////////////////////// void CullBinStateSorted:: -draw(Thread *current_thread) { +draw(bool force, Thread *current_thread) { PStatTimer timer(_draw_this_pcollector, current_thread); Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; - CullHandler::draw(object, _gsg, current_thread); + CullHandler::draw(object, _gsg, force, current_thread); } } diff --git a/panda/src/cull/cullBinStateSorted.h b/panda/src/cull/cullBinStateSorted.h index 680547906a..a353fefbea 100644 --- a/panda/src/cull/cullBinStateSorted.h +++ b/panda/src/cull/cullBinStateSorted.h @@ -53,7 +53,7 @@ public: virtual void add_object(CullableObject *object, Thread *current_thread); virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread); - virtual void draw(Thread *current_thread); + virtual void draw(bool force, Thread *current_thread); private: class ObjectData { diff --git a/panda/src/cull/cullBinUnsorted.cxx b/panda/src/cull/cullBinUnsorted.cxx index 75add46a42..6f1ed73e8a 100644 --- a/panda/src/cull/cullBinUnsorted.cxx +++ b/panda/src/cull/cullBinUnsorted.cxx @@ -67,12 +67,12 @@ add_object(CullableObject *object, Thread *current_thread) { // order. //////////////////////////////////////////////////////////////////// void CullBinUnsorted:: -draw(Thread *current_thread) { +draw(bool force, Thread *current_thread) { PStatTimer timer(_draw_this_pcollector, current_thread); Objects::iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi); - CullHandler::draw(object, _gsg, current_thread); + CullHandler::draw(object, _gsg, force, current_thread); } } diff --git a/panda/src/cull/cullBinUnsorted.h b/panda/src/cull/cullBinUnsorted.h index a339134c7a..5e67a62c02 100644 --- a/panda/src/cull/cullBinUnsorted.h +++ b/panda/src/cull/cullBinUnsorted.h @@ -43,7 +43,7 @@ public: const PStatCollector &draw_region_pcollector); virtual void add_object(CullableObject *object, Thread *current_thread); - virtual void draw(Thread *current_thread); + virtual void draw(bool force, Thread *current_thread); private: typedef pvector Objects; diff --git a/panda/src/cull/drawCullHandler.cxx b/panda/src/cull/drawCullHandler.cxx index 3a3e621b42..3fbe6b5b0e 100644 --- a/panda/src/cull/drawCullHandler.cxx +++ b/panda/src/cull/drawCullHandler.cxx @@ -40,10 +40,8 @@ record_object(CullableObject *object, const CullTraverser *traverser) { Thread *current_thread = traverser->get_current_thread(); if (object->munge_geom(_gsg, _gsg->get_geom_munger(object->_state, current_thread), traverser, force)) { - if (force || object->request_resident()) { - // Now we can immediately draw the object. - draw(object, _gsg, current_thread); - } + // Now we can immediately draw the object. + draw(object, _gsg, force, current_thread); } // Dispense with the object. diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index eb168032a1..642bea5ff8 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -1312,7 +1312,8 @@ finish_decal() { bool GraphicsStateGuardian:: begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, - const GeomVertexDataPipelineReader *data_reader) { + const GeomVertexDataPipelineReader *data_reader, + bool) { _munger = munger; _data_reader = data_reader; return _data_reader->has_vertex(); @@ -1323,8 +1324,9 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, // Access: Public, Virtual // Description: Draws a series of disconnected triangles. //////////////////////////////////////////////////////////////////// -void GraphicsStateGuardian:: -draw_triangles(const GeomPrimitivePipelineReader *) { +bool GraphicsStateGuardian:: +draw_triangles(const GeomPrimitivePipelineReader *, bool) { + return false; } //////////////////////////////////////////////////////////////////// @@ -1332,8 +1334,9 @@ draw_triangles(const GeomPrimitivePipelineReader *) { // Access: Public, Virtual // Description: Draws a series of triangle strips. //////////////////////////////////////////////////////////////////// -void GraphicsStateGuardian:: -draw_tristrips(const GeomPrimitivePipelineReader *) { +bool GraphicsStateGuardian:: +draw_tristrips(const GeomPrimitivePipelineReader *, bool) { + return false; } //////////////////////////////////////////////////////////////////// @@ -1341,8 +1344,9 @@ draw_tristrips(const GeomPrimitivePipelineReader *) { // Access: Public, Virtual // Description: Draws a series of triangle fans. //////////////////////////////////////////////////////////////////// -void GraphicsStateGuardian:: -draw_trifans(const GeomPrimitivePipelineReader *) { +bool GraphicsStateGuardian:: +draw_trifans(const GeomPrimitivePipelineReader *, bool) { + return false; } //////////////////////////////////////////////////////////////////// @@ -1350,8 +1354,9 @@ draw_trifans(const GeomPrimitivePipelineReader *) { // Access: Public, Virtual // Description: Draws a series of disconnected line segments. //////////////////////////////////////////////////////////////////// -void GraphicsStateGuardian:: -draw_lines(const GeomPrimitivePipelineReader *) { +bool GraphicsStateGuardian:: +draw_lines(const GeomPrimitivePipelineReader *, bool) { + return false; } //////////////////////////////////////////////////////////////////// @@ -1359,8 +1364,9 @@ draw_lines(const GeomPrimitivePipelineReader *) { // Access: Public, Virtual // Description: Draws a series of line strips. //////////////////////////////////////////////////////////////////// -void GraphicsStateGuardian:: -draw_linestrips(const GeomPrimitivePipelineReader *) { +bool GraphicsStateGuardian:: +draw_linestrips(const GeomPrimitivePipelineReader *, bool) { + return false; } //////////////////////////////////////////////////////////////////// @@ -1368,8 +1374,9 @@ draw_linestrips(const GeomPrimitivePipelineReader *) { // Access: Public, Virtual // Description: Draws a series of disconnected points. //////////////////////////////////////////////////////////////////// -void GraphicsStateGuardian:: -draw_points(const GeomPrimitivePipelineReader *) { +bool GraphicsStateGuardian:: +draw_points(const GeomPrimitivePipelineReader *, bool) { + return false; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 3cfba8c299..ee56dbd60b 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -215,13 +215,20 @@ public: virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, - const GeomVertexDataPipelineReader *data_reader); - virtual void draw_triangles(const GeomPrimitivePipelineReader *reader); - virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader); - virtual void draw_trifans(const GeomPrimitivePipelineReader *reader); - virtual void draw_lines(const GeomPrimitivePipelineReader *reader); - virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader); - virtual void draw_points(const GeomPrimitivePipelineReader *reader); + const GeomVertexDataPipelineReader *data_reader, + bool force); + virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_points(const GeomPrimitivePipelineReader *reader, + bool force); virtual void end_draw_primitives(); INLINE bool reset_if_new(); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 0c185fd362..9fdcd0ddf3 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -797,9 +797,10 @@ end_frame(Thread *current_thread) { bool DXGraphicsStateGuardian8:: begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, - const GeomVertexDataPipelineReader *data_reader) { + const GeomVertexDataPipelineReader *data_reader, + bool force) { if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, - data_reader)) { + data_reader, force)) { return false; } nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false); @@ -903,8 +904,8 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, // Access: Public, Virtual // Description: Draws a series of disconnected triangles. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian8:: -draw_triangles(const GeomPrimitivePipelineReader *reader) { +bool DXGraphicsStateGuardian8:: +draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector); _vertices_tri_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_tri_pcollector.add_level(1); @@ -915,7 +916,7 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { if (_active_vbuffer != NULL) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertv(ibc != (IndexBufferContext *)NULL); + nassertr(ibc != (IndexBufferContext *)NULL, false); apply_index_buffer(ibc, reader); _d3d_device->DrawIndexedPrimitive @@ -925,14 +926,20 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { } else { // Indexed, client arrays. + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_indexed_primitive_up (D3DPT_TRIANGLELIST, min_vertex, max_vertex, reader->get_num_primitives(), - reader->get_read_pointer(true), - index_type, - _data_reader->get_array_reader(0)->get_read_pointer(true), + index_pointer, index_type, vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } else { @@ -945,14 +952,18 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { } else { // Nonindexed, client arrays. - + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(), reader->get_first_vertex(), reader->get_num_vertices(), - _data_reader->get_array_reader(0)->get_read_pointer(true), + vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } + return true; } //////////////////////////////////////////////////////////////////// @@ -960,8 +971,8 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of triangle strips. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian8:: -draw_tristrips(const GeomPrimitivePipelineReader *reader) { +bool DXGraphicsStateGuardian8:: +draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector); if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) { // One long triangle strip, connected by the degenerate vertices @@ -975,7 +986,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { if (_active_vbuffer != NULL) { // Indexed, vbuffers, one line triangle strip. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertv(ibc != (IndexBufferContext *)NULL); + nassertr(ibc != (IndexBufferContext *)NULL, false); apply_index_buffer(ibc, reader); _d3d_device->DrawIndexedPrimitive @@ -985,13 +996,20 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { } else { // Indexed, client arrays, one long triangle strip. + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_indexed_primitive_up (D3DPT_TRIANGLESTRIP, min_vertex, max_vertex, reader->get_num_vertices() - 2, - reader->get_read_pointer(true), index_type, - _data_reader->get_array_reader(0)->get_read_pointer(true), + index_pointer, index_type, vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } else { @@ -1004,11 +1022,15 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { } else { // Indexed, client arrays, one long triangle strip. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_primitive_up(D3DPT_TRIANGLESTRIP, reader->get_num_vertices() - 2, reader->get_first_vertex(), reader->get_num_vertices(), - _data_reader->get_array_reader(0)->get_read_pointer(true), + vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } @@ -1026,13 +1048,13 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { GeomVertexReader mins(reader->get_mins(), 0); GeomVertexReader maxs(reader->get_maxs(), 0); - nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() && - reader->get_maxs()->get_num_rows() == (int)ends.size()); + nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() && + reader->get_maxs()->get_num_rows() == (int)ends.size(), false); if (_active_vbuffer != NULL) { // Indexed, vbuffers, individual triangle strips. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertv(ibc != (IndexBufferContext *)NULL); + nassertr(ibc != (IndexBufferContext *)NULL, false); apply_index_buffer(ibc, reader); unsigned int start = 0; @@ -1050,10 +1072,16 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { } else { // Indexed, client arrays, individual triangle strips. - const unsigned char *array_data = _data_reader->get_array_reader(0)->get_read_pointer(true); int stride = _data_reader->get_format()->get_array(0)->get_stride(); - const unsigned char *vertices = reader->get_read_pointer(true); + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } unsigned int start = 0; for (size_t i = 0; i < ends.size(); i++) { @@ -1064,8 +1092,8 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { (D3DPT_TRIANGLESTRIP, min, max, ends[i] - start - 2, - vertices + start * index_stride, index_type, - array_data, stride); + index_pointer + start * index_stride, index_type, + vertex_pointer, stride); start = ends[i] + 2; } @@ -1087,7 +1115,10 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { } else { // Nonindexed, client arrays, individual triangle strips. - const unsigned char *array_data = _data_reader->get_array_reader(0)->get_read_pointer(true); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } int stride = _data_reader->get_format()->get_array(0)->get_stride(); unsigned int start = 0; @@ -1096,13 +1127,14 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { draw_primitive_up(D3DPT_TRIANGLESTRIP, ends[i] - start - 2, first_vertex + start, ends[i] - start, - array_data, stride); + vertex_pointer, stride); start = ends[i] + 2; } } } } + return true; } //////////////////////////////////////////////////////////////////// @@ -1110,8 +1142,8 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of triangle fans. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian8:: -draw_trifans(const GeomPrimitivePipelineReader *reader) { +bool DXGraphicsStateGuardian8:: +draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector); CPTA_int ends = reader->get_ends(); _primitive_batches_trifan_pcollector.add_level(ends.size()); @@ -1126,13 +1158,13 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { GeomVertexReader mins(reader->get_mins(), 0); GeomVertexReader maxs(reader->get_maxs(), 0); - nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() && - reader->get_maxs()->get_num_rows() == (int)ends.size()); + nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() && + reader->get_maxs()->get_num_rows() == (int)ends.size(), false); if (_active_vbuffer != NULL) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertv(ibc != (IndexBufferContext *)NULL); + nassertr(ibc != (IndexBufferContext *)NULL, false); apply_index_buffer(ibc, reader); unsigned int start = 0; @@ -1150,10 +1182,16 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { } else { // Indexed, client arrays. - const unsigned char *array_data = _data_reader->get_array_reader(0)->get_read_pointer(true); int stride = _data_reader->get_format()->get_array(0)->get_stride(); - const unsigned char *vertices = reader->get_read_pointer(true); + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } unsigned int start = 0; for (size_t i = 0; i < ends.size(); i++) { @@ -1164,8 +1202,8 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { (D3DPT_TRIANGLEFAN, min, max, ends[i] - start - 2, - vertices + start * index_stride, index_type, - array_data, stride); + index_pointer + start * index_stride, index_type, + vertex_pointer, stride); start = ends[i]; } @@ -1187,7 +1225,10 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { } else { // Nonindexed, client arrays. - const unsigned char *array_data = _data_reader->get_array_reader(0)->get_read_pointer(true); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } int stride = _data_reader->get_format()->get_array(0)->get_stride(); unsigned int start = 0; @@ -1197,11 +1238,12 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { ends[i] - start - 2, first_vertex, ends[i] - start, - array_data, stride); + vertex_pointer, stride); start = ends[i]; } } } + return true; } //////////////////////////////////////////////////////////////////// @@ -1209,8 +1251,8 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of disconnected line segments. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian8:: -draw_lines(const GeomPrimitivePipelineReader *reader) { +bool DXGraphicsStateGuardian8:: +draw_lines(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector); _vertices_other_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_other_pcollector.add_level(1); @@ -1222,7 +1264,7 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { if (_active_vbuffer != NULL) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertv(ibc != (IndexBufferContext *)NULL); + nassertr(ibc != (IndexBufferContext *)NULL, false); apply_index_buffer(ibc, reader); _d3d_device->DrawIndexedPrimitive @@ -1232,15 +1274,21 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { } else { // Indexed, client arrays. + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_indexed_primitive_up (D3DPT_LINELIST, min_vertex, max_vertex, reader->get_num_primitives(), - reader->get_read_pointer(true), - index_type, - _data_reader->get_array_reader(0)->get_read_pointer(true), + index_pointer, index_type, vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } else { @@ -1253,13 +1301,18 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { } else { // Nonindexed, client arrays. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(), reader->get_first_vertex(), reader->get_num_vertices(), - _data_reader->get_array_reader(0)->get_read_pointer(true), + vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } + return true; } //////////////////////////////////////////////////////////////////// @@ -1267,9 +1320,9 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of line strips. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian8:: -draw_linestrips(const GeomPrimitivePipelineReader *reader) { - PStatTimer timer(_draw_primitive_pcollector); +bool DXGraphicsStateGuardian8:: +draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) { + return false; } //////////////////////////////////////////////////////////////////// @@ -1277,15 +1330,15 @@ draw_linestrips(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of disconnected points. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian8:: -draw_points(const GeomPrimitivePipelineReader *reader) { +bool DXGraphicsStateGuardian8:: +draw_points(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector); _vertices_other_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_other_pcollector.add_level(1); // The munger should have protected us from indexed points--DirectX // doesn't support them. - nassertv(!reader->is_indexed()); + nassertr(!reader->is_indexed(), false); if (_active_vbuffer != NULL) { // Nonindexed, vbuffers. @@ -1296,12 +1349,17 @@ draw_points(const GeomPrimitivePipelineReader *reader) { } else { // Nonindexed, client arrays. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(), reader->get_first_vertex(), reader->get_num_vertices(), - _data_reader->get_array_reader(0)->get_read_pointer(true), + vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } + return true; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 091531e8cf..58a2ec07f9 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -84,13 +84,20 @@ public: virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, - const GeomVertexDataPipelineReader *data_reader); - virtual void draw_triangles(const GeomPrimitivePipelineReader *reader); - virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader); - virtual void draw_trifans(const GeomPrimitivePipelineReader *reader); - virtual void draw_lines(const GeomPrimitivePipelineReader *reader); - virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader); - virtual void draw_points(const GeomPrimitivePipelineReader *reader); + const GeomVertexDataPipelineReader *data_reader, + bool force); + virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_points(const GeomPrimitivePipelineReader *reader, + bool force); virtual void end_draw_primitives(); virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index adc10f0511..76d42ed1cf 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -1227,9 +1227,10 @@ DBG_S dxgsg9_cat.debug ( ) << "@@@@@@@@@@ end_frame \n"; DBG_E bool DXGraphicsStateGuardian9:: begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, - const GeomVertexDataPipelineReader *data_reader) { + const GeomVertexDataPipelineReader *data_reader, + bool force) { if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, - data_reader)) { + data_reader, force)) { return false; } nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false); @@ -1458,8 +1459,8 @@ vertex_element_array -> vertex_element_type_array; // Access: Public, Virtual // Description: Draws a series of disconnected triangles. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian9:: -draw_triangles(const GeomPrimitivePipelineReader *reader) { +bool DXGraphicsStateGuardian9:: +draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector); // DBG_SH5 dxgsg9_cat.debug ( ) << "draw_triangles 1\n"; DBG_E @@ -1473,7 +1474,7 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { if (_active_vbuffer != NULL) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertv(ibc != (IndexBufferContext *)NULL); + nassertr(ibc != (IndexBufferContext *)NULL, false); apply_index_buffer(ibc, reader); //DBG_SH2 dxgsg9_cat.debug ( ) << "DrawIndexedPrimitive \n"; DBG_E @@ -1488,14 +1489,21 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { //DBG_SH2 dxgsg9_cat.debug ( ) << "draw_indexed_primitive_up \n"; DBG_E + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } + draw_indexed_primitive_up (D3DPT_TRIANGLELIST, min_vertex, max_vertex, reader->get_num_primitives(), - reader->get_read_pointer(true), - index_type, - _data_reader->get_array_reader(0)->get_read_pointer(true), + index_pointer, index_type, vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } else { @@ -1513,16 +1521,20 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { // Nonindexed, client arrays. //DBG_SH2 dxgsg9_cat.debug ( ) << "draw_primitive_up \n"; DBG_E + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(), reader->get_first_vertex(), - reader->get_num_vertices(), - _data_reader->get_array_reader(0)->get_read_pointer(true), + reader->get_num_vertices(), vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } // DBG_SH5 dxgsg9_cat.debug ( ) << "end draw_triangles 1\n"; DBG_E + return true; } //////////////////////////////////////////////////////////////////// @@ -1530,8 +1542,8 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of triangle strips. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian9:: -draw_tristrips(const GeomPrimitivePipelineReader *reader) { +bool DXGraphicsStateGuardian9:: +draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector); DBG_SH5 dxgsg9_cat.debug ( ) << "draw_tristrips\n"; DBG_E @@ -1548,7 +1560,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { if (_active_vbuffer != NULL) { // Indexed, vbuffers, one line triangle strip. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertv(ibc != (IndexBufferContext *)NULL); + nassertr(ibc != (IndexBufferContext *)NULL, false); apply_index_buffer(ibc, reader); //dxgsg9_cat.error ( ) << "DrawIndexedPrimitive D3DPT_TRIANGLESTRIP VERTICES: " << reader->get_num_vertices ( ) << "\n"; @@ -1563,13 +1575,21 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { //dxgsg9_cat.error ( ) << "draw_indexed_primitive_up D3DPT_TRIANGLESTRIP VERTICES: " << reader->get_num_vertices ( ) << "\n"; // Indexed, client arrays, one long triangle strip. + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } + draw_indexed_primitive_up (D3DPT_TRIANGLESTRIP, min_vertex, max_vertex, reader->get_num_vertices() - 2, - reader->get_read_pointer(true), index_type, - _data_reader->get_array_reader(0)->get_read_pointer(true), + index_pointer, index_type, vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } else { @@ -1585,11 +1605,14 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { } else { // Indexed, client arrays, one long triangle strip. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_primitive_up(D3DPT_TRIANGLESTRIP, reader->get_num_vertices() - 2, reader->get_first_vertex(), - reader->get_num_vertices(), - _data_reader->get_array_reader(0)->get_read_pointer(true), + reader->get_num_vertices(), vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } @@ -1607,13 +1630,13 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { GeomVertexReader mins(reader->get_mins(), 0); GeomVertexReader maxs(reader->get_maxs(), 0); - nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() && - reader->get_maxs()->get_num_rows() == (int)ends.size()); + nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() && + reader->get_maxs()->get_num_rows() == (int)ends.size(), false); if (_active_vbuffer != NULL) { // Indexed, vbuffers, individual triangle strips. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertv(ibc != (IndexBufferContext *)NULL); + nassertr(ibc != (IndexBufferContext *)NULL, false); apply_index_buffer(ibc, reader); unsigned int start = 0; @@ -1632,10 +1655,16 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { } else { // Indexed, client arrays, individual triangle strips. - const unsigned char *array_data = _data_reader->get_array_reader(0)->get_read_pointer(true); int stride = _data_reader->get_format()->get_array(0)->get_stride(); - const unsigned char *vertices = reader->get_read_pointer(true); + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } unsigned int start = 0; for (size_t i = 0; i < ends.size(); i++) { @@ -1646,8 +1675,8 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { (D3DPT_TRIANGLESTRIP, min, max, ends[i] - start - 2, - vertices + start * index_stride, index_type, - array_data, stride); + index_pointer + start * index_stride, index_type, + vertex_pointer, stride); start = ends[i] + 2; } @@ -1669,7 +1698,10 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { } else { // Nonindexed, client arrays, individual triangle strips. - const unsigned char *array_data = _data_reader->get_array_reader(0)->get_read_pointer(true); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } int stride = _data_reader->get_format()->get_array(0)->get_stride(); unsigned int start = 0; @@ -1678,13 +1710,14 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { draw_primitive_up(D3DPT_TRIANGLESTRIP, ends[i] - start - 2, first_vertex + start, ends[i] - start, - array_data, stride); + vertex_pointer, stride); start = ends[i] + 2; } } } } + return true; } //////////////////////////////////////////////////////////////////// @@ -1692,8 +1725,8 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of triangle fans. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian9:: -draw_trifans(const GeomPrimitivePipelineReader *reader) { +bool DXGraphicsStateGuardian9:: +draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector); DBG_SH5 dxgsg9_cat.debug ( ) << "draw_trifans\n"; DBG_E @@ -1711,13 +1744,13 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { GeomVertexReader mins(reader->get_mins(), 0); GeomVertexReader maxs(reader->get_maxs(), 0); - nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() && - reader->get_maxs()->get_num_rows() == (int)ends.size()); + nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() && + reader->get_maxs()->get_num_rows() == (int)ends.size(), false); if (_active_vbuffer != NULL) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertv(ibc != (IndexBufferContext *)NULL); + nassertr(ibc != (IndexBufferContext *)NULL, false); apply_index_buffer(ibc, reader); unsigned int start = 0; @@ -1735,10 +1768,16 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { } else { // Indexed, client arrays. - const unsigned char *array_data = _data_reader->get_array_reader(0)->get_read_pointer(true); int stride = _data_reader->get_format()->get_array(0)->get_stride(); - const unsigned char *vertices = reader->get_read_pointer(true); + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } unsigned int start = 0; for (size_t i = 0; i < ends.size(); i++) { @@ -1749,8 +1788,8 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { (D3DPT_TRIANGLEFAN, min, max, ends[i] - start - 2, - vertices + start * index_stride, index_type, - array_data, stride); + index_pointer + start * index_stride, index_type, + vertex_pointer, stride); start = ends[i]; } @@ -1772,7 +1811,10 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { } else { // Nonindexed, client arrays. - const unsigned char *array_data = _data_reader->get_array_reader(0)->get_read_pointer(true); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } int stride = _data_reader->get_format()->get_array(0)->get_stride(); unsigned int start = 0; @@ -1782,11 +1824,12 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { ends[i] - start - 2, first_vertex, ends[i] - start, - array_data, stride); + vertex_pointer, stride); start = ends[i]; } } } + return true; } //////////////////////////////////////////////////////////////////// @@ -1794,8 +1837,8 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of disconnected line segments. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian9:: -draw_lines(const GeomPrimitivePipelineReader *reader) { +bool DXGraphicsStateGuardian9:: +draw_lines(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector); _vertices_other_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_other_pcollector.add_level(1); @@ -1807,7 +1850,7 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { if (_active_vbuffer != NULL) { // Indexed, vbuffers. IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertv(ibc != (IndexBufferContext *)NULL); + nassertr(ibc != (IndexBufferContext *)NULL, false); apply_index_buffer(ibc, reader); _d3d_device->DrawIndexedPrimitive @@ -1818,15 +1861,21 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { } else { // Indexed, client arrays. + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_indexed_primitive_up (D3DPT_LINELIST, min_vertex, max_vertex, reader->get_num_primitives(), - reader->get_read_pointer(true), - index_type, - _data_reader->get_array_reader(0)->get_read_pointer(true), + index_pointer, index_type, vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } else { @@ -1839,13 +1888,17 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { } else { // Nonindexed, client arrays. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(), reader->get_first_vertex(), - reader->get_num_vertices(), - _data_reader->get_array_reader(0)->get_read_pointer(true), + reader->get_num_vertices(), vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } } + return true; } //////////////////////////////////////////////////////////////////// @@ -1853,9 +1906,9 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of line strips. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian9:: -draw_linestrips(const GeomPrimitivePipelineReader *reader) { - PStatTimer timer(_draw_primitive_pcollector); +bool DXGraphicsStateGuardian9:: +draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) { + return false; } //////////////////////////////////////////////////////////////////// @@ -1863,15 +1916,15 @@ draw_linestrips(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of disconnected points. //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian9:: -draw_points(const GeomPrimitivePipelineReader *reader) { +bool DXGraphicsStateGuardian9:: +draw_points(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector); _vertices_other_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_other_pcollector.add_level(1); // The munger should have protected us from indexed points--DirectX // doesn't support them. - nassertv(!reader->is_indexed()); + nassertr(!reader->is_indexed(), false); if (_active_vbuffer != NULL) { // Nonindexed, vbuffers. @@ -1882,12 +1935,16 @@ draw_points(const GeomPrimitivePipelineReader *reader) { } else { // Nonindexed, client arrays. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(), reader->get_first_vertex(), - reader->get_num_vertices(), - _data_reader->get_array_reader(0)->get_read_pointer(true), + reader->get_num_vertices(), vertex_pointer, _data_reader->get_format()->get_array(0)->get_stride()); } + return true; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 9a750bdb22..afdc3abdad 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -124,13 +124,20 @@ public: virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, - const GeomVertexDataPipelineReader *data_reader); - virtual void draw_triangles(const GeomPrimitivePipelineReader *reader); - virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader); - virtual void draw_trifans(const GeomPrimitivePipelineReader *reader); - virtual void draw_lines(const GeomPrimitivePipelineReader *reader); - virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader); - virtual void draw_points(const GeomPrimitivePipelineReader *reader); + const GeomVertexDataPipelineReader *data_reader, + bool force); + virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_points(const GeomPrimitivePipelineReader *reader, + bool force); virtual void end_draw_primitives(); virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 3b210bb762..24ae903d42 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1468,14 +1468,15 @@ end_frame(Thread *current_thread) { bool CLP(GraphicsStateGuardian):: begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, - const GeomVertexDataPipelineReader *data_reader) { + const GeomVertexDataPipelineReader *data_reader, + bool force) { #ifndef NDEBUG if (GLCAT.is_spam()) { GLCAT.spam() << "begin_draw_primitives: " << *(data_reader->get_object()) << "\n"; } #endif // NDEBUG - if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, data_reader)) { + if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, data_reader, force)) { return false; } nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false); @@ -1687,18 +1688,26 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, #endif if (_vertex_array_shader_context==0) { if (_current_shader_context==0) { - update_standard_vertex_arrays(); + if (!update_standard_vertex_arrays(force)) { + return false; + } } else { disable_standard_vertex_arrays(); - _current_shader_context->update_shader_vertex_arrays(NULL,this); + if (!_current_shader_context->update_shader_vertex_arrays(NULL, this, force)) { + return false; + } } } else { if (_current_shader_context==0) { _vertex_array_shader_context->disable_shader_vertex_arrays(this); - update_standard_vertex_arrays(); + if (!update_standard_vertex_arrays(force)) { + return false; + } } else { - _current_shader_context-> - update_shader_vertex_arrays(_vertex_array_shader_context,this); + if (!_current_shader_context-> + update_shader_vertex_arrays(_vertex_array_shader_context, this, force)) { + return false; + } } } _vertex_array_shader_expansion = _current_shader_expansion; @@ -1720,8 +1729,8 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, // is about to be used - glShaderContexts are responsible // for setting up their own vertex arrays. //////////////////////////////////////////////////////////////////// -void CLP(GraphicsStateGuardian):: -update_standard_vertex_arrays() { +bool CLP(GraphicsStateGuardian):: +update_standard_vertex_arrays(bool force) { const GeomVertexAnimationSpec &animation = _data_reader->get_format()->get_animation(); bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware); @@ -1804,6 +1813,7 @@ update_standard_vertex_arrays() { { // We may use vertex arrays or buffers to render primitives. const GeomVertexArrayDataHandle *array_reader; + const unsigned char *client_pointer; int num_values; Geom::NumericType numeric_type; int start; @@ -1811,7 +1821,9 @@ update_standard_vertex_arrays() { if (_data_reader->get_normal_info(array_reader, numeric_type, start, stride)) { - const unsigned char *client_pointer = setup_array_data(array_reader); + if (!setup_array_data(client_pointer, array_reader, force)) { + return false; + } GLP(NormalPointer)(get_numeric_type(numeric_type), stride, client_pointer + start); GLP(EnableClientState)(GL_NORMAL_ARRAY); @@ -1822,7 +1834,9 @@ update_standard_vertex_arrays() { if (_data_reader->get_color_info(array_reader, num_values, numeric_type, start, stride) && numeric_type != Geom::NT_packed_dabc) { - const unsigned char *client_pointer = setup_array_data(array_reader); + if (!setup_array_data(client_pointer, array_reader, force)) { + return false; + } GLP(ColorPointer)(num_values, get_numeric_type(numeric_type), stride, client_pointer + start); GLP(EnableClientState)(GL_COLOR_ARRAY); @@ -1855,7 +1869,9 @@ update_standard_vertex_arrays() { if (_data_reader->get_array_info(name, array_reader, num_values, numeric_type, start, stride)) { // The vertex data does have texcoords for this stage. - const unsigned char *client_pointer = setup_array_data(array_reader); + if (!setup_array_data(client_pointer, array_reader, force)) { + return false; + } GLP(TexCoordPointer)(num_values, get_numeric_type(numeric_type), stride, client_pointer + start); GLP(EnableClientState)(GL_TEXTURE_COORD_ARRAY); @@ -1887,7 +1903,9 @@ update_standard_vertex_arrays() { if (_data_reader->get_array_info(InternalName::get_transform_weight(), array_reader, num_values, numeric_type, start, stride)) { - const unsigned char *client_pointer = setup_array_data(array_reader); + if (!setup_array_data(client_pointer, array_reader, force)) { + return false; + } _glWeightPointerARB(num_values, get_numeric_type(numeric_type), stride, client_pointer + start); GLP(EnableClientState)(GL_WEIGHT_ARRAY_ARB); @@ -1900,7 +1918,9 @@ update_standard_vertex_arrays() { if (_data_reader->get_array_info(InternalName::get_transform_index(), array_reader, num_values, numeric_type, start, stride)) { - const unsigned char *client_pointer = setup_array_data(array_reader); + if (!setup_array_data(client_pointer, array_reader, force)) { + return false; + } _glMatrixIndexPointerARB(num_values, get_numeric_type(numeric_type), stride, client_pointer + start); GLP(EnableClientState)(GL_MATRIX_INDEX_ARRAY_ARB); @@ -1921,12 +1941,15 @@ update_standard_vertex_arrays() { // anyway. if (_data_reader->get_vertex_info(array_reader, num_values, numeric_type, start, stride)) { - const unsigned char *client_pointer = setup_array_data(array_reader); + if (!setup_array_data(client_pointer, array_reader, force)) { + return false; + } GLP(VertexPointer)(num_values, get_numeric_type(numeric_type), stride, client_pointer + start); GLP(EnableClientState)(GL_VERTEX_ARRAY); } } + return true; } //////////////////////////////////////////////////////////////////// @@ -1974,8 +1997,8 @@ disable_standard_vertex_arrays() // Access: Public, Virtual // Description: Draws a series of disconnected triangles. //////////////////////////////////////////////////////////////////// -void CLP(GraphicsStateGuardian):: -draw_triangles(const GeomPrimitivePipelineReader *reader) { +bool CLP(GraphicsStateGuardian):: +draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG @@ -1996,7 +2019,10 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { _primitive_batches_tri_pcollector.add_level(1); if (reader->is_indexed()) { - const unsigned char *client_pointer = setup_primitive(reader); + const unsigned char *client_pointer; + if (!setup_primitive(client_pointer, reader, force)) { + return false; + } _glDrawRangeElements(GL_TRIANGLES, reader->get_min_vertex(), @@ -2012,6 +2038,7 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { } report_my_gl_errors(); + return true; } //////////////////////////////////////////////////////////////////// @@ -2019,8 +2046,8 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of triangle strips. //////////////////////////////////////////////////////////////////// -void CLP(GraphicsStateGuardian):: -draw_tristrips(const GeomPrimitivePipelineReader *reader) { +bool CLP(GraphicsStateGuardian):: +draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); report_my_gl_errors(); @@ -2045,7 +2072,10 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { _vertices_tristrip_pcollector.add_level(num_vertices); _primitive_batches_tristrip_pcollector.add_level(1); if (reader->is_indexed()) { - const unsigned char *client_pointer = setup_primitive(reader); + const unsigned char *client_pointer; + if (!setup_primitive(client_pointer, reader, force)) { + return false; + } _glDrawRangeElements(GL_TRIANGLE_STRIP, reader->get_min_vertex(), reader->get_max_vertex(), @@ -2065,12 +2095,15 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { _primitive_batches_tristrip_pcollector.add_level(ends.size()); if (reader->is_indexed()) { - const unsigned char *client_pointer = setup_primitive(reader); + const unsigned char *client_pointer; + if (!setup_primitive(client_pointer, reader, force)) { + return false; + } int index_stride = reader->get_index_stride(); GeomVertexReader mins(reader->get_mins(), 0); GeomVertexReader maxs(reader->get_maxs(), 0); - nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() && - reader->get_maxs()->get_num_rows() == (int)ends.size()); + nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() && + reader->get_maxs()->get_num_rows() == (int)ends.size(), false); unsigned int start = 0; for (size_t i = 0; i < ends.size(); i++) { @@ -2096,6 +2129,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { } report_my_gl_errors(); + return true; } //////////////////////////////////////////////////////////////////// @@ -2103,8 +2137,8 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of triangle fans. //////////////////////////////////////////////////////////////////// -void CLP(GraphicsStateGuardian):: -draw_trifans(const GeomPrimitivePipelineReader *reader) { +bool CLP(GraphicsStateGuardian):: +draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { @@ -2124,12 +2158,15 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { _primitive_batches_trifan_pcollector.add_level(ends.size()); if (reader->is_indexed()) { - const unsigned char *client_pointer = setup_primitive(reader); + const unsigned char *client_pointer; + if (!setup_primitive(client_pointer, reader, force)) { + return false; + } int index_stride = reader->get_index_stride(); GeomVertexReader mins(reader->get_mins(), 0); GeomVertexReader maxs(reader->get_maxs(), 0); - nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() && - reader->get_maxs()->get_num_rows() == (int)ends.size()); + nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() && + reader->get_maxs()->get_num_rows() == (int)ends.size(), false); unsigned int start = 0; for (size_t i = 0; i < ends.size(); i++) { @@ -2153,6 +2190,7 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { } report_my_gl_errors(); + return true; } //////////////////////////////////////////////////////////////////// @@ -2160,8 +2198,8 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of disconnected line segments. //////////////////////////////////////////////////////////////////// -void CLP(GraphicsStateGuardian):: -draw_lines(const GeomPrimitivePipelineReader *reader) { +bool CLP(GraphicsStateGuardian):: +draw_lines(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { @@ -2180,7 +2218,10 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { _primitive_batches_other_pcollector.add_level(1); if (reader->is_indexed()) { - const unsigned char *client_pointer = setup_primitive(reader); + const unsigned char *client_pointer; + if (!setup_primitive(client_pointer, reader, force)) { + return false; + } _glDrawRangeElements(GL_LINES, reader->get_min_vertex(), reader->get_max_vertex(), @@ -2195,6 +2236,7 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { } report_my_gl_errors(); + return true; } //////////////////////////////////////////////////////////////////// @@ -2202,15 +2244,9 @@ draw_lines(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of line strips. //////////////////////////////////////////////////////////////////// -void CLP(GraphicsStateGuardian):: -draw_linestrips(const GeomPrimitivePipelineReader *reader) { - PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); -#ifndef NDEBUG - if (GLCAT.is_spam()) { - GLCAT.spam() << "draw_linestrips: " << *(reader->get_object()) << "\n"; - } -#endif // NDEBUG - +bool CLP(GraphicsStateGuardian):: +draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) { + return false; } //////////////////////////////////////////////////////////////////// @@ -2218,8 +2254,8 @@ draw_linestrips(const GeomPrimitivePipelineReader *reader) { // Access: Public, Virtual // Description: Draws a series of disconnected points. //////////////////////////////////////////////////////////////////// -void CLP(GraphicsStateGuardian):: -draw_points(const GeomPrimitivePipelineReader *reader) { +bool CLP(GraphicsStateGuardian):: +draw_points(const GeomPrimitivePipelineReader *reader, bool force) { PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread()); #ifndef NDEBUG if (GLCAT.is_spam()) { @@ -2238,7 +2274,10 @@ draw_points(const GeomPrimitivePipelineReader *reader) { _primitive_batches_other_pcollector.add_level(1); if (reader->is_indexed()) { - const unsigned char *client_pointer = setup_primitive(reader); + const unsigned char *client_pointer; + if (!setup_primitive(client_pointer, reader, force)) { + return false; + } _glDrawRangeElements(GL_POINTS, reader->get_min_vertex(), reader->get_max_vertex(), @@ -2253,6 +2292,7 @@ draw_points(const GeomPrimitivePipelineReader *reader) { } report_my_gl_errors(); + return true; } //////////////////////////////////////////////////////////////////// @@ -2716,11 +2756,11 @@ prepare_vertex_buffer(GeomVertexArrayData *data) { // Description: Makes the data the currently available data for // rendering. //////////////////////////////////////////////////////////////////// -void CLP(GraphicsStateGuardian):: +bool CLP(GraphicsStateGuardian):: apply_vertex_buffer(VertexBufferContext *vbc, - const GeomVertexArrayDataHandle *reader) { - nassertv(_supports_buffers); - nassertv(reader->get_modified() != UpdateSeq::initial()); + const GeomVertexArrayDataHandle *reader, bool force) { + nassertr(_supports_buffers, false); + nassertr(reader->get_modified() != UpdateSeq::initial(), false); CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc); @@ -2743,14 +2783,17 @@ apply_vertex_buffer(VertexBufferContext *vbc, << " bytes into vertex buffer " << gvbc->_index << "\n"; } if (num_bytes != 0) { + const unsigned char *client_pointer = reader->get_read_pointer(force); + if (client_pointer == NULL) { + return false; + } + if (gvbc->changed_size(reader) || gvbc->changed_usage_hint(reader)) { - _glBufferData(GL_ARRAY_BUFFER, num_bytes, - reader->get_read_pointer(true), + _glBufferData(GL_ARRAY_BUFFER, num_bytes, client_pointer, get_usage(reader->get_usage_hint())); } else { - _glBufferSubData(GL_ARRAY_BUFFER, 0, num_bytes, - reader->get_read_pointer(true)); + _glBufferSubData(GL_ARRAY_BUFFER, 0, num_bytes, client_pointer); } _data_transferred_pcollector.add_level(num_bytes); } @@ -2759,6 +2802,7 @@ apply_vertex_buffer(VertexBufferContext *vbc, } report_my_gl_errors(); + return true; } //////////////////////////////////////////////////////////////////// @@ -2809,17 +2853,24 @@ release_vertex_buffer(VertexBufferContext *vbc) { // buffer object if it should be rendered from client // memory. // -// If the buffer object is bound, this function returns -// NULL (representing the start of the buffer object in -// server memory); if the buffer object is not bound, -// this function returns the pointer to the data array -// in client memory, that is, the data array passed in. +// If the buffer object is bound, this function sets +// client_pointer to NULL (representing the start of the +// buffer object in server memory); if the buffer object +// is not bound, this function sets client_pointer the +// pointer to the data array in client memory, that is, +// the data array passed in. +// +// If force is not true, the function may return false +// indicating the data is not currently available. //////////////////////////////////////////////////////////////////// -const unsigned char *CLP(GraphicsStateGuardian):: -setup_array_data(const GeomVertexArrayDataHandle *array_reader) { +bool CLP(GraphicsStateGuardian):: +setup_array_data(const unsigned char *&client_pointer, + const GeomVertexArrayDataHandle *array_reader, + bool force) { if (!_supports_buffers) { // No support for buffer objects; always render from client. - return array_reader->get_read_pointer(true); + client_pointer = array_reader->get_read_pointer(force); + return (client_pointer != NULL); } if (!vertex_buffers || _geom_display_list != 0 || array_reader->get_usage_hint() == Geom::UH_client) { @@ -2833,16 +2884,20 @@ setup_array_data(const GeomVertexArrayDataHandle *array_reader) { _glBindBuffer(GL_ARRAY_BUFFER, 0); _current_vbuffer_index = 0; } - return array_reader->get_read_pointer(true); + client_pointer = array_reader->get_read_pointer(force); + return (client_pointer != NULL); } // Prepare the buffer object and bind it. VertexBufferContext *vbc = ((GeomVertexArrayData *)array_reader->get_object())->prepare_now(get_prepared_objects(), this); - nassertr(vbc != (VertexBufferContext *)NULL, array_reader->get_read_pointer(true)); - apply_vertex_buffer(vbc, array_reader); + nassertr(vbc != (VertexBufferContext *)NULL, false); + if (!apply_vertex_buffer(vbc, array_reader, force)) { + return false; + } // NULL is the OpenGL convention for the first byte of the buffer object. - return NULL; + client_pointer = NULL; + return true; } //////////////////////////////////////////////////////////////////// @@ -2885,11 +2940,12 @@ prepare_index_buffer(GeomPrimitive *data) { // Description: Makes the data the currently available data for // rendering. //////////////////////////////////////////////////////////////////// -void CLP(GraphicsStateGuardian):: +bool CLP(GraphicsStateGuardian):: apply_index_buffer(IndexBufferContext *ibc, - const GeomPrimitivePipelineReader *reader) { - nassertv(_supports_buffers); - nassertv(reader->get_modified() != UpdateSeq::initial()); + const GeomPrimitivePipelineReader *reader, + bool force) { + nassertr(_supports_buffers, false); + nassertr(reader->get_modified() != UpdateSeq::initial(), false); CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc); @@ -2913,14 +2969,18 @@ apply_index_buffer(IndexBufferContext *ibc, << " bytes into index buffer " << gibc->_index << "\n"; } if (num_bytes != 0) { + const unsigned char *client_pointer = reader->get_read_pointer(force); + if (client_pointer == NULL) { + return false; + } + if (gibc->changed_size(reader) || gibc->changed_usage_hint(reader)) { - _glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_bytes, - reader->get_read_pointer(true), + _glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_bytes, client_pointer, get_usage(reader->get_usage_hint())); } else { _glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, num_bytes, - reader->get_read_pointer(true)); + client_pointer); } _data_transferred_pcollector.add_level(num_bytes); } @@ -2928,6 +2988,7 @@ apply_index_buffer(IndexBufferContext *ibc, } report_my_gl_errors(); + return true; } //////////////////////////////////////////////////////////////////// @@ -2978,17 +3039,24 @@ release_index_buffer(IndexBufferContext *ibc) { // to unbind a buffer object if it should be rendered // from client memory. // -// If the buffer object is bound, this function returns -// NULL (reprsenting the start of the buffer object in -// server memory); if the buffer object is not bound, -// this function returns the pointer to the data array -// in client memory, that is, the data array passed in. +// If the buffer object is bound, this function sets +// client_pointer to NULL (representing the start of the +// buffer object in server memory); if the buffer object +// is not bound, this function sets client_pointer to to +// the data array in client memory, that is, the data +// array passed in. +// +// If force is not true, the function may return false +// indicating the data is not currently available. //////////////////////////////////////////////////////////////////// -const unsigned char *CLP(GraphicsStateGuardian):: -setup_primitive(const GeomPrimitivePipelineReader *reader) { +bool CLP(GraphicsStateGuardian):: +setup_primitive(const unsigned char *&client_pointer, + const GeomPrimitivePipelineReader *reader, + bool force) { if (!_supports_buffers) { // No support for buffer objects; always render from client. - return reader->get_read_pointer(true); + client_pointer = reader->get_read_pointer(force); + return (client_pointer != NULL); } if (!vertex_buffers || _geom_display_list != 0 || reader->get_usage_hint() == Geom::UH_client) { @@ -3002,16 +3070,20 @@ setup_primitive(const GeomPrimitivePipelineReader *reader) { _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); _current_ibuffer_index = 0; } - return reader->get_read_pointer(true); + client_pointer = reader->get_read_pointer(force); + return (client_pointer != NULL); } // Prepare the buffer object and bind it. IndexBufferContext *ibc = ((GeomPrimitive *)reader->get_object())->prepare_now(get_prepared_objects(), this); - nassertr(ibc != (IndexBufferContext *)NULL, reader->get_read_pointer(true)); - apply_index_buffer(ibc, reader); + nassertr(ibc != (IndexBufferContext *)NULL, false); + if (!apply_index_buffer(ibc, reader, force)) { + return false; + } // NULL is the OpenGL convention for the first byte of the buffer object. - return NULL; + client_pointer = NULL; + return true; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 394b49c9a4..b9d5571c55 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -108,13 +108,20 @@ public: virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, - const GeomVertexDataPipelineReader *data_reader); - virtual void draw_triangles(const GeomPrimitivePipelineReader *reader); - virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader); - virtual void draw_trifans(const GeomPrimitivePipelineReader *reader); - virtual void draw_lines(const GeomPrimitivePipelineReader *reader); - virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader); - virtual void draw_points(const GeomPrimitivePipelineReader *reader); + const GeomVertexDataPipelineReader *data_reader, + bool force); + virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, + bool force); + virtual bool draw_points(const GeomPrimitivePipelineReader *reader, + bool force); virtual void end_draw_primitives(); INLINE bool draw_display_list(GeomContext *gc); @@ -132,16 +139,23 @@ public: void record_deleted_display_list(GLuint index); virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data); - void apply_vertex_buffer(VertexBufferContext *vbc, - const GeomVertexArrayDataHandle *reader); + bool apply_vertex_buffer(VertexBufferContext *vbc, + const GeomVertexArrayDataHandle *reader, + bool force); virtual void release_vertex_buffer(VertexBufferContext *vbc); - const unsigned char *setup_array_data(const GeomVertexArrayDataHandle *data); + + bool setup_array_data(const unsigned char *&client_pointer, + const GeomVertexArrayDataHandle *data, + bool force); virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data); - void apply_index_buffer(IndexBufferContext *ibc, - const GeomPrimitivePipelineReader *reader); + bool apply_index_buffer(IndexBufferContext *ibc, + const GeomPrimitivePipelineReader *reader, + bool force); virtual void release_index_buffer(IndexBufferContext *ibc); - const unsigned char *setup_primitive(const GeomPrimitivePipelineReader *reader); + bool setup_primitive(const unsigned char *&client_pointer, + const GeomPrimitivePipelineReader *reader, + bool force); virtual void begin_occlusion_query(); virtual PT(OcclusionQueryContext) end_occlusion_query(); @@ -287,7 +301,7 @@ protected: static GLenum get_usage(Geom::UsageHint usage_hint); void disable_standard_vertex_arrays(); - void update_standard_vertex_arrays(); + bool update_standard_vertex_arrays(bool force); void disable_standard_texture_bindings(); void update_standard_texture_bindings(); diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 865d068f2d..2e40afc391 100755 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -204,12 +204,13 @@ disable_shader_vertex_arrays(GSG *gsg) { // it may unnecessarily disable arrays then immediately // reenable them. We may optimize this someday. //////////////////////////////////////////////////////////////////// -void CLP(ShaderContext):: -update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg) { +bool CLP(ShaderContext):: +update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, + bool force) { if (prev) prev->disable_shader_vertex_arrays(gsg); #ifdef HAVE_CG if (_cg_context == 0) { - return; + return true; } #ifdef SUPPORT_IMMEDIATE_MODE @@ -242,7 +243,10 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg) { if (gsg->_data_reader->get_array_info(name, array_reader, num_values, numeric_type, start, stride)) { - const unsigned char *client_pointer = gsg->setup_array_data(array_reader); + const unsigned char *client_pointer; + if (!gsg->setup_array_data(client_pointer, array_reader, force)) { + return false; + } cgGLSetParameterPointer(p, num_values, gsg->get_numeric_type(numeric_type), stride, client_pointer + start); @@ -253,6 +257,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg) { } } #endif // HAVE_CG + return true; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h index c98a641ef8..81f70f6d50 100755 --- a/panda/src/glstuff/glShaderContext_src.h +++ b/panda/src/glstuff/glShaderContext_src.h @@ -43,7 +43,8 @@ public: void unbind(); void issue_parameters(GSG *gsg, bool all); void disable_shader_vertex_arrays(GSG *gsg); - void update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg); + bool update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, + bool force); void disable_shader_texture_bindings(GSG *gsg); void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg); diff --git a/panda/src/gobj/geom.cxx b/panda/src/gobj/geom.cxx index d84ff60e4d..fa3e5415d3 100644 --- a/panda/src/gobj/geom.cxx +++ b/panda/src/gobj/geom.cxx @@ -1063,17 +1063,24 @@ prepare_now(PreparedGraphicsObjects *prepared_objects, // Description: Actually draws the Geom with the indicated GSG, using // the indicated vertex data (which might have been // pre-munged to support the GSG's needs). +// +// Returns true if all of the primitives were drawn +// normally, false if there was a problem (for instance, +// some of the data was nonresident). If force is +// passed true, it will wait for the data to become +// resident if necessary. //////////////////////////////////////////////////////////////////// -void Geom:: +bool Geom:: draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger, - const GeomVertexData *vertex_data, Thread *current_thread) const { + const GeomVertexData *vertex_data, bool force, + Thread *current_thread) const { GeomPipelineReader geom_reader(this, current_thread); geom_reader.check_usage_hint(); GeomVertexDataPipelineReader data_reader(vertex_data, current_thread); data_reader.check_array_readers(); - geom_reader.draw(gsg, munger, &data_reader); + return geom_reader.draw(gsg, munger, &data_reader, force); } //////////////////////////////////////////////////////////////////// @@ -1611,11 +1618,12 @@ check_valid(const GeomVertexDataPipelineReader *data_reader) const { // Access: Public // Description: The implementation of Geom::draw(). //////////////////////////////////////////////////////////////////// -void GeomPipelineReader:: +bool GeomPipelineReader:: draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger, - const GeomVertexDataPipelineReader *data_reader) const { + const GeomVertexDataPipelineReader *data_reader, bool force) const { PStatTimer timer(Geom::_draw_primitive_setup_pcollector); - if (gsg->begin_draw_primitives(this, munger, data_reader)) { + bool all_ok = gsg->begin_draw_primitives(this, munger, data_reader, force); + if (all_ok) { Geom::Primitives::const_iterator pi; for (pi = _cdata->_primitives.begin(); pi != _cdata->_primitives.end(); @@ -1624,10 +1632,14 @@ draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger, GeomPrimitivePipelineReader reader(primitive, _current_thread); if (reader.get_num_vertices() != 0) { reader.check_minmax(); - nassertv(reader.check_valid(data_reader)); - primitive->draw(gsg, &reader); + nassertr(reader.check_valid(data_reader), false); + if (!primitive->draw(gsg, &reader, force)) { + all_ok = false; + } } } gsg->end_draw_primitives(); } + + return all_ok; } diff --git a/panda/src/gobj/geom.h b/panda/src/gobj/geom.h index d6597682ff..9f00f36f97 100644 --- a/panda/src/gobj/geom.h +++ b/panda/src/gobj/geom.h @@ -137,10 +137,10 @@ PUBLISHED: GraphicsStateGuardianBase *gsg); public: - void draw(GraphicsStateGuardianBase *gsg, + bool draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger, const GeomVertexData *vertex_data, - Thread *current_thread) const; + bool force, Thread *current_thread) const; INLINE void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, @@ -396,8 +396,9 @@ public: bool check_valid(const GeomVertexDataPipelineReader *data_reader) const; - void draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger, - const GeomVertexDataPipelineReader *data_reader) const; + bool draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger, + const GeomVertexDataPipelineReader *data_reader, + bool force) const; private: CPT(Geom) _object; diff --git a/panda/src/gobj/geomLines.cxx b/panda/src/gobj/geomLines.cxx index 567ab105d4..44b40272f6 100644 --- a/panda/src/gobj/geomLines.cxx +++ b/panda/src/gobj/geomLines.cxx @@ -116,9 +116,10 @@ get_min_num_vertices_per_primitive() const { // Description: Calls the appropriate method on the GSG to draw the // primitive. //////////////////////////////////////////////////////////////////// -void GeomLines:: -draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const { - gsg->draw_lines(reader); +bool GeomLines:: +draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader, + bool force) const { + return gsg->draw_lines(reader, force); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geomLines.h b/panda/src/gobj/geomLines.h index e3ae4aeef1..000a96aae9 100644 --- a/panda/src/gobj/geomLines.h +++ b/panda/src/gobj/geomLines.h @@ -40,8 +40,9 @@ public: virtual int get_min_num_vertices_per_primitive() const; public: - virtual void draw(GraphicsStateGuardianBase *gsg, - const GeomPrimitivePipelineReader *reader) const; + virtual bool draw(GraphicsStateGuardianBase *gsg, + const GeomPrimitivePipelineReader *reader, + bool force) const; protected: virtual CPT(GeomVertexArrayData) rotate_impl() const; diff --git a/panda/src/gobj/geomLinestrips.cxx b/panda/src/gobj/geomLinestrips.cxx index 565aeaeb59..3c49837eb2 100644 --- a/panda/src/gobj/geomLinestrips.cxx +++ b/panda/src/gobj/geomLinestrips.cxx @@ -116,9 +116,10 @@ get_min_num_vertices_per_primitive() const { // Description: Calls the appropriate method on the GSG to draw the // primitive. //////////////////////////////////////////////////////////////////// -void GeomLinestrips:: -draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const { - gsg->draw_linestrips(reader); +bool GeomLinestrips:: +draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader, + bool force) const { + return gsg->draw_linestrips(reader, force); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geomLinestrips.h b/panda/src/gobj/geomLinestrips.h index 5ee0e8e11e..538d5b20b5 100644 --- a/panda/src/gobj/geomLinestrips.h +++ b/panda/src/gobj/geomLinestrips.h @@ -39,8 +39,9 @@ public: virtual int get_min_num_vertices_per_primitive() const; public: - virtual void draw(GraphicsStateGuardianBase *gsg, - const GeomPrimitivePipelineReader *reader) const; + virtual bool draw(GraphicsStateGuardianBase *gsg, + const GeomPrimitivePipelineReader *reader, + bool force) const; protected: virtual CPT(GeomPrimitive) decompose_impl() const; diff --git a/panda/src/gobj/geomPoints.cxx b/panda/src/gobj/geomPoints.cxx index 192d1141a8..c19057bd45 100644 --- a/panda/src/gobj/geomPoints.cxx +++ b/panda/src/gobj/geomPoints.cxx @@ -133,9 +133,10 @@ get_min_num_vertices_per_primitive() const { // Description: Calls the appropriate method on the GSG to draw the // primitive. //////////////////////////////////////////////////////////////////// -void GeomPoints:: -draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const { - gsg->draw_points(reader); +bool GeomPoints:: +draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader, + bool force) const { + return gsg->draw_points(reader, force); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geomPoints.h b/panda/src/gobj/geomPoints.h index 4bb9eac697..5e7292d572 100644 --- a/panda/src/gobj/geomPoints.h +++ b/panda/src/gobj/geomPoints.h @@ -41,8 +41,9 @@ public: virtual int get_min_num_vertices_per_primitive() const; public: - virtual void draw(GraphicsStateGuardianBase *gsg, - const GeomPrimitivePipelineReader *reader) const; + virtual bool draw(GraphicsStateGuardianBase *gsg, + const GeomPrimitivePipelineReader *reader, + bool force) const; public: static void register_with_read_factory(); diff --git a/panda/src/gobj/geomPrimitive.h b/panda/src/gobj/geomPrimitive.h index c148bb398a..9c02f8d81e 100644 --- a/panda/src/gobj/geomPrimitive.h +++ b/panda/src/gobj/geomPrimitive.h @@ -193,8 +193,9 @@ private: static int get_highest_index_value(NumericType index_type); public: - virtual void draw(GraphicsStateGuardianBase *gsg, - const GeomPrimitivePipelineReader *reader) const=0; + virtual bool draw(GraphicsStateGuardianBase *gsg, + const GeomPrimitivePipelineReader *reader, + bool force) const=0; void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point, bool &found_any, diff --git a/panda/src/gobj/geomTriangles.cxx b/panda/src/gobj/geomTriangles.cxx index ada2b33d20..feff5527b0 100644 --- a/panda/src/gobj/geomTriangles.cxx +++ b/panda/src/gobj/geomTriangles.cxx @@ -104,9 +104,10 @@ get_num_vertices_per_primitive() const { // Description: Calls the appropriate method on the GSG to draw the // primitive. //////////////////////////////////////////////////////////////////// -void GeomTriangles:: -draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const { - gsg->draw_triangles(reader); +bool GeomTriangles:: +draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader, + bool force) const { + return gsg->draw_triangles(reader, force); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geomTriangles.h b/panda/src/gobj/geomTriangles.h index 891579436f..8ffeea27c0 100644 --- a/panda/src/gobj/geomTriangles.h +++ b/panda/src/gobj/geomTriangles.h @@ -39,8 +39,9 @@ public: virtual int get_num_vertices_per_primitive() const; public: - virtual void draw(GraphicsStateGuardianBase *gsg, - const GeomPrimitivePipelineReader *reader) const; + virtual bool draw(GraphicsStateGuardianBase *gsg, + const GeomPrimitivePipelineReader *reader, + bool force) const; protected: virtual CPT(GeomVertexArrayData) rotate_impl() const; diff --git a/panda/src/gobj/geomTrifans.cxx b/panda/src/gobj/geomTrifans.cxx index 17fa084362..c75b6415d6 100644 --- a/panda/src/gobj/geomTrifans.cxx +++ b/panda/src/gobj/geomTrifans.cxx @@ -104,9 +104,10 @@ get_geom_rendering() const { // Description: Calls the appropriate method on the GSG to draw the // primitive. //////////////////////////////////////////////////////////////////// -void GeomTrifans:: -draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const { - gsg->draw_trifans(reader); +bool GeomTrifans:: +draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader, + bool force) const { + return gsg->draw_trifans(reader, force); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geomTrifans.h b/panda/src/gobj/geomTrifans.h index 8f35f3700c..69c22f61c7 100644 --- a/panda/src/gobj/geomTrifans.h +++ b/panda/src/gobj/geomTrifans.h @@ -38,8 +38,9 @@ public: virtual int get_geom_rendering() const; public: - virtual void draw(GraphicsStateGuardianBase *gsg, - const GeomPrimitivePipelineReader *reader) const; + virtual bool draw(GraphicsStateGuardianBase *gsg, + const GeomPrimitivePipelineReader *reader, + bool force) const; protected: virtual CPT(GeomPrimitive) decompose_impl() const; diff --git a/panda/src/gobj/geomTristrips.cxx b/panda/src/gobj/geomTristrips.cxx index 00566b5a96..85a678e7c0 100644 --- a/panda/src/gobj/geomTristrips.cxx +++ b/panda/src/gobj/geomTristrips.cxx @@ -119,9 +119,10 @@ get_num_unused_vertices_per_primitive() const { // Description: Calls the appropriate method on the GSG to draw the // primitive. //////////////////////////////////////////////////////////////////// -void GeomTristrips:: -draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const { - gsg->draw_tristrips(reader); +bool GeomTristrips:: +draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader, + bool force) const { + return gsg->draw_tristrips(reader, force); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/geomTristrips.h b/panda/src/gobj/geomTristrips.h index bd31593643..2f2eac6901 100644 --- a/panda/src/gobj/geomTristrips.h +++ b/panda/src/gobj/geomTristrips.h @@ -39,8 +39,9 @@ public: virtual int get_num_unused_vertices_per_primitive() const; public: - virtual void draw(GraphicsStateGuardianBase *gsg, - const GeomPrimitivePipelineReader *reader) const; + virtual bool draw(GraphicsStateGuardianBase *gsg, + const GeomPrimitivePipelineReader *reader, + bool force) const; protected: virtual CPT(GeomPrimitive) decompose_impl() const; diff --git a/panda/src/gobj/geomVertexArrayData.I b/panda/src/gobj/geomVertexArrayData.I index 6c4c072fe9..d93252de88 100644 --- a/panda/src/gobj/geomVertexArrayData.I +++ b/panda/src/gobj/geomVertexArrayData.I @@ -157,7 +157,7 @@ get_modified() const { INLINE bool GeomVertexArrayData:: request_resident() const { CPT(GeomVertexArrayDataHandle) handle = get_handle(); - return (handle->get_read_pointer(false) != (const unsigned char *)NULL); + return handle->request_resident(); } //////////////////////////////////////////////////////////////////// @@ -458,6 +458,20 @@ get_modified() const { return _cdata->_modified; } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexArrayData::request_resident +// Access: Published +// Description: Returns true if the vertex data is currently resident +// in memory. If this returns true, the next call to +// get_handle()->get_read_pointer() will probably not +// block. If this returns false, the vertex data will +// be brought back into memory shortly; try again later. +//////////////////////////////////////////////////////////////////// +INLINE bool GeomVertexArrayDataHandle:: +request_resident() const { + return (get_read_pointer(false) != (const unsigned char *)NULL); +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexArrayDataHandle::get_data // Access: Published diff --git a/panda/src/gobj/geomVertexArrayData.h b/panda/src/gobj/geomVertexArrayData.h index ff2ac9b491..a1936bd66c 100644 --- a/panda/src/gobj/geomVertexArrayData.h +++ b/panda/src/gobj/geomVertexArrayData.h @@ -275,6 +275,8 @@ PUBLISHED: INLINE int get_data_size_bytes() const; INLINE UpdateSeq get_modified() const; + INLINE bool request_resident() const; + void copy_data_from(const GeomVertexArrayDataHandle *other); void copy_subdata_from(size_t to_start, size_t to_size, const GeomVertexArrayDataHandle *other, diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index e915f2f28b..e7242a6668 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -183,13 +183,14 @@ public: virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader, const GeomMunger *munger, - const GeomVertexDataPipelineReader *data_reader)=0; - virtual void draw_triangles(const GeomPrimitivePipelineReader *reader)=0; - virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader)=0; - virtual void draw_trifans(const GeomPrimitivePipelineReader *reader)=0; - virtual void draw_lines(const GeomPrimitivePipelineReader *reader)=0; - virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader)=0; - virtual void draw_points(const GeomPrimitivePipelineReader *reader)=0; + const GeomVertexDataPipelineReader *data_reader, + bool force)=0; + virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, bool force)=0; + virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force)=0; + virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, bool force)=0; + virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, bool force)=0; + virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force)=0; + virtual bool draw_points(const GeomPrimitivePipelineReader *reader, bool force)=0; virtual void end_draw_primitives()=0; virtual void framebuffer_copy_to_texture diff --git a/panda/src/pgraph/cullBin.h b/panda/src/pgraph/cullBin.h index dcf21df588..3d98b81be7 100644 --- a/panda/src/pgraph/cullBin.h +++ b/panda/src/pgraph/cullBin.h @@ -58,7 +58,7 @@ public: virtual void add_object(CullableObject *object, Thread *current_thread)=0; virtual void finish_cull(SceneSetup *scene_setup, Thread *current_thread); - virtual void draw(Thread *current_thread)=0; + virtual void draw(bool force, Thread *current_thread)=0; INLINE bool has_flash_color() const; INLINE const Colorf &get_flash_color() const; diff --git a/panda/src/pgraph/cullHandler.I b/panda/src/pgraph/cullHandler.I index 4d7f53504a..7c0f7d1cb5 100644 --- a/panda/src/pgraph/cullHandler.I +++ b/panda/src/pgraph/cullHandler.I @@ -26,11 +26,11 @@ //////////////////////////////////////////////////////////////////// INLINE void CullHandler:: draw(CullableObject *object, GraphicsStateGuardianBase *gsg, - Thread *current_thread) { + bool force, Thread *current_thread) { if (object->_next != (CullableObject *)NULL) { - draw_with_decals(object, gsg, current_thread); + draw_with_decals(object, gsg, force, current_thread); } else { gsg->set_state_and_transform(object->_state, object->_internal_transform); - object->draw(gsg, current_thread); + object->draw(gsg, force, current_thread); } } diff --git a/panda/src/pgraph/cullHandler.cxx b/panda/src/pgraph/cullHandler.cxx index 0eb0cd2c5f..75b6cf9bf6 100644 --- a/panda/src/pgraph/cullHandler.cxx +++ b/panda/src/pgraph/cullHandler.cxx @@ -58,7 +58,7 @@ record_object(CullableObject *object, const CullTraverser *traverser) { //////////////////////////////////////////////////////////////////// void CullHandler:: draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg, - Thread *current_thread) { + bool force, Thread *current_thread) { // We draw with a three-step process. // First, render all of the base geometry for the first pass. @@ -67,7 +67,7 @@ draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg, CullableObject *base = object; while (base != (CullableObject *)NULL && base->_geom != (Geom *)NULL) { gsg->set_state_and_transform(base->_state->compose(state), base->_internal_transform); - base->draw(gsg, current_thread); + base->draw(gsg, force, current_thread); base = base->_next; } @@ -79,7 +79,7 @@ draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg, CullableObject *decal = base->_next; while (decal != (CullableObject *)NULL) { gsg->set_state_and_transform(decal->_state->compose(state), decal->_internal_transform); - decal->draw(gsg, current_thread); + decal->draw(gsg, force, current_thread); decal = decal->_next; } } @@ -90,7 +90,7 @@ draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg, base = object; while (base != (CullableObject *)NULL && base->_geom != (Geom *)NULL) { gsg->set_state_and_transform(base->_state->compose(state), base->_internal_transform); - base->draw(gsg, current_thread); + base->draw(gsg, force, current_thread); base = base->_next; } diff --git a/panda/src/pgraph/cullHandler.h b/panda/src/pgraph/cullHandler.h index 913b508d4f..4115d340eb 100644 --- a/panda/src/pgraph/cullHandler.h +++ b/panda/src/pgraph/cullHandler.h @@ -41,10 +41,10 @@ public: INLINE static void draw(CullableObject *object, GraphicsStateGuardianBase *gsg, - Thread *current_thread); + bool force, Thread *current_thread); static void draw_with_decals(CullableObject *object, GraphicsStateGuardianBase *gsg, - Thread *current_thread); + bool force, Thread *current_thread); }; #include "cullHandler.I" diff --git a/panda/src/pgraph/cullResult.cxx b/panda/src/pgraph/cullResult.cxx index cc64a7aeac..f29e550b68 100644 --- a/panda/src/pgraph/cullResult.cxx +++ b/panda/src/pgraph/cullResult.cxx @@ -176,9 +176,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) { #ifndef NDEBUG check_flash_bin(transparent_part->_state, bin); #endif - if (force || transparent_part->request_resident()) { - bin->add_object(transparent_part, current_thread); - } + bin->add_object(transparent_part, current_thread); } } @@ -213,9 +211,11 @@ add_object(CullableObject *object, const CullTraverser *traverser) { // Munge vertices as needed for the GSG's requirements, and the // object's current state. if (object->munge_geom(_gsg, _gsg->get_geom_munger(object->_state, current_thread), traverser, force)) { - if (force || object->request_resident()) { - bin->add_object(object, current_thread); - } + // The object may or may not now be fully resident, but this may + // not matter, since the GSG may have the necessary buffers + // already loaded. We'll let the GSG ultimately decide whether to + // render it. + bin->add_object(object, current_thread); } } @@ -255,6 +255,8 @@ finish_cull(SceneSetup *scene_setup, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void CullResult:: draw(Thread *current_thread) { + bool force = !allow_incomplete_render; + // Ask the bin manager for the correct order to draw all the bins. CullBinManager *bin_manager = CullBinManager::get_global_ptr(); int num_bins = bin_manager->get_num_bins(); @@ -263,7 +265,7 @@ draw(Thread *current_thread) { nassertv(bin_index >= 0); if (bin_index < (int)_bins.size() && _bins[bin_index] != (CullBin *)NULL) { - _bins[bin_index]->draw(current_thread); + _bins[bin_index]->draw(force, current_thread); } } } diff --git a/panda/src/pgraph/cullableObject.I b/panda/src/pgraph/cullableObject.I index 63fa43c384..cb994c9485 100644 --- a/panda/src/pgraph/cullableObject.I +++ b/panda/src/pgraph/cullableObject.I @@ -126,8 +126,8 @@ has_decals() const { // from the draw thread. //////////////////////////////////////////////////////////////////// INLINE void CullableObject:: -draw(GraphicsStateGuardianBase *gsg, Thread *current_thread) { - _geom->draw(gsg, _munger, _munged_data, current_thread); +draw(GraphicsStateGuardianBase *gsg, bool force, Thread *current_thread) { + _geom->draw(gsg, _munger, _munged_data, force, current_thread); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/cullableObject.h b/panda/src/pgraph/cullableObject.h index a8d482c37b..af540e047f 100644 --- a/panda/src/pgraph/cullableObject.h +++ b/panda/src/pgraph/cullableObject.h @@ -65,7 +65,7 @@ public: GeomMunger *munger, const CullTraverser *traverser, bool force); INLINE void draw(GraphicsStateGuardianBase *gsg, - Thread *current_thread); + bool force, Thread *current_thread); INLINE bool request_resident() const; INLINE static void flush_level();