TAMSVIZ
Visualization and annotation tool for ROS
uniformbuffer.h
1 // TAMSVIZ
2 // (c) 2020 Philipp Ruppel
3 
4 #pragma once
5 
6 #include "opengl.h"
7 #include "resource.h"
8 
9 #include <cstring>
10 #include <vector>
11 
12 #include "../core/log.h"
13 
15  GLuint _buffer = 0;
16  void destroy();
17 
18 protected:
19  void bind(size_t binding_point);
20  void bind(size_t binding_point, size_t offset, size_t size);
21 
22 public:
23  ~UniformBufferBase() { destroy(); }
24  void update(const void *data, size_t size);
25 };
26 
27 template <class T> class UniformBuffer : public UniformBufferBase {
28  std::vector<uint8_t> _aligned_data;
29  ssize_t _aligned_stride = -1;
30  GLuint _buffer = 0;
31  size_t _binding_point = 0;
32  void destroy();
33 
34 public:
35  UniformBuffer(size_t binding_point) : _binding_point(binding_point) {}
36  void update(const T &value) { UniformBufferBase::update(&value, sizeof(T)); }
37  template <class CONTAINER> void update(const CONTAINER &data) {
38  if (_aligned_stride < 0) {
39  GLint buffer_alignment = -1;
40  V_GL(
41  glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &buffer_alignment));
42  if (buffer_alignment < 1) {
43  LOG_ERROR("failed to get buffer alignment, using 256");
44  buffer_alignment = 256;
45  }
46 
47  _aligned_stride =
48  ((sizeof(T) + buffer_alignment - 1) / buffer_alignment) *
49  buffer_alignment;
50  }
51  _aligned_data.resize(_aligned_stride * data.size());
52  for (size_t index = 0; index < data.size(); index++) {
53  std::memcpy(_aligned_data.data() + index * _aligned_stride,
54  (const T *)&(data[index]), sizeof(T));
55  }
56  UniformBufferBase::update(_aligned_data.data(), _aligned_data.size());
57  }
58  void bind() { UniformBufferBase::bind(_binding_point); }
59  void bind(size_t index) {
60  UniformBufferBase::bind(_binding_point, _aligned_stride * index,
61  _aligned_stride);
62  }
63 };