jubilant-funicular
DebugBatch.cpp
1 #include "nta/DebugBatch.h"
2 #include "nta/PrimitiveBatch.h"
3 #include "nta/utils.h"
4 
5 namespace nta {
7  }
8  DebugBatch::~DebugBatch() {
9  if (m_ibo != 0) glDeleteBuffers(1, &m_ibo);
10  if (m_vbo != 0) glDeleteBuffers(1, &m_vbo);
11  if (m_vao != 0) glDeleteVertexArrays(1, &m_vao);
12  m_ibo = m_vbo = m_vao = 0;
13 
14  m_vertices.clear();
15  m_indices.clear();
16  }
18  if (m_ibo == 0) glGenBuffers(1, &m_ibo);
19  if (m_vbo == 0) glGenBuffers(1, &m_vbo);
20  if (m_vao == 0) glGenVertexArrays(1, &m_vao);
21 
22  glBindVertexArray(m_vao);
23  glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
24  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
25 
26  for (int i = 0; i < NUM_VERTEX_ATTRIBS; i++) {
27  auto& attrib = Vertex2D::attribs[i];
28 
29  glEnableVertexAttribArray(i);
30  glVertexAttribPointer(i, attrib.size, attrib.type, attrib.normalized, sizeof(Vertex2D),
31  attrib.pointer);
32  }
33  glBindVertexArray(0);
34  }
36  m_vertices.clear();
37  m_indices.clear();
38  }
39  void DebugBatch::end() {
40  glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
41  glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex2D)*m_vertices.size(), nullptr, GL_DYNAMIC_DRAW);
42  glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertex2D)*m_vertices.size(), m_vertices.data());
43  glBindBuffer(GL_ARRAY_BUFFER, 0);
44 
45  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
46  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*m_indices.size(), nullptr, GL_DYNAMIC_DRAW);
47  glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(GLuint)*m_indices.size(), m_indices.data());
48  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
49  }
50  void DebugBatch::addLine(crvec2 start, crvec2 end, crvec4 color, int num_pieces) {
51  const int start_index = m_vertices.size();
52  const glm::vec2 diff = end - start;
53  m_vertices.reserve(start_index + num_pieces + 1);
54  m_indices.reserve(m_indices.size() + 2*num_pieces);
55  for (int i = 0; i <= num_pieces; i++) {
56  m_vertices.emplace_back(start + (float)i*diff/(float)num_pieces, color);
57  if (i > 0) {
58  m_indices.push_back(start_index + i - 1);
59  m_indices.push_back(start_index + i);
60  }
61  }
62  }
63  void DebugBatch::addLine(crvec2 start, crvec2 end, int num_pieces, crvec4 color) {
64  addLine(start, end, color, num_pieces);
65  }
66  void DebugBatch::addRect(crvec4 posRect, crvec4 color, float orientation) {
67  const int start = m_vertices.size();
68  glm::vec2 half_dims(posRect[2]/2, posRect[3]/2);
69  glm::vec2 center(posRect.x + half_dims.x, posRect.y - half_dims.y);
70 
71  glm::vec2 tl = center + glm::vec2(-half_dims.x, half_dims.y),
72  tr = center + half_dims,
73  br = center - glm::vec2(-half_dims.x, half_dims.y),
74  bl = center - half_dims;
75 
76  m_vertices.emplace_back(center + utils::rotate(tl, orientation), color);
77  m_vertices.emplace_back(center + utils::rotate(tr, orientation), color);
78  m_vertices.emplace_back(center + utils::rotate(br, orientation), color);
79  m_vertices.emplace_back(center + utils::rotate(bl, orientation), color);
80 
81  for (int offset = 0; offset < 4; offset++) {
82  m_indices.push_back(start + offset);
83  m_indices.push_back(start + (offset + 1)%4);
84  }
85  }
86  void DebugBatch::addRect(crvec4 posRect, float orientation, crvec4 color) {
87  addRect(posRect, color, orientation);
88  }
89  void DebugBatch::addCircle(crvec2 center, float radius, crvec4 color) {
90  static const std::size_t NUM_SIDES = 100;
91  float side_length = radius * glm::sqrt(2.-2.*glm::cos(2.*M_PI/NUM_SIDES));
92  addPolygon(NUM_SIDES, center, side_length, 0., color);
93  }
94  void DebugBatch::addPolygon(std::size_t numSides, crvec2 center, float sideLength,
95  float orientation, crvec4 color) {
96  const int start = m_vertices.size();
97 
98  Primitive poly(numSides, center, sideLength, color, orientation, NTA_DEFAULT_DEPTH);
99  m_vertices.insert(m_vertices.end(), std::begin(poly.vertices), std::end(poly.vertices));
100 
101  for (int offset = 0; offset < poly.vertices.size(); offset++) {
102  m_indices.push_back(start + offset);
103  m_indices.push_back(start + (offset + 1)%poly.vertices.size());
104  }
105  }
106  void DebugBatch::render() const {
107  glBindVertexArray(m_vao);
108  glDrawElements(GL_LINES, m_indices.size(), GL_UNSIGNED_INT, 0);
109  glBindVertexArray(0);
110  }
111 }
nta::DebugBatch::render
void render() const
renders the batch
Definition: DebugBatch.cpp:106
nta
Definition: Animation2D.h:6
nta::DebugBatch::DebugBatch
DebugBatch()
Constructor. Doesn't actually do anything; use init() to initialize instead.
Definition: DebugBatch.cpp:6
nta::utils::rotate
glm::vec2 rotate(crvec2 pt, float angle)
Rotates a point (about the origin) by the given angle.
Definition: utils.cpp:29
nta::DebugBatch::init
void init()
initializes the batch (only needs to be called once)
Definition: DebugBatch.cpp:17
nta::Vertex2D
represents a vertex in 2 dimensions
Definition: Vertex.h:26
nta::DebugBatch::addLine
void addLine(crvec2 start, crvec2 end, crvec4 color=glm::vec4(1), int num_pieces=2)
Adds a shape to the batch.
Definition: DebugBatch.cpp:50
nta::DebugBatch::end
void end()
ends collecting shapes
Definition: DebugBatch.cpp:39
nta::DebugBatch::begin
void begin()
begins collecting shapes to be drawn
Definition: DebugBatch.cpp:35