don't prune nonresident geometry in cull--wait until draw

This commit is contained in:
David Rose 2007-06-07 21:45:33 +00:00
parent 97f794be0e
commit 68c9ef5207
46 changed files with 608 additions and 330 deletions

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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<CullableObject *> Objects;

View File

@ -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.

View File

@ -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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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();

View File

@ -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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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,

View File

@ -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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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,

View File

@ -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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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();

View File

@ -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;
}
////////////////////////////////////////////////////////////////////

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}
////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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);
}
////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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);
}
////////////////////////////////////////////////////////////////////

View File

@ -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();

View File

@ -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,

View File

@ -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);
}
////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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);
}
////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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);
}
////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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"

View File

@ -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);
}
}
}

View File

@ -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);
}
////////////////////////////////////////////////////////////////////

View File

@ -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();