mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
gl display lists with new geom
This commit is contained in:
parent
70a94646f7
commit
3f7956f4e9
@ -670,7 +670,7 @@ finish_decal() {
|
|||||||
// are ok, false to abort this group of primitives.
|
// are ok, false to abort this group of primitives.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool GraphicsStateGuardian::
|
bool GraphicsStateGuardian::
|
||||||
begin_draw_primitives(const qpGeomVertexData *data) {
|
begin_draw_primitives(const qpGeom *, const qpGeomVertexData *data) {
|
||||||
_vertex_data = data;
|
_vertex_data = data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -719,6 +719,7 @@ draw_trifans(const qpGeomTrifans *primitive) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void GraphicsStateGuardian::
|
void GraphicsStateGuardian::
|
||||||
end_draw_primitives() {
|
end_draw_primitives() {
|
||||||
|
_vertex_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -148,7 +148,7 @@ public:
|
|||||||
virtual CPT(RenderState) begin_decal_base_second();
|
virtual CPT(RenderState) begin_decal_base_second();
|
||||||
virtual void finish_decal();
|
virtual void finish_decal();
|
||||||
|
|
||||||
virtual bool begin_draw_primitives(const qpGeomVertexData *vertex_data);
|
virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data);
|
||||||
virtual void draw_triangles(const qpGeomTriangles *primitive);
|
virtual void draw_triangles(const qpGeomTriangles *primitive);
|
||||||
virtual void draw_tristrips(const qpGeomTristrips *primitive);
|
virtual void draw_tristrips(const qpGeomTristrips *primitive);
|
||||||
virtual void draw_trifans(const qpGeomTrifans *primitive);
|
virtual void draw_trifans(const qpGeomTrifans *primitive);
|
||||||
|
@ -2606,10 +2606,10 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) {
|
|||||||
// are ok, false to abort this group of primitives.
|
// are ok, false to abort this group of primitives.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool DXGraphicsStateGuardian8::
|
bool DXGraphicsStateGuardian8::
|
||||||
begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data) {
|
||||||
DO_PSTATS_STUFF(_draw_primitive_pcollector.start());
|
DO_PSTATS_STUFF(_draw_primitive_pcollector.start());
|
||||||
|
|
||||||
if (!GraphicsStateGuardian::begin_draw_primitives(vertex_data)) {
|
if (!GraphicsStateGuardian::begin_draw_primitives(geom, vertex_data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
nassertr(_vertex_data != (qpGeomVertexData *)NULL, false);
|
nassertr(_vertex_data != (qpGeomVertexData *)NULL, false);
|
||||||
@ -2694,6 +2694,7 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void DXGraphicsStateGuardian8::
|
void DXGraphicsStateGuardian8::
|
||||||
end_draw_primitives() {
|
end_draw_primitives() {
|
||||||
|
GraphicsStateGuardian::end_draw_primitives();
|
||||||
DO_PSTATS_STUFF(_draw_primitive_pcollector.stop());
|
DO_PSTATS_STUFF(_draw_primitive_pcollector.stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ public:
|
|||||||
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
|
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
|
||||||
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
|
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
|
||||||
|
|
||||||
virtual bool begin_draw_primitives(const qpGeomVertexData *vertex_data);
|
virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data);
|
||||||
virtual void draw_triangles(const qpGeomTriangles *primitive);
|
virtual void draw_triangles(const qpGeomTriangles *primitive);
|
||||||
virtual void draw_tristrips(const qpGeomTristrips *primitive);
|
virtual void draw_tristrips(const qpGeomTristrips *primitive);
|
||||||
virtual void end_draw_primitives();
|
virtual void end_draw_primitives();
|
||||||
|
@ -30,6 +30,8 @@ public:
|
|||||||
// This is the GL display list index.
|
// This is the GL display list index.
|
||||||
GLuint _index;
|
GLuint _index;
|
||||||
|
|
||||||
|
UpdateSeq _modified;
|
||||||
|
|
||||||
// The number of vertices encoded in the display list, for stats
|
// The number of vertices encoded in the display list, for stats
|
||||||
// reporting.
|
// reporting.
|
||||||
#ifdef DO_PSTATS
|
#ifdef DO_PSTATS
|
||||||
|
@ -2030,14 +2030,53 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) {
|
|||||||
// are ok, false to abort this group of primitives.
|
// are ok, false to abort this group of primitives.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool CLP(GraphicsStateGuardian)::
|
bool CLP(GraphicsStateGuardian)::
|
||||||
begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data) {
|
||||||
DO_PSTATS_STUFF(_draw_primitive_pcollector.start());
|
DO_PSTATS_STUFF(_draw_primitive_pcollector.start());
|
||||||
|
|
||||||
if (!GraphicsStateGuardian::begin_draw_primitives(vertex_data)) {
|
if (!GraphicsStateGuardian::begin_draw_primitives(geom, vertex_data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
nassertr(_vertex_data != (qpGeomVertexData *)NULL, false);
|
nassertr(_vertex_data != (qpGeomVertexData *)NULL, false);
|
||||||
|
|
||||||
|
_geom_display_list = NULL;
|
||||||
|
|
||||||
|
if (geom->get_usage_hint() == qpGeomUsageHint::UH_static &&
|
||||||
|
_vertex_data->get_usage_hint() == qpGeomUsageHint::UH_static &&
|
||||||
|
display_lists) {
|
||||||
|
// If the geom appears to be totally static, try to build it into
|
||||||
|
// a display list.
|
||||||
|
GeomContext *gc = ((qpGeom *)geom)->prepare_now(get_prepared_objects(), this);
|
||||||
|
nassertr(gc != (GeomContext *)NULL, false);
|
||||||
|
CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
|
||||||
|
if (ggc->_modified == geom->get_modified()) {
|
||||||
|
// If it hasn't been modified, just play the display list again.
|
||||||
|
GLP(CallList)(ggc->_index);
|
||||||
|
#ifdef DO_PSTATS
|
||||||
|
_vertices_display_list_pcollector.add_level(ggc->_num_verts);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// And now we don't need to do anything else for this geom.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it has been modified, or this is the first time, then we
|
||||||
|
// need to build the display list up.
|
||||||
|
GLP(NewList)(ggc->_index, GL_COMPILE_AND_EXECUTE);
|
||||||
|
ggc->_modified = geom->get_modified();
|
||||||
|
_geom_display_list = ggc;
|
||||||
|
|
||||||
|
#ifdef DO_PSTATS
|
||||||
|
// Count up the number of vertices we're about to render, by
|
||||||
|
// checking the PStats vertex counters now, and at the end. This is
|
||||||
|
// kind of hacky, but this is debug code.
|
||||||
|
_num_display_list_verts_before =
|
||||||
|
_vertices_tristrip_pcollector.get_level() +
|
||||||
|
_vertices_trifan_pcollector.get_level() +
|
||||||
|
_vertices_tri_pcollector.get_level() +
|
||||||
|
_vertices_other_pcollector.get_level();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
const qpGeomVertexArrayData *array_data;
|
const qpGeomVertexArrayData *array_data;
|
||||||
int num_components;
|
int num_components;
|
||||||
qpGeomVertexDataType::NumericType numeric_type;
|
qpGeomVertexDataType::NumericType numeric_type;
|
||||||
@ -2051,9 +2090,6 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
|||||||
GLP(VertexPointer)(num_components, get_numeric_type(numeric_type),
|
GLP(VertexPointer)(num_components, get_numeric_type(numeric_type),
|
||||||
stride, client_pointer + start);
|
stride, client_pointer + start);
|
||||||
GLP(EnableClientState)(GL_VERTEX_ARRAY);
|
GLP(EnableClientState)(GL_VERTEX_ARRAY);
|
||||||
} else {
|
|
||||||
// No vertex data? No primitives!
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wants_normals() &&
|
if (wants_normals() &&
|
||||||
@ -2073,14 +2109,8 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
|||||||
array_data, num_components, numeric_type,
|
array_data, num_components, numeric_type,
|
||||||
start, stride)) {
|
start, stride)) {
|
||||||
const unsigned char *client_pointer = setup_array_data(array_data);
|
const unsigned char *client_pointer = setup_array_data(array_data);
|
||||||
if (numeric_type == qpGeomVertexDataType::NT_packed_argb) {
|
GLP(ColorPointer)(num_components, get_numeric_type(numeric_type),
|
||||||
// Temporary hack--this will probably reverse r and b.
|
stride, client_pointer + start);
|
||||||
GLP(ColorPointer)(4, GL_UNSIGNED_BYTE, stride, client_pointer + start);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
GLP(ColorPointer)(num_components, get_numeric_type(numeric_type),
|
|
||||||
stride, client_pointer + start);
|
|
||||||
}
|
|
||||||
GLP(EnableClientState)(GL_COLOR_ARRAY);
|
GLP(EnableClientState)(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -2105,8 +2135,6 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
|||||||
GLP(DisableClientState)(GL_TEXTURE_COORD_ARRAY);
|
GLP(DisableClientState)(GL_TEXTURE_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_scene_graph_color();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2168,7 +2196,23 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CLP(GraphicsStateGuardian)::
|
void CLP(GraphicsStateGuardian)::
|
||||||
end_draw_primitives() {
|
end_draw_primitives() {
|
||||||
GLP(DisableClientState)(GL_VERTEX_ARRAY);
|
if (_geom_display_list != NULL) {
|
||||||
|
// If we were building a display list, close it now.
|
||||||
|
GLP(EndList)();
|
||||||
|
|
||||||
|
#ifdef DO_PSTATS
|
||||||
|
float num_verts_after =
|
||||||
|
_vertices_tristrip_pcollector.get_level() +
|
||||||
|
_vertices_trifan_pcollector.get_level() +
|
||||||
|
_vertices_tri_pcollector.get_level() +
|
||||||
|
_vertices_other_pcollector.get_level();
|
||||||
|
float num_verts = num_verts_after - _num_display_list_verts_before;
|
||||||
|
_geom_display_list->_num_verts = (int)(num_verts + 0.5);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
_geom_display_list = NULL;
|
||||||
|
|
||||||
|
GraphicsStateGuardian::end_draw_primitives();
|
||||||
|
|
||||||
DO_PSTATS_STUFF(_draw_primitive_pcollector.stop());
|
DO_PSTATS_STUFF(_draw_primitive_pcollector.stop());
|
||||||
}
|
}
|
||||||
@ -2262,69 +2306,94 @@ release_texture(TextureContext *tc) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
GeomContext *CLP(GraphicsStateGuardian)::
|
GeomContext *CLP(GraphicsStateGuardian)::
|
||||||
prepare_geom(Geom *geom) {
|
prepare_geom(Geom *geom) {
|
||||||
if (!_vertex_colors_enabled) {
|
// Temporary test until the experimental Geom rewrite becomes the
|
||||||
// We can't build a display list (or play back a display list) if
|
// actual Geom implementation.
|
||||||
// its color is overridden with a scene graph color. Maybe if we
|
if (geom->is_exact_type(qpGeom::get_class_type())) {
|
||||||
// take advantage of the OpenGL color matrix we can do this, but
|
CLP(GeomContext) *ggc = new CLP(GeomContext)(geom);
|
||||||
// for now we'll just ignore it.
|
ggc->_index = GLP(GenLists)(1);
|
||||||
return NULL;
|
if (GLCAT.is_debug()) {
|
||||||
}
|
GLCAT.debug()
|
||||||
|
<< "preparing " << *geom << ", index " << ggc->_index << "\n";
|
||||||
|
}
|
||||||
|
if (ggc->_index == 0) {
|
||||||
|
GLCAT.error()
|
||||||
|
<< "Ran out of display list indices.\n";
|
||||||
|
delete ggc;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (geom->is_dynamic()) {
|
report_my_gl_errors();
|
||||||
// If the Geom is dynamic in some way, we shouldn't try to
|
return ggc;
|
||||||
// display-list it.
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLP(GeomContext) *ggc = new CLP(GeomContext)(geom);
|
} else {
|
||||||
ggc->_index = GLP(GenLists)(1);
|
// Original Geom display list implementation. Slightly broken,
|
||||||
if (GLCAT.is_debug()) {
|
// since it doesn't work well with scene graph color
|
||||||
GLCAT.debug()
|
// manipulations.
|
||||||
<< "preparing " << *geom << ", index " << ggc->_index << "\n";
|
|
||||||
}
|
|
||||||
if (ggc->_index == 0) {
|
|
||||||
GLCAT.error()
|
|
||||||
<< "Ran out of display list indices.\n";
|
|
||||||
delete ggc;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to temporarily force normals and UV's on, so the display
|
if (!_vertex_colors_enabled) {
|
||||||
// list will have them built in.
|
// We can't build a display list (or play back a display list) if
|
||||||
//force_texcoords();
|
// its color is overridden with a scene graph color. Maybe if we
|
||||||
force_normals();
|
// take advantage of the OpenGL color matrix we can do this, but
|
||||||
|
// for now we'll just ignore it.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (geom->is_dynamic()) {
|
||||||
|
// If the Geom is dynamic in some way, we shouldn't try to
|
||||||
|
// display-list it.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLP(GeomContext) *ggc = new CLP(GeomContext)(geom);
|
||||||
|
ggc->_index = GLP(GenLists)(1);
|
||||||
|
if (GLCAT.is_debug()) {
|
||||||
|
GLCAT.debug()
|
||||||
|
<< "preparing " << *geom << ", index " << ggc->_index << "\n";
|
||||||
|
}
|
||||||
|
if (ggc->_index == 0) {
|
||||||
|
GLCAT.error()
|
||||||
|
<< "Ran out of display list indices.\n";
|
||||||
|
delete ggc;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to temporarily force normals and UV's on, so the display
|
||||||
|
// list will have them built in.
|
||||||
|
//force_texcoords();
|
||||||
|
force_normals();
|
||||||
|
|
||||||
#ifdef DO_PSTATS
|
#ifdef DO_PSTATS
|
||||||
// Count up the number of vertices we're about to render, by
|
// Count up the number of vertices we're about to render, by
|
||||||
// checking the PStats vertex counters now, and at the end. This is
|
// checking the PStats vertex counters now, and at the end. This is
|
||||||
// kind of hacky, but this is debug code.
|
// kind of hacky, but this is debug code.
|
||||||
float num_verts_before =
|
float num_verts_before =
|
||||||
_vertices_tristrip_pcollector.get_level() +
|
_vertices_tristrip_pcollector.get_level() +
|
||||||
_vertices_trifan_pcollector.get_level() +
|
_vertices_trifan_pcollector.get_level() +
|
||||||
_vertices_tri_pcollector.get_level() +
|
_vertices_tri_pcollector.get_level() +
|
||||||
_vertices_other_pcollector.get_level();
|
_vertices_other_pcollector.get_level();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Now define the display list.
|
// Now define the display list.
|
||||||
GLP(NewList)(ggc->_index, GL_COMPILE);
|
GLP(NewList)(ggc->_index, GL_COMPILE);
|
||||||
geom->draw_immediate(this, NULL);
|
geom->draw_immediate(this, NULL);
|
||||||
GLP(EndList)();
|
GLP(EndList)();
|
||||||
|
|
||||||
#ifdef DO_PSTATS
|
#ifdef DO_PSTATS
|
||||||
float num_verts_after =
|
float num_verts_after =
|
||||||
_vertices_tristrip_pcollector.get_level() +
|
_vertices_tristrip_pcollector.get_level() +
|
||||||
_vertices_trifan_pcollector.get_level() +
|
_vertices_trifan_pcollector.get_level() +
|
||||||
_vertices_tri_pcollector.get_level() +
|
_vertices_tri_pcollector.get_level() +
|
||||||
_vertices_other_pcollector.get_level();
|
_vertices_other_pcollector.get_level();
|
||||||
float num_verts = num_verts_after - num_verts_before;
|
float num_verts = num_verts_after - num_verts_before;
|
||||||
ggc->_num_verts = (int)(num_verts + 0.5);
|
ggc->_num_verts = (int)(num_verts + 0.5);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
undo_force_normals();
|
undo_force_normals();
|
||||||
//undo_force_texcoords();
|
//undo_force_texcoords();
|
||||||
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
return ggc;
|
return ggc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -2464,7 +2533,7 @@ setup_array_data(const qpGeomVertexArrayData *data) {
|
|||||||
// No support for buffer objects; always render from client.
|
// No support for buffer objects; always render from client.
|
||||||
return data->get_data();
|
return data->get_data();
|
||||||
}
|
}
|
||||||
if (!vertex_buffers ||
|
if (!vertex_buffers || _geom_display_list != NULL ||
|
||||||
data->get_usage_hint() == qpGeomUsageHint::UH_client) {
|
data->get_usage_hint() == qpGeomUsageHint::UH_client) {
|
||||||
// The array specifies client rendering only, or buffer objects
|
// The array specifies client rendering only, or buffer objects
|
||||||
// are configured off.
|
// are configured off.
|
||||||
@ -2534,12 +2603,12 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
|||||||
}
|
}
|
||||||
if (gibc->changed_size()) {
|
if (gibc->changed_size()) {
|
||||||
_glBufferData(GL_ELEMENT_ARRAY_BUFFER, gibc->get_data()->get_data_size_bytes(),
|
_glBufferData(GL_ELEMENT_ARRAY_BUFFER, gibc->get_data()->get_data_size_bytes(),
|
||||||
gibc->get_data()->get_vertices(),
|
gibc->get_data()->get_flat_last_vertices(),
|
||||||
get_usage(gibc->get_data()->get_usage_hint()));
|
get_usage(gibc->get_data()->get_usage_hint()));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, gibc->get_data_size_bytes(),
|
_glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, gibc->get_data_size_bytes(),
|
||||||
gibc->get_data()->get_vertices());
|
gibc->get_data()->get_flat_last_vertices());
|
||||||
}
|
}
|
||||||
|
|
||||||
gibc->mark_loaded();
|
gibc->mark_loaded();
|
||||||
@ -2593,19 +2662,19 @@ const unsigned short *CLP(GraphicsStateGuardian)::
|
|||||||
setup_primitive(const qpGeomPrimitive *data) {
|
setup_primitive(const qpGeomPrimitive *data) {
|
||||||
if (!_supports_buffers) {
|
if (!_supports_buffers) {
|
||||||
// No support for buffer objects; always render from client.
|
// No support for buffer objects; always render from client.
|
||||||
return data->get_vertices();
|
return data->get_flat_last_vertices();
|
||||||
}
|
}
|
||||||
if (!vertex_buffers ||
|
if (!vertex_buffers || _geom_display_list != NULL ||
|
||||||
data->get_usage_hint() == qpGeomUsageHint::UH_client) {
|
data->get_usage_hint() == qpGeomUsageHint::UH_client) {
|
||||||
// The array specifies client rendering only, or buffer objects
|
// The array specifies client rendering only, or buffer objects
|
||||||
// are configured off.
|
// are configured off.
|
||||||
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
return data->get_vertices();
|
return data->get_flat_last_vertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the buffer object and bind it.
|
// Prepare the buffer object and bind it.
|
||||||
IndexBufferContext *ibc = ((qpGeomPrimitive *)data)->prepare_now(get_prepared_objects(), this);
|
IndexBufferContext *ibc = ((qpGeomPrimitive *)data)->prepare_now(get_prepared_objects(), this);
|
||||||
nassertr(ibc != (IndexBufferContext *)NULL, data->get_vertices());
|
nassertr(ibc != (IndexBufferContext *)NULL, data->get_flat_last_vertices());
|
||||||
apply_index_buffer(ibc);
|
apply_index_buffer(ibc);
|
||||||
|
|
||||||
// NULL is the OpenGL convention for the first byte of the buffer.
|
// NULL is the OpenGL convention for the first byte of the buffer.
|
||||||
|
@ -58,6 +58,8 @@ typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat
|
|||||||
typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
|
typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
|
||||||
typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
||||||
|
|
||||||
|
class CLP(GeomContext);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : GLGraphicsStateGuardian
|
// Class : GLGraphicsStateGuardian
|
||||||
// Description : A GraphicsStateGuardian specialized for rendering
|
// Description : A GraphicsStateGuardian specialized for rendering
|
||||||
@ -90,7 +92,7 @@ public:
|
|||||||
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
|
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
|
||||||
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
|
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
|
||||||
|
|
||||||
virtual bool begin_draw_primitives(const qpGeomVertexData *vertex_data);
|
virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data);
|
||||||
virtual void draw_triangles(const qpGeomTriangles *primitive);
|
virtual void draw_triangles(const qpGeomTriangles *primitive);
|
||||||
virtual void draw_tristrips(const qpGeomTristrips *primitive);
|
virtual void draw_tristrips(const qpGeomTristrips *primitive);
|
||||||
virtual void end_draw_primitives();
|
virtual void end_draw_primitives();
|
||||||
@ -315,6 +317,8 @@ protected:
|
|||||||
|
|
||||||
int _pass_number;
|
int _pass_number;
|
||||||
bool _auto_rescale_normal;
|
bool _auto_rescale_normal;
|
||||||
|
CLP(GeomContext) *_geom_display_list;
|
||||||
|
float _num_display_list_verts_before;
|
||||||
|
|
||||||
int _error_count;
|
int _error_count;
|
||||||
|
|
||||||
|
@ -84,7 +84,9 @@ ConfigVariableBool retained_mode
|
|||||||
"creates specific cache information (like display lists or vertex "
|
"creates specific cache information (like display lists or vertex "
|
||||||
"buffers) with the GSG for static geometry, when supported by the "
|
"buffers) with the GSG for static geometry, when supported by the "
|
||||||
"GSG. Set it false to use only immediate mode, which sends the "
|
"GSG. Set it false to use only immediate mode, which sends the "
|
||||||
"vertices to the GSG every frame."));
|
"vertices to the GSG every frame. This is used only in the "
|
||||||
|
"original Geom implementation; it is replaced by display-lists "
|
||||||
|
"in the experimental Geom rewrite."));
|
||||||
|
|
||||||
ConfigVariableBool vertex_buffers
|
ConfigVariableBool vertex_buffers
|
||||||
("vertex-buffers", false,
|
("vertex-buffers", false,
|
||||||
@ -95,6 +97,16 @@ ConfigVariableBool vertex_buffers
|
|||||||
"graphics memory (which might otherwise be used for textures "
|
"graphics memory (which might otherwise be used for textures "
|
||||||
"or offscreen buffers)."));
|
"or offscreen buffers)."));
|
||||||
|
|
||||||
|
ConfigVariableBool display_lists
|
||||||
|
("display-lists", false,
|
||||||
|
PRC_DESC("Set this true to allow the use of OpenGL display lists for "
|
||||||
|
"rendering static geometry. On some systems, this can result "
|
||||||
|
"in a performance improvement over vertex buffers alone; on "
|
||||||
|
"other systems (particularly low-end systems) it makes little to "
|
||||||
|
"no difference. This has no effect on DirectX rendering. If "
|
||||||
|
"vertex-buffers is also enabled, then OpenGL buffer objects "
|
||||||
|
"will also be created for dynamic geometry."));
|
||||||
|
|
||||||
ConfigVariableBool use_qpgeom
|
ConfigVariableBool use_qpgeom
|
||||||
("use-qpgeom", false,
|
("use-qpgeom", false,
|
||||||
PRC_DESC("A temporary variable while the experimental Geom rewrite is "
|
PRC_DESC("A temporary variable while the experimental Geom rewrite is "
|
||||||
|
@ -52,6 +52,7 @@ extern EXPCL_PANDA ConfigVariableBool keep_texture_ram;
|
|||||||
extern EXPCL_PANDA ConfigVariableBool keep_geom_ram;
|
extern EXPCL_PANDA ConfigVariableBool keep_geom_ram;
|
||||||
extern EXPCL_PANDA ConfigVariableBool retained_mode;
|
extern EXPCL_PANDA ConfigVariableBool retained_mode;
|
||||||
extern EXPCL_PANDA ConfigVariableBool vertex_buffers;
|
extern EXPCL_PANDA ConfigVariableBool vertex_buffers;
|
||||||
|
extern EXPCL_PANDA ConfigVariableBool display_lists;
|
||||||
|
|
||||||
extern EXPCL_PANDA ConfigVariableBool use_qpgeom;
|
extern EXPCL_PANDA ConfigVariableBool use_qpgeom;
|
||||||
|
|
||||||
|
@ -17,6 +17,23 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeom::get_usage_hint
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the minimum (i.e. most dynamic) usage_hint
|
||||||
|
// among all of the individual GeomPrimitives that have
|
||||||
|
// been added to the geom.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE qpGeomUsageHint::UsageHint qpGeom::
|
||||||
|
get_usage_hint() const {
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
if (!cdata->_got_usage_hint) {
|
||||||
|
CDWriter cdataw(((qpGeom *)this)->_cycler, cdata);
|
||||||
|
((qpGeom *)this)->reset_usage_hint(cdataw);
|
||||||
|
}
|
||||||
|
return cdata->_usage_hint;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeom::get_vertex_data
|
// Function: qpGeom::get_vertex_data
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -71,6 +88,7 @@ modify_primitive(int i) {
|
|||||||
clear_cache();
|
clear_cache();
|
||||||
CDWriter cdata(_cycler);
|
CDWriter cdata(_cycler);
|
||||||
nassertr(i >= 0 && i < (int)cdata->_primitives.size(), NULL);
|
nassertr(i >= 0 && i < (int)cdata->_primitives.size(), NULL);
|
||||||
|
cdata->_got_usage_hint = false;
|
||||||
return cdata->_primitives[i];
|
return cdata->_primitives[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +103,19 @@ set_primitive(int i, const qpGeomPrimitive *primitive) {
|
|||||||
clear_cache();
|
clear_cache();
|
||||||
CDWriter cdata(_cycler);
|
CDWriter cdata(_cycler);
|
||||||
nassertv(i >= 0 && i < (int)cdata->_primitives.size());
|
nassertv(i >= 0 && i < (int)cdata->_primitives.size());
|
||||||
|
if (cdata->_got_usage_hint &&
|
||||||
|
cdata->_primitives[i]->get_usage_hint() != primitive->get_usage_hint()) {
|
||||||
|
if (cdata->_primitives[i]->get_usage_hint() < primitive->get_usage_hint()) {
|
||||||
|
// If we're reducing the usage hint, we might also be reducing
|
||||||
|
// the minimum usage hit.
|
||||||
|
cdata->_usage_hint = min(cdata->_usage_hint, primitive->get_usage_hint());
|
||||||
|
} else { // (cdata->_primitives[i]->get_usage_hint() > primitive->get_usage_hint())
|
||||||
|
// If we're increasing it, we might have to rederive the minimum.
|
||||||
|
if (cdata->_usage_hint == cdata->_primitives[i]->get_usage_hint()) {
|
||||||
|
cdata->_got_usage_hint = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
cdata->_primitives[i] = (qpGeomPrimitive *)primitive;
|
cdata->_primitives[i] = (qpGeomPrimitive *)primitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +125,10 @@ set_primitive(int i, const qpGeomPrimitive *primitive) {
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE qpGeom::CData::
|
INLINE qpGeom::CData::
|
||||||
CData() {
|
CData() :
|
||||||
|
_usage_hint(qpGeomUsageHint::UH_static),
|
||||||
|
_got_usage_hint(false)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -105,7 +139,9 @@ CData() {
|
|||||||
INLINE qpGeom::CData::
|
INLINE qpGeom::CData::
|
||||||
CData(const qpGeom::CData ©) :
|
CData(const qpGeom::CData ©) :
|
||||||
_data(copy._data),
|
_data(copy._data),
|
||||||
_primitives(copy._primitives)
|
_primitives(copy._primitives),
|
||||||
|
_usage_hint(copy._usage_hint),
|
||||||
|
_got_usage_hint(copy._got_usage_hint)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "bamReader.h"
|
#include "bamReader.h"
|
||||||
#include "bamWriter.h"
|
#include "bamWriter.h"
|
||||||
|
|
||||||
|
UpdateSeq qpGeom::_next_modified;
|
||||||
TypeHandle qpGeom::_type_handle;
|
TypeHandle qpGeom::_type_handle;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -152,6 +153,10 @@ add_primitive(const qpGeomPrimitive *primitive) {
|
|||||||
clear_cache();
|
clear_cache();
|
||||||
CDWriter cdata(_cycler);
|
CDWriter cdata(_cycler);
|
||||||
cdata->_primitives.push_back((qpGeomPrimitive *)primitive);
|
cdata->_primitives.push_back((qpGeomPrimitive *)primitive);
|
||||||
|
|
||||||
|
if (cdata->_got_usage_hint) {
|
||||||
|
cdata->_usage_hint = min(cdata->_usage_hint, primitive->get_usage_hint());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -164,6 +169,12 @@ remove_primitive(int i) {
|
|||||||
clear_cache();
|
clear_cache();
|
||||||
CDWriter cdata(_cycler);
|
CDWriter cdata(_cycler);
|
||||||
nassertv(i >= 0 && i < (int)cdata->_primitives.size());
|
nassertv(i >= 0 && i < (int)cdata->_primitives.size());
|
||||||
|
if (cdata->_got_usage_hint &&
|
||||||
|
cdata->_usage_hint == cdata->_primitives[i]->get_usage_hint()) {
|
||||||
|
// Maybe we're raising the minimum usage_hint; we have to rederive
|
||||||
|
// the usage_hint later.
|
||||||
|
cdata->_got_usage_hint = false;
|
||||||
|
}
|
||||||
cdata->_primitives.erase(cdata->_primitives.begin() + i);
|
cdata->_primitives.erase(cdata->_primitives.begin() + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,6 +214,34 @@ get_num_bytes() const {
|
|||||||
return num_bytes;
|
return num_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeom::get_modified
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the maximum UpdateSeq of all the Geom's
|
||||||
|
// individual primitives and vertex arrays. This,
|
||||||
|
// therefore, will change only when any part of the Geom
|
||||||
|
// changes.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
UpdateSeq qpGeom::
|
||||||
|
get_modified() const {
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
UpdateSeq seq;
|
||||||
|
|
||||||
|
Primitives::const_iterator pi;
|
||||||
|
for (pi = cdata->_primitives.begin();
|
||||||
|
pi != cdata->_primitives.end();
|
||||||
|
++pi) {
|
||||||
|
seq = max(seq, (*pi)->get_modified());
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_arrays = cdata->_data->get_num_arrays();
|
||||||
|
for (int i = 0; i < num_arrays; ++i) {
|
||||||
|
seq = max(seq, cdata->_data->get_array(i)->get_modified());
|
||||||
|
}
|
||||||
|
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeom::munge_geom
|
// Function: qpGeom::munge_geom
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -342,9 +381,25 @@ clear_cache() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void qpGeom::
|
void qpGeom::
|
||||||
draw(GraphicsStateGuardianBase *gsg, const qpGeomVertexData *vertex_data) const {
|
draw(GraphicsStateGuardianBase *gsg, const qpGeomVertexData *vertex_data) const {
|
||||||
|
#ifdef DO_PIPELINING
|
||||||
|
// Make sure the usage_hint is already updated before we start to
|
||||||
|
// draw, so we don't end up with a circular lock if the GSG asks us
|
||||||
|
// to update this while we're holding the read lock.
|
||||||
|
{
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
if (!cdata->_got_usage_hint) {
|
||||||
|
CDWriter cdataw(((qpGeom *)this)->_cycler, cdata);
|
||||||
|
((qpGeom *)this)->reset_usage_hint(cdataw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: fix up the race condition between this line and the next.
|
||||||
|
// Maybe CDWriter's elevate-to-write should return the read lock to
|
||||||
|
// its original locked state when it's done.
|
||||||
|
#endif // DO_PIPELINING
|
||||||
|
|
||||||
CDReader cdata(_cycler);
|
CDReader cdata(_cycler);
|
||||||
|
|
||||||
if (gsg->begin_draw_primitives(vertex_data)) {
|
if (gsg->begin_draw_primitives(this, vertex_data)) {
|
||||||
Primitives::const_iterator pi;
|
Primitives::const_iterator pi;
|
||||||
for (pi = cdata->_primitives.begin();
|
for (pi = cdata->_primitives.begin();
|
||||||
pi != cdata->_primitives.end();
|
pi != cdata->_primitives.end();
|
||||||
@ -355,6 +410,25 @@ draw(GraphicsStateGuardianBase *gsg, const qpGeomVertexData *vertex_data) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeom::get_next_modified
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns a monotonically increasing sequence. Each
|
||||||
|
// time this is called, a new sequence number is
|
||||||
|
// returned, higher than the previous value.
|
||||||
|
//
|
||||||
|
// This is used to ensure that
|
||||||
|
// GeomVertexArrayData::get_modified() and
|
||||||
|
// GeomPrimitive::get_modified() update from the same
|
||||||
|
// space, so that Geom::get_modified() returns a
|
||||||
|
// meaningful value.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
UpdateSeq qpGeom::
|
||||||
|
get_next_modified() {
|
||||||
|
++_next_modified;
|
||||||
|
return _next_modified;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeom::recompute_bound
|
// Function: qpGeom::recompute_bound
|
||||||
// Access: Protected, Virtual
|
// Access: Protected, Virtual
|
||||||
@ -445,6 +519,23 @@ remove_cache_entry(const qpGeomMunger *modifier) const {
|
|||||||
((qpGeom *)this)->_cycler.release_write_stage(0, cdata);
|
((qpGeom *)this)->_cycler.release_write_stage(0, cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeom::reset_usage_hint
|
||||||
|
// Access: Private
|
||||||
|
// Description: Recomputes the minimum usage_hint.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void qpGeom::
|
||||||
|
reset_usage_hint(qpGeom::CDWriter &cdata) {
|
||||||
|
cdata->_usage_hint = qpGeomUsageHint::UH_static;
|
||||||
|
Primitives::const_iterator pi;
|
||||||
|
for (pi = cdata->_primitives.begin();
|
||||||
|
pi != cdata->_primitives.end();
|
||||||
|
++pi) {
|
||||||
|
cdata->_usage_hint = min(cdata->_usage_hint, (*pi)->get_usage_hint());
|
||||||
|
}
|
||||||
|
cdata->_got_usage_hint = true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeom::register_with_read_factory
|
// Function: qpGeom::register_with_read_factory
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include "qpgeomVertexData.h"
|
#include "qpgeomVertexData.h"
|
||||||
#include "qpgeomPrimitive.h"
|
#include "qpgeomPrimitive.h"
|
||||||
#include "qpgeomMunger.h"
|
#include "qpgeomMunger.h"
|
||||||
|
#include "qpgeomUsageHint.h"
|
||||||
|
#include "updateSeq.h"
|
||||||
#include "pointerTo.h"
|
#include "pointerTo.h"
|
||||||
#include "geom.h"
|
#include "geom.h"
|
||||||
|
|
||||||
@ -61,6 +63,8 @@ PUBLISHED:
|
|||||||
// Temporary.
|
// Temporary.
|
||||||
virtual Geom *make_copy() const;
|
virtual Geom *make_copy() const;
|
||||||
|
|
||||||
|
INLINE qpGeomUsageHint::UsageHint get_usage_hint() const;
|
||||||
|
|
||||||
INLINE CPT(qpGeomVertexData) get_vertex_data() const;
|
INLINE CPT(qpGeomVertexData) get_vertex_data() const;
|
||||||
PT(qpGeomVertexData) modify_vertex_data();
|
PT(qpGeomVertexData) modify_vertex_data();
|
||||||
void set_vertex_data(const qpGeomVertexData *data);
|
void set_vertex_data(const qpGeomVertexData *data);
|
||||||
@ -74,6 +78,7 @@ PUBLISHED:
|
|||||||
void clear_primitives();
|
void clear_primitives();
|
||||||
|
|
||||||
int get_num_bytes() const;
|
int get_num_bytes() const;
|
||||||
|
UpdateSeq get_modified() const;
|
||||||
|
|
||||||
void munge_geom(const qpGeomMunger *munger,
|
void munge_geom(const qpGeomMunger *munger,
|
||||||
CPT(qpGeom) &result, CPT(qpGeomVertexData) &data) const;
|
CPT(qpGeom) &result, CPT(qpGeomVertexData) &data) const;
|
||||||
@ -87,6 +92,8 @@ public:
|
|||||||
void draw(GraphicsStateGuardianBase *gsg,
|
void draw(GraphicsStateGuardianBase *gsg,
|
||||||
const qpGeomVertexData *vertex_data) const;
|
const qpGeomVertexData *vertex_data) const;
|
||||||
|
|
||||||
|
static UpdateSeq get_next_modified();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual BoundingVolume *recompute_bound();
|
virtual BoundingVolume *recompute_bound();
|
||||||
|
|
||||||
@ -120,6 +127,8 @@ private:
|
|||||||
|
|
||||||
PT(qpGeomVertexData) _data;
|
PT(qpGeomVertexData) _data;
|
||||||
Primitives _primitives;
|
Primitives _primitives;
|
||||||
|
qpGeomUsageHint::UsageHint _usage_hint;
|
||||||
|
bool _got_usage_hint;
|
||||||
MungedCache _munged_cache;
|
MungedCache _munged_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -127,6 +136,10 @@ private:
|
|||||||
typedef CycleDataReader<CData> CDReader;
|
typedef CycleDataReader<CData> CDReader;
|
||||||
typedef CycleDataWriter<CData> CDWriter;
|
typedef CycleDataWriter<CData> CDWriter;
|
||||||
|
|
||||||
|
void reset_usage_hint(CDWriter &cdata);
|
||||||
|
|
||||||
|
static UpdateSeq _next_modified;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void register_with_read_factory();
|
static void register_with_read_factory();
|
||||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "qpgeomPrimitive.h"
|
#include "qpgeomPrimitive.h"
|
||||||
|
#include "qpgeom.h"
|
||||||
#include "qpgeomVertexData.h"
|
#include "qpgeomVertexData.h"
|
||||||
#include "qpgeomVertexArrayFormat.h"
|
#include "qpgeomVertexArrayFormat.h"
|
||||||
#include "qpgeomVertexDataType.h"
|
#include "qpgeomVertexDataType.h"
|
||||||
@ -536,7 +537,7 @@ clear_cache() {
|
|||||||
|
|
||||||
// This, on the other hand, should be applied to the current
|
// This, on the other hand, should be applied to the current
|
||||||
// pipeline stage.
|
// pipeline stage.
|
||||||
++(cdata->_modified);
|
cdata->_modified = qpGeom::get_next_modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,26 +50,30 @@
|
|||||||
class EXPCL_PANDA qpGeomUsageHint {
|
class EXPCL_PANDA qpGeomUsageHint {
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
enum UsageHint {
|
enum UsageHint {
|
||||||
|
// The following are intentionally ordered from most dynamic to
|
||||||
|
// most static. In general, if usage_a < usage_b, then usage_a is
|
||||||
|
// more dynamic than usage_b.
|
||||||
|
|
||||||
// UH_client: don't attempt to upload the data; always keep it on
|
// UH_client: don't attempt to upload the data; always keep it on
|
||||||
// the client.
|
// the client.
|
||||||
UH_client,
|
UH_client,
|
||||||
|
|
||||||
// UH_stream: the data will be created once, used to render a few
|
// UH_stream: the data will be created once, used to render a few
|
||||||
// times, and then discarded. This should be used for short-lived
|
// times, and then discarded. This should be used for short-lived
|
||||||
// temporary arrays.
|
// temporary objects.
|
||||||
UH_stream,
|
UH_stream,
|
||||||
|
|
||||||
|
// UH_dynamic: the data will be repeatedly modified and
|
||||||
|
// re-rendered. This is for data that will be modified at
|
||||||
|
// runtime, such as animated or soft-skinned vertices.
|
||||||
|
UH_dynamic,
|
||||||
|
|
||||||
// UH_static: the data will be created once, and used to render
|
// UH_static: the data will be created once, and used to render
|
||||||
// many times, without modification. This is the most common
|
// many times, without modification. This is the most common
|
||||||
// case, since typically vertex data is not directly animated
|
// case, since typically vertex data is not directly animated
|
||||||
// (this is not related to scene graph animation, e.g. from
|
// (this is not related to scene graph animation, e.g. from
|
||||||
// adjusting transforms on a node).
|
// adjusting transforms on a node).
|
||||||
UH_static,
|
UH_static,
|
||||||
|
|
||||||
// UH_dynamic: the data will be repeatedly modified and
|
|
||||||
// re-rendered. This is for data that will be modified at
|
|
||||||
// runtime, such as animated or soft-skinned vertices.
|
|
||||||
UH_dynamic,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,43 +52,6 @@ get_data() const {
|
|||||||
return cdata->_data;
|
return cdata->_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: qpGeomVertexArrayData::modify_data
|
|
||||||
// Access: Published
|
|
||||||
// Description: Returns a modifiable pointer to the actual vertex
|
|
||||||
// array, so that application code may directly
|
|
||||||
// manipulate the vertices.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE PTA_uchar qpGeomVertexArrayData::
|
|
||||||
modify_data() {
|
|
||||||
// Perform copy-on-write: if the reference count on the vertex data
|
|
||||||
// is greater than 1, assume some other GeomVertexData has the same
|
|
||||||
// pointer, so make a copy of it first.
|
|
||||||
CDWriter cdata(_cycler);
|
|
||||||
|
|
||||||
if (cdata->_data.get_ref_count() > 1) {
|
|
||||||
PTA_uchar orig_data = cdata->_data;
|
|
||||||
cdata->_data = PTA_uchar();
|
|
||||||
cdata->_data.v() = orig_data.v();
|
|
||||||
}
|
|
||||||
++(cdata->_modified);
|
|
||||||
|
|
||||||
return cdata->_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: qpGeomVertexArrayData::set_data
|
|
||||||
// Access: Published
|
|
||||||
// Description: Replaces the vertex data array with a completely new
|
|
||||||
// array.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE void qpGeomVertexArrayData::
|
|
||||||
set_data(CPTA_uchar array) {
|
|
||||||
CDWriter cdata(_cycler);
|
|
||||||
cdata->_data = (PTA_uchar &)array;
|
|
||||||
++(cdata->_modified);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomVertexArrayData::get_num_vertices
|
// Function: qpGeomVertexArrayData::get_num_vertices
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "qpgeomVertexArrayData.h"
|
#include "qpgeomVertexArrayData.h"
|
||||||
|
#include "qpgeom.h"
|
||||||
#include "preparedGraphicsObjects.h"
|
#include "preparedGraphicsObjects.h"
|
||||||
#include "bamReader.h"
|
#include "bamReader.h"
|
||||||
#include "bamWriter.h"
|
#include "bamWriter.h"
|
||||||
@ -82,6 +83,43 @@ qpGeomVertexArrayData::
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomVertexArrayData::modify_data
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a modifiable pointer to the actual vertex
|
||||||
|
// array, so that application code may directly
|
||||||
|
// manipulate the vertices.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PTA_uchar qpGeomVertexArrayData::
|
||||||
|
modify_data() {
|
||||||
|
// Perform copy-on-write: if the reference count on the vertex data
|
||||||
|
// is greater than 1, assume some other GeomVertexData has the same
|
||||||
|
// pointer, so make a copy of it first.
|
||||||
|
CDWriter cdata(_cycler);
|
||||||
|
|
||||||
|
if (cdata->_data.get_ref_count() > 1) {
|
||||||
|
PTA_uchar orig_data = cdata->_data;
|
||||||
|
cdata->_data = PTA_uchar();
|
||||||
|
cdata->_data.v() = orig_data.v();
|
||||||
|
}
|
||||||
|
cdata->_modified = qpGeom::get_next_modified();
|
||||||
|
|
||||||
|
return cdata->_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomVertexArrayData::set_data
|
||||||
|
// Access: Published
|
||||||
|
// Description: Replaces the vertex data array with a completely new
|
||||||
|
// array.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void qpGeomVertexArrayData::
|
||||||
|
set_data(CPTA_uchar array) {
|
||||||
|
CDWriter cdata(_cycler);
|
||||||
|
cdata->_data = (PTA_uchar &)array;
|
||||||
|
cdata->_modified = qpGeom::get_next_modified();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomVertexArrayData::set_num_vertices
|
// Function: qpGeomVertexArrayData::set_num_vertices
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -125,7 +163,7 @@ set_num_vertices(int n) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++(cdata->_modified);
|
cdata->_modified = qpGeom::get_next_modified();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -66,8 +66,8 @@ PUBLISHED:
|
|||||||
INLINE qpGeomUsageHint::UsageHint get_usage_hint() const;
|
INLINE qpGeomUsageHint::UsageHint get_usage_hint() const;
|
||||||
|
|
||||||
INLINE CPTA_uchar get_data() const;
|
INLINE CPTA_uchar get_data() const;
|
||||||
INLINE PTA_uchar modify_data();
|
PTA_uchar modify_data();
|
||||||
INLINE void set_data(CPTA_uchar data);
|
void set_data(CPTA_uchar data);
|
||||||
|
|
||||||
INLINE int get_num_vertices() const;
|
INLINE int get_num_vertices() const;
|
||||||
bool set_num_vertices(int n);
|
bool set_num_vertices(int n);
|
||||||
|
@ -45,6 +45,7 @@ class GeomTri;
|
|||||||
class GeomTristrip;
|
class GeomTristrip;
|
||||||
class GeomTrifan;
|
class GeomTrifan;
|
||||||
class GeomSphere;
|
class GeomSphere;
|
||||||
|
class qpGeom;
|
||||||
class qpGeomVertexData;
|
class qpGeomVertexData;
|
||||||
class qpGeomVertexArrayData;
|
class qpGeomVertexArrayData;
|
||||||
class qpGeomPrimitive;
|
class qpGeomPrimitive;
|
||||||
@ -183,7 +184,7 @@ public:
|
|||||||
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc)=0;
|
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc)=0;
|
||||||
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc)=0;
|
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc)=0;
|
||||||
|
|
||||||
virtual bool begin_draw_primitives(const qpGeomVertexData *vertex_data)=0;
|
virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data)=0;
|
||||||
virtual void draw_triangles(const qpGeomTriangles *primitive)=0;
|
virtual void draw_triangles(const qpGeomTriangles *primitive)=0;
|
||||||
virtual void draw_tristrips(const qpGeomTristrips *primitive)=0;
|
virtual void draw_tristrips(const qpGeomTristrips *primitive)=0;
|
||||||
virtual void draw_trifans(const qpGeomTrifans *primitive)=0;
|
virtual void draw_trifans(const qpGeomTrifans *primitive)=0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user