VertexDeclaration.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #include "Precompiled.h"
  24. #include "Log.h"
  25. #include "Renderer.h"
  26. #include "RendererImpl.h"
  27. #include "VertexBuffer.h"
  28. #include "VertexDeclaration.h"
  29. #include "DebugNew.h"
  30. const BYTE d3dElementType[] =
  31. {
  32. D3DDECLTYPE_FLOAT3, // Position
  33. D3DDECLTYPE_FLOAT3, // Normal
  34. D3DDECLTYPE_D3DCOLOR, // Color
  35. D3DDECLTYPE_FLOAT2, // Texcoord1
  36. D3DDECLTYPE_FLOAT2, // Texcoord2
  37. D3DDECLTYPE_FLOAT3, // Cubetexcoord1
  38. D3DDECLTYPE_FLOAT3, // Cubetexcoord2
  39. D3DDECLTYPE_FLOAT4, // Tangent
  40. D3DDECLTYPE_FLOAT4, // Blendweights
  41. D3DDECLTYPE_UBYTE4, // Blendindices
  42. D3DDECLTYPE_FLOAT1, // Instancenumber
  43. D3DDECLTYPE_FLOAT4, // Instancematrix1
  44. D3DDECLTYPE_FLOAT4, // Instancematrix2
  45. D3DDECLTYPE_FLOAT4 // Instancematrix3
  46. };
  47. const BYTE d3dElementUsage[] =
  48. {
  49. D3DDECLUSAGE_POSITION, // Position
  50. D3DDECLUSAGE_NORMAL, // Normal
  51. D3DDECLUSAGE_COLOR, // Color
  52. D3DDECLUSAGE_TEXCOORD, // Texcoord1
  53. D3DDECLUSAGE_TEXCOORD, // Texcoord2
  54. D3DDECLUSAGE_TEXCOORD, // Cubetexcoord1
  55. D3DDECLUSAGE_TEXCOORD, // Cubetexcoord2
  56. D3DDECLUSAGE_TANGENT, // Tangent
  57. D3DDECLUSAGE_BLENDWEIGHT, // Blendweights
  58. D3DDECLUSAGE_BLENDINDICES, // Blendindices
  59. D3DDECLUSAGE_TEXCOORD, // Instancenumber
  60. D3DDECLUSAGE_TEXCOORD, // Instancematrix1
  61. D3DDECLUSAGE_TEXCOORD, // Instancematrix2
  62. D3DDECLUSAGE_TEXCOORD // Instancematrix3
  63. };
  64. const BYTE d3dElementUsageIndex[] =
  65. {
  66. 0, // Position
  67. 0, // Normal
  68. 0, // Color
  69. 0, // Texcoord1
  70. 1, // Texcoord2
  71. 0, // Cubetexcoord1
  72. 1, // Cubetexcoord2
  73. 0, // Tangent
  74. 0, // Blendweights
  75. 0, // Blendindices
  76. 2, // Instancenumber
  77. 2, // Instancematrix1
  78. 3, // Instancematrix2
  79. 4 // Instancematrix3
  80. };
  81. VertexDeclaration::VertexDeclaration(Renderer* renderer, unsigned elementMask) :
  82. mDeclaration(0)
  83. {
  84. std::vector<VertexDeclarationElement> elements;
  85. unsigned offset = 0;
  86. for (unsigned i = 0; i < MAX_VERTEX_ELEMENTS; ++i)
  87. {
  88. VertexElement element = (VertexElement)i;
  89. if (elementMask & (1 << i))
  90. {
  91. VertexDeclarationElement newElement;
  92. newElement.mStream = 0;
  93. newElement.mElement = element;
  94. newElement.mOffset = offset;
  95. offset += VertexBuffer::sElementSize[i];
  96. elements.push_back(newElement);
  97. }
  98. }
  99. create(renderer, elements);
  100. }
  101. VertexDeclaration::VertexDeclaration(Renderer* renderer, const std::vector<VertexBuffer*>& buffers, const std::vector<unsigned>& elementMasks) :
  102. mDeclaration(0)
  103. {
  104. unsigned usedElementMask = 0;
  105. std::vector<VertexDeclarationElement> elements;
  106. for (unsigned i = 0; i < buffers.size(); ++i)
  107. {
  108. if (buffers[i])
  109. {
  110. unsigned elementMask = elementMasks[i];
  111. if (elementMask == MASK_DEFAULT)
  112. elementMask = buffers[i]->getElementMask();
  113. else
  114. {
  115. if ((buffers[i]->getElementMask() & elementMask) != elementMask)
  116. EXCEPTION("Vertex buffer does not contain all required elements");
  117. }
  118. for (unsigned j = 0; j < MAX_VERTEX_ELEMENTS; ++j)
  119. {
  120. VertexElement element = (VertexElement)j;
  121. if ((elementMask & (1 << j)) && (!(usedElementMask & (1 << j))))
  122. {
  123. VertexDeclarationElement newElement;
  124. newElement.mStream = i;
  125. newElement.mElement = element;
  126. newElement.mOffset = buffers[i]->getElementOffset(element);
  127. usedElementMask |= 1 << j;
  128. elements.push_back(newElement);
  129. }
  130. }
  131. }
  132. }
  133. create(renderer, elements);
  134. }
  135. VertexDeclaration::VertexDeclaration(Renderer* renderer, const std::vector<SharedPtr<VertexBuffer> >& buffers, const std::vector<unsigned>& elementMasks) :
  136. mDeclaration(0)
  137. {
  138. unsigned usedElementMask = 0;
  139. std::vector<VertexDeclarationElement> elements;
  140. for (unsigned i = 0; i < buffers.size(); ++i)
  141. {
  142. if (buffers[i])
  143. {
  144. unsigned elementMask = elementMasks[i];
  145. if (elementMask == MASK_DEFAULT)
  146. elementMask = buffers[i]->getElementMask();
  147. else
  148. {
  149. if ((buffers[i]->getElementMask() & elementMask) != elementMask)
  150. EXCEPTION("Vertex buffer does not contain all required elements");
  151. }
  152. for (unsigned j = 0; j < MAX_VERTEX_ELEMENTS; ++j)
  153. {
  154. VertexElement element = (VertexElement)j;
  155. if ((elementMask & (1 << j)) && (!(usedElementMask & (1 << j))))
  156. {
  157. VertexDeclarationElement newElement;
  158. newElement.mStream = i;
  159. newElement.mElement = element;
  160. newElement.mOffset = buffers[i]->getElementOffset(element);
  161. usedElementMask |= 1 << j;
  162. elements.push_back(newElement);
  163. }
  164. }
  165. }
  166. }
  167. create(renderer, elements);
  168. }
  169. VertexDeclaration::~VertexDeclaration()
  170. {
  171. release();
  172. }
  173. void VertexDeclaration::create(Renderer* renderer, const std::vector<VertexDeclarationElement>& elements)
  174. {
  175. SharedArrayPtr<D3DVERTEXELEMENT9> elementArray(new D3DVERTEXELEMENT9[elements.size() + 1]);
  176. D3DVERTEXELEMENT9* dest = elementArray;
  177. for (std::vector<VertexDeclarationElement>::const_iterator i = elements.begin(); i != elements.end(); ++i)
  178. {
  179. dest->Stream = i->mStream;
  180. dest->Offset = i->mOffset;
  181. dest->Type = d3dElementType[i->mElement];
  182. dest->Method = D3DDECLMETHOD_DEFAULT;
  183. dest->Usage = d3dElementUsage[i->mElement];
  184. dest->UsageIndex = d3dElementUsageIndex[i->mElement];
  185. dest++;
  186. }
  187. dest->Stream = 0xff;
  188. dest->Offset = 0;
  189. dest->Type = D3DDECLTYPE_UNUSED;
  190. dest->Method = 0;
  191. dest->Usage = 0;
  192. dest->UsageIndex = 0;
  193. if (FAILED(renderer->getImpl()->getDevice()->CreateVertexDeclaration(elementArray, &mDeclaration)))
  194. EXCEPTION("Could not create vertex declaration");
  195. }
  196. void VertexDeclaration::release()
  197. {
  198. if (mDeclaration)
  199. {
  200. mDeclaration->Release();
  201. mDeclaration = 0;
  202. }
  203. }