D3D9VertexDeclaration.cpp 7.3 KB

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