D3D9VertexDeclaration.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. //
  2. // Copyright (c) 2008-2014 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.h"
  24. #include "GraphicsImpl.h"
  25. #include "VertexBuffer.h"
  26. #include "VertexDeclaration.h"
  27. #include "DebugNew.h"
  28. namespace Urho3D
  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, const PODVector<unsigned>& elementMasks) :
  99. declaration_(0)
  100. {
  101. unsigned usedElementMask = 0;
  102. PODVector<VertexDeclarationElement> elements;
  103. for (unsigned i = 0; i < buffers.Size(); ++i)
  104. {
  105. if (buffers[i])
  106. {
  107. unsigned elementMask = elementMasks[i];
  108. if (elementMask == MASK_DEFAULT)
  109. elementMask = buffers[i]->GetElementMask();
  110. else
  111. {
  112. if ((buffers[i]->GetElementMask() & elementMask) != elementMask)
  113. return;
  114. }
  115. for (unsigned j = 0; j < MAX_VERTEX_ELEMENTS; ++j)
  116. {
  117. VertexElement element = (VertexElement)j;
  118. if (elementMask & (1 << j) && !(usedElementMask & (1 << j)))
  119. {
  120. VertexDeclarationElement newElement;
  121. newElement.stream_ = i;
  122. newElement.element_ = element;
  123. newElement.offset_ = buffers[i]->GetElementOffset(element);
  124. usedElementMask |= 1 << j;
  125. elements.Push(newElement);
  126. }
  127. }
  128. }
  129. }
  130. Create(graphics, elements);
  131. }
  132. VertexDeclaration::VertexDeclaration(Graphics* graphics, const Vector<SharedPtr<VertexBuffer> >& buffers, const PODVector<unsigned>& elementMasks) :
  133. declaration_(0)
  134. {
  135. unsigned usedElementMask = 0;
  136. PODVector<VertexDeclarationElement> elements;
  137. for (unsigned i = 0; i < buffers.Size(); ++i)
  138. {
  139. if (buffers[i])
  140. {
  141. unsigned elementMask = elementMasks[i];
  142. if (elementMask == MASK_DEFAULT)
  143. elementMask = buffers[i]->GetElementMask();
  144. else
  145. {
  146. if ((buffers[i]->GetElementMask() & elementMask) != elementMask)
  147. return;
  148. }
  149. for (unsigned j = 0; j < MAX_VERTEX_ELEMENTS; ++j)
  150. {
  151. VertexElement element = (VertexElement)j;
  152. if (elementMask & (1 << j) && !(usedElementMask & (1 << j)))
  153. {
  154. VertexDeclarationElement newElement;
  155. newElement.stream_ = i;
  156. newElement.element_ = element;
  157. newElement.offset_ = buffers[i]->GetElementOffset(element);
  158. usedElementMask |= 1 << j;
  159. elements.Push(newElement);
  160. }
  161. }
  162. }
  163. }
  164. Create(graphics, elements);
  165. }
  166. VertexDeclaration::~VertexDeclaration()
  167. {
  168. Release();
  169. }
  170. void VertexDeclaration::Create(Graphics* graphics, const PODVector<VertexDeclarationElement>& elements)
  171. {
  172. SharedArrayPtr<D3DVERTEXELEMENT9> elementArray(new D3DVERTEXELEMENT9[elements.Size() + 1]);
  173. D3DVERTEXELEMENT9* dest = elementArray;
  174. for (Vector<VertexDeclarationElement>::ConstIterator i = elements.Begin(); i != elements.End(); ++i)
  175. {
  176. dest->Stream = i->stream_;
  177. dest->Offset = i->offset_;
  178. dest->Type = d3dElementType[i->element_];
  179. dest->Method = D3DDECLMETHOD_DEFAULT;
  180. dest->Usage = d3dElementUsage[i->element_];
  181. dest->UsageIndex = d3dElementUsageIndex[i->element_];
  182. dest++;
  183. }
  184. dest->Stream = 0xff;
  185. dest->Offset = 0;
  186. dest->Type = D3DDECLTYPE_UNUSED;
  187. dest->Method = 0;
  188. dest->Usage = 0;
  189. dest->UsageIndex = 0;
  190. IDirect3DDevice9* device = graphics->GetImpl()->GetDevice();
  191. if (!device)
  192. return;
  193. device->CreateVertexDeclaration(elementArray, &declaration_);
  194. }
  195. void VertexDeclaration::Release()
  196. {
  197. if (declaration_)
  198. {
  199. declaration_->Release();
  200. declaration_ = 0;
  201. }
  202. }
  203. }