Pyrogenesis  trunk
VertexArray.h
Go to the documentation of this file.
1 /* Copyright (C) 2023 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 
25 
26 #include <vector>
27 
28 // Iterator
29 template<typename T>
31 {
32 public:
33  typedef T Type;
34 
35 public:
37  m_Data(0), m_Stride(0)
38  {
39  }
40 
41  VertexArrayIterator(char* data, size_t stride) :
42  m_Data(data), m_Stride(stride)
43  {
44  }
45 
47  m_Data(rhs.m_Data), m_Stride(rhs.m_Stride)
48  {
49  }
50 
52  {
53  m_Data = rhs.m_Data;
54  m_Stride = rhs.m_Stride;
55  return *this;
56  }
57 
58  // Accessors
59  T& operator*() const { return *(T*)m_Data; }
60  T* operator->() const { return (T*)m_Data; }
61  T& operator[](size_t idx) const { return *(T*)(m_Data + idx*m_Stride); }
62 
63  // Walking
65  {
66  m_Data += m_Stride;
67  return *this;
68  }
70  {
71  VertexArrayIterator tmp = *this;
72  m_Data += m_Stride;
73  return tmp;
74  }
76  {
77  m_Data -= m_Stride;
78  return *this;
79  }
81  {
82  VertexArrayIterator tmp = *this;
83  m_Data -= m_Stride;
84  return tmp;
85  }
86 
88  {
89  m_Data += rhs*m_Stride;
90  return *this;
91  }
93  {
94  m_Data -= rhs*m_Stride;
95  return *this;
96  }
97 
99  {
100  VertexArrayIterator tmp = *this;
101  tmp.m_Data += rhs*m_Stride;
102  return tmp;
103  }
105  {
106  VertexArrayIterator tmp = *this;
107  tmp.m_Data -= rhs*m_Stride;
108  return tmp;
109  }
110 
111  // Accessors for raw buffer data, for performance-critical code
112  char* GetData() const
113  {
114  return m_Data;
115  }
116  size_t GetStride() const
117  {
118  return m_Stride;
119  }
120 
121 private:
122  char* m_Data;
123  size_t m_Stride;
124 };
125 
126 
127 // Manage a vertex array with a runtime-determined set of attributes.
128 //
129 // Purpose: Different rendering paths sometimes require different sets of
130 // attributes (e.g. normal vector vs. color data), which is difficult to
131 // support with hardcoded vertex structures.
132 // This class chooses the vertex layout at runtime, based on the attributes
133 // that are actually needed.
134 //
135 // Note that this class will not allocate any backend resources until one
136 // of the Upload functions is called.
138 {
139 public:
140  struct Attribute
141  {
143 
144  // Offset (in bytes) into a vertex structure (filled in by Layout())
145  uint32_t offset = 0;
146 
147  VertexArray* vertexArray = nullptr;
148 
150 
151  // Get an iterator over the backing store for the given attribute that
152  // initially points at the first vertex.
153  // Supported types T: CVector3D, CVector4D, float[2], SColor4ub,
154  // u16, u16[2], u8[4], short, short[2].
155  // This function verifies at runtime that the requested type T matches
156  // the attribute definition passed to AddAttribute().
157  template<typename T>
158  VertexArrayIterator<T> GetIterator() const;
159  };
160 
161 public:
162  VertexArray(
163  const Renderer::Backend::IBuffer::Type type, const bool dynamic);
164  ~VertexArray();
165 
166  // Set the number of vertices stored in the array
167  void SetNumberOfVertices(const size_t numberOfVertices);
168  // Add vertex attributes
169  void AddAttribute(Attribute* attr);
170 
171  size_t GetNumberOfVertices() const { return m_NumberOfVertices; }
172  uint32_t GetStride() const { return m_Stride; }
173 
174  // Layout the vertex array format and create backing buffer in RAM.
175  // You must call Layout() after changing the number of vertices or
176  // attributes.
177  // All vertex data is lost when a vertex array is re-layouted.
178  void Layout();
179  // (Re-)Upload the attributes of the vertex array from the backing store to
180  // the underlying buffer.
181  void Upload();
182  // Make this vertex array's data available for the next series of calls to Bind
183  void PrepareForRendering();
184 
185  void UploadIfNeeded(Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
186 
187  // If you know for certain that you'll never have to change the data again,
188  // call this to free some memory.
189  void FreeBackingStore();
190 
191  Renderer::Backend::IBuffer* GetBuffer() { return m_VB ? m_VB->m_Owner->GetBuffer() : nullptr; }
192 
193  uint32_t GetOffset() const { return m_VB ? m_VB->m_Index : 0; }
194 
195 private:
196  void Free();
197 
198  template<typename T>
200  {
202  return VertexArrayIterator<T>(m_BackingStore + attr->offset, m_Stride);
203  }
204 
206  bool m_Dynamic;
208  std::vector<Attribute*> m_Attributes;
209 
212  char* m_BackingStore; // 16-byte aligned, to allow fast SSE access
213 };
214 
215 /**
216  * A VertexArray that is specialised to handle 16-bit array indices.
217  * Call UploadIfNeeded() before use in Draw/DrawIndexed.
218  */
220 {
221 public:
222  VertexIndexArray(const bool dynamic);
223 
224  /// Gets the iterator over the (only) attribute in this array, i.e. a u16.
225  VertexArrayIterator<u16> GetIterator() const;
226 
227 private:
229 };
230 
231 #endif // INCLUDED_VERTEXARRAY
Definition: IBuffer.h:31
size_t m_NumberOfVertices
Definition: VertexArray.h:207
CVertexBufferManager::Handle m_VB
Definition: VertexArray.h:210
Type
Definition: IBuffer.h:34
VertexArrayIterator & operator--()
Definition: VertexArray.h:75
uint32_t m_Stride
Definition: VertexArray.h:211
size_t GetNumberOfVertices() const
Definition: VertexArray.h:171
VertexArrayIterator operator+(ssize_t rhs) const
Definition: VertexArray.h:98
VertexArrayIterator< T > MakeIterator(const Attribute *attr)
Definition: VertexArray.h:199
A VertexArray that is specialised to handle 16-bit array indices.
Definition: VertexArray.h:219
T & operator[](size_t idx) const
Definition: VertexArray.h:61
char * GetData() const
Definition: VertexArray.h:112
Renderer::Backend::Format format
Definition: VertexArray.h:142
Format
Definition: Format.h:27
Definition: VertexBufferManager.h:46
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
Definition: debug.h:290
uint32_t offset
Definition: VertexArray.h:145
uint32_t GetStride() const
Definition: VertexArray.h:172
Definition: VertexArray.h:140
VertexArrayIterator operator++(int)
Definition: VertexArray.h:69
T * operator->() const
Definition: VertexArray.h:60
Definition: VertexArray.h:137
VertexArrayIterator & operator-=(ssize_t rhs)
Definition: VertexArray.h:92
char * m_BackingStore
Definition: VertexArray.h:212
bool m_Dynamic
Definition: VertexArray.h:206
#define T(string_literal)
Definition: secure_crt.cpp:77
Renderer::Backend::IBuffer * GetBuffer()
Definition: VertexArray.h:191
T Type
Definition: VertexArray.h:33
std::vector< Attribute * > m_Attributes
Definition: VertexArray.h:208
Attribute m_Attr
Definition: VertexArray.h:228
intptr_t ssize_t
Definition: wposix_types.h:82
VertexArrayIterator()
Definition: VertexArray.h:36
uint32_t GetOffset() const
Definition: VertexArray.h:193
void Free(void *p, size_t size)
decommit memory and release address space.
Definition: uvm.cpp:113
char * m_Data
Definition: VertexArray.h:122
unsigned int uint32_t
Definition: wposix_types.h:53
VertexArrayIterator & operator++()
Definition: VertexArray.h:64
VertexArrayIterator(char *data, size_t stride)
Definition: VertexArray.h:41
size_t m_Stride
Definition: VertexArray.h:123
VertexArrayIterator & operator+=(ssize_t rhs)
Definition: VertexArray.h:87
Definition: VertexArray.h:30
VertexArrayIterator operator--(int)
Definition: VertexArray.h:80
Renderer::Backend::IBuffer::Type m_Type
Definition: VertexArray.h:205
size_t GetStride() const
Definition: VertexArray.h:116
VertexArrayIterator operator-(ssize_t rhs) const
Definition: VertexArray.h:104
Definition: IDeviceCommandContext.h:40
T & operator*() const
Definition: VertexArray.h:59
VertexArrayIterator & operator=(const VertexArrayIterator &rhs)
Definition: VertexArray.h:51
VertexArrayIterator(const VertexArrayIterator &rhs)
Definition: VertexArray.h:46
Attribute()
Definition: VertexArray.h:149