30 |
30 |
31 layout(location=0) in vec3 position; |
31 layout(location=0) in vec3 position; |
32 layout(location=1) in vec4 color; |
32 layout(location=1) in vec4 color; |
33 layout(location=2) in vec3 normal; |
33 layout(location=2) in vec3 normal; |
34 layout(location=3) in int id; |
34 layout(location=3) in int id; |
|
35 layout(location=4) in int selected; |
35 out vec4 vColor; |
36 out vec4 vColor; |
36 out vec3 vFragPos; |
37 out vec3 vFragPos; |
37 out vec3 vNormal; |
38 out vec3 vNormal; |
38 uniform mat4 modelMatrix; |
39 uniform mat4 modelMatrix; |
39 uniform mat4 viewMatrix; |
40 uniform mat4 viewMatrix; |
59 */ |
60 */ |
60 int r = (id / 0x10000) % 0x100; |
61 int r = (id / 0x10000) % 0x100; |
61 int g = (id / 0x100) % 0x100; |
62 int g = (id / 0x100) % 0x100; |
62 int b = id % 0x100; |
63 int b = id % 0x100; |
63 vColor = vec4(r / 255.0, g / 255.0, b / 255.0, 1.0); |
64 vColor = vec4(r / 255.0, g / 255.0, b / 255.0, 1.0); |
|
65 } |
|
66 else if (selected == 1) |
|
67 { |
|
68 vColor = vec4(selectedColor, 1.0); |
64 } |
69 } |
65 else |
70 else |
66 { |
71 { |
67 if (fragmentStyle == FRAGSTYLE_BfcGreen) |
72 if (fragmentStyle == FRAGSTYLE_BfcGreen) |
68 { |
73 { |
156 object.buffer.create(); |
161 object.buffer.create(); |
157 object.buffer.bind(); |
162 object.buffer.bind(); |
158 object.buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); |
163 object.buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); |
159 object.vertexArray.create(); |
164 object.vertexArray.create(); |
160 object.vertexArray.bind(); |
165 object.vertexArray.bind(); |
161 for (int k : {0, 1, 2, 3}) |
166 for (int k : {0, 1, 2, 3, 4}) |
162 { |
167 { |
163 object.program->enableAttributeArray(k); |
168 object.program->enableAttributeArray(k); |
164 } |
169 } |
165 constexpr int stride = sizeof(gl::Vertex); |
170 constexpr int stride = sizeof(gl::Vertex); |
166 object.program->setAttributeBuffer(0, GL_FLOAT, offsetof(gl::Vertex, position), 3, stride); |
171 object.program->setAttributeBuffer(0, GL_FLOAT, offsetof(gl::Vertex, position), 3, stride); |
167 object.program->setAttributeBuffer(1, GL_FLOAT, offsetof(gl::Vertex, color), 4, stride); |
172 object.program->setAttributeBuffer(1, GL_FLOAT, offsetof(gl::Vertex, color), 4, stride); |
168 object.program->setAttributeBuffer(2, GL_FLOAT, offsetof(gl::Vertex, normal), 3, stride); |
173 object.program->setAttributeBuffer(2, GL_FLOAT, offsetof(gl::Vertex, normal), 3, stride); |
169 glVertexAttribIPointer(3, 1, GL_INT, stride, reinterpret_cast<void*>(offsetof(gl::Vertex, id))); |
174 glVertexAttribIPointer(3, 1, GL_INT, stride, reinterpret_cast<void*>(offsetof(gl::Vertex, id))); |
|
175 glVertexAttribIPointer(4, 1, GL_INT, stride, reinterpret_cast<void*>(offsetof(gl::Vertex, selected))); |
170 object.vertexArray.release(); |
176 object.vertexArray.release(); |
171 object.buffer.release(); |
177 object.buffer.release(); |
172 object.program->release(); |
178 object.program->release(); |
173 } |
179 } |
174 this->initialized = true; |
180 this->initialized = true; |
187 for (int arrayId = 0; arrayId < gl::NUM_ARRAY_CLASSES; arrayId += 1) |
193 for (int arrayId = 0; arrayId < gl::NUM_ARRAY_CLASSES; arrayId += 1) |
188 { |
194 { |
189 auto& buffer = this->glObjects[arrayId].buffer; |
195 auto& buffer = this->glObjects[arrayId].buffer; |
190 auto& vector = vboData[arrayId]; |
196 auto& vector = vboData[arrayId]; |
191 this->storedVertexCounts[arrayId] = vector.size(); |
197 this->storedVertexCounts[arrayId] = vector.size(); |
|
198 this->glObjects[arrayId].cachedData = vector; // todo: get rid of this copy |
192 buffer.bind(); |
199 buffer.bind(); |
193 buffer.allocate(vector.data(), static_cast<int>(vector.size() * sizeof vector[0])); |
200 buffer.allocate(vector.data(), static_cast<int>(vector.size() * sizeof vector[0])); |
194 buffer.release(); |
201 buffer.release(); |
195 } |
202 } |
196 } |
203 } |
264 glm::vec3 gl::Compiler::modelCenter() const |
271 glm::vec3 gl::Compiler::modelCenter() const |
265 { |
272 { |
266 return boxCenter(this->boundingBox); |
273 return boxCenter(this->boundingBox); |
267 } |
274 } |
268 |
275 |
269 float gl::Compiler::modelDistance() const |
276 double gl::Compiler::modelDistance() const |
270 { |
277 { |
271 return longestMeasure(this->boundingBox); |
278 return static_cast<double>(longestMeasure(this->boundingBox)); |
272 } |
279 } |
273 |
280 |
274 void gl::Compiler::bindVertexArray(gl::ArrayClass arrayClass) |
281 void gl::Compiler::bindVertexArray(gl::ArrayClass arrayClass) |
275 { |
282 { |
276 auto& object = this->glObjects[static_cast<int>(arrayClass)]; |
283 auto& object = this->glObjects[static_cast<int>(arrayClass)]; |
283 auto& object = this->glObjects[static_cast<int>(arrayClass)]; |
290 auto& object = this->glObjects[static_cast<int>(arrayClass)]; |
284 object.program->release(); |
291 object.program->release(); |
285 object.vertexArray.release(); |
292 object.vertexArray.release(); |
286 } |
293 } |
287 |
294 |
|
295 void gl::Compiler::setSelectedObjects(const QSet<ldraw::Id> ids) |
|
296 { |
|
297 for (int i = 0; i < gl::NUM_ARRAY_CLASSES; i += 1) |
|
298 { |
|
299 auto& vector = this->glObjects[i].cachedData; |
|
300 for (gl::Vertex& vertex : vector) |
|
301 { |
|
302 vertex.selected = (ids.contains({vertex.id})) ? 1 : 0; |
|
303 } |
|
304 const GLsizeiptr size = static_cast<int>(vector.size() * sizeof vector[0]); |
|
305 this->glObjects[i].buffer.bind(); |
|
306 glBufferSubData(GL_ARRAY_BUFFER, 0, size, vector.data()); |
|
307 } |
|
308 } |
|
309 |
288 std::size_t gl::Compiler::vertexCount(const gl::ArrayClass arrayClass) const |
310 std::size_t gl::Compiler::vertexCount(const gl::ArrayClass arrayClass) const |
289 { |
311 { |
290 return this->storedVertexCounts[static_cast<int>(arrayClass)]; |
312 return this->storedVertexCounts[static_cast<int>(arrayClass)]; |
291 } |
313 } |