1 /* Copyright (C) 2012 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #ifndef INCLUDED_VERTEXARRAY
19 #define INCLUDED_VERTEXARRAY
21 #include "renderer/VertexBuffer.h"
25 class VertexArrayIterator
31 VertexArrayIterator() :
32 m_Data(0), m_Stride(0)
36 VertexArrayIterator(char* data
, size_t stride
) :
37 m_Data(data
), m_Stride(stride
)
41 VertexArrayIterator(const VertexArrayIterator
& rhs
) :
42 m_Data(rhs
.m_Data
), m_Stride(rhs
.m_Stride
)
46 VertexArrayIterator
& operator=(const VertexArrayIterator
& rhs
)
49 m_Stride
= rhs
.m_Stride
;
54 T
& operator*() const { return *(T
*)m_Data
; }
55 T
* operator->() const { return (T
*)m_Data
; }
56 T
& operator[](size_t idx
) const { return *(T
*)(m_Data
+ idx
*m_Stride
); }
59 VertexArrayIterator
& operator++()
64 VertexArrayIterator
operator++(int)
66 VertexArrayIterator tmp
= *this;
70 VertexArrayIterator
& operator--()
75 VertexArrayIterator
operator--(int)
77 VertexArrayIterator tmp
= *this;
82 VertexArrayIterator
& operator+=(ssize_t rhs
)
84 m_Data
+= rhs
*m_Stride
;
87 VertexArrayIterator
& operator-=(ssize_t rhs
)
89 m_Data
-= rhs
*m_Stride
;
93 VertexArrayIterator
operator+(ssize_t rhs
) const
95 VertexArrayIterator tmp
= *this;
96 tmp
.m_Data
+= rhs
*m_Stride
;
99 VertexArrayIterator
operator-(ssize_t rhs
) const
101 VertexArrayIterator tmp
= *this;
102 tmp
.m_Data
-= rhs
*m_Stride
;
106 // Accessors for raw buffer data, for performance-critical code
107 char* GetData() const
111 size_t GetStride() const
122 // Manage a vertex array with a runtime-determined set of attributes.
124 // Purpose: Different rendering paths sometimes require different sets of
125 // attributes (e.g. normal vector vs. color data), which is difficult to
126 // support with hardcoded vertex structures.
127 // This class chooses the vertex layout at runtime, based on the attributes
128 // that are actually needed.
130 // Note that this class will not allocate any OpenGL resources until one
131 // of the Upload functions is called.
137 // Data type. Currently supported: GL_FLOAT, GL_SHORT, GL_UNSIGNED_SHORT, GL_UNSIGNED_BYTE.
139 // How many elements per vertex (e.g. 3 for RGB, 2 for UV)
142 // Offset (in bytes) into a vertex structure (filled in by Layout())
145 VertexArray
* vertexArray
;
147 Attribute() : type(0), elems(0), offset(0), vertexArray(0) { }
149 // Get an iterator over the backing store for the given attribute that
150 // initially points at the first vertex.
151 // Supported types T: CVector3D, CVector4D, float[2], SColor3ub, SColor4ub,
152 // u16, u16[2], u8, u8[4], short, short[2].
153 // This function verifies at runtime that the requested type T matches
154 // the attribute definition passed to AddAttribute().
156 VertexArrayIterator
<T
> GetIterator() const;
160 VertexArray(GLenum usage
, GLenum target
= GL_ARRAY_BUFFER
);
163 // Set the number of vertices stored in the array
164 void SetNumVertices(size_t num
);
165 // Add vertex attributes
166 void AddAttribute(Attribute
* attr
);
168 size_t GetNumVertices() const { return m_NumVertices
; }
169 size_t GetStride() const { return m_Stride
; }
171 // Layout the vertex array format and create backing buffer in RAM.
172 // You must call Layout() after changing the number of vertices or
174 // All vertex data is lost when a vertex array is re-layouted.
176 // (Re-)Upload the attributes of the vertex array from the backing store to
177 // the underlying VBO object.
179 // Make this vertex array's data available for the next series of calls to Bind
180 void PrepareForRendering();
181 // Bind this array, returns the base address for calls to glVertexPointer etc.
184 // If you know for certain that you'll never have to change the data again,
185 // call this to free some memory.
186 void FreeBackingStore();
192 VertexArrayIterator
<T
> MakeIterator(const Attribute
* attr
)
194 ENSURE(attr
->type
&& attr
->elems
);
195 return VertexArrayIterator
<T
>(m_BackingStore
+ attr
->offset
, m_Stride
);
200 size_t m_NumVertices
;
201 std::vector
<Attribute
*> m_Attributes
;
203 CVertexBuffer::VBChunk
* m_VB
;
205 char* m_BackingStore
; // 16-byte aligned, to allow fast SSE access
209 * A VertexArray that is specialised to handle 16-bit array indices.
210 * Call Bind() and pass the return value to the indices parameter of
211 * glDrawElements/glDrawRangeElements/glMultiDrawElements.
212 * Use CVertexBuffer::Unbind() to unbind the array when done.
214 class VertexIndexArray
: public VertexArray
217 VertexIndexArray(GLenum usage
);
219 /// Gets the iterator over the (only) attribute in this array, i.e. a u16.
220 VertexArrayIterator
<u16
> GetIterator() const;
226 #endif // INCLUDED_VERTEXARRAY