VertexDeclaration.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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 "Graphics.h"
  25. #include "GraphicsImpl.h"
  26. #include "VertexBuffer.h"
  27. #include "VertexDeclaration.h"
  28. #include "DebugNew.h"
  29. const BYTE d3dElementType[] =
  30. {
  31. D3DDECLTYPE_FLOAT3, // Position
  32. D3DDECLTYPE_FLOAT3, // Normal
  33. D3DDECLTYPE_D3DCOLOR, // Color
  34. D3DDECLTYPE_FLOAT2, // Texcoord1
  35. D3DDECLTYPE_FLOAT2, // Texcoord2
  36. D3DDECLTYPE_FLOAT3, // Cubetexcoord1
  37. D3DDECLTYPE_FLOAT3, // Cubetexcoord2
  38. D3DDECLTYPE_FLOAT4, // Tangent
  39. D3DDECLTYPE_FLOAT4, // Blendweights
  40. D3DDECLTYPE_UBYTE4, // Blendindices
  41. D3DDECLTYPE_FLOAT4, // Instancematrix1
  42. D3DDECLTYPE_FLOAT4, // Instancematrix2
  43. D3DDECLTYPE_FLOAT4 // Instancematrix3
  44. };
  45. const BYTE d3dElementUsage[] =
  46. {
  47. D3DDECLUSAGE_POSITION, // Position
  48. D3DDECLUSAGE_NORMAL, // Normal
  49. D3DDECLUSAGE_COLOR, // Color
  50. D3DDECLUSAGE_TEXCOORD, // Texcoord1
  51. D3DDECLUSAGE_TEXCOORD, // Texcoord2
  52. D3DDECLUSAGE_TEXCOORD, // Cubetexcoord1
  53. D3DDECLUSAGE_TEXCOORD, // Cubetexcoord2
  54. D3DDECLUSAGE_TANGENT, // Tangent
  55. D3DDECLUSAGE_BLENDWEIGHT, // Blendweights
  56. D3DDECLUSAGE_BLENDINDICES, // Blendindices
  57. D3DDECLUSAGE_TEXCOORD, // Instancematrix1
  58. D3DDECLUSAGE_TEXCOORD, // Instancematrix2
  59. D3DDECLUSAGE_TEXCOORD // Instancematrix3
  60. };
  61. const BYTE d3dElementUsageIndex[] =
  62. {
  63. 0, // Position
  64. 0, // Normal
  65. 0, // Color
  66. 0, // Texcoord1
  67. 1, // Texcoord2
  68. 0, // Cubetexcoord1
  69. 1, // Cubetexcoord2
  70. 0, // Tangent
  71. 0, // Blendweights
  72. 0, // Blendindices
  73. 2, // Instancematrix1
  74. 3, // Instancematrix2
  75. 4 // Instancematrix3
  76. };
  77. VertexDeclaration::VertexDeclaration(Graphics* graphics, unsigned elementMask) :
  78. declaration_(0)
  79. {
  80. Vector<VertexDeclarationElement> elements;
  81. unsigned offset = 0;
  82. for (unsigned i = 0; i < MAX_VERTEX_ELEMENTS; ++i)
  83. {
  84. VertexElement element = (VertexElement)i;
  85. if (elementMask & (1 << i))
  86. {
  87. VertexDeclarationElement newElement;
  88. newElement.stream_ = 0;
  89. newElement.element_ = element;
  90. newElement.offset_ = offset;
  91. offset += VertexBuffer::elementSize[i];
  92. elements.Push(newElement);
  93. }
  94. }
  95. Create(graphics, elements);
  96. }
  97. VertexDeclaration::VertexDeclaration(Graphics* graphics, const Vector<VertexBuffer*>& buffers, const Vector<unsigned>& elementMasks) :
  98. declaration_(0)
  99. {
  100. unsigned usedElementMask = 0;
  101. Vector<VertexDeclarationElement> elements;
  102. for (unsigned i = 0; i < buffers.Size(); ++i)
  103. {
  104. if (buffers[i])
  105. {
  106. unsigned elementMask = elementMasks[i];
  107. if (elementMask == MASK_DEFAULT)
  108. elementMask = buffers[i]->GetElementMask();
  109. else
  110. {
  111. if ((buffers[i]->GetElementMask() & elementMask) != elementMask)
  112. return;
  113. }
  114. for (unsigned j = 0; j < MAX_VERTEX_ELEMENTS; ++j)
  115. {
  116. VertexElement element = (VertexElement)j;
  117. if ((elementMask & (1 << j)) && (!(usedElementMask & (1 << j))))
  118. {
  119. VertexDeclarationElement newElement;
  120. newElement.stream_ = i;
  121. newElement.element_ = element;
  122. newElement.offset_ = buffers[i]->GetElementOffset(element);
  123. usedElementMask |= 1 << j;
  124. elements.Push(newElement);
  125. }
  126. }
  127. }
  128. }
  129. Create(graphics, elements);
  130. }
  131. VertexDeclaration::VertexDeclaration(Graphics* graphics, const Vector<SharedPtr<VertexBuffer> >& buffers, const Vector<unsigned>& elementMasks) :
  132. declaration_(0)
  133. {
  134. unsigned usedElementMask = 0;
  135. Vector<VertexDeclarationElement> elements;
  136. for (unsigned i = 0; i < buffers.Size(); ++i)
  137. {
  138. if (buffers[i])
  139. {
  140. unsigned elementMask = elementMasks[i];
  141. if (elementMask == MASK_DEFAULT)
  142. elementMask = buffers[i]->GetElementMask();
  143. else
  144. {
  145. if ((buffers[i]->GetElementMask() & elementMask) != elementMask)
  146. return;
  147. }
  148. for (unsigned j = 0; j < MAX_VERTEX_ELEMENTS; ++j)
  149. {
  150. VertexElement element = (VertexElement)j;
  151. if ((elementMask & (1 << j)) && (!(usedElementMask & (1 << j))))
  152. {
  153. VertexDeclarationElement newElement;
  154. newElement.stream_ = i;
  155. newElement.element_ = element;
  156. newElement.offset_ = buffers[i]->GetElementOffset(element);
  157. usedElementMask |= 1 << j;
  158. elements.Push(newElement);
  159. }
  160. }
  161. }
  162. }
  163. Create(graphics, elements);
  164. }
  165. VertexDeclaration::~VertexDeclaration()
  166. {
  167. Release();
  168. }
  169. void VertexDeclaration::Create(Graphics* graphics, const Vector<VertexDeclarationElement>& elements)
  170. {
  171. SharedArrayPtr<D3DVERTEXELEMENT9> elementArray(new D3DVERTEXELEMENT9[elements.Size() + 1]);
  172. D3DVERTEXELEMENT9* dest = elementArray;
  173. for (Vector<VertexDeclarationElement>::ConstIterator i = elements.Begin(); i != elements.End(); ++i)
  174. {
  175. dest->Stream = i->stream_;
  176. dest->Offset = i->offset_;
  177. dest->Type = d3dElementType[i->element_];
  178. dest->Method = D3DDECLMETHOD_DEFAULT;
  179. dest->Usage = d3dElementUsage[i->element_];
  180. dest->UsageIndex = d3dElementUsageIndex[i->element_];
  181. dest++;
  182. }
  183. dest->Stream = 0xff;
  184. dest->Offset = 0;
  185. dest->Type = D3DDECLTYPE_UNUSED;
  186. dest->Method = 0;
  187. dest->Usage = 0;
  188. dest->UsageIndex = 0;
  189. IDirect3DDevice9* device = graphics->GetImpl()->GetDevice();
  190. if (!device)
  191. return;
  192. device->CreateVertexDeclaration(elementArray, &declaration_);
  193. }
  194. void VertexDeclaration::Release()
  195. {
  196. if (declaration_)
  197. {
  198. declaration_->Release();
  199. declaration_ = 0;
  200. }
  201. }