From 227d3f4df10462f80c4dc0d4dee082468c9757fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 1 Jan 2015 11:14:20 -0800 Subject: [PATCH] Updated ib-compress. --- .../ib-compress/indexbuffercompression.cpp | 42 +++++++++++++++++-- 3rdparty/ib-compress/indexbuffercompression.h | 7 +++- .../indexbuffercompressionformat.h | 6 ++- .../ib-compress/indexbufferdecompression.cpp | 2 + README.md | 4 ++ tools/geometryc/geometryc.cpp | 10 ++--- 6 files changed, 58 insertions(+), 13 deletions(-) diff --git a/3rdparty/ib-compress/indexbuffercompression.cpp b/3rdparty/ib-compress/indexbuffercompression.cpp index 03c15fe7..5d4f5603 100644 --- a/3rdparty/ib-compress/indexbuffercompression.cpp +++ b/3rdparty/ib-compress/indexbuffercompression.cpp @@ -525,8 +525,8 @@ void CompressTriangleCodes1( const Ty* triangles, break; } - default: // IB_EDGE_NEW, IB_EDGE_CACHED, IB_EDGE_0_NEW, IB_EDGE_1_NEW - break; + default: // IB_EDGE_NEW, IB_EDGE_CACHED, IB_EDGE_0_NEW, IB_EDGE_1_NEW + break; } // 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 +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 void CompressIndexBuffer( const Ty* triangles, uint32_t triangleCount, @@ -755,19 +774,34 @@ void CompressIndexBuffer( const Ty* triangles, IndexBufferCompressionFormat format, WriteBitstream& output ) { - output.WriteVInt( format ); - switch ( format ) { case IBCF_PER_INDICE_1: + output.WriteVInt( IBCF_PER_INDICE_1 ); CompressIndiceCodes1( triangles, triangleCount, vertexRemap, vertexCount, output ); break; case IBCF_PER_TRIANGLE_1: + output.WriteVInt( IBCF_PER_TRIANGLE_1 ); CompressTriangleCodes1( triangles, triangleCount, vertexRemap, vertexCount, output ); break; + + case ICBF_AUTO: + + if ( ContainsDegenerates( triangles, triangleCount ) ) + { + output.WriteVInt( IBCF_PER_INDICE_1 ); + CompressIndiceCodes1( triangles, triangleCount, vertexRemap, vertexCount, output ); + } + else + { + output.WriteVInt( IBCF_PER_TRIANGLE_1 ); + CompressTriangleCodes1( triangles, triangleCount, vertexRemap, vertexCount, output ); + } + + break; } } diff --git a/3rdparty/ib-compress/indexbuffercompression.h b/3rdparty/ib-compress/indexbuffercompression.h index e61acb8e..883dcec9 100644 --- a/3rdparty/ib-compress/indexbuffercompression.h +++ b/3rdparty/ib-compress/indexbuffercompression.h @@ -38,8 +38,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Parameters: // [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. -// [out] vertexRemap - This will be populated with re-mappings that map old vertices to new vertices, -// where indexing with the old vertex index will get you the new one. +// [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. 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. // [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. diff --git a/3rdparty/ib-compress/indexbuffercompressionformat.h b/3rdparty/ib-compress/indexbuffercompressionformat.h index a558d626..16903a15 100644 --- a/3rdparty/ib-compress/indexbuffercompressionformat.h +++ b/3rdparty/ib-compress/indexbuffercompressionformat.h @@ -8,7 +8,11 @@ enum IndexBufferCompressionFormat IBCF_PER_INDICE_1 = 0, // 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__ \ No newline at end of file diff --git a/3rdparty/ib-compress/indexbufferdecompression.cpp b/3rdparty/ib-compress/indexbufferdecompression.cpp index f64be77d..10c8881d 100644 --- a/3rdparty/ib-compress/indexbufferdecompression.cpp +++ b/3rdparty/ib-compress/indexbufferdecompression.cpp @@ -465,6 +465,8 @@ void DecompressIndexBuffer( Ty* triangles, uint32_t triangleCount, ReadBitstream DecompressTriangleCodes1( triangles, triangleCount, input ); break; + default: // ICBF_AUTO: + break; } } diff --git a/README.md b/README.md index bdeaa411..26bf0e52 100644 --- a/README.md +++ b/README.md @@ -649,6 +649,10 @@ https://github.com/memononen/SDF http://nothings.org +### Vertex Cache Optimised Index Buffer Compression + +https://github.com/ConorStokes/IndexBufferCompression + Assets ------ diff --git a/tools/geometryc/geometryc.cpp b/tools/geometryc/geometryc.cpp index a240ddce..a90d113d 100644 --- a/tools/geometryc/geometryc.cpp +++ b/tools/geometryc/geometryc.cpp @@ -115,7 +115,6 @@ typedef std::vector PrimitiveArray; 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_IB BX_MAKEFOURCC('I', 'B', ' ', 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) ); WriteBitstream writer; - CompressIndexBuffer(_indices, _numIndices/3, vertexRemap, _numVertices, IBCF_PER_TRIANGLE_1, writer); + CompressIndexBuffer(_indices, _numIndices/3, vertexRemap, _numVertices, ICBF_AUTO, writer); writer.Finish(); printf( "uncompressed: %10d, compressed: %10d, ratio: %0.2f%%\n" , _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); for (uint32_t ii = 0; ii < _numVertices; ++ii) { - if (UINT32_MAX != vertexRemap[ii]) - { - memcpy(&outVertexData[vertexRemap[ii]*_stride], &_vertexData[ii*_stride], _stride); - } + uint32_t remap = vertexRemap[ii]; + remap = UINT32_MAX == remap ? ii : remap; + memcpy(&outVertexData[remap*_stride], &_vertexData[ii*_stride], _stride); } memcpy(_vertexData, outVertexData, _numVertices*_stride); free(outVertexData);