src/gl/compiler.cpp

changeset 80
764381756899
parent 78
97c3ce5aa498
child 115
ed884a2fb009
equal deleted inserted replaced
79:5fe2dd4e161a 80:764381756899
169 void gl::Compiler::initialize() 169 void gl::Compiler::initialize()
170 { 170 {
171 if (not this->initialized) 171 if (not this->initialized)
172 { 172 {
173 this->initializeOpenGLFunctions(); 173 this->initializeOpenGLFunctions();
174 for (int i = 0; i < gl::NUM_ARRAY_CLASSES; i += 1) 174 for (auto& object : this->glObjects)
175 { 175 {
176 auto& object = this->glObjects[i];
177 object.program = new QOpenGLShaderProgram; 176 object.program = new QOpenGLShaderProgram;
178 gl::buildShaders(object.program, ::vertexShaderSource, ::fragmentShaderSource); 177 gl::buildShaders(object.program, ::vertexShaderSource, ::fragmentShaderSource);
179 object.program->bind(); 178 object.program->bind();
180 object.buffer.create(); 179 object.buffer.create();
181 object.buffer.bind(); 180 object.buffer.bind();
184 object.vertexArray.bind(); 183 object.vertexArray.bind();
185 for (int k : {0, 1, 2, 3, 4}) 184 for (int k : {0, 1, 2, 3, 4})
186 { 185 {
187 object.program->enableAttributeArray(k); 186 object.program->enableAttributeArray(k);
188 } 187 }
189 constexpr int stride = sizeof(gl::Vertex); 188 constexpr int stride = sizeof(Vertex);
190 object.program->setAttributeBuffer(0, GL_FLOAT, offsetof(gl::Vertex, position), 3, stride); 189 object.program->setAttributeBuffer(0, GL_FLOAT, offsetof(Vertex, position), 3, stride);
191 object.program->setAttributeBuffer(1, GL_FLOAT, offsetof(gl::Vertex, color), 4, stride); 190 object.program->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, color), 4, stride);
192 object.program->setAttributeBuffer(2, GL_FLOAT, offsetof(gl::Vertex, normal), 3, stride); 191 object.program->setAttributeBuffer(2, GL_FLOAT, offsetof(Vertex, normal), 3, stride);
193 glVertexAttribIPointer(3, 1, GL_INT, stride, reinterpret_cast<void*>(offsetof(gl::Vertex, id))); 192 glVertexAttribIPointer(3, 1, GL_INT, stride, reinterpret_cast<void*>(offsetof(Vertex, id)));
194 glVertexAttribIPointer(4, 1, GL_INT, stride, reinterpret_cast<void*>(offsetof(gl::Vertex, selected))); 193 glVertexAttribIPointer(4, 1, GL_INT, stride, reinterpret_cast<void*>(offsetof(Vertex, selected)));
195 object.vertexArray.release(); 194 object.vertexArray.release();
196 object.buffer.release(); 195 object.buffer.release();
197 object.program->release(); 196 object.program->release();
198 } 197 }
199 this->initialized = true; 198 this->initialized = true;
201 } 200 }
202 201
203 void gl::Compiler::build(Model* model, DocumentManager* context, const gl::RenderPreferences& preferences) 202 void gl::Compiler::build(Model* model, DocumentManager* context, const gl::RenderPreferences& preferences)
204 { 203 {
205 this->boundingBox = {}; 204 this->boundingBox = {};
206 std::vector<gl::Vertex> vboData[gl::NUM_ARRAY_CLASSES]; 205 std::vector<Vertex> vboData[gl::NUM_POLYGON_TYPES];
207 const std::vector<gl::Polygon> polygons = model->getPolygons(context); 206 const std::vector<gl::Polygon> polygons = model->getPolygons(context);
208 for (const gl::Polygon& polygon : polygons) 207 for (const gl::Polygon& polygon : polygons)
209 { 208 {
210 this->buildPolygon(polygon, vboData, preferences); 209 this->buildPolygon(polygon, vboData, preferences);
211 } 210 }
212 for (int arrayId = 0; arrayId < gl::NUM_ARRAY_CLASSES; arrayId += 1) 211 for (int arrayId = 0; arrayId < gl::NUM_POLYGON_TYPES; arrayId += 1)
213 { 212 {
214 auto& buffer = this->glObjects[arrayId].buffer; 213 auto& buffer = this->glObjects[arrayId].buffer;
215 auto& vector = vboData[arrayId]; 214 auto& vector = vboData[arrayId];
216 this->storedVertexCounts[arrayId] = vector.size(); 215 this->storedVertexCounts[arrayId] = vector.size();
217 this->glObjects[arrayId].cachedData = vector; // todo: get rid of this copy 216 this->glObjects[arrayId].cachedData = vector; // todo: get rid of this copy
242 return {data[0] * std::int32_t{0x10000} + data[1] * std::int32_t{0x100} + data[2]}; 241 return {data[0] * std::int32_t{0x10000} + data[1] * std::int32_t{0x100} + data[2]};
243 } 242 }
244 243
245 void gl::Compiler::buildPolygon( 244 void gl::Compiler::buildPolygon(
246 gl::Polygon polygon, 245 gl::Polygon polygon,
247 std::vector<gl::Vertex>* vboData, 246 std::vector<Vertex>* vboData,
248 const gl::RenderPreferences& preferences) 247 const gl::RenderPreferences& preferences)
249 { 248 {
250 const gl::ArrayClass vboClass = classifyPolygon(polygon); 249 const gl::ArrayClass vboClass = classifyPolygon(polygon);
251 std::vector<gl::Vertex>& vertexBuffer = vboData[static_cast<int>(vboClass)]; 250 std::vector<Vertex>& vertexBuffer = vboData[static_cast<int>(vboClass)];
252 auto vertexRing = iter::ring(polygon.vertices, polygon.numPolygonVertices()); 251 auto vertexRing = iter::ring(polygon.vertices, polygon.numPolygonVertices());
253 reserveMore(vertexBuffer, polygon.numPolygonVertices()); 252 reserveMore(vertexBuffer, polygon.numPolygonVertices());
254 const QColor color = this->getColorForPolygon(polygon, preferences); 253 const QColor color = this->getColorForPolygon(polygon, preferences);
255 for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) 254 for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
256 { 255 {
257 const glm::vec3& v1 = vertexRing[i - 1]; 256 const glm::vec3& v1 = vertexRing[i - 1];
258 const glm::vec3& v2 = vertexRing[i]; 257 const glm::vec3& v2 = vertexRing[i];
259 const glm::vec3& v3 = vertexRing[i + 1]; 258 const glm::vec3& v3 = vertexRing[i + 1];
260 this->boundingBox.consider(polygon.vertices[i]); 259 this->boundingBox.consider(polygon.vertices[i]);
261 gl::Vertex& vertex = vertexBuffer.emplace_back(); 260 Vertex& vertex = vertexBuffer.emplace_back();
262 vertex.position = polygon.vertices[i]; 261 vertex.position = polygon.vertices[i];
263 vertex.normal = glm::normalize(glm::cross(v1 - v2, v3 - v2)); 262 vertex.normal = glm::normalize(glm::cross(v1 - v2, v3 - v2));
264 vertex.color = glm::vec4{color.redF(), color.greenF(), color.blueF(), color.alphaF()}; 263 vertex.color = glm::vec4{color.redF(), color.greenF(), color.blueF(), color.alphaF()};
265 vertex.id = polygon.id.value; 264 vertex.id = polygon.id.value;
266 } 265 }
311 object.vertexArray.release(); 310 object.vertexArray.release();
312 } 311 }
313 312
314 void gl::Compiler::setSelectedObjects(const QSet<ldraw::id_t> ids) 313 void gl::Compiler::setSelectedObjects(const QSet<ldraw::id_t> ids)
315 { 314 {
316 for (int i = 0; i < gl::NUM_ARRAY_CLASSES; i += 1) 315 for (auto& object : this->glObjects)
317 { 316 {
318 auto& vector = this->glObjects[i].cachedData; 317 std::vector<Vertex>& vector = object.cachedData;
319 for (gl::Vertex& vertex : vector) 318 for (Vertex& vertex : vector)
320 { 319 {
321 vertex.selected = (ids.contains({vertex.id})) ? 1 : 0; 320 vertex.selected = (ids.contains({vertex.id})) ? 1 : 0;
322 } 321 }
323 const GLsizeiptr size = static_cast<int>(vector.size() * sizeof vector[0]); 322 const GLsizeiptr size = static_cast<int>(vector.size() * sizeof vector[0]);
324 this->glObjects[i].buffer.bind(); 323 object.buffer.bind();
325 glBufferSubData(GL_ARRAY_BUFFER, 0, size, vector.data()); 324 glBufferSubData(GL_ARRAY_BUFFER, 0, size, vector.data());
325 object.buffer.release();
326 } 326 }
327 } 327 }
328 328
329 std::size_t gl::Compiler::vertexCount(const gl::ArrayClass arrayClass) const 329 std::size_t gl::Compiler::vertexCount(const gl::ArrayClass arrayClass) const
330 { 330 {

mercurial