]> git.localhorst.tv Git - blank.git/blob - src/model.cpp
add chunk inspect button (C)
[blank.git] / src / model.cpp
1 #include "model.hpp"
2
3 #include <iostream>
4
5
6 namespace blank {
7
8 Model::Model()
9 :  va(0)
10 , handle{}
11 , count(0) {
12         glGenVertexArrays(1, &va);
13         glGenBuffers(ATTRIB_COUNT, handle);
14 }
15
16 Model::~Model() {
17         glDeleteBuffers(ATTRIB_COUNT, handle);
18         glDeleteVertexArrays(1, &va);
19 }
20
21 Model::Model(Model &&other)
22 : va(other.va)
23 , count(other.count) {
24         other.va = 0;
25         for (int i = 0; i < ATTRIB_COUNT; ++i) {
26                 handle[i] = other.handle[i];
27                 other.handle[i] = 0;
28         }
29 }
30
31 Model &Model::operator =(Model &&other) {
32         std::swap(va, other.va);
33         for (int i = 0; i < ATTRIB_COUNT; ++i) {
34                 std::swap(handle[i], other.handle[i]);
35         }
36         count = other.count;
37         return *this;
38 }
39
40 void Model::Update(const Buffer &buf) {
41         glBindVertexArray(va);
42         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
43         glBufferData(GL_ARRAY_BUFFER, buf.vertices.size() * sizeof(glm::vec3), buf.vertices.data(), GL_STATIC_DRAW);
44         glEnableVertexAttribArray(ATTRIB_VERTEX);
45         glVertexAttribPointer(
46                 ATTRIB_VERTEX, // location (for shader)
47                 3,             // size
48                 GL_FLOAT,      // type
49                 GL_FALSE,      // normalized
50                 0,             // stride
51                 nullptr        // offset
52         );
53
54 #ifndef NDEBUG
55         if (buf.colors.size() < buf.vertices.size()) {
56                 std::cerr << "Model: not enough colors!" << std::endl;
57         }
58 #endif
59         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
60         glBufferData(GL_ARRAY_BUFFER, buf.colors.size() * sizeof(glm::vec3), buf.colors.data(), GL_STATIC_DRAW);
61         glEnableVertexAttribArray(ATTRIB_COLOR);
62         glVertexAttribPointer(
63                 ATTRIB_COLOR,  // location (for shader)
64                 3,             // size
65                 GL_FLOAT,      // type
66                 GL_FALSE,      // normalized
67                 0,             // stride
68                 nullptr        // offset
69         );
70
71 #ifndef NDEBUG
72         if (buf.normals.size() < buf.vertices.size()) {
73                 std::cerr << "Model: not enough normals!" << std::endl;
74         }
75 #endif
76         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_NORMAL]);
77         glBufferData(GL_ARRAY_BUFFER, buf.normals.size() * sizeof(glm::vec3), buf.normals.data(), GL_STATIC_DRAW);
78         glEnableVertexAttribArray(ATTRIB_NORMAL);
79         glVertexAttribPointer(
80                 ATTRIB_NORMAL, // location (for shader)
81                 3,             // size
82                 GL_FLOAT,      // type
83                 GL_FALSE,      // normalized
84                 0,             // stride
85                 nullptr        // offset
86         );
87
88         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
89         glBufferData(GL_ELEMENT_ARRAY_BUFFER, buf.indices.size() * sizeof(Index), buf.indices.data(), GL_STATIC_DRAW);
90         count = buf.indices.size();
91 }
92
93
94 void Model::Draw() const {
95         glBindVertexArray(va);
96         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
97         glDrawElements(
98                 GL_TRIANGLES,    // how
99                 count,           // count
100                 GL_UNSIGNED_INT, // type
101                 nullptr          // offset
102         );
103 }
104
105
106 OutlineModel::OutlineModel()
107 : vertices()
108 , colors()
109 , indices()
110 , va(0)
111 , handle{}
112 , dirty(false) {
113         glGenVertexArrays(1, &va);
114         glGenBuffers(ATTRIB_COUNT, handle);
115 }
116
117 OutlineModel::~OutlineModel() {
118         glDeleteBuffers(ATTRIB_COUNT, handle);
119         glDeleteVertexArrays(1, &va);
120 }
121
122
123 void OutlineModel::Clear() {
124         vertices.clear();
125         colors.clear();
126         indices.clear();
127         Invalidate();
128 }
129
130 void OutlineModel::Reserve(int v, int i) {
131         vertices.reserve(v);
132         colors.reserve(v);
133         indices.reserve(i);
134 }
135
136
137 void OutlineModel::Update() {
138         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
139         glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);
140         glEnableVertexAttribArray(ATTRIB_VERTEX);
141         glVertexAttribPointer(
142                 ATTRIB_VERTEX, // location (for shader)
143                 3,             // size
144                 GL_FLOAT,      // type
145                 GL_FALSE,      // normalized
146                 0,             // stride
147                 nullptr        // offset
148         );
149
150 #ifndef NDEBUG
151         if (colors.size() < vertices.size()) {
152                 std::cerr << "OutlineModel: not enough colors!" << std::endl;
153                 colors.resize(vertices.size(), { 1, 0, 1 });
154         }
155 #endif
156         glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
157         glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_STATIC_DRAW);
158         glEnableVertexAttribArray(ATTRIB_COLOR);
159         glVertexAttribPointer(
160                 ATTRIB_COLOR,  // location (for shader)
161                 3,             // size
162                 GL_FLOAT,      // type
163                 GL_FALSE,      // normalized
164                 0,             // stride
165                 nullptr        // offset
166         );
167
168         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
169         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(Index), indices.data(), GL_STATIC_DRAW);
170
171         dirty = false;
172 }
173
174
175 void OutlineModel::Draw() {
176         glBindVertexArray(va);
177
178         if (dirty) {
179                 Update();
180         }
181
182         glEnable(GL_LINE_SMOOTH);
183         glLineWidth(2.0f);
184
185         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
186         glDrawElements(
187                 GL_LINES,          // how
188                 indices.size(),    // count
189                 GL_UNSIGNED_SHORT, // type
190                 nullptr            // offset
191         );
192 }
193
194 }