Saga3D API Documentation  1.0-RC4
CMeshBuffer.h
Go to the documentation of this file.
1 #ifndef __CMESH_BUFFER_H_INCLUDED__
2 #define __CMESH_BUFFER_H_INCLUDED__
3 
4 #include "EPrimitiveTypes.h"
5 #include "IMeshBuffer.h"
6 #include "IVideoDriver.h"
7 #include <vector>
8 #include <unordered_map>
9 #include <algorithm>
10 #include <cstring>
11 
12 namespace saga
13 {
14 namespace scene
15 {
17  class CMeshBuffer : public IMeshBuffer
18  {
19  public:
22  : ID(++RootID)
23  {
25  }
26 
27  virtual bool isGPUBuffer() const override { return false; }
28 
29  virtual ~CMeshBuffer() {}
30 
31  virtual std::uint64_t getID() const override { return ID; }
32 
33  virtual void buildBuffer(video::IVideoDriver& driver, const video::PipelineHandle pipeline) override
34  {
35  if (GPUBuffers.count(pipeline) == 0)
36  {
37  GPUBuffers[pipeline] = {};
38  auto& buffer = GPUBuffers[pipeline];
39  std::size_t bufferSize = 0;
40  for (const auto& attr : driver.getPipeline(pipeline).Layout.Attributes.at(Binding))
41  {
42  if (attr.Type != video::E_ATTRIBUTE_TYPE::INVALID)
43  bufferSize += GetAttributeSize(attr.Format);
44  }
45  bufferSize *= getVertexCount();
46  buffer.clear();
47  buffer.resize(bufferSize);
48  std::size_t position = 0;
49  for (std::size_t i = 0 ; i < getVertexCount(); ++i)
50  {
51  std::size_t customAttributeCount = 0;
52  for (const auto& attr : driver.getPipeline(pipeline).Layout.Attributes.at(Binding))
53  {
54  switch (attr.Type)
55  {
56  case video::E_ATTRIBUTE_TYPE::INVALID: continue;
58  {
59  const auto size = GetAttributeComponentSize(attr.Format);
60  std::memcpy(buffer.data() + position, &PositionBuffer.at(i).x, size);
61  position += size;
62  std::memcpy(buffer.data() + position, &PositionBuffer.at(i).y, size);
63  position += size;
64  std::memcpy(buffer.data() + position, &PositionBuffer.at(i).z, size);
65  position += size;
66  } break;
67 
69  {
70  const auto size = GetAttributeComponentSize(attr.Format);
71  std::memcpy(buffer.data() + position, &NormalBuffer.at(i).x, size);
72  position += size;
73  std::memcpy(buffer.data() + position, &NormalBuffer.at(i).y, size);
74  position += size;
75  std::memcpy(buffer.data() + position, &NormalBuffer.at(i).z, size);
76  position += size;
77  } break;
78 
80  {
81  const auto size = GetAttributeComponentSize(attr.Format);
82  std::memcpy(buffer.data() + position, &ColorBuffer.at(i).x, size);
83  position += size;
84  std::memcpy(buffer.data() + position, &ColorBuffer.at(i).y, size);
85  position += size;
86  std::memcpy(buffer.data() + position, &ColorBuffer.at(i).z, size);
87  position += size;
88  } break;
89 
91  {
92  const auto size = GetAttributeComponentSize(attr.Format);
93  std::memcpy(buffer.data() + position, &TCoordBuffer.at(i).x, size);
94  position += size;
95  std::memcpy(buffer.data() + position, &TCoordBuffer.at(i).y, size);
96  position += size;
97  } break;
98 
100  {
101  const auto size = GetAttributeComponentSize(attr.Format);
102  std::memcpy(buffer.data() + position, &TangentBuffer.at(i).x, size);
103  position += size;
104  std::memcpy(buffer.data() + position, &TangentBuffer.at(i).y, size);
105  position += size;
106  std::memcpy(buffer.data() + position, &TangentBuffer.at(i).z, size);
107  position += size;
108  } break;
109 
111  {
112  const auto size = GetAttributeComponentSize(attr.Format);
113  std::memcpy(buffer.data() + position, &BiTangentBuffer.at(i).x, size);
114  position += size;
115  std::memcpy(buffer.data() + position, &BiTangentBuffer.at(i).y, size);
116  position += size;
117  std::memcpy(buffer.data() + position, &BiTangentBuffer.at(i).z, size);
118  position += size;
119  } break;
120 
122  {
123  const auto size = GetAttributeComponentSize(attr.Format);
124  std::memcpy(buffer.data() + position, &BoneWeightBuffer.at(i).x, size);
125  position += size;
126  std::memcpy(buffer.data() + position, &BoneWeightBuffer.at(i).y, size);
127  position += size;
128  std::memcpy(buffer.data() + position, &BoneWeightBuffer.at(i).z, size);
129  position += size;
130  std::memcpy(buffer.data() + position, &BoneWeightBuffer.at(i).w, size);
131  position += size;
132  } break;
133 
135  {
136  const auto size = GetAttributeComponentSize(attr.Format);
137  std::memcpy(buffer.data() + position, &BoneIDBuffer.at(i).x, size);
138  position += size;
139  std::memcpy(buffer.data() + position, &BoneIDBuffer.at(i).y, size);
140  position += size;
141  std::memcpy(buffer.data() + position, &BoneIDBuffer.at(i).z, size);
142  position += size;
143  std::memcpy(buffer.data() + position, &BoneIDBuffer.at(i).w, size);
144  position += size;
145  } break;
146 
148  {
149  const auto size = GetAttributeSize(attr.Format);
150  std::memcpy(buffer.data() + position, AttributeBuffer.at(i).data() + customAttributeCount++ * size, size);
151  position += size;
152  } break;
153  }
154  }
155  }
156  }
157  }
158 
160 
161  virtual void* getVertices() override
162  {
163  return PositionBuffer.data();
164  }
165 
167 
168  virtual const void* getData(const video::PipelineHandle pipeline) const override
169  {
170  return GPUBuffers.at(pipeline).data();
171  }
172 
174 
175  virtual std::size_t getSize(const video::PipelineHandle pipeline) const override
176  {
177  return GPUBuffers.at(pipeline).size();
178  }
179 
181 
182  virtual std::size_t getVertexCount() const override
183  {
184  return PositionBuffer.size();
185  }
186 
188  virtual void setVertexCount(const size_t count) override { }
189 
191 
192  virtual const std::uint32_t* getIndices() const override
193  {
194  return Indices.data();
195  }
196 
198  virtual std::uint32_t getIndex(std::size_t offset) const override
199  {
200  return Indices.at(offset);
201  }
202 
204 
205  virtual std::uint32_t* getIndices() override
206  {
207  return Indices.data();
208  }
209 
211 
212  virtual std::uint32_t getIndexCount() const override
213  {
214  return Indices.size();
215  }
216 
218  virtual void setIndexCount(const std::uint32_t count) override { }
219 
221 
222  virtual const core::aabbox3d<float>& getBoundingBox() const override
223  {
224  return BoundingBox;
225  }
226 
228 
229  virtual void setBoundingBox(const core::aabbox3df& box) override
231  {
232  BoundingBox = box;
233  }
234 
236 
237  virtual void recalculateBoundingBox() override
238  {
239  if (!PositionBuffer.empty())
240  {
242  const std::uint32_t vsize = PositionBuffer.size();
243  for (std::uint32_t i=1; i < vsize; ++i)
245  }
246  else
247  BoundingBox.reset(0,0,0);
248  }
249 
251  virtual const glm::vec3& getPosition(std::uint32_t i) const override
252  {
253  return PositionBuffer[i];
254  }
255 
257  virtual const glm::vec3& getNormal(std::uint32_t i) const override
258  {
259  return NormalBuffer[i];
260  }
261 
263  virtual const glm::vec2& getTCoords(std::uint32_t i) const override
264  {
265  return TCoordBuffer[i];
266  }
267 
269  virtual const glm::vec3& getTangent(std::uint32_t i) const override
270  {
271  return TangentBuffer[i];
272  }
273 
275  virtual const glm::vec3& getBiTangent(std::uint32_t i) const override
276  {
277  return BiTangentBuffer[i];
278  }
279 
281 
285  virtual void append(
286  std::vector<S3DVertex>&& vertices,
287  std::vector<uint32_t>&& indices) override
288  {
289  const std::uint32_t vertexCount = getVertexCount();
290  std::uint32_t i;
291 
292  for (i = 0; i < vertices.size(); ++i)
293  {
294  PositionBuffer.push_back(std::move(vertices[i].Position));
295  NormalBuffer.push_back(std::move(vertices[i].Normal));
296  ColorBuffer.push_back(std::move(vertices[i].Color));
297  TCoordBuffer.push_back(std::move(vertices[i].TextureCoords));
298  TangentBuffer.push_back(std::move(vertices[i].Tangent));
299  BiTangentBuffer.push_back(std::move(vertices[i].BiTangent));
300  BoneWeightBuffer.push_back(std::move(vertices[i].BoneWeights));
301  BoneIDBuffer.push_back(std::move(vertices[i].BoneIDs));
302  if (vertices[i].Attributes.empty() == false)
303  AttributeBuffer.push_back(std::move(vertices[i].Attributes));
305  }
306 
307  for (i = 0; i < indices.size(); ++i)
308  {
309  Indices.push_back(indices[i]+vertexCount);
310  }
311  }
312 
314 
318  virtual void appendAttribute(const char* buffer, const size_t size, const size_t stride) override
319  {
320  for (size_t i = 0; i < size / stride; ++i)
321  {
322  std::vector<unsigned char> buf(buffer + i * stride, buffer + (i+1) * stride);
323  AttributeBuffer.push_back(std::move(buf));
324  }
325  }
326 
328 
333  virtual void append(const IMeshBuffer* const other) override
334  {
335  /*
336  if (this==other)
337  return;
338 
339  const std::uint32_t vertexCount = getVertexCount();
340  std::uint32_t i;
341 
342  PositionBuffer.reallocate(vertexCount+other->getVertexCount());
343  for (i = 0; i < other->getVertexCount(); ++i)
344  {
345  PositionBuffer.push_back(reinterpret_cast<const T*>(other->getPositionBuffer())[i]);
346  }
347 
348  Indices.reallocate(getIndexCount()+other->getIndexCount());
349  for (i = 0; i < other->getIndexCount(); ++i)
350  {
351  Indices.push_back(other->getIndices()[i]+vertexCount);
352  }
353  BoundingBox.addInternalBox(other->getBoundingBox());
354  */
355  }
356 
357  const std::uint64_t ID;
358 
359  std::vector<glm::vec3> PositionBuffer;
360  std::vector<glm::vec3> NormalBuffer;
361  std::vector<glm::vec4> ColorBuffer;
362  std::vector<glm::vec2> TCoordBuffer;
363  std::vector<glm::vec3> TangentBuffer;
364  std::vector<glm::vec3> BiTangentBuffer;
365  std::vector<glm::vec4> BoneWeightBuffer;
366  std::vector<glm::vec4> BoneIDBuffer;
367  std::vector<std::vector<unsigned char>> AttributeBuffer;
368 
370  std::unordered_map<video::PipelineHandle, std::vector<unsigned char>> GPUBuffers;
372  std::vector<std::uint32_t> Indices;
375  };
376 
377 } // namespace scene
378 } // namespace saga
379 
380 #endif
381 
382 
saga::scene::CMeshBuffer::getBoundingBox
virtual const core::aabbox3d< float > & getBoundingBox() const override
Get the axis aligned bounding box.
Definition: CMeshBuffer.h:222
saga::scene::CMeshBuffer::getTangent
virtual const glm::vec3 & getTangent(std::uint32_t i) const override
returns tangent of vertex i
Definition: CMeshBuffer.h:269
saga::scene::CMeshBuffer::setVertexCount
virtual void setVertexCount(const size_t count) override
Set number of vertices.
Definition: CMeshBuffer.h:188
saga::video::SPipelineLayout::Attributes
std::array< std::array< SVertexAttribute, MAX_VERTEX_ATTRIBUTES >, MAX_VERTEX_BUFFERS > Attributes
Definition: SPipelineLayout.h:32
saga::scene::E_PRIMITIVE_TYPE::TRIANGLES
@ TRIANGLES
Explicitly set all vertices for each triangle.
saga::video::GetAttributeComponentSize
uint32_t GetAttributeComponentSize(const E_ATTRIBUTE_FORMAT format)
saga::scene::CMeshBuffer::PositionBuffer
std::vector< glm::vec3 > PositionBuffer
Definition: CMeshBuffer.h:359
saga::scene::IMeshBuffer::PrimitiveType
scene::E_PRIMITIVE_TYPE PrimitiveType
Primitive type used for rendering (triangles, lines, ...)
Definition: IMeshBuffer.h:259
saga::scene::CMeshBuffer::BoneIDBuffer
std::vector< glm::vec4 > BoneIDBuffer
Definition: CMeshBuffer.h:366
saga::video::PipelineHandle
SGPUResource::HandleType PipelineHandle
Definition: SPipeline.h:27
saga::video::E_ATTRIBUTE_TYPE::TANGENT
@ TANGENT
saga::video::E_ATTRIBUTE_TYPE::NORMAL
@ NORMAL
saga::scene::CMeshBuffer::appendAttribute
virtual void appendAttribute(const char *buffer, const size_t size, const size_t stride) override
Append the custom attribute buffer to the current mesh buffer.
Definition: CMeshBuffer.h:318
IVideoDriver.h
saga::video::E_ATTRIBUTE_TYPE::BONE_WEIGHT
@ BONE_WEIGHT
saga::scene::CMeshBuffer::isGPUBuffer
virtual bool isGPUBuffer() const override
Definition: CMeshBuffer.h:27
saga::scene::CMeshBuffer::TCoordBuffer
std::vector< glm::vec2 > TCoordBuffer
Definition: CMeshBuffer.h:362
saga::scene::CMeshBuffer::setBoundingBox
virtual void setBoundingBox(const core::aabbox3df &box) override
Set the axis aligned bounding box.
Definition: CMeshBuffer.h:230
saga::scene::CMeshBuffer::buildBuffer
virtual void buildBuffer(video::IVideoDriver &driver, const video::PipelineHandle pipeline) override
Generate GPU-compatible data.
Definition: CMeshBuffer.h:33
saga::scene::CMeshBuffer::append
virtual void append(const IMeshBuffer *const other) override
Append the meshbuffer to the current buffer.
Definition: CMeshBuffer.h:333
saga::scene::IMeshBuffer
Struct for holding a mesh with a single material.
Definition: IMeshBuffer.h:43
saga::scene::CMeshBuffer::ColorBuffer
std::vector< glm::vec4 > ColorBuffer
Definition: CMeshBuffer.h:361
saga::video::GetAttributeSize
uint32_t GetAttributeSize(const E_ATTRIBUTE_FORMAT format)
saga::scene::CMeshBuffer::CMeshBuffer
CMeshBuffer()
Default constructor for empty meshbuffer.
Definition: CMeshBuffer.h:21
saga::ID
std::uint32_t ID
Type for node ID.
Definition: ID.h:11
saga::scene::IMeshBuffer::Binding
int Binding
Binding location.
Definition: IMeshBuffer.h:265
saga::video::E_ATTRIBUTE_TYPE::INVALID
@ INVALID
saga::scene::CMeshBuffer::getData
virtual const void * getData(const video::PipelineHandle pipeline) const override
Get pointer to GPU staging buffer.
Definition: CMeshBuffer.h:168
saga::video::IVideoDriver
Definition: IVideoDriver.h:68
saga::core::aabbox3d< float >
saga::scene::CMeshBuffer
Implementation of the CPU IMeshBuffer interface.
Definition: CMeshBuffer.h:17
saga::core::aabbox3d::reset
void reset(T x, T y, T z)
Resets the bounding box to a one-point box.
Definition: aabbox3d.h:49
saga::scene::CMeshBuffer::getSize
virtual std::size_t getSize(const video::PipelineHandle pipeline) const override
Get size of GPU staging buffer.
Definition: CMeshBuffer.h:175
saga::scene::CMeshBuffer::getIndexCount
virtual std::uint32_t getIndexCount() const override
Get number of indices.
Definition: CMeshBuffer.h:212
saga::scene::CMeshBuffer::BoneWeightBuffer
std::vector< glm::vec4 > BoneWeightBuffer
Definition: CMeshBuffer.h:365
saga::video::E_ATTRIBUTE_TYPE::POSITION
@ POSITION
saga::video::E_ATTRIBUTE_TYPE::COLOR
@ COLOR
saga::scene::CMeshBuffer::AttributeBuffer
std::vector< std::vector< unsigned char > > AttributeBuffer
Definition: CMeshBuffer.h:367
saga::scene::CMeshBuffer::getVertices
virtual void * getVertices() override
Get pointer to vertices.
Definition: CMeshBuffer.h:161
saga::scene::CMeshBuffer::ID
const std::uint64_t ID
Definition: CMeshBuffer.h:357
saga::scene::CMeshBuffer::getIndex
virtual std::uint32_t getIndex(std::size_t offset) const override
returns vertex index at this offset
Definition: CMeshBuffer.h:198
saga::video::SPipeline::Layout
SPipelineLayout Layout
Definition: SPipeline.h:22
saga::scene::CMeshBuffer::~CMeshBuffer
virtual ~CMeshBuffer()
Definition: CMeshBuffer.h:29
saga::scene::CMeshBuffer::getIndices
virtual const std::uint32_t * getIndices() const override
Get pointer to indices.
Definition: CMeshBuffer.h:192
saga::scene::CMeshBuffer::getIndices
virtual std::uint32_t * getIndices() override
Get pointer to indices.
Definition: CMeshBuffer.h:205
saga::scene::CMeshBuffer::append
virtual void append(std::vector< S3DVertex > &&vertices, std::vector< uint32_t > &&indices) override
Append the vertices and indices to the current buffer.
Definition: CMeshBuffer.h:285
saga::scene::CMeshBuffer::recalculateBoundingBox
virtual void recalculateBoundingBox() override
Recalculate the bounding box.
Definition: CMeshBuffer.h:237
saga::video::E_ATTRIBUTE_TYPE::TEXTURE_COORDINATE
@ TEXTURE_COORDINATE
saga::video::E_ATTRIBUTE_TYPE::BONE_ID
@ BONE_ID
saga::scene::CMeshBuffer::getPosition
virtual const glm::vec3 & getPosition(std::uint32_t i) const override
returns position of vertex i
Definition: CMeshBuffer.h:251
saga::scene::CMeshBuffer::GPUBuffers
std::unordered_map< video::PipelineHandle, std::vector< unsigned char > > GPUBuffers
GPU staging buffer.
Definition: CMeshBuffer.h:370
saga::video::E_ATTRIBUTE_TYPE::CUSTOM
@ CUSTOM
saga::scene::CMeshBuffer::getBiTangent
virtual const glm::vec3 & getBiTangent(std::uint32_t i) const override
returns bi-tangent of vertex i
Definition: CMeshBuffer.h:275
IMeshBuffer.h
saga::core::aabbox3d::addInternalPoint
void addInternalPoint(const glm::vec3 &p)
Adds a point to the bounding box.
Definition: aabbox3d.h:73
EPrimitiveTypes.h
saga::scene::CMeshBuffer::setIndexCount
virtual void setIndexCount(const std::uint32_t count) override
Set number of indices.
Definition: CMeshBuffer.h:218
saga::scene::CMeshBuffer::getID
virtual std::uint64_t getID() const override
Returns internal ID to identify mesh buffer.
Definition: CMeshBuffer.h:31
saga::scene::CMeshBuffer::getNormal
virtual const glm::vec3 & getNormal(std::uint32_t i) const override
returns normal of vertex i
Definition: CMeshBuffer.h:257
saga::scene::CMeshBuffer::getTCoords
virtual const glm::vec2 & getTCoords(std::uint32_t i) const override
returns texture coord of vertex i
Definition: CMeshBuffer.h:263
saga::scene::CMeshBuffer::BoundingBox
core::aabbox3d< float > BoundingBox
Bounding box of this meshbuffer.
Definition: CMeshBuffer.h:374
saga::scene::CMeshBuffer::TangentBuffer
std::vector< glm::vec3 > TangentBuffer
Definition: CMeshBuffer.h:363
saga::scene::CMeshBuffer::NormalBuffer
std::vector< glm::vec3 > NormalBuffer
Definition: CMeshBuffer.h:360
saga::scene::IMeshBuffer::RootID
static MeshBufferID RootID
To set ID for mesh buffer when created.
Definition: IMeshBuffer.h:256
saga::video::E_ATTRIBUTE_TYPE::BITANGENT
@ BITANGENT
saga::video::IVideoDriver::getPipeline
virtual SPipeline & getPipeline(const PipelineHandle p)=0
saga
Definition: aabbox3d.h:11
saga::scene::CMeshBuffer::getVertexCount
virtual std::size_t getVertexCount() const override
Get number of vertices.
Definition: CMeshBuffer.h:182
saga::scene::CMeshBuffer::BiTangentBuffer
std::vector< glm::vec3 > BiTangentBuffer
Definition: CMeshBuffer.h:364
saga::scene::CMeshBuffer::Indices
std::vector< std::uint32_t > Indices
Indices into the vertices of this buffer.
Definition: CMeshBuffer.h:372