D3D9VertexDeclaration.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2012 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 "Graphics.h"
  25. #include "GraphicsImpl.h"
  26. #include "VertexBuffer.h"
  27. #include "VertexDeclaration.h"
  28. #include "DebugNew.h"
  29. namespace Urho3D
  30. {
  31. const BYTE d3dElementType[] =
  32. {
  33. D3DDECLTYPE_FLOAT3, // Position
  34. D3DDECLTYPE_FLOAT3, // Normal
  35. D3DDECLTYPE_UBYTE4N, // Color
  36. D3DDECLTYPE_FLOAT2, // Texcoord1
  37. D3DDECLTYPE_FLOAT2, // Texcoord2
  38. D3DDECLTYPE_FLOAT3, // Cubetexcoord1
  39. D3DDECLTYPE_FLOAT3, // Cubetexcoord2
  40. D3DDECLTYPE_FLOAT4, // Tangent
  41. D3DDECLTYPE_FLOAT4, // Blendweights
  42. D3DDECLTYPE_UBYTE4, // Blendindices
  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, // Instancematrix1
  60. D3DDECLUSAGE_TEXCOORD, // Instancematrix2
  61. D3DDECLUSAGE_TEXCOORD // Instancematrix3
  62. };
  63. const BYTE d3dElementUsageIndex[] =
  64. {
  65. 0, // Position
  66. 0, // Normal
  67. 0, // Color
  68. 0, // Texcoord1
  69. 1, // Texcoord2
  70. 0, // Cubetexcoord1
  71. 1, // Cubetexcoord2
  72. 0, // Tangent
  73. 0, // Blendweights
  74. 0, // Blendindices
  75. 2, // Instancematrix1
  76. 3, // Instancematrix2
  77. 4 // Instancematrix3
  78. };
  79. VertexDeclaration::VertexDeclaration(Graphics* graphics, unsigned elementMask) :
  80. declaration_(0)
  81. {
  82. PODVector<VertexDeclarationElement> elements;
  83. unsigned offset = 0;
  84. for (unsigned i = 0; i < MAX_VERTEX_ELEMENTS; ++i)
  85. {
  86. VertexElement element = (VertexElement)i;
  87. if (elementMask & (1 << i))
  88. {
  89. VertexDeclarationElement newElement;
  90. newElement.stream_ = 0;
  91. newElement.element_ = element;
  92. newElement.offset_ = offset;
  93. offset += VertexBuffer::elementSize[i];
  94. elements.Push(newElement);
  95. }
  96. }
  97. Create(graphics, elements);
  98. }
  99. VertexDeclaration::VertexDeclaration(Graphics* graphics, const Vector<VertexBuffer*>& buffers, 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, const PODVector<unsigned>& elementMasks) :
  134. declaration_(0)
  135. {
  136. unsigned usedElementMask = 0;
  137. PODVector<VertexDeclarationElement> elements;
  138. for (unsigned i = 0; i < buffers.Size(); ++i)
  139. {
  140. if (buffers[i])
  141. {
  142. unsigned elementMask = elementMasks[i];
  143. if (elementMask == MASK_DEFAULT)
  144. elementMask = buffers[i]->GetElementMask();
  145. else
  146. {
  147. if ((buffers[i]->GetElementMask() & elementMask) != elementMask)
  148. return;
  149. }
  150. for (unsigned j = 0; j < MAX_VERTEX_ELEMENTS; ++j)
  151. {
  152. VertexElement element = (VertexElement)j;
  153. if (elementMask & (1 << j) && !(usedElementMask & (1 << j)))
  154. {
  155. VertexDeclarationElement newElement;
  156. newElement.stream_ = i;
  157. newElement.element_ = element;
  158. newElement.offset_ = buffers[i]->GetElementOffset(element);
  159. usedElementMask |= 1 << j;
  160. elements.Push(newElement);
  161. }
  162. }
  163. }
  164. }
  165. Create(graphics, elements);
  166. }
  167. VertexDeclaration::~VertexDeclaration()
  168. {
  169. Release();
  170. }
  171. void VertexDeclaration::Create(Graphics* graphics, const PODVector<VertexDeclarationElement>& elements)
  172. {
  173. SharedArrayPtr<D3DVERTEXELEMENT9> elementArray(new D3DVERTEXELEMENT9[elements.Size() + 1]);
  174. D3DVERTEXELEMENT9* dest = elementArray;
  175. for (Vector<VertexDeclarationElement>::ConstIterator i = elements.Begin(); i != elements.End(); ++i)
  176. {
  177. dest->Stream = i->stream_;
  178. dest->Offset = i->offset_;
  179. dest->Type = d3dElementType[i->element_];
  180. dest->Method = D3DDECLMETHOD_DEFAULT;
  181. dest->Usage = d3dElementUsage[i->element_];
  182. dest->UsageIndex = d3dElementUsageIndex[i->element_];
  183. dest++;
  184. }
  185. dest->Stream = 0xff;
  186. dest->Offset = 0;
  187. dest->Type = D3DDECLTYPE_UNUSED;
  188. dest->Method = 0;
  189. dest->Usage = 0;
  190. dest->UsageIndex = 0;
  191. IDirect3DDevice9* device = graphics->GetImpl()->GetDevice();
  192. if (!device)
  193. return;
  194. device->CreateVertexDeclaration(elementArray, &declaration_);
  195. }
  196. void VertexDeclaration::Release()
  197. {
  198. if (declaration_)
  199. {
  200. declaration_->Release();
  201. declaration_ = 0;
  202. }
  203. }
  204. }