Pyrogenesis  trunk
VertexArray.h
Go to the documentation of this file.
1 /* Copyright (C) 2012 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
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.
8  *
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.
13  *
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/>.
16  */
17 
18 #ifndef INCLUDED_VERTEXARRAY
19 #define INCLUDED_VERTEXARRAY
20 
21 #include "renderer/VertexBuffer.h"
22 
23 // Iterator
24 template<typename T>
26 {
27 public:
28  typedef T Type;
29 
30 public:
32  m_Data(0), m_Stride(0)
33  {
34  }
35 
36  VertexArrayIterator(char* data, size_t stride) :
37  m_Data(data), m_Stride(stride)
38  {
39  }
40 
42  m_Data(rhs.m_Data), m_Stride(rhs.m_Stride)
43  {
44  }
45 
47  {
48  m_Data = rhs.m_Data;
49  m_Stride = rhs.m_Stride;
50  return *this;
51  }
52 
53  // Accessors
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); }
57 
58  // Walking
60  {
61  m_Data += m_Stride;
62  return *this;
63  }
65  {
66  VertexArrayIterator tmp = *this;
67  m_Data += m_Stride;
68  return tmp;
69  }
71  {
72  m_Data -= m_Stride;
73  return *this;
74  }
76  {
77  VertexArrayIterator tmp = *this;
78  m_Data -= m_Stride;
79  return tmp;
80  }
81 
83  {
84  m_Data += rhs*m_Stride;
85  return *this;
86  }
88  {
89  m_Data -= rhs*m_Stride;
90  return *this;
91  }
92 
94  {
95  VertexArrayIterator tmp = *this;
96  tmp.m_Data += rhs*m_Stride;
97  return tmp;
98  }
100  {
101  VertexArrayIterator tmp = *this;
102  tmp.m_Data -= rhs*m_Stride;
103  return tmp;
104  }
105 
106  // Accessors for raw buffer data, for performance-critical code
107  char* GetData() const
108  {
109  return m_Data;
110  }
111  size_t GetStride() const
112  {
113  return m_Stride;
114  }
115 
116 private:
117  char* m_Data;
118  size_t m_Stride;
119 };
120 
121 
122 // Manage a vertex array with a runtime-determined set of attributes.
123 //
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.
129 //
130 // Note that this class will not allocate any OpenGL resources until one
131 // of the Upload functions is called.
133 {
134 public:
135  struct Attribute
136  {
137  // Data type. Currently supported: GL_FLOAT, GL_SHORT, GL_UNSIGNED_SHORT, GL_UNSIGNED_BYTE.
138  GLenum type;
139  // How many elements per vertex (e.g. 3 for RGB, 2 for UV)
140  GLuint elems;
141 
142  // Offset (in bytes) into a vertex structure (filled in by Layout())
143  size_t offset;
144 
146 
147  Attribute() : type(0), elems(0), offset(0), vertexArray(0) { }
148 
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().
155  template<typename T>
156  VertexArrayIterator<T> GetIterator() const;
157  };
158 
159 public:
160  VertexArray(GLenum usage, GLenum target = GL_ARRAY_BUFFER);
161  ~VertexArray();
162 
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);
167 
168  size_t GetNumVertices() const { return m_NumVertices; }
169  size_t GetStride() const { return m_Stride; }
170 
171  // Layout the vertex array format and create backing buffer in RAM.
172  // You must call Layout() after changing the number of vertices or
173  // attributes.
174  // All vertex data is lost when a vertex array is re-layouted.
175  void Layout();
176  // (Re-)Upload the attributes of the vertex array from the backing store to
177  // the underlying VBO object.
178  void Upload();
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.
182  u8* Bind();
183 
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();
187 
188 private:
189  void Free();
190 
191  template<typename T>
193  {
194  ENSURE(attr->type && attr->elems);
195  return VertexArrayIterator<T>(m_BackingStore + attr->offset, m_Stride);
196  }
197 
198  GLenum m_Usage;
199  GLenum m_Target;
201  std::vector<Attribute*> m_Attributes;
202 
204  size_t m_Stride;
205  char* m_BackingStore; // 16-byte aligned, to allow fast SSE access
206 };
207 
208 /**
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.
213  */
215 {
216 public:
217  VertexIndexArray(GLenum usage);
218 
219  /// Gets the iterator over the (only) attribute in this array, i.e. a u16.
220  VertexArrayIterator<u16> GetIterator() const;
221 
222 private:
224 };
225 
226 #endif // INCLUDED_VERTEXARRAY
GLenum m_Target
Definition: VertexArray.h:199
VertexArray * vertexArray
Definition: VertexArray.h:145
VertexArrayIterator operator-(ssize_t rhs) const
Definition: VertexArray.h:99
size_t GetStride() const
Definition: VertexArray.h:111
CVertexBuffer::VBChunk * m_VB
Definition: VertexArray.h:203
VertexArrayIterator & operator--()
Definition: VertexArray.h:70
T & operator*() const
Definition: VertexArray.h:54
VertexArrayIterator< T > MakeIterator(const Attribute *attr)
Definition: VertexArray.h:192
VBChunk: describes a portion of this vertex buffer.
Definition: VertexBuffer.h:62
uint8_t u8
Definition: types.h:37
A VertexArray that is specialised to handle 16-bit array indices.
Definition: VertexArray.h:214
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
Definition: debug.h:287
size_t m_Stride
Definition: VertexArray.h:204
Definition: VertexArray.h:135
T & operator[](size_t idx) const
Definition: VertexArray.h:56
VertexArrayIterator operator++(int)
Definition: VertexArray.h:64
T * operator->() const
Definition: VertexArray.h:55
Definition: VertexArray.h:132
VertexArrayIterator & operator-=(ssize_t rhs)
Definition: VertexArray.h:87
char * m_BackingStore
Definition: VertexArray.h:205
#define T(string_literal)
Definition: secure_crt.cpp:76
GLenum type
Definition: VertexArray.h:138
T Type
Definition: VertexArray.h:28
GLuint elems
Definition: VertexArray.h:140
std::vector< Attribute * > m_Attributes
Definition: VertexArray.h:201
Attribute m_Attr
Definition: VertexArray.h:223
intptr_t ssize_t
Definition: wposix_types.h:82
VertexArrayIterator()
Definition: VertexArray.h:31
char * m_Data
Definition: VertexArray.h:117
VertexArrayIterator & operator++()
Definition: VertexArray.h:59
VertexArrayIterator(char *data, size_t stride)
Definition: VertexArray.h:36
size_t m_Stride
Definition: VertexArray.h:118
VertexArrayIterator operator+(ssize_t rhs) const
Definition: VertexArray.h:93
VertexArrayIterator & operator+=(ssize_t rhs)
Definition: VertexArray.h:82
Definition: VertexArray.h:25
VertexArrayIterator operator--(int)
Definition: VertexArray.h:75
char * GetData() const
Definition: VertexArray.h:107
GLenum m_Usage
Definition: VertexArray.h:198
size_t m_NumVertices
Definition: VertexArray.h:200
size_t offset
Definition: VertexArray.h:143
void Free(void *p, size_t size)
decommit memory and release address space.
Definition: uvm.cpp:113
size_t GetStride() const
Definition: VertexArray.h:169
VertexArrayIterator & operator=(const VertexArrayIterator &rhs)
Definition: VertexArray.h:46
VertexArrayIterator(const VertexArrayIterator &rhs)
Definition: VertexArray.h:41
size_t GetNumVertices() const
Definition: VertexArray.h:168
Attribute()
Definition: VertexArray.h:147