diff --git a/examples/06-bump/bump.cpp b/examples/06-bump/bump.cpp index a2282713d..285f4c15f 100644 --- a/examples/06-bump/bump.cpp +++ b/examples/06-bump/bump.cpp @@ -42,21 +42,6 @@ uint32_t packUint32(uint8_t _x, uint8_t _y, uint8_t _z, uint8_t _w) return un.ui32; } -void unpackUint32(uint8_t _result[4], uint32_t _packed) -{ - union - { - uint32_t ui32; - uint8_t arr[4]; - } un; - - un.ui32 = _packed; - _result[0] = un.arr[0]; - _result[1] = un.arr[1]; - _result[2] = un.arr[2]; - _result[3] = un.arr[3]; -} - uint32_t packF4u(float _x, float _y = 0.0f, float _z = 0.0f, float _w = 0.0f) { const uint8_t xx = uint8_t(_x*127.0f + 128.0f); @@ -66,16 +51,6 @@ uint32_t packF4u(float _x, float _y = 0.0f, float _z = 0.0f, float _w = 0.0f) return packUint32(xx, yy, zz, ww); } -void unpackF4u(float _result[4], uint32_t _packed) -{ - uint8_t unpacked[4]; - unpackUint32(unpacked, _packed); - _result[0] = (float(unpacked[0]) - 128.0f)/127.0f; - _result[1] = (float(unpacked[1]) - 128.0f)/127.0f; - _result[2] = (float(unpacked[2]) - 128.0f)/127.0f; - _result[3] = (float(unpacked[3]) - 128.0f)/127.0f; -} - static PosNormalTangentTexcoordVertex s_cubeVertices[24] = { {-1.0f, 1.0f, 1.0f, packF4u( 0.0f, 0.0f, 1.0f), 0, 0.0f, 0.0f }, @@ -172,18 +147,42 @@ static const bgfx::Memory* loadTexture(const char* _name) return load(filePath); } -template -void calcTangents(const uint16_t* _indices, uint32_t _numIndices, Ty* _vertices, uint16_t _numVertices) +void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices) { + struct PosTexcoord + { + float m_x; + float m_y; + float m_z; + float m_pad0; + float m_u; + float m_v; + float m_pad1; + float m_pad2; + }; + float* tangents = new float[6*_numVertices]; memset(tangents, 0, 6*_numVertices*sizeof(float) ); + PosTexcoord v0; + PosTexcoord v1; + PosTexcoord v2; + for (uint32_t ii = 0, num = _numIndices/3; ii < num; ++ii) { const uint16_t* indices = &_indices[ii*3]; - const Ty& v0 = _vertices[indices[0] ]; - const Ty& v1 = _vertices[indices[1] ]; - const Ty& v2 = _vertices[indices[2] ]; + uint32_t i0 = indices[0]; + uint32_t i1 = indices[1]; + uint32_t i2 = indices[2]; + + bgfx::vertexUnpack(&v0.m_x, bgfx::Attrib::Position, _decl, _vertices, i0); + bgfx::vertexUnpack(&v0.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i0); + + bgfx::vertexUnpack(&v1.m_x, bgfx::Attrib::Position, _decl, _vertices, i1); + bgfx::vertexUnpack(&v1.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i1); + + bgfx::vertexUnpack(&v2.m_x, bgfx::Attrib::Position, _decl, _vertices, i2); + bgfx::vertexUnpack(&v2.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i2); const float bax = v1.m_x - v0.m_x; const float bay = v1.m_y - v0.m_y; @@ -224,12 +223,11 @@ void calcTangents(const uint16_t* _indices, uint32_t _numIndices, Ty* _vertices, for (uint32_t ii = 0; ii < _numVertices; ++ii) { - Ty& v0 = _vertices[ii]; const float* tanu = &tangents[ii*6]; const float* tanv = &tangents[ii*6 + 3]; float normal[4]; - unpackF4u(normal, v0.m_normal); + bgfx::vertexUnpack(normal, bgfx::Attrib::Normal, _decl, _vertices, ii); float ndt = vec3Dot(normal, tanu); float nxt[3]; @@ -240,13 +238,13 @@ void calcTangents(const uint16_t* _indices, uint32_t _numIndices, Ty* _vertices, tmp[1] = tanu[1] - normal[1] * ndt; tmp[2] = tanu[2] - normal[2] * ndt; - float tangent[3]; + float tangent[4]; vec3Norm(tangent, tmp); - float tw = vec3Dot(nxt, tanv) < 0.0f ? -1.0f : 1.0f; - v0.m_tangent = packF4u(tangent[0], tangent[1], tangent[2], tw); + tangent[3] = vec3Dot(nxt, tanv) < 0.0f ? -1.0f : 1.0f; + bgfx::vertexPack(tangent, true, bgfx::Attrib::Tangent, _decl, _vertices, ii); } -} +} int _main_(int _argc, char** _argv) { @@ -293,14 +291,14 @@ int _main_(int _argc, char** _argv) // Create vertex stream declaration. s_PosNormalTangentTexcoordDecl.begin(); s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float); - s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true); - s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true); + s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true); + s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true); s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float); s_PosNormalTangentTexcoordDecl.end(); const bgfx::Memory* mem; - calcTangents(s_cubeIndices, countof(s_cubeIndices), s_cubeVertices, countof(s_cubeVertices) ); + calcTangents(s_cubeVertices, countof(s_cubeVertices), s_PosNormalTangentTexcoordDecl, s_cubeIndices, countof(s_cubeIndices) ); // Create static vertex buffer. mem = bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ); diff --git a/examples/07-callback/callback.cpp b/examples/07-callback/callback.cpp index 54d29c4b8..8bba83536 100644 --- a/examples/07-callback/callback.cpp +++ b/examples/07-callback/callback.cpp @@ -329,7 +329,10 @@ struct BgfxCallback : public bgfx::CallbackI virtual void fatal(bgfx::Fatal::Enum _code, const char* _str) BX_OVERRIDE { + // Something unexpected happened, inform user and bail out. dbgPrintf("Fatal error: 0x%08x: %s", _code, _str); + + // Must terminate, continuing will cause crash anyway. abort(); } @@ -337,14 +340,18 @@ struct BgfxCallback : public bgfx::CallbackI { char filePath[256]; bx::snprintf(filePath, sizeof(filePath), "%016" PRIx64, _id); + + // Use cache id as filename. FILE* file = fopen(filePath, "rb"); if (NULL != file) { uint32_t size = fsize(file); fclose(file); + // Return size of shader file. return size; } + // Return 0 if shader is not found. return 0; } @@ -352,14 +359,20 @@ struct BgfxCallback : public bgfx::CallbackI { char filePath[256]; bx::snprintf(filePath, sizeof(filePath), "%016" PRIx64, _id); + + // Use cache id as filename. FILE* file = fopen(filePath, "rb"); if (NULL != file) { + // Read shader. size_t result = fread(_data, 1, _size, file); fclose(file); + + // Make sure that read size matches requested size. return result == _size; } + // Shader is not found in cache, needs to be rebuilt. return false; } @@ -368,9 +381,11 @@ struct BgfxCallback : public bgfx::CallbackI char filePath[256]; bx::snprintf(filePath, sizeof(filePath), "%016" PRIx64, _id); + // Use cache id as filename. FILE* file = fopen(filePath, "wb"); if (NULL != file) { + // Write shader to cache location. fwrite(_data, 1, _size, file); fclose(file); } @@ -378,6 +393,7 @@ struct BgfxCallback : public bgfx::CallbackI virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t /*_size*/, bool _yflip) BX_OVERRIDE { + // Save screen shot as TGA. saveTga(_filePath, _width, _height, _pitch, _data, false, _yflip); } @@ -556,7 +572,7 @@ int _main_(int _argc, char** _argv) } } - // Take screenshot at frame 150. + // Take screen shot at frame 150. if (150 == frame) { bgfx::saveScreenShot("frame150.tga"); diff --git a/examples/runtime/meshes/bunny.bin b/examples/runtime/meshes/bunny.bin index c41f646f4..c16b62c73 100644 Binary files a/examples/runtime/meshes/bunny.bin and b/examples/runtime/meshes/bunny.bin differ diff --git a/examples/runtime/meshes/bunny.ctm b/examples/runtime/meshes/bunny.ctm deleted file mode 100644 index 693c37f2c..000000000 Binary files a/examples/runtime/meshes/bunny.ctm and /dev/null differ diff --git a/include/bgfx.h b/include/bgfx.h index f91776bc6..805be6249 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -386,8 +386,8 @@ namespace bgfx virtual void captureFrame(const void* _data, uint32_t _size) = 0; }; - inline CallbackI::~CallbackI() - { + inline CallbackI::~CallbackI() + { } struct Memory @@ -442,10 +442,10 @@ namespace bgfx void end(); /// Add attribute to VertexDecl. Note: Must be called between begin/end. - void add(Attrib::Enum _attrib, uint8_t _num, AttribType::Enum _type, bool _normalized = false); + void add(Attrib::Enum _attrib, uint8_t _num, AttribType::Enum _type, bool _normalized = false, bool _asInt = false); /// Decode attribute. - void decode(Attrib::Enum _attrib, uint8_t& _num, AttribType::Enum& _type, bool& _normalized) const; + void decode(Attrib::Enum _attrib, uint8_t& _num, AttribType::Enum& _type, bool& _normalized, bool& _asInt) const; /// Returns true if VertexDecl contains attribute. bool has(Attrib::Enum _attrib) const { return 0xff != m_attributes[_attrib]; } @@ -465,6 +465,12 @@ namespace bgfx uint8_t m_attributes[Attrib::Count]; }; + /// Pack vec4 into vertex stream format. + void vertexPack(const float _input[4], bool _inputNormalized, Attrib::Enum _attr, const VertexDecl& _decl, void* _data, uint32_t _index = 0); + + /// Unpack vec4 from vertex stream format. + void vertexUnpack(float _output[4], Attrib::Enum _attr, const VertexDecl& _decl, const void* _data, uint32_t _index = 0); + /// Returns renderer backend API type. RendererType::Enum getRendererType(); diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 6d6b54bd7..576430da1 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -229,7 +229,8 @@ namespace bgfx uint8_t num; AttribType::Enum type; bool normalized; - _decl.decode(Attrib::Enum(attr), num, type, normalized); + bool asInt; + _decl.decode(Attrib::Enum(attr), num, type, normalized, asInt); elem->Format = s_attribType[type][num-1][normalized]; elem->AlignedByteOffset = _decl.m_offset[attr]; } diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 25fe1eff2..4ad3ba117 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -1045,7 +1045,8 @@ namespace bgfx uint8_t num; AttribType::Enum type; bool normalized; - _decl.decode(Attrib::Enum(attr), num, type, normalized); + bool asInt; + _decl.decode(Attrib::Enum(attr), num, type, normalized, asInt); memcpy(elem, &s_attrib[attr], sizeof(D3DVERTEXELEMENT9) ); diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 4f71f8bb0..56ab4ffb2 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -1269,7 +1269,8 @@ namespace bgfx uint8_t num; AttribType::Enum type; bool normalized; - _vertexDecl.decode(attr, num, type, normalized); + bool asInt; + _vertexDecl.decode(attr, num, type, normalized, asInt); if (-1 != loc && 0xff != _vertexDecl.m_attributes[attr]) diff --git a/src/vertexdecl.cpp b/src/vertexdecl.cpp index c74b6c17f..111c1113b 100644 --- a/src/vertexdecl.cpp +++ b/src/vertexdecl.cpp @@ -5,6 +5,7 @@ #include #include +#include #include "vertexdecl.h" @@ -65,23 +66,25 @@ namespace bgfx m_hash = bx::hashMurmur2A(m_attributes, sizeof(m_attributes) ); } - void VertexDecl::add(Attrib::Enum _attrib, uint8_t _num, AttribType::Enum _type, bool _normalized) + void VertexDecl::add(Attrib::Enum _attrib, uint8_t _num, AttribType::Enum _type, bool _normalized, bool _asInt) { - const uint8_t encoded_norm = (_normalized&1)<<6; - const uint8_t encoded_type = (_type&3)<<3; - const uint8_t encoded_num = (_num-1)&3; + const uint8_t encodedNorm = (_normalized&1)<<6; + const uint8_t encodedType = (_type&3)<<3; + const uint8_t encodedNum = (_num-1)&3; + const uint8_t encodeAsInt = (_asInt&(!!"\x1\x1\x0\x0"[_type]) )<<7; - m_attributes[_attrib] = encoded_norm|encoded_type|encoded_num; + m_attributes[_attrib] = encodedNorm|encodedType|encodedNum|encodeAsInt; m_offset[_attrib] = m_stride; m_stride += (*s_attribTypeSize[m_hash])[_type][_num-1]; } - void VertexDecl::decode(Attrib::Enum _attrib, uint8_t& _num, AttribType::Enum& _type, bool& _normalized) const + void VertexDecl::decode(Attrib::Enum _attrib, uint8_t& _num, AttribType::Enum& _type, bool& _normalized, bool& _asInt) const { uint8_t val = m_attributes[_attrib]; _num = (val&3)+1; _type = AttribType::Enum((val>>3)&3); _normalized = !!(val&(1<<6) ); + _asInt = !!(val&(1<<7) ); } const char* getAttribName(Attrib::Enum _attr) @@ -123,14 +126,16 @@ namespace bgfx uint8_t num; AttribType::Enum type; bool normalized; - _decl.decode(Attrib::Enum(attr), num, type, normalized); + bool asInt; + _decl.decode(Attrib::Enum(attr), num, type, normalized, asInt); - BX_TRACE("\tattr %d - %s, num %d, type %d, norm %d, offset %d" + BX_TRACE("\tattr %d - %s, num %d, type %d, norm %d, asint %d, offset %d" , attr , getAttribName(Attrib::Enum(attr) ) , num , type , normalized + , asInt , _decl.m_offset[attr] ); } @@ -140,4 +145,218 @@ namespace bgfx #endif // BGFX_CONFIG_DEBUG } + void vertexPack(const float _input[4], bool _inputNormalized, Attrib::Enum _attr, const VertexDecl& _decl, void* _data, uint32_t _index) + { + if (!_decl.has(_attr) ) + { + return; + } + + uint32_t stride = _decl.getStride(); + uint8_t* data = (uint8_t*)_data + _index*stride + _decl.getOffset(_attr); + + uint8_t num; + AttribType::Enum type; + bool normalized; + bool asInt; + _decl.decode(_attr, num, type, normalized, asInt); + + switch (type) + { + case AttribType::Uint8: + { + uint8_t* packed = (uint8_t*)data; + if (_inputNormalized) + { + if (asInt) + { + switch (num) + { + default: *packed++ = uint8_t(*_input++ * 127.0f + 128.0f); + case 3: *packed++ = uint8_t(*_input++ * 127.0f + 128.0f); + case 2: *packed++ = uint8_t(*_input++ * 127.0f + 128.0f); + case 1: *packed++ = uint8_t(*_input++ * 127.0f + 128.0f); + } + } + else + { + switch (num) + { + default: *packed++ = uint8_t(*_input++ * 255.0f); + case 3: *packed++ = uint8_t(*_input++ * 255.0f); + case 2: *packed++ = uint8_t(*_input++ * 255.0f); + case 1: *packed++ = uint8_t(*_input++ * 255.0f); + } + } + } + else + { + switch (num) + { + default: *packed++ = uint8_t(*_input++); + case 3: *packed++ = uint8_t(*_input++); + case 2: *packed++ = uint8_t(*_input++); + case 1: *packed++ = uint8_t(*_input++); + } + } + } + break; + + case AttribType::Uint16: + { + uint16_t* packed = (uint16_t*)data; + if (_inputNormalized) + { + if (asInt) + { + switch (num) + { + default: *packed++ = uint16_t(*_input++ * 32767.0f + 32768.0f); + case 3: *packed++ = uint16_t(*_input++ * 32767.0f + 32768.0f); + case 2: *packed++ = uint16_t(*_input++ * 32767.0f + 32768.0f); + case 1: *packed++ = uint16_t(*_input++ * 32767.0f + 32768.0f); + } + } + else + { + switch (num) + { + default: *packed++ = uint16_t(*_input++ * 65535.0f); + case 3: *packed++ = uint16_t(*_input++ * 65535.0f); + case 2: *packed++ = uint16_t(*_input++ * 65535.0f); + case 1: *packed++ = uint16_t(*_input++ * 65535.0f); + } + } + } + else + { + switch (num) + { + default: *packed++ = uint16_t(*_input++); + case 3: *packed++ = uint16_t(*_input++); + case 2: *packed++ = uint16_t(*_input++); + case 1: *packed++ = uint16_t(*_input++); + } + } + } + break; + + case AttribType::Half: + { + uint16_t* packed = (uint16_t*)data; + switch (num) + { + default: *packed++ = bx::halfFromFloat(*_input++); + case 3: *packed++ = bx::halfFromFloat(*_input++); + case 2: *packed++ = bx::halfFromFloat(*_input++); + case 1: *packed++ = bx::halfFromFloat(*_input++); + } + } + break; + + case AttribType::Float: + memcpy(data, _input, num*sizeof(float) ); + break; + } + } + + void vertexUnpack(float _output[4], Attrib::Enum _attr, const VertexDecl& _decl, const void* _data, uint32_t _index) + { + if (!_decl.has(_attr) ) + { + memset(_output, 0, 4*sizeof(float) ); + return; + } + + uint32_t stride = _decl.getStride(); + uint8_t* data = (uint8_t*)_data + _index*stride + _decl.getOffset(_attr); + + uint8_t num; + AttribType::Enum type; + bool normalized; + bool asInt; + _decl.decode(_attr, num, type, normalized, asInt); + + switch (type) + { + case AttribType::Uint8: + { + uint8_t* packed = (uint8_t*)data; + if (asInt) + { + switch (num) + { + default: *_output++ = (float(*packed++) - 128.0f)*1.0f/127.0f; + case 3: *_output++ = (float(*packed++) - 128.0f)*1.0f/127.0f; + case 2: *_output++ = (float(*packed++) - 128.0f)*1.0f/127.0f; + case 1: *_output++ = (float(*packed++) - 128.0f)*1.0f/127.0f; + } + } + else + { + switch (num) + { + default: *_output++ = float(*packed++)*1.0f/255.0f; + case 3: *_output++ = float(*packed++)*1.0f/255.0f; + case 2: *_output++ = float(*packed++)*1.0f/255.0f; + case 1: *_output++ = float(*packed++)*1.0f/255.0f; + } + } + } + break; + + case AttribType::Uint16: + { + uint16_t* packed = (uint16_t*)data; + if (asInt) + { + switch (num) + { + default: *_output++ = (float(*packed++) - 32768.0f)*1.0f/32767.0f; + case 3: *_output++ = (float(*packed++) - 32768.0f)*1.0f/32767.0f; + case 2: *_output++ = (float(*packed++) - 32768.0f)*1.0f/32767.0f; + case 1: *_output++ = (float(*packed++) - 32768.0f)*1.0f/32767.0f; + } + } + else + { + switch (num) + { + default: *_output++ = float(*packed++)*1.0f/65535.0f; + case 3: *_output++ = float(*packed++)*1.0f/65535.0f; + case 2: *_output++ = float(*packed++)*1.0f/65535.0f; + case 1: *_output++ = float(*packed++)*1.0f/65535.0f; + } + } + } + break; + + case AttribType::Half: + { + uint16_t* packed = (uint16_t*)data; + switch (num) + { + default: *_output++ = bx::halfToFloat(*packed++); + case 3: *_output++ = bx::halfToFloat(*packed++); + case 2: *_output++ = bx::halfToFloat(*packed++); + case 1: *_output++ = bx::halfToFloat(*packed++); + } + } + break; + + case AttribType::Float: + memcpy(_output, data, num*sizeof(float) ); + _output += num; + break; + } + + switch (num) + { + case 1: *_output++ = 0.0f; + case 2: *_output++ = 0.0f; + case 3: *_output++ = 0.0f; + default: break; + } + } + } // namespace bgfx diff --git a/src/vertexdecl.h b/src/vertexdecl.h index 45c83da1d..e3ec89038 100644 --- a/src/vertexdecl.h +++ b/src/vertexdecl.h @@ -7,7 +7,10 @@ namespace bgfx { + /// Returns attribute name. const char* getAttribName(Attrib::Enum _attr); + + /// Dump vertex declaration into debug output. void dump(const VertexDecl& _decl); } // namespace bgfx diff --git a/tools/geometryc/geometryc.cpp b/tools/geometryc/geometryc.cpp index 91b50bc37..f5b7849e0 100644 --- a/tools/geometryc/geometryc.cpp +++ b/tools/geometryc/geometryc.cpp @@ -133,95 +133,42 @@ void triangleReorder(uint16_t* _indices, uint32_t _numIndices, uint32_t _numVert delete [] newIndexList; } -uint32_t packUint32(uint8_t _x, uint8_t _y, uint8_t _z, uint8_t _w) -{ - union - { - uint32_t ui32; - uint8_t arr[4]; - } un; - - un.arr[0] = _x; - un.arr[1] = _y; - un.arr[2] = _z; - un.arr[3] = _w; - - return un.ui32; -} - -void unpackUint32(uint8_t _result[4], uint32_t _packed) -{ - union - { - uint32_t ui32; - uint8_t arr[4]; - } un; - - un.ui32 = _packed; - _result[0] = un.arr[0]; - _result[1] = un.arr[1]; - _result[2] = un.arr[2]; - _result[3] = un.arr[3]; -} - -uint32_t packF4u(float _x, float _y = 0.0f, float _z = 0.0f, float _w = 0.0f) -{ - const uint8_t xx = uint8_t(_x*127.0f + 128.0f); - const uint8_t yy = uint8_t(_y*127.0f + 128.0f); - const uint8_t zz = uint8_t(_z*127.0f + 128.0f); - const uint8_t ww = uint8_t(_w*127.0f + 128.0f); - return packUint32(xx, yy, zz, ww); -} - -void unpackF4u(float _result[4], uint32_t _packed) -{ - uint8_t unpacked[4]; - unpackUint32(unpacked, _packed); - _result[0] = (float(unpacked[0]) - 128.0f)/127.0f; - _result[1] = (float(unpacked[1]) - 128.0f)/127.0f; - _result[2] = (float(unpacked[2]) - 128.0f)/127.0f; - _result[3] = (float(unpacked[3]) - 128.0f)/127.0f; -} - -uint32_t packF2h(float _x, float _y) -{ - union - { - uint32_t ui32; - uint16_t arr[2]; - } un; - - un.arr[0] = bx::halfFromFloat(_x); - un.arr[1] = bx::halfFromFloat(_y); - - return un.ui32; -} - -void unpackF2h(float _result[2], uint32_t _packed) -{ - union - { - uint32_t ui32; - uint16_t arr[2]; - } un; - - un.ui32 = _packed; - _result[0] = bx::halfToFloat(un.arr[0]); - _result[1] = bx::halfToFloat(un.arr[1]); -} - -template -void calcTangents(const uint16_t* _indices, uint32_t _numIndices, Ty* _vertices, uint16_t _numVertices) +void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices) { + struct PosTexcoord + { + float m_x; + float m_y; + float m_z; + float m_pad0; + float m_u; + float m_v; + float m_pad1; + float m_pad2; + }; + float* tangents = new float[6*_numVertices]; memset(tangents, 0, 6*_numVertices*sizeof(float) ); + PosTexcoord v0; + PosTexcoord v1; + PosTexcoord v2; + for (uint32_t ii = 0, num = _numIndices/3; ii < num; ++ii) { const uint16_t* indices = &_indices[ii*3]; - const Ty& v0 = _vertices[indices[0] ]; - const Ty& v1 = _vertices[indices[1] ]; - const Ty& v2 = _vertices[indices[2] ]; + uint32_t i0 = indices[0]; + uint32_t i1 = indices[1]; + uint32_t i2 = indices[2]; + + bgfx::vertexUnpack(&v0.m_x, bgfx::Attrib::Position, _decl, _vertices, i0); + bgfx::vertexUnpack(&v0.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i0); + + bgfx::vertexUnpack(&v1.m_x, bgfx::Attrib::Position, _decl, _vertices, i1); + bgfx::vertexUnpack(&v1.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i1); + + bgfx::vertexUnpack(&v2.m_x, bgfx::Attrib::Position, _decl, _vertices, i2); + bgfx::vertexUnpack(&v2.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i2); const float bax = v1.m_x - v0.m_x; const float bay = v1.m_y - v0.m_y; @@ -262,12 +209,11 @@ void calcTangents(const uint16_t* _indices, uint32_t _numIndices, Ty* _vertices, for (uint32_t ii = 0; ii < _numVertices; ++ii) { - Ty& v0 = _vertices[ii]; const float* tanu = &tangents[ii*6]; const float* tanv = &tangents[ii*6 + 3]; float normal[4]; - unpackF4u(normal, v0.m_normal); + bgfx::vertexUnpack(normal, bgfx::Attrib::Normal, _decl, _vertices, ii); float ndt = vec3Dot(normal, tanu); float nxt[3]; @@ -278,11 +224,11 @@ void calcTangents(const uint16_t* _indices, uint32_t _numIndices, Ty* _vertices, tmp[1] = tanu[1] - normal[1] * ndt; tmp[2] = tanu[2] - normal[2] * ndt; - float tangent[3]; + float tangent[4]; vec3Norm(tangent, tmp); - float tw = vec3Dot(nxt, tanv) < 0.0f ? -1.0f : 1.0f; - v0.m_tangent = packF4u(tangent[0], tangent[1], tangent[2], tw); + tangent[3] = vec3Dot(nxt, tanv) < 0.0f ? -1.0f : 1.0f; + bgfx::vertexPack(tangent, true, bgfx::Attrib::Tangent, _decl, _vertices, ii); } } @@ -752,6 +698,8 @@ int main(int _argc, const char* _argv[]) if (hasNormal) { + hasTangent &= hasTexcoord; + switch (packNormal) { default: @@ -764,10 +712,10 @@ int main(int _argc, const char* _argv[]) break; case 1: - decl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true); + decl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true); if (hasTangent) { - decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true); + decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true); } break; } @@ -828,6 +776,11 @@ int main(int _argc, const char* _argv[]) } triReorderElapsed += bx::getHPCounter(); + if (hasTangent) + { + calcTangents(vertexData, numVertices, decl, indexData, numIndices); + } + write(&writer, vertexData, numVertices, decl, indexData, numIndices, material, primitives); primitives.clear(); @@ -875,58 +828,14 @@ int main(int _argc, const char* _argv[]) uv[1] = -uv[1]; } - switch (packUv) - { - default: - case 0: - { - float* texcoord0 = (float*)(vertices + texcoord0Offset); - memcpy(texcoord0, uv, 2*sizeof(float) ); - } - break; - - case 1: - { - uint32_t* texcoord0 = (uint32_t*)(vertices + texcoord0Offset); - *texcoord0 = packF2h(uv[0], uv[1]); - } - break; - } + bgfx::vertexPack(uv, true, bgfx::Attrib::TexCoord0, decl, vertices); } if (hasNormal) { - switch (packNormal) - { - default: - case 0: - { - float* normal = (float*)(vertices + normalOffset); - vec3Norm(normal, (float*)&normals[index.m_normal]); - - if (hasTangent) - { - float* tangent = (float*)(vertices + tangentOffset); - memset(tangent, 0, 3*sizeof(float) ); - } - } - break; - - case 1: - { - float normal[3]; - vec3Norm(normal, (float*)&normals[index.m_normal]); - uint32_t* nxyz0 = (uint32_t*)(vertices + normalOffset); - *nxyz0 = packF4u(normal[0], normal[1], normal[2]); - - if (hasTangent) - { - uint32_t* txyz0 = (uint32_t*)(vertices + tangentOffset); - *txyz0 = packF4u(0.0f); - } - } - break; - } + float normal[4]; + vec3Norm(normal, (float*)&normals[index.m_normal]); + bgfx::vertexPack(normal, true, bgfx::Attrib::Normal, decl, vertices); } vertices += stride; @@ -965,6 +874,11 @@ int main(int _argc, const char* _argv[]) } triReorderElapsed += bx::getHPCounter(); + if (hasTangent) + { + calcTangents(vertexData, numVertices, decl, indexData, numIndices); + } + write(&writer, vertexData, numVertices, decl, indexData, numIndices, material, primitives); }