vertexdecl.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /*
  2. * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include <string.h>
  6. #include <bx/hash.h>
  7. #include <bx/uint32_t.h>
  8. #include "vertexdecl.h"
  9. namespace bgfx
  10. {
  11. static const uint8_t s_attribTypeSizeDx9[AttribType::Count][4] =
  12. {
  13. { 4, 4, 4, 4 },
  14. { 4, 4, 8, 8 },
  15. { 4, 4, 8, 8 },
  16. { 4, 8, 12, 16 },
  17. };
  18. static const uint8_t s_attribTypeSizeDx11[AttribType::Count][4] =
  19. {
  20. { 1, 2, 4, 4 },
  21. { 2, 4, 8, 8 },
  22. { 2, 4, 8, 8 },
  23. { 4, 8, 12, 16 },
  24. };
  25. static const uint8_t s_attribTypeSizeGl[AttribType::Count][4] =
  26. {
  27. { 1, 2, 4, 4 },
  28. { 2, 4, 6, 8 },
  29. { 2, 4, 6, 8 },
  30. { 4, 8, 12, 16 },
  31. };
  32. static const uint8_t (*s_attribTypeSize[RendererType::Count])[AttribType::Count][4] =
  33. {
  34. #if BGFX_CONFIG_RENDERER_DIRECT3D9
  35. &s_attribTypeSizeDx9,
  36. #elif BGFX_CONFIG_RENDERER_DIRECT3D11
  37. &s_attribTypeSizeDx11,
  38. #elif BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES2|BGFX_CONFIG_RENDERER_OPENGLES3
  39. &s_attribTypeSizeGl,
  40. #else
  41. &s_attribTypeSizeDx9,
  42. #endif // BGFX_CONFIG_RENDERER_
  43. &s_attribTypeSizeDx9,
  44. &s_attribTypeSizeDx11,
  45. &s_attribTypeSizeGl,
  46. &s_attribTypeSizeGl,
  47. &s_attribTypeSizeGl,
  48. };
  49. void VertexDecl::begin(RendererType::Enum _renderer)
  50. {
  51. m_hash = _renderer; // use hash to store renderer type while building VertexDecl.
  52. m_stride = 0;
  53. memset(m_attributes, 0xff, sizeof(m_attributes) );
  54. memset(m_offset, 0, sizeof(m_offset) );
  55. }
  56. void VertexDecl::end()
  57. {
  58. m_hash = bx::hashMurmur2A(m_attributes, sizeof(m_attributes) );
  59. }
  60. void VertexDecl::add(Attrib::Enum _attrib, uint8_t _num, AttribType::Enum _type, bool _normalized, bool _asInt)
  61. {
  62. const uint8_t encodedNorm = (_normalized&1)<<6;
  63. const uint8_t encodedType = (_type&3)<<3;
  64. const uint8_t encodedNum = (_num-1)&3;
  65. const uint8_t encodeAsInt = (_asInt&(!!"\x1\x1\x0\x0"[_type]) )<<7;
  66. m_attributes[_attrib] = encodedNorm|encodedType|encodedNum|encodeAsInt;
  67. m_offset[_attrib] = m_stride;
  68. m_stride += (*s_attribTypeSize[m_hash])[_type][_num-1];
  69. }
  70. void VertexDecl::decode(Attrib::Enum _attrib, uint8_t& _num, AttribType::Enum& _type, bool& _normalized, bool& _asInt) const
  71. {
  72. uint8_t val = m_attributes[_attrib];
  73. _num = (val&3)+1;
  74. _type = AttribType::Enum((val>>3)&3);
  75. _normalized = !!(val&(1<<6) );
  76. _asInt = !!(val&(1<<7) );
  77. }
  78. static const char* s_attrName[Attrib::Count] =
  79. {
  80. "Attrib::Position",
  81. "Attrib::Normal",
  82. "Attrib::Tangent",
  83. "Attrib::Color0",
  84. "Attrib::Color1",
  85. "Attrib::Indices",
  86. "Attrib::Weights",
  87. "Attrib::TexCoord0",
  88. "Attrib::TexCoord1",
  89. "Attrib::TexCoord2",
  90. "Attrib::TexCoord3",
  91. "Attrib::TexCoord4",
  92. "Attrib::TexCoord5",
  93. "Attrib::TexCoord6",
  94. "Attrib::TexCoord7",
  95. };
  96. const char* getAttribName(Attrib::Enum _attr)
  97. {
  98. return s_attrName[_attr];
  99. }
  100. void dump(const VertexDecl& _decl)
  101. {
  102. #if BGFX_CONFIG_DEBUG
  103. BX_TRACE("vertexdecl %08x (%08x), stride %d"
  104. , _decl.m_hash
  105. , hashMurmur2A(_decl.m_attributes, sizeof(_decl.m_attributes) )
  106. , _decl.m_stride
  107. );
  108. for (uint32_t attr = 0; attr < Attrib::Count; ++attr)
  109. {
  110. if (0xff != _decl.m_attributes[attr])
  111. {
  112. uint8_t num;
  113. AttribType::Enum type;
  114. bool normalized;
  115. bool asInt;
  116. _decl.decode(Attrib::Enum(attr), num, type, normalized, asInt);
  117. BX_TRACE("\tattr %d - %s, num %d, type %d, norm %d, asint %d, offset %d"
  118. , attr
  119. , getAttribName(Attrib::Enum(attr) )
  120. , num
  121. , type
  122. , normalized
  123. , asInt
  124. , _decl.m_offset[attr]
  125. );
  126. }
  127. }
  128. #else
  129. BX_UNUSED(_decl);
  130. #endif // BGFX_CONFIG_DEBUG
  131. }
  132. void vertexPack(const float _input[4], bool _inputNormalized, Attrib::Enum _attr, const VertexDecl& _decl, void* _data, uint32_t _index)
  133. {
  134. if (!_decl.has(_attr) )
  135. {
  136. return;
  137. }
  138. uint32_t stride = _decl.getStride();
  139. uint8_t* data = (uint8_t*)_data + _index*stride + _decl.getOffset(_attr);
  140. uint8_t num;
  141. AttribType::Enum type;
  142. bool normalized;
  143. bool asInt;
  144. _decl.decode(_attr, num, type, normalized, asInt);
  145. switch (type)
  146. {
  147. default:
  148. case AttribType::Uint8:
  149. {
  150. uint8_t* packed = (uint8_t*)data;
  151. if (_inputNormalized)
  152. {
  153. if (asInt)
  154. {
  155. switch (num)
  156. {
  157. default: *packed++ = uint8_t(*_input++ * 127.0f + 128.0f);
  158. case 3: *packed++ = uint8_t(*_input++ * 127.0f + 128.0f);
  159. case 2: *packed++ = uint8_t(*_input++ * 127.0f + 128.0f);
  160. case 1: *packed++ = uint8_t(*_input++ * 127.0f + 128.0f);
  161. }
  162. }
  163. else
  164. {
  165. switch (num)
  166. {
  167. default: *packed++ = uint8_t(*_input++ * 255.0f);
  168. case 3: *packed++ = uint8_t(*_input++ * 255.0f);
  169. case 2: *packed++ = uint8_t(*_input++ * 255.0f);
  170. case 1: *packed++ = uint8_t(*_input++ * 255.0f);
  171. }
  172. }
  173. }
  174. else
  175. {
  176. switch (num)
  177. {
  178. default: *packed++ = uint8_t(*_input++);
  179. case 3: *packed++ = uint8_t(*_input++);
  180. case 2: *packed++ = uint8_t(*_input++);
  181. case 1: *packed++ = uint8_t(*_input++);
  182. }
  183. }
  184. }
  185. break;
  186. case AttribType::Uint16:
  187. {
  188. uint16_t* packed = (uint16_t*)data;
  189. if (_inputNormalized)
  190. {
  191. if (asInt)
  192. {
  193. switch (num)
  194. {
  195. default: *packed++ = uint16_t(*_input++ * 32767.0f + 32768.0f);
  196. case 3: *packed++ = uint16_t(*_input++ * 32767.0f + 32768.0f);
  197. case 2: *packed++ = uint16_t(*_input++ * 32767.0f + 32768.0f);
  198. case 1: *packed++ = uint16_t(*_input++ * 32767.0f + 32768.0f);
  199. }
  200. }
  201. else
  202. {
  203. switch (num)
  204. {
  205. default: *packed++ = uint16_t(*_input++ * 65535.0f);
  206. case 3: *packed++ = uint16_t(*_input++ * 65535.0f);
  207. case 2: *packed++ = uint16_t(*_input++ * 65535.0f);
  208. case 1: *packed++ = uint16_t(*_input++ * 65535.0f);
  209. }
  210. }
  211. }
  212. else
  213. {
  214. switch (num)
  215. {
  216. default: *packed++ = uint16_t(*_input++);
  217. case 3: *packed++ = uint16_t(*_input++);
  218. case 2: *packed++ = uint16_t(*_input++);
  219. case 1: *packed++ = uint16_t(*_input++);
  220. }
  221. }
  222. }
  223. break;
  224. case AttribType::Half:
  225. {
  226. uint16_t* packed = (uint16_t*)data;
  227. switch (num)
  228. {
  229. default: *packed++ = bx::halfFromFloat(*_input++);
  230. case 3: *packed++ = bx::halfFromFloat(*_input++);
  231. case 2: *packed++ = bx::halfFromFloat(*_input++);
  232. case 1: *packed++ = bx::halfFromFloat(*_input++);
  233. }
  234. }
  235. break;
  236. case AttribType::Float:
  237. memcpy(data, _input, num*sizeof(float) );
  238. break;
  239. }
  240. }
  241. void vertexUnpack(float _output[4], Attrib::Enum _attr, const VertexDecl& _decl, const void* _data, uint32_t _index)
  242. {
  243. if (!_decl.has(_attr) )
  244. {
  245. memset(_output, 0, 4*sizeof(float) );
  246. return;
  247. }
  248. uint32_t stride = _decl.getStride();
  249. uint8_t* data = (uint8_t*)_data + _index*stride + _decl.getOffset(_attr);
  250. uint8_t num;
  251. AttribType::Enum type;
  252. bool normalized;
  253. bool asInt;
  254. _decl.decode(_attr, num, type, normalized, asInt);
  255. switch (type)
  256. {
  257. default:
  258. case AttribType::Uint8:
  259. {
  260. uint8_t* packed = (uint8_t*)data;
  261. if (asInt)
  262. {
  263. switch (num)
  264. {
  265. default: *_output++ = (float(*packed++) - 128.0f)*1.0f/127.0f;
  266. case 3: *_output++ = (float(*packed++) - 128.0f)*1.0f/127.0f;
  267. case 2: *_output++ = (float(*packed++) - 128.0f)*1.0f/127.0f;
  268. case 1: *_output++ = (float(*packed++) - 128.0f)*1.0f/127.0f;
  269. }
  270. }
  271. else
  272. {
  273. switch (num)
  274. {
  275. default: *_output++ = float(*packed++)*1.0f/255.0f;
  276. case 3: *_output++ = float(*packed++)*1.0f/255.0f;
  277. case 2: *_output++ = float(*packed++)*1.0f/255.0f;
  278. case 1: *_output++ = float(*packed++)*1.0f/255.0f;
  279. }
  280. }
  281. }
  282. break;
  283. case AttribType::Uint16:
  284. {
  285. uint16_t* packed = (uint16_t*)data;
  286. if (asInt)
  287. {
  288. switch (num)
  289. {
  290. default: *_output++ = (float(*packed++) - 32768.0f)*1.0f/32767.0f;
  291. case 3: *_output++ = (float(*packed++) - 32768.0f)*1.0f/32767.0f;
  292. case 2: *_output++ = (float(*packed++) - 32768.0f)*1.0f/32767.0f;
  293. case 1: *_output++ = (float(*packed++) - 32768.0f)*1.0f/32767.0f;
  294. }
  295. }
  296. else
  297. {
  298. switch (num)
  299. {
  300. default: *_output++ = float(*packed++)*1.0f/65535.0f;
  301. case 3: *_output++ = float(*packed++)*1.0f/65535.0f;
  302. case 2: *_output++ = float(*packed++)*1.0f/65535.0f;
  303. case 1: *_output++ = float(*packed++)*1.0f/65535.0f;
  304. }
  305. }
  306. }
  307. break;
  308. case AttribType::Half:
  309. {
  310. uint16_t* packed = (uint16_t*)data;
  311. switch (num)
  312. {
  313. default: *_output++ = bx::halfToFloat(*packed++);
  314. case 3: *_output++ = bx::halfToFloat(*packed++);
  315. case 2: *_output++ = bx::halfToFloat(*packed++);
  316. case 1: *_output++ = bx::halfToFloat(*packed++);
  317. }
  318. }
  319. break;
  320. case AttribType::Float:
  321. memcpy(_output, data, num*sizeof(float) );
  322. _output += num;
  323. break;
  324. }
  325. switch (num)
  326. {
  327. case 1: *_output++ = 0.0f;
  328. case 2: *_output++ = 0.0f;
  329. case 3: *_output++ = 0.0f;
  330. default: break;
  331. }
  332. }
  333. } // namespace bgfx