Updated ib-compress.

This commit is contained in:
Branimir Karadžić 2015-01-01 11:14:20 -08:00
parent 7d81db60e1
commit 227d3f4df1
6 changed files with 58 additions and 13 deletions

View file

@ -525,8 +525,8 @@ void CompressTriangleCodes1( const Ty* triangles,
break; break;
} }
default: // IB_EDGE_NEW, IB_EDGE_CACHED, IB_EDGE_0_NEW, IB_EDGE_1_NEW default: // IB_EDGE_NEW, IB_EDGE_CACHED, IB_EDGE_0_NEW, IB_EDGE_1_NEW
break; break;
} }
// populate the edge fifo with the 3 most recent edges // populate the edge fifo with the 3 most recent edges
@ -747,6 +747,25 @@ void CompressIndiceCodes1( const Ty* triangles,
} }
} }
// Detects if there are any degenerate triangles in a set of triangles, where there is 1 or more duplicate vertices.
template <typename Ty>
bool ContainsDegenerates( const Ty* triangles, uint32_t triangleCount )
{
const Ty* triangleEnd = triangles + ( triangleCount * 3 );
bool result = false;
for ( const Ty* triangle = triangles; triangle < triangleEnd; triangle += 3 )
{
if ( triangle[ 0 ] == triangle[ 1 ] || triangle[ 0 ] == triangle[ 2 ] || triangle[ 1 ] == triangle[ 2 ] )
{
result = true;
break;
}
}
return result;
}
template <typename Ty> template <typename Ty>
void CompressIndexBuffer( const Ty* triangles, void CompressIndexBuffer( const Ty* triangles,
uint32_t triangleCount, uint32_t triangleCount,
@ -755,19 +774,34 @@ void CompressIndexBuffer( const Ty* triangles,
IndexBufferCompressionFormat format, IndexBufferCompressionFormat format,
WriteBitstream& output ) WriteBitstream& output )
{ {
output.WriteVInt( format );
switch ( format ) switch ( format )
{ {
case IBCF_PER_INDICE_1: case IBCF_PER_INDICE_1:
output.WriteVInt( IBCF_PER_INDICE_1 );
CompressIndiceCodes1<Ty>( triangles, triangleCount, vertexRemap, vertexCount, output ); CompressIndiceCodes1<Ty>( triangles, triangleCount, vertexRemap, vertexCount, output );
break; break;
case IBCF_PER_TRIANGLE_1: case IBCF_PER_TRIANGLE_1:
output.WriteVInt( IBCF_PER_TRIANGLE_1 );
CompressTriangleCodes1<Ty>( triangles, triangleCount, vertexRemap, vertexCount, output ); CompressTriangleCodes1<Ty>( triangles, triangleCount, vertexRemap, vertexCount, output );
break; break;
case ICBF_AUTO:
if ( ContainsDegenerates( triangles, triangleCount ) )
{
output.WriteVInt( IBCF_PER_INDICE_1 );
CompressIndiceCodes1<Ty>( triangles, triangleCount, vertexRemap, vertexCount, output );
}
else
{
output.WriteVInt( IBCF_PER_TRIANGLE_1 );
CompressTriangleCodes1<Ty>( triangles, triangleCount, vertexRemap, vertexCount, output );
}
break;
} }
} }

View file

@ -38,8 +38,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Parameters: // Parameters:
// [in] triangles - A typical triangle list index buffer (3 indices to vertices per triangle). 16 bit indices. // [in] triangles - A typical triangle list index buffer (3 indices to vertices per triangle). 16 bit indices.
// [in] triangle count - The number of triangles to process. // [in] triangle count - The number of triangles to process.
// [out] vertexRemap - This will be populated with re-mappings that map old vertices to new vertices, // [out] vertexRemap - This will be populated with re-mappings that map old vertices to new vertex locations (a new ordering),
// where indexing with the old vertex index will get you the new one. // where indexing with the old vertex index will get you the new one. Vertices that are unused will
// be mapped to 0xFFFFFFFF.
// You should re-order the vertices and removed unused ones based on the vertex remap, instead of storing
// the remap.
// It should be allocated as a with at least vertexCount entries. // It should be allocated as a with at least vertexCount entries.
// [in] vertexCount - The number of vertices in the mesh. This should be less than 0xFFFFFFFF/2^32 - 1. // [in] vertexCount - The number of vertices in the mesh. This should be less than 0xFFFFFFFF/2^32 - 1.
// [in] format - The compression format to use for encoding - note the format will be encoded with the compressed data so the decompressor can select the correct algorithm. // [in] format - The compression format to use for encoding - note the format will be encoded with the compressed data so the decompressor can select the correct algorithm.

View file

@ -8,7 +8,11 @@ enum IndexBufferCompressionFormat
IBCF_PER_INDICE_1 = 0, IBCF_PER_INDICE_1 = 0,
// Per triangle encoding - better compression/speed, does not handle degenerates. // Per triangle encoding - better compression/speed, does not handle degenerates.
IBCF_PER_TRIANGLE_1 = 1 IBCF_PER_TRIANGLE_1 = 1,
// Automatically pick the best encoding dependent on whether degenerate triangles are detected in the mesh.
// Will take longer to compress (due to the degenerate triangle check).
ICBF_AUTO = 2
}; };
#endif // -- INDEX_BUFFER_COMPRESSION_FORMAT_H__ #endif // -- INDEX_BUFFER_COMPRESSION_FORMAT_H__

View file

@ -465,6 +465,8 @@ void DecompressIndexBuffer( Ty* triangles, uint32_t triangleCount, ReadBitstream
DecompressTriangleCodes1<Ty>( triangles, triangleCount, input ); DecompressTriangleCodes1<Ty>( triangles, triangleCount, input );
break; break;
default: // ICBF_AUTO:
break;
} }
} }

View file

@ -649,6 +649,10 @@ https://github.com/memononen/SDF
http://nothings.org http://nothings.org
### Vertex Cache Optimised Index Buffer Compression
https://github.com/ConorStokes/IndexBufferCompression
Assets Assets
------ ------

View file

@ -115,7 +115,6 @@ typedef std::vector<Primitive> PrimitiveArray;
static uint32_t s_obbSteps = 17; static uint32_t s_obbSteps = 17;
#define BGFX_CHUNK_MAGIC_GEO BX_MAKEFOURCC('G', 'E', 'O', 0x0)
#define BGFX_CHUNK_MAGIC_VB BX_MAKEFOURCC('V', 'B', ' ', 0x1) #define BGFX_CHUNK_MAGIC_VB BX_MAKEFOURCC('V', 'B', ' ', 0x1)
#define BGFX_CHUNK_MAGIC_IB BX_MAKEFOURCC('I', 'B', ' ', 0x0) #define BGFX_CHUNK_MAGIC_IB BX_MAKEFOURCC('I', 'B', ' ', 0x0)
#define BGFX_CHUNK_MAGIC_IBC BX_MAKEFOURCC('I', 'B', 'C', 0x0) #define BGFX_CHUNK_MAGIC_IBC BX_MAKEFOURCC('I', 'B', 'C', 0x0)
@ -143,7 +142,7 @@ void triangleCompress(bx::WriterI* _writer, uint16_t* _indices, uint32_t _numInd
uint32_t* vertexRemap = (uint32_t*)malloc(_numVertices*sizeof(uint32_t) ); uint32_t* vertexRemap = (uint32_t*)malloc(_numVertices*sizeof(uint32_t) );
WriteBitstream writer; WriteBitstream writer;
CompressIndexBuffer(_indices, _numIndices/3, vertexRemap, _numVertices, IBCF_PER_TRIANGLE_1, writer); CompressIndexBuffer(_indices, _numIndices/3, vertexRemap, _numVertices, ICBF_AUTO, writer);
writer.Finish(); writer.Finish();
printf( "uncompressed: %10d, compressed: %10d, ratio: %0.2f%%\n" printf( "uncompressed: %10d, compressed: %10d, ratio: %0.2f%%\n"
, _numIndices * 2 , _numIndices * 2
@ -155,10 +154,9 @@ void triangleCompress(bx::WriterI* _writer, uint16_t* _indices, uint32_t _numInd
uint8_t* outVertexData = (uint8_t*)malloc(_numVertices*_stride); uint8_t* outVertexData = (uint8_t*)malloc(_numVertices*_stride);
for (uint32_t ii = 0; ii < _numVertices; ++ii) for (uint32_t ii = 0; ii < _numVertices; ++ii)
{ {
if (UINT32_MAX != vertexRemap[ii]) uint32_t remap = vertexRemap[ii];
{ remap = UINT32_MAX == remap ? ii : remap;
memcpy(&outVertexData[vertexRemap[ii]*_stride], &_vertexData[ii*_stride], _stride); memcpy(&outVertexData[remap*_stride], &_vertexData[ii*_stride], _stride);
}
} }
memcpy(_vertexData, outVertexData, _numVertices*_stride); memcpy(_vertexData, outVertexData, _numVertices*_stride);
free(outVertexData); free(outVertexData);