You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

227 line
7.7 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. //
  11. // The VertexBuffer and VertexDeclaration classes
  12. // ----------------------------------------------
  13. //
  14. #if !defined __LOL_VERTEXBUFFER_H__
  15. #define __LOL_VERTEXBUFFER_H__
  16. #include <cstring>
  17. namespace lol
  18. {
  19. class VertexBuffer
  20. {
  21. friend class VertexDeclaration;
  22. public:
  23. VertexBuffer(size_t size);
  24. ~VertexBuffer();
  25. void *Lock(size_t offset, size_t size);
  26. void Unlock();
  27. private:
  28. class VertexBufferData *m_data;
  29. };
  30. /* A safe enum to indicate how a vertex stream is going to be used. For
  31. * now there is only TexCoord and not TexCoord0 TexCoord1 etc. because
  32. * we can always reorganise the vertex declaration for the indices to
  33. * match. If the need arises these enums will be added. */
  34. struct VertexUsage
  35. {
  36. enum Value
  37. {
  38. Position = 0,
  39. BlendWeight,
  40. BlendIndices,
  41. Normal,
  42. PointSize,
  43. TexCoord,
  44. Tangent,
  45. Binormal,
  46. TessFactor,
  47. PositionT,
  48. Color,
  49. Fog,
  50. Depth,
  51. Sample,
  52. }
  53. m_value;
  54. inline VertexUsage(Value v) : m_value(v) {}
  55. inline operator Value() { return m_value; }
  56. };
  57. /* A safe enum to indicate what kind of primitive to draw. Used in
  58. * VertexDeclaration::DrawElements() for instance. */
  59. struct MeshPrimitive
  60. {
  61. enum Value
  62. {
  63. Triangles,
  64. TriangleStrips,
  65. TriangleFans,
  66. Points,
  67. }
  68. m_value;
  69. inline MeshPrimitive(Value v) : m_value(v) {}
  70. inline operator Value() { return m_value; }
  71. };
  72. class VertexStreamBase
  73. {
  74. friend class VertexDeclaration;
  75. protected:
  76. enum
  77. {
  78. Typevoid = 0,
  79. Typehalf, Typef16vec2, Typef16vec3, Typef16vec4,
  80. Typefloat, Typevec2, Typevec3, Typevec4,
  81. Typedouble, Typedvec2, Typedvec3, Typedvec4,
  82. Typeint8_t, Typei8vec2, Typei8vec3, Typei8vec4,
  83. Typeuint8_t, Typeu8vec2, Typeu8vec3, Typeu8vec4,
  84. Typeint16_t, Typei16vec2, Typei16vec3, Typei16vec4,
  85. Typeuint16_t, Typeu16vec2, Typeu16vec3, Typeu16vec4,
  86. Typeint32_t, Typeivec2, Typeivec3, Typeivec4,
  87. Typeuint32_t, Typeuvec2, Typeuvec3, Typeuvec4,
  88. };
  89. #define LOL_TYPE(T) \
  90. static uint8_t GetType(T *x) { (void)x; return Type##T; }
  91. LOL_TYPE(void)
  92. LOL_TYPE(half) LOL_TYPE(f16vec2) LOL_TYPE(f16vec3) LOL_TYPE(f16vec4)
  93. LOL_TYPE(float) LOL_TYPE(vec2) LOL_TYPE(vec3) LOL_TYPE(vec4)
  94. LOL_TYPE(double) LOL_TYPE(dvec2) LOL_TYPE(dvec3) LOL_TYPE(dvec4)
  95. LOL_TYPE(int8_t) LOL_TYPE(i8vec2) LOL_TYPE(i8vec3) LOL_TYPE(i8vec4)
  96. LOL_TYPE(uint8_t) LOL_TYPE(u8vec2) LOL_TYPE(u8vec3) LOL_TYPE(u8vec4)
  97. LOL_TYPE(int16_t) LOL_TYPE(i16vec2) LOL_TYPE(i16vec3) LOL_TYPE(i16vec4)
  98. LOL_TYPE(uint16_t) LOL_TYPE(u16vec2) LOL_TYPE(u16vec3) LOL_TYPE(u16vec4)
  99. LOL_TYPE(int32_t) LOL_TYPE(ivec2) LOL_TYPE(ivec3) LOL_TYPE(ivec4)
  100. LOL_TYPE(uint32_t) LOL_TYPE(uvec2) LOL_TYPE(uvec3) LOL_TYPE(uvec4)
  101. #undef LOL_TYPE
  102. template<typename T> inline void AddStream(int n, VertexUsage usage)
  103. {
  104. m_streams[n].stream_type = GetType((T *)NULL);
  105. m_streams[n].usage = usage;
  106. m_streams[n].size = sizeof(T);
  107. }
  108. VertexStreamBase() {}
  109. private:
  110. struct { uint8_t stream_type, usage, size; } m_streams[12 + 1];
  111. static VertexStreamBase const Empty;
  112. };
  113. /* Specialise this template for "void" to act as a NOP */
  114. template<>
  115. inline void VertexStreamBase::AddStream<void>(int n, VertexUsage usage)
  116. {
  117. (void)usage;
  118. m_streams[n].size = 0;
  119. }
  120. template<typename T1 = void, typename T2 = void, typename T3 = void,
  121. typename T4 = void, typename T5 = void, typename T6 = void,
  122. typename T7 = void, typename T8 = void, typename T9 = void,
  123. typename T10 = void, typename T11 = void, typename T12 = void>
  124. class VertexStream : public VertexStreamBase
  125. {
  126. public:
  127. inline VertexStream(VertexUsage u1,
  128. VertexUsage u2 = VertexUsage::Position,
  129. VertexUsage u3 = VertexUsage::Position,
  130. VertexUsage u4 = VertexUsage::Position,
  131. VertexUsage u5 = VertexUsage::Position,
  132. VertexUsage u6 = VertexUsage::Position,
  133. VertexUsage u7 = VertexUsage::Position,
  134. VertexUsage u8 = VertexUsage::Position,
  135. VertexUsage u9 = VertexUsage::Position,
  136. VertexUsage u10 = VertexUsage::Position,
  137. VertexUsage u11 = VertexUsage::Position,
  138. VertexUsage u12 = VertexUsage::Position)
  139. {
  140. AddStream<T1>(0, u1); AddStream<T2>(1, u2);
  141. AddStream<T3>(2, u3); AddStream<T4>(3, u4);
  142. AddStream<T5>(4, u5); AddStream<T6>(5, u6);
  143. AddStream<T7>(6, u7); AddStream<T8>(7, u8);
  144. AddStream<T9>(8, u9); AddStream<T10>(9, u10);
  145. AddStream<T11>(10, u11); AddStream<T12>(11, u12);
  146. }
  147. };
  148. class VertexDeclaration
  149. {
  150. public:
  151. VertexDeclaration(VertexStreamBase const &s1,
  152. VertexStreamBase const &s2 = VertexStreamBase::Empty,
  153. VertexStreamBase const &s3 = VertexStreamBase::Empty,
  154. VertexStreamBase const &s4 = VertexStreamBase::Empty,
  155. VertexStreamBase const &s5 = VertexStreamBase::Empty,
  156. VertexStreamBase const &s6 = VertexStreamBase::Empty,
  157. VertexStreamBase const &s7 = VertexStreamBase::Empty,
  158. VertexStreamBase const &s8 = VertexStreamBase::Empty,
  159. VertexStreamBase const &s9 = VertexStreamBase::Empty,
  160. VertexStreamBase const &s10 = VertexStreamBase::Empty,
  161. VertexStreamBase const &s11 = VertexStreamBase::Empty,
  162. VertexStreamBase const &s12 = VertexStreamBase::Empty);
  163. ~VertexDeclaration();
  164. void Bind();
  165. /* Draw elements. See MeshPrimitive for a list of all available
  166. * types. Both skip and count are numbers of vertices, not primitives. */
  167. void DrawElements(MeshPrimitive type, int skip, int count);
  168. /* Draw elements. See MeshPrimitive for a list of all available
  169. * types. Both skip and count are numbers of indices, not primitives. */
  170. void DrawIndexedElements(MeshPrimitive type, int vbase, int vskip,
  171. int vcount, int skip, int count);
  172. void Unbind();
  173. void SetStream(VertexBuffer *vb, ShaderAttrib attr1,
  174. ShaderAttrib attr2 = ShaderAttrib(),
  175. ShaderAttrib attr3 = ShaderAttrib(),
  176. ShaderAttrib attr4 = ShaderAttrib(),
  177. ShaderAttrib attr5 = ShaderAttrib(),
  178. ShaderAttrib attr6 = ShaderAttrib(),
  179. ShaderAttrib attr7 = ShaderAttrib(),
  180. ShaderAttrib attr8 = ShaderAttrib(),
  181. ShaderAttrib attr9 = ShaderAttrib(),
  182. ShaderAttrib attr10 = ShaderAttrib(),
  183. ShaderAttrib attr11 = ShaderAttrib(),
  184. ShaderAttrib attr12 = ShaderAttrib());
  185. private:
  186. void Initialize();
  187. void AddStream(VertexStreamBase const &);
  188. struct { uint8_t stream_type, index, usage, size; int reg; } m_streams[12 + 1];
  189. int m_count;
  190. void *m_data;
  191. };
  192. } /* namespace lol */
  193. #endif // __LOL_VERTEXBUFFER_H__