Euphoria
buffer.cc
Go to the documentation of this file.
1 #include "render/buffer.h"
2 
3 #include <algorithm>
4 
5 #include "assert/assert.h"
6 #include "log/log.h"
7 
8 #include "render/gl.h"
9 #include "render/shader.h"
10 
11 #include "euph_generated_config.h"
12 
13 
14 namespace eu::render
15 {
17  {
18  glGenBuffers(1, &id);
19  }
20 
21 
23  {
24  glDeleteBuffers(1, &id);
25  }
26 
27 
28  void
29  VertexBuffer::set_data(const std::vector<float>& data)
30  {
31  ASSERT(get_bound() == this);
32  // use GL_DYNAMIC_DRAW or GL_STREAM_DRAW instead?
33  glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(sizeof(float) * data.size()), data.data(), GL_STATIC_DRAW);
34  }
35 
36 
37  void
39  {
40  const gl::Uint id = vbo != nullptr ? vbo->id : 0;
41  glBindBuffer(GL_ARRAY_BUFFER, id);
42  get_bound() = vbo;
43  }
44 
45 
46  const VertexBuffer*&
48  {
49  static const VertexBuffer* vbo = nullptr;
50  return vbo;
51  }
52 
53 
55 
56 
58  {
59  glGenVertexArrays(1, &id);
60  }
61 
62 
64  {
65  glDeleteVertexArrays(1, &id);
66  }
67 
68 
69  namespace
70  {
71  GLenum
73  {
74  switch(type)
75  {
81  case ShaderAttributeType::float44: return GL_FLOAT;
82  default: LOG_ERROR("Unhandled shader type"); return GL_FLOAT;
83  }
84  }
85  }
86 
87 
88  namespace
89  {
90  void* offset_to_pointer_offset(int aoffset)
91  {
92  // reinterpret_cast is probably ok since the void* is an offset
93  // and not a actual pointer
94 
95  // use arch detection to store in a (potentially) bigger integer before converting to a pointer
96 #if EU_ARCH_32 == 1
97  std::int32_t
98 #elif EU_ARCH_64 == 1
99  std::int64_t
100 #else
101  #error unknown arch
102 #endif
103  offset = aoffset;
104  return reinterpret_cast<GLvoid*>(offset); // NOLINT
105  }
106  }
107 
108 
109  void
110  PointLayout::bind_data(const ShaderAttribute& attribute, int stride, int offset)
111  {
112  ASSERT(get_bound() == this);
113  ASSERT(VertexBuffer::get_bound() != nullptr);
114  glVertexAttribPointer
115  (
116  attribute.id,
117  attribute.get_element_count(),
118  con(attribute.type),
119  attribute.normalize ? GL_TRUE : GL_FALSE,
120  stride,
121  offset_to_pointer_offset(offset)
122  );
123  glEnableVertexAttribArray(attribute.id);
124 
125  attributes.push_back(attribute);
126  }
127 
128 
129  void
131  {
132  const gl::Uint id = vao != nullptr ? vao->id : 0;
133  glBindVertexArray(id);
134  get_bound() = vao;
135  }
136 
137 
138  const PointLayout*&
140  {
141  static const PointLayout* vao = nullptr;
142  return vao;
143  }
144 
145 
147 
148 
150  {
151  glGenBuffers(1, &id);
152  }
153 
154 
156  {
157  glDeleteBuffers(1, &id);
158  }
159 
160 
161  void
162  IndexBuffer::set_data(const std::vector<unsigned int>& indices)
163  {
164  ASSERT(get_bound() == this);
165  glBufferData
166  (
167  GL_ELEMENT_ARRAY_BUFFER,
168  static_cast<GLsizeiptr>(indices.size() * sizeof(unsigned int)),
169  indices.data(),
170  GL_STATIC_DRAW
171  );
172  }
173 
174 
175  void
176  IndexBuffer::draw(RenderMode mode, int count) const
177  {
178  ASSERT(PointLayout::get_bound() != nullptr);
180 
181  const PointLayout* vao = PointLayout::get_bound();
183 
184  ASSERT(vao);
185  ASSERT(shader);
186 
187  ASSERTX(get_bound() == this, static_cast<const void*>(get_bound()), static_cast<const void*>(this));
188 
189  const auto& a = shader->get_attributes();
190  for(const auto& attribute: vao->attributes)
191  {
192  const bool found_in_shader = std::find(a.begin(), a.end(), attribute) != a.end();
193  if(!found_in_shader)
194  {
195  LOG_ERROR
196  (
197  "Failed to find attribute {0} bound in shader {1}",
198  attribute.name,
199  shader->get_name()
200  );
201  ASSERT(found_in_shader);
202  }
203  }
204 
205  if(mode == RenderMode::triangles)
206  {
207  glDrawElements(GL_TRIANGLES, count * 3, GL_UNSIGNED_INT, nullptr);
208  }
209  else
210  {
211  glDrawElements(GL_LINES, count * 2, GL_UNSIGNED_INT, nullptr);
212  }
213  }
214 
215  void
217  {
218  const gl::Uint id = ebo != nullptr ? ebo->id : 0;
219  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id);
220  get_bound() = ebo;
221  }
222 
223  const IndexBuffer*&
225  {
226  static const IndexBuffer* ebo = nullptr;
227  return ebo;
228  }
229 }
#define ASSERTX(x,...)
Definition: assert.h:48
#define ASSERT(x)
Definition: assert.h:29
#define LOG_ERROR(...)
Definition: log.h:9
constexpr Rgbi con(unsigned char r, unsigned char g, unsigned char b)
bool find(const std::string &target, const std::string &search)
Definition: findstring.cc:8
unsigned int Uint
Definition: gltypes.h:6
RenderMode
Definition: buffer.h:54
constexpr int stride
Definition: spritebatch.cc:11
gl::Uint id
Definition: id.h:23
Reuses points.
Definition: buffer.h:64
static const IndexBuffer *& get_bound()
Definition: buffer.cc:224
void set_data(const std::vector< unsigned int > &indices)
Definition: buffer.cc:162
void draw(RenderMode mode, int count) const
Definition: buffer.cc:176
static void bind(const IndexBuffer *ebo)
Definition: buffer.cc:216
Stores what the data in the vertex_buffer is and how it is laid out/used Represents a OpenGL Vertex A...
Definition: buffer.h:34
static const PointLayout *& get_bound()
Definition: buffer.cc:139
std::vector< ShaderAttribute > attributes
Definition: buffer.h:35
static void bind(const PointLayout *vao)
Definition: buffer.cc:130
void bind_data(const ShaderAttribute &attribute, int stride, int offset)
Definition: buffer.cc:110
Represents a shader attribute like vertex, normal or uv coord.
gl::Int id
the id of the attribute
ShaderAttributeType type
the type of the attribute
const io::FilePath & get_name() const
Definition: shader.cc:459
static const ShaderProgram * get_current_bound_for_debug()
Definition: shader.cc:129
const std::vector< ShaderAttribute > & get_attributes() const
Definition: shader.cc:452
Stores vertices, uv, etc.
Definition: buffer.h:13
static const VertexBuffer *& get_bound()
Definition: buffer.cc:47
void set_data(const std::vector< float > &data)
Definition: buffer.cc:29
static void bind(const VertexBuffer *vbo)
Definition: buffer.cc:38