add vertex-column-alignment

This commit is contained in:
David Rose 2011-12-17 01:55:52 +00:00
parent 73e89c8254
commit 7de805989f
8 changed files with 105 additions and 17 deletions

View File

@ -272,6 +272,12 @@ ConfigVariableBool vertices_float64
"driver to downsample the vertices at load time, making everything "
"slower."));
ConfigVariableInt vertex_column_alignment
("vertex-column-alignment", 0,
PRC_DESC("This specifies the default byte alignment for each column of "
"data within a GeomVertexData when it is assembled using the default "
"interfaces. See GeomVertexFormat::set_column_alignment()."));
ConfigVariableEnum<AutoTextureScale> textures_power_2
("textures-power-2", ATS_down,
PRC_DESC("Specify whether textures should automatically be constrained to "

View File

@ -64,6 +64,7 @@ extern EXPCL_PANDA_GOBJ ConfigVariableBool preserve_triangle_strips;
extern EXPCL_PANDA_GOBJ ConfigVariableBool dump_generated_shaders;
extern EXPCL_PANDA_GOBJ ConfigVariableBool enforce_attrib_lock;
extern EXPCL_PANDA_GOBJ ConfigVariableBool vertices_float64;
extern EXPCL_PANDA_GOBJ ConfigVariableInt vertex_column_alignment;
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<AutoTextureScale> textures_power_2;
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<AutoTextureScale> textures_square;

View File

@ -415,19 +415,6 @@ add_vertices(int v1, int v2, int v3, int v4) {
add_vertex(v4);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_index_format
// Access: Public
// Description: Returns a registered format appropriate for using to
// store the index table.
////////////////////////////////////////////////////////////////////
INLINE CPT(GeomVertexArrayFormat) GeomPrimitive::
get_index_format() const {
return GeomVertexArrayFormat::register_format
(new GeomVertexArrayFormat(InternalName::get_index(), 1,
get_index_type(), C_index));
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::make_index_data
// Access: Public

View File

@ -1416,6 +1416,22 @@ release_all() {
return num_freed;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_index_format
// Access: Public
// Description: Returns a registered format appropriate for using to
// store the index table.
////////////////////////////////////////////////////////////////////
CPT(GeomVertexArrayFormat) GeomPrimitive::
get_index_format() const {
PT(GeomVertexArrayFormat) format = new GeomVertexArrayFormat;
// It's important that the index format not attempt to have any kind
// of SSE2 alignment or whatever. It needs to be tightly packed.
format->set_column_alignment(1);
format->add_column(InternalName::get_index(), 1, get_index_type(), C_index);
return GeomVertexArrayFormat::register_format(format);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::clear_prepared
// Access: Private

View File

@ -186,7 +186,7 @@ public:
bool release(PreparedGraphicsObjects *prepared_objects);
int release_all();
INLINE CPT(GeomVertexArrayFormat) get_index_format() const;
CPT(GeomVertexArrayFormat) get_index_format() const;
INLINE PT(GeomVertexArrayData) make_index_data() const;
private:

View File

@ -60,14 +60,58 @@ get_stride() const {
// Function: GeomVertexArrayFormat::set_stride
// Access: Published
// Description: Changes the total number of bytes reserved in the
// array for each vertex.
// array for each vertex. You may not reduce this below
// get_total_bytes(), but you may increase it
// arbitrarily.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexArrayFormat::
set_stride(int stride) {
nassertv(!_is_registered);
nassertv(_stride >= _total_bytes);
_stride = stride;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayFormat::get_column_alignment
// Access: Published
// Description: See set_column_alignment().
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexArrayFormat::
get_column_alignment() const {
return _column_alignment;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayFormat::set_column_alignment
// Access: Published
// Description: This specifies the byte alignment for each
// column of data within the format when add_column() is
// subsequently called with default parameters.
// Normally this is 0 or 1 to specify no particular
// alignment, but you may specify a higher number, for
// instace 4 to guarantee that all columns start at a
// word alignment, or 16 to align all columns for SSE2
// processing. This will introduce unused bytes between
// columns as needed to guarantee the requested
// alignment.
//
// Note that this does not change existing columns, only
// subsequent columns; and if you specify the start byte
// explicitly in add_column(), it will override this
// setting. Note also that there is no point in
// exceeding the memory alignment of Panda3D itself,
// which is compiled into Panda and can be determined by
// MemoryHook::get_memory_alignment().
//
// Also see the config variable vertex-column-alignment
// for a way to change the global default.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexArrayFormat::
set_column_alignment(int column_alignment) {
nassertv(!_is_registered);
_column_alignment = column_alignment;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayFormat::get_total_bytes
// Access: Published

View File

@ -34,6 +34,7 @@ GeomVertexArrayFormat::
GeomVertexArrayFormat() :
_is_registered(false),
_stride(0),
_column_alignment(vertex_column_alignment),
_total_bytes(0),
_pad_to(1),
_columns_unsorted(false)
@ -51,6 +52,7 @@ GeomVertexArrayFormat(InternalName *name0, int num_components0,
GeomVertexArrayFormat::Contents contents0) :
_is_registered(false),
_stride(0),
_column_alignment(vertex_column_alignment),
_total_bytes(0),
_pad_to(1),
_columns_unsorted(false)
@ -72,6 +74,7 @@ GeomVertexArrayFormat(InternalName *name0, int num_components0,
GeomVertexArrayFormat::Contents contents1) :
_is_registered(false),
_stride(0),
_column_alignment(vertex_column_alignment),
_total_bytes(0),
_pad_to(1),
_columns_unsorted(false)
@ -97,6 +100,7 @@ GeomVertexArrayFormat(InternalName *name0, int num_components0,
GeomVertexArrayFormat::Contents contents2) :
_is_registered(false),
_stride(0),
_column_alignment(vertex_column_alignment),
_total_bytes(0),
_pad_to(1),
_columns_unsorted(false)
@ -126,6 +130,7 @@ GeomVertexArrayFormat(InternalName *name0, int num_components0,
GeomVertexArrayFormat::Contents contents3) :
_is_registered(false),
_stride(0),
_column_alignment(vertex_column_alignment),
_total_bytes(0),
_pad_to(1),
_columns_unsorted(false)
@ -145,6 +150,7 @@ GeomVertexArrayFormat::
GeomVertexArrayFormat(const GeomVertexArrayFormat &copy) :
_is_registered(false),
_stride(copy._stride),
_column_alignment(copy._column_alignment),
_total_bytes(copy._total_bytes),
_pad_to(copy._pad_to),
_columns_unsorted(copy._columns_unsorted)
@ -164,6 +170,7 @@ void GeomVertexArrayFormat::
operator = (const GeomVertexArrayFormat &copy) {
nassertv(!_is_registered);
_stride = copy._stride;
_column_alignment = copy._column_alignment;
_total_bytes = copy._total_bytes;
_pad_to = copy._pad_to;
@ -233,6 +240,10 @@ add_column(InternalName *name, int num_components,
GeomVertexArrayFormat::Contents contents, int start) {
if (start < 0) {
start = _total_bytes;
if (_column_alignment > 1) {
// Round up to the next multiple of _column_alignment.
start = ((start + (_column_alignment - 1)) / _column_alignment) * _column_alignment;
}
GeomVertexColumn temp_column
(name, num_components, numeric_type, contents, 0);
@ -275,9 +286,19 @@ add_column(const GeomVertexColumn &column) {
orig_column = get_column(column.get_start(), column.get_total_bytes());
}
_total_bytes = max(_total_bytes, column.get_start() + column.get_total_bytes());
int column_bytes = column.get_total_bytes();
if (_column_alignment > 1 && (column.get_start() % _column_alignment == 0)) {
// Round up to the next multiple of _column_alignment.
column_bytes = ((column_bytes + _column_alignment - 1) / _column_alignment) * _column_alignment;
}
_total_bytes = max(_total_bytes, column.get_start() + column_bytes);
_pad_to = max(_pad_to, column.get_component_bytes());
_stride = max(_stride, ((_total_bytes + _pad_to - 1) / _pad_to) * _pad_to);
_stride = max(_stride, _total_bytes);
_stride = ((_stride + _pad_to - 1) / _pad_to) * _pad_to;
if (_column_alignment > 1) {
_stride = ((_stride + _column_alignment - 1) / _column_alignment) * _column_alignment;
}
GeomVertexColumn *new_column = new GeomVertexColumn(column);
@ -554,6 +575,14 @@ compare_to(const GeomVertexArrayFormat &other) const {
if (_stride != other._stride) {
return _stride - other._stride;
}
/*
// We don't compare column_alignment. That's a setting used only
// when constructing the format, and no longer relevant after it's
// been constructed.
if (_column_alignment != other._column_alignment) {
return _column_alignment - other._column_alignment;
}
*/
if (_total_bytes != other._total_bytes) {
return _total_bytes - other._total_bytes;
}
@ -731,6 +760,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
TypedWritableReferenceCount::fillin(scan, manager);
nassertv(!_is_registered);
// Maybe we should record _column_alignment, but we don't.
_stride = scan.get_uint16();
_total_bytes = scan.get_uint16();
_pad_to = scan.get_uint8();

View File

@ -85,6 +85,9 @@ PUBLISHED:
INLINE int get_stride() const;
INLINE void set_stride(int stride);
INLINE int get_column_alignment() const;
INLINE void set_column_alignment(int column_alignment);
INLINE int get_total_bytes() const;
INLINE int get_pad_to() const;
@ -128,6 +131,7 @@ private:
bool _is_registered;
int _stride;
int _column_alignment;
int _total_bytes;
int _pad_to;