src/gl/compiler.cpp

changeset 211
b27b90fb993f
parent 210
232e7634cc8a
child 250
2837b549e616
equal deleted inserted replaced
210:232e7634cc8a 211:b27b90fb993f
123 fColor = vColor; 123 fColor = vColor;
124 } 124 }
125 } 125 }
126 )"; 126 )";
127 127
128 template<typename Fn>
129 constexpr void pointsToRender(const PolygonElement& element, Fn func)
130 {
131 visitPolygon<void>(
132 [&func](const LineSegment& edge)
133 {
134 func(edge.p1, glm::vec3{});
135 func(edge.p2, glm::vec3{});
136 },
137 [&func](const Triangle& tri)
138 {
139 func(tri.p1, normalVector({tri.p3, tri.p1, tri.p2}));
140 func(tri.p2, normalVector({tri.p1, tri.p2, tri.p3}));
141 func(tri.p3, normalVector({tri.p2, tri.p3, tri.p1}));
142 },
143 [&func](const Quadrilateral& quad)
144 {
145 func(quad.p1, normalVector({quad.p4, quad.p1, quad.p2}));
146 func(quad.p2, normalVector({quad.p1, quad.p2, quad.p3}));
147 func(quad.p3, normalVector({quad.p2, quad.p3, quad.p4}));
148 func(quad.p4, normalVector({quad.p3, quad.p4, quad.p1}));
149 },
150 [&func](const ConditionalEdge& cedge)
151 {
152 func(cedge.p1, glm::vec3{});
153 func(cedge.p2, glm::vec3{});
154 },
155 element);
156 }
157
128 void gl::buildShaders( 158 void gl::buildShaders(
129 QOpenGLShaderProgram* shaderProgram, 159 QOpenGLShaderProgram* shaderProgram,
130 const char* vertexShaderSource, 160 const char* vertexShaderSource,
131 const char* fragmentShaderSource) 161 const char* fragmentShaderSource)
132 { 162 {
163 } 193 }
164 } 194 }
165 195
166 void gl::initializeModelShaders(gl::ModelShaders *modelShaders) 196 void gl::initializeModelShaders(gl::ModelShaders *modelShaders)
167 { 197 {
168 if (not modelShaders->initialized) 198 if (not modelShaders->initialized) {
169 { 199 for (auto& shader : modelShaders->shaderObjects) {
170 for (auto& shader : modelShaders->shaderObjects)
171 {
172 shader.program = std::make_unique<QOpenGLShaderProgram>(); 200 shader.program = std::make_unique<QOpenGLShaderProgram>();
173 gl::buildShaders(shader.program.get(), ::vertexShaderSource, ::fragmentShaderSource); 201 gl::buildShaders(shader.program.get(), ::vertexShaderSource, ::fragmentShaderSource);
174 shader.program->bind(); 202 shader.program->bind();
175 shader.buffer.create(); 203 shader.buffer.create();
176 shader.buffer.bind(); 204 shader.buffer.bind();
177 shader.buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); 205 shader.buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw);
178 shader.vertexArray.create(); 206 shader.vertexArray.create();
179 shader.vertexArray.bind(); 207 shader.vertexArray.bind();
180 for (int k : {0, 1, 2, 3, 4}) 208 for (int k : {0, 1, 2, 3, 4}) {
181 {
182 shader.program->enableAttributeArray(k); 209 shader.program->enableAttributeArray(k);
183 } 210 }
184 using Vertex = ModelShaders::Vertex; 211 using Vertex = ModelShaders::Vertex;
185 constexpr int stride = sizeof(Vertex); 212 constexpr int stride = sizeof(Vertex);
186 shader.program->setAttributeBuffer(0, GL_FLOAT, offsetof(Vertex, position), 3, stride); 213 shader.program->setAttributeBuffer(0, GL_FLOAT, offsetof(Vertex, position), 3, stride);
207 } 234 }
208 235
209 template<typename Fn> 236 template<typename Fn>
210 void iterateModelPolygons(Model* model, DocumentManager* context, Fn&& fn) 237 void iterateModelPolygons(Model* model, DocumentManager* context, Fn&& fn)
211 { 238 {
212 std::optional<ModelId> modelId = context->findIdForModel(model); 239 PolygonCache* cache = findPolygonCacheForModel(model, context);
213 if (modelId.has_value()) 240 if (cache != nullptr) {
214 { 241 const PolygonCache::vector_type* polygons = getCachedPolygons(cache, model, context);
215 PolygonCache* cache = context->getPolygonCacheForModel(modelId.value()); 242 for (const WithId<PolygonElement>& polygon : *polygons) {
216 if (cache != nullptr) 243 fn(polygon);
217 {
218 for (const WithId<PolygonElement>& polygon : getCachedPolygons(cache, model, context))
219 {
220 fn(polygon);
221 }
222 } 244 }
223 } 245 }
224 } 246 }
225 247
226 static QColor getColorForPolygon( 248 static QColor getColorForPolygon(
253 BoundingBox gl::boundingBoxForModel(Model* model, DocumentManager* context) 275 BoundingBox gl::boundingBoxForModel(Model* model, DocumentManager* context)
254 { 276 {
255 BoundingBox result = emptyBoundingBox; 277 BoundingBox result = emptyBoundingBox;
256 iterateModelPolygons(model, context, [&](const PolygonElement& polygon) 278 iterateModelPolygons(model, context, [&](const PolygonElement& polygon)
257 { 279 {
258 visitPoints( 280 visitPoints([&result](const glm::vec3& p) {
259 [&result](const glm::vec3& p) { addPointToBox(result, p); }, 281 addPointToBox(result, p);
260 polygon); 282 }, polygon);
261 }); 283 });
262 return result; 284 return result;
263 } 285 }
264 286
265 /** 287 /**
273 const gl::RenderPreferences& preferences) 295 const gl::RenderPreferences& preferences)
274 { 296 {
275 for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) { 297 for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) {
276 shader.cachedData.clear(); 298 shader.cachedData.clear();
277 } 299 }
278 iterateModelPolygons(model, context, [&](const PolygonElement& polygon) 300 iterateModelPolygons(model, context, [&](const WithId<PolygonElement>& polygon)
279 { 301 {
280 const int index = static_cast<int>(classifyPolygon(polygon)); 302 const int index = static_cast<int>(classifyPolygon(polygon));
281 std::vector<gl::ModelShaders::Vertex>& vertexBuffer = shaders->shaderObjects[index].cachedData; 303 std::vector<gl::ModelShaders::Vertex>& vertexBuffer = shaders->shaderObjects[index].cachedData;
282 auto vertexRing = iter::ring(polygon.vertices, polygon.numPolygonVertices());
283 reserveMore(vertexBuffer, polygon.numPolygonVertices());
284 const QColor color = getColorForPolygon(polygon, preferences, colorTable); 304 const QColor color = getColorForPolygon(polygon, preferences, colorTable);
285 for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) 305 pointsToRender(polygon, [&](const glm::vec3& point, const glm::vec3& normal){
286 {
287 const glm::vec3& v1 = vertexRing[i - 1];
288 const glm::vec3& v2 = vertexRing[i];
289 const glm::vec3& v3 = vertexRing[i + 1];
290 gl::ModelShaders::Vertex& vertex = vertexBuffer.emplace_back(); 306 gl::ModelShaders::Vertex& vertex = vertexBuffer.emplace_back();
291 vertex.position = polygon.vertices[i]; 307 vertex.position = point;
292 vertex.normal = glm::normalize(glm::cross(v1 - v2, v3 - v2)); 308 vertex.normal = normal;
293 vertex.color = glm::vec4{color.redF(), color.greenF(), color.blueF(), color.alphaF()}; 309 vertex.color = glm::vec4{color.redF(), color.greenF(), color.blueF(), color.alphaF()};
294 vertex.id = polygon.id.value; 310 vertex.id = polygon.id.value;
295 } 311 });
296 }); 312 });
297 for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) 313 for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects)
298 { 314 {
299 shader.vertexCount = shader.cachedData.size(); 315 shader.vertexCount = shader.cachedData.size();
300 shader.buffer.bind(); 316 shader.buffer.bind();

mercurial