source: trunk/src/lol/gpu/vertexbuffer.h @ 2610

Last change on this file since 2610 was 2610, checked in by sam, 8 years ago

base: a few minor style tweaks.

  • Property svn:keywords set to Id
File size: 9.6 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2013 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://www.wtfpl.net/ for more details.
9//
10
11//
12// The VertexBuffer and VertexDeclaration classes
13// ----------------------------------------------
14//
15
16#if !defined __LOL_GPU_VERTEXBUFFER_H__
17#define __LOL_GPU_VERTEXBUFFER_H__
18
19#include <cstring>
20
21namespace lol
22{
23
24class VertexBuffer
25{
26    friend class VertexDeclaration;
27
28public:
29    VertexBuffer(size_t size);
30    ~VertexBuffer();
31
32    void *Lock(size_t offset, size_t size);
33    void Unlock();
34
35private:
36    class VertexBufferData *m_data;
37};
38
39/* A safe enum to indicate how a vertex stream is going to be used. For
40 * now there is only TexCoord and not TexCoord0 TexCoord1 etc. because
41 * we can always reorganise the vertex declaration for the indices to
42 * match. If the need arises these enums will be added. */
43struct VertexUsage
44{
45    enum Value
46    {
47        Position = 0,
48        BlendWeight,
49        BlendIndices,
50        Normal,
51        PointSize,
52        TexCoord,
53        TexCoordExt,
54        Tangent,
55        Binormal,
56        TessFactor,
57        PositionT,
58        Color,
59        Fog,
60        Depth,
61        Sample,
62
63        Max
64    }
65    m_value;
66
67private:
68    static String GetName(Value v, bool use_simple)
69    {
70        String tmp = String("");
71        if (!use_simple) tmp += "<";
72        switch (v)
73        {
74            case Position:      { tmp += "Position";    break; }
75            case BlendWeight:   { tmp += "BlendWeight"; break; }
76            case BlendIndices:  { tmp += "BlendIndices";break; }
77            case Normal:        { tmp += "Normal";      break; }
78            case PointSize:     { tmp += "PointSize";   break; }
79            case TexCoord:      { tmp += "TexCoord";    break; }
80            case TexCoordExt:   { tmp += "TexCoordExt"; break; }
81            case Tangent:       { tmp += "Tangent";     break; }
82            case Binormal:      { tmp += "Binormal";    break; }
83            case TessFactor:    { tmp += "TessFactor";  break; }
84            case PositionT:     { tmp += "PositionT";   break; }
85            case Color:         { tmp += "Color";       break; }
86            case Fog:           { tmp += "Fog";         break; }
87            case Depth:         { tmp += "Depth";       break; }
88            case Sample:        { tmp += "Sample";      break; }
89            default:            { tmp += "UNDEFINED";   break; }
90        }
91        if (!use_simple) tmp += ">";
92        return tmp;
93    }
94
95public:
96    static String GetName(Value v)
97    {
98        return GetName(v, false);
99    }
100
101    static String GetNameList(uint32_t v)
102    {
103        String tmp = String("<");
104        int nb = 0;
105        for (int i = 0; i < Max; ++i)
106        {
107            if (v & (1<<i))
108            {
109                if (nb != 0)
110                    tmp += ", ";
111                tmp += GetName(Value(i), true);
112                ++nb;
113            }
114        }
115        return tmp + ">";
116    }
117
118    inline VertexUsage(Value v) : m_value(v) {}
119    inline VertexUsage(int v) : m_value((Value)v) {}
120    inline operator Value() { return m_value; }
121};
122
123/* A safe enum to indicate what kind of primitive to draw. Used in
124 * VertexDeclaration::DrawElements() for instance. */
125struct MeshPrimitive
126{
127    enum Value
128    {
129        Triangles,
130        TriangleStrips,
131        TriangleFans,
132        Points,
133        Lines,
134    }
135    m_value;
136
137    inline MeshPrimitive(Value v) : m_value(v) {}
138    inline operator Value() { return m_value; }
139};
140
141class VertexStreamBase
142{
143    friend class VertexDeclaration;
144
145protected:
146    enum
147    {
148        Typevoid = 0,
149        Typehalf,     Typef16vec2, Typef16vec3, Typef16vec4,
150        Typefloat,    Typevec2,    Typevec3,    Typevec4,
151        Typedouble,   Typedvec2,   Typedvec3,   Typedvec4,
152        Typeint8_t,   Typei8vec2,  Typei8vec3,  Typei8vec4,
153        Typeuint8_t,  Typeu8vec2,  Typeu8vec3,  Typeu8vec4,
154        Typeint16_t,  Typei16vec2, Typei16vec3, Typei16vec4,
155        Typeuint16_t, Typeu16vec2, Typeu16vec3, Typeu16vec4,
156        Typeint32_t,  Typeivec2,   Typeivec3,   Typeivec4,
157        Typeuint32_t, Typeuvec2,   Typeuvec3,   Typeuvec4,
158    };
159
160#define LOL_TYPE(T) \
161    static uint8_t GetType(T *x) { UNUSED(x); return Type##T; }
162
163    LOL_TYPE(void)
164    LOL_TYPE(half)     LOL_TYPE(f16vec2) LOL_TYPE(f16vec3) LOL_TYPE(f16vec4)
165    LOL_TYPE(float)    LOL_TYPE(vec2)    LOL_TYPE(vec3)    LOL_TYPE(vec4)
166    LOL_TYPE(double)   LOL_TYPE(dvec2)   LOL_TYPE(dvec3)   LOL_TYPE(dvec4)
167    LOL_TYPE(int8_t)   LOL_TYPE(i8vec2)  LOL_TYPE(i8vec3)  LOL_TYPE(i8vec4)
168    LOL_TYPE(uint8_t)  LOL_TYPE(u8vec2)  LOL_TYPE(u8vec3)  LOL_TYPE(u8vec4)
169    LOL_TYPE(int16_t)  LOL_TYPE(i16vec2) LOL_TYPE(i16vec3) LOL_TYPE(i16vec4)
170    LOL_TYPE(uint16_t) LOL_TYPE(u16vec2) LOL_TYPE(u16vec3) LOL_TYPE(u16vec4)
171    LOL_TYPE(int32_t)  LOL_TYPE(ivec2)   LOL_TYPE(ivec3)   LOL_TYPE(ivec4)
172    LOL_TYPE(uint32_t) LOL_TYPE(uvec2)   LOL_TYPE(uvec3)   LOL_TYPE(uvec4)
173#undef LOL_TYPE
174
175    template<typename T> inline void AddStream(int n, VertexUsage usage)
176    {
177        m_streams[n].stream_type = GetType((T *)nullptr);
178        m_streams[n].usage = usage;
179        m_streams[n].size = sizeof(T);
180    }
181
182    VertexStreamBase() {}
183
184private:
185    struct { uint8_t stream_type, usage, size; } m_streams[12 + 1];
186
187    static VertexStreamBase const Empty;
188};
189
190/* Specialise this template for "void" to act as a NOP */
191template<>
192inline void VertexStreamBase::AddStream<void>(int n, VertexUsage usage)
193{
194    UNUSED(usage);
195    m_streams[n].size = 0;
196}
197
198template<typename T1 = void,  typename T2 = void,  typename T3 = void,
199         typename T4 = void,  typename T5 = void,  typename T6 = void,
200         typename T7 = void,  typename T8 = void,  typename T9 = void,
201         typename T10 = void, typename T11 = void, typename T12 = void>
202class VertexStream : public VertexStreamBase
203{
204public:
205    inline VertexStream(VertexUsage u1,
206                        VertexUsage u2 = VertexUsage::Position,
207                        VertexUsage u3 = VertexUsage::Position,
208                        VertexUsage u4 = VertexUsage::Position,
209                        VertexUsage u5 = VertexUsage::Position,
210                        VertexUsage u6 = VertexUsage::Position,
211                        VertexUsage u7 = VertexUsage::Position,
212                        VertexUsage u8 = VertexUsage::Position,
213                        VertexUsage u9 = VertexUsage::Position,
214                        VertexUsage u10 = VertexUsage::Position,
215                        VertexUsage u11 = VertexUsage::Position,
216                        VertexUsage u12 = VertexUsage::Position)
217    {
218        AddStream<T1>(0, u1);    AddStream<T2>(1, u2);
219        AddStream<T3>(2, u3);    AddStream<T4>(3, u4);
220        AddStream<T5>(4, u5);    AddStream<T6>(5, u6);
221        AddStream<T7>(6, u7);    AddStream<T8>(7, u8);
222        AddStream<T9>(8, u9);    AddStream<T10>(9, u10);
223        AddStream<T11>(10, u11); AddStream<T12>(11, u12);
224    }
225};
226
227class VertexDeclaration
228{
229public:
230    VertexDeclaration(VertexStreamBase const &s1 = VertexStreamBase::Empty,
231                      VertexStreamBase const &s2 = VertexStreamBase::Empty,
232                      VertexStreamBase const &s3 = VertexStreamBase::Empty,
233                      VertexStreamBase const &s4 = VertexStreamBase::Empty,
234                      VertexStreamBase const &s5 = VertexStreamBase::Empty,
235                      VertexStreamBase const &s6 = VertexStreamBase::Empty,
236                      VertexStreamBase const &s7 = VertexStreamBase::Empty,
237                      VertexStreamBase const &s8 = VertexStreamBase::Empty,
238                      VertexStreamBase const &s9 = VertexStreamBase::Empty,
239                      VertexStreamBase const &s10 = VertexStreamBase::Empty,
240                      VertexStreamBase const &s11 = VertexStreamBase::Empty,
241                      VertexStreamBase const &s12 = VertexStreamBase::Empty);
242    ~VertexDeclaration();
243
244    void Bind();
245
246    /* Draw elements. See MeshPrimitive for a list of all available
247     * types. Both skip and count are numbers of vertices, not primitives. */
248    void DrawElements(MeshPrimitive type, int skip, int count);
249
250    /* Draw elements. See MeshPrimitive for a list of all available
251     * types. Both skip and count are numbers of indices, not primitives. */
252    void DrawIndexedElements(MeshPrimitive type, int vbase, int vskip,
253                             int vcount, int skip, int count);
254
255    void Unbind();
256    void SetStream(VertexBuffer *vb, ShaderAttrib attr1,
257                                     ShaderAttrib attr2 = ShaderAttrib(),
258                                     ShaderAttrib attr3 = ShaderAttrib(),
259                                     ShaderAttrib attr4 = ShaderAttrib(),
260                                     ShaderAttrib attr5 = ShaderAttrib(),
261                                     ShaderAttrib attr6 = ShaderAttrib(),
262                                     ShaderAttrib attr7 = ShaderAttrib(),
263                                     ShaderAttrib attr8 = ShaderAttrib(),
264                                     ShaderAttrib attr9 = ShaderAttrib(),
265                                     ShaderAttrib attr10 = ShaderAttrib(),
266                                     ShaderAttrib attr11 = ShaderAttrib(),
267                                     ShaderAttrib attr12 = ShaderAttrib());
268
269private:
270    void Initialize();
271    void AddStream(VertexStreamBase const &);
272
273    struct { uint8_t stream_type, index, usage, size; int reg; } m_streams[12 + 1];
274    int m_count;
275
276    void *m_data;
277};
278
279} /* namespace lol */
280
281#endif // __LOL_GPU_VERTEXBUFFER_H__
282
Note: See TracBrowser for help on using the repository browser.