src/gl/compiler.cpp

changeset 211
b27b90fb993f
parent 210
232e7634cc8a
child 250
2837b549e616
--- a/src/gl/compiler.cpp	Thu Jun 09 13:32:55 2022 +0300
+++ b/src/gl/compiler.cpp	Thu Jun 09 19:11:27 2022 +0300
@@ -125,6 +125,36 @@
 }
 )";
 
+template<typename Fn>
+constexpr void pointsToRender(const PolygonElement& element, Fn func)
+{
+	visitPolygon<void>(
+		[&func](const LineSegment& edge)
+		{
+			func(edge.p1, glm::vec3{});
+			func(edge.p2, glm::vec3{});
+		},
+		[&func](const Triangle& tri)
+		{
+			func(tri.p1, normalVector({tri.p3, tri.p1, tri.p2}));
+			func(tri.p2, normalVector({tri.p1, tri.p2, tri.p3}));
+			func(tri.p3, normalVector({tri.p2, tri.p3, tri.p1}));
+		},
+		[&func](const Quadrilateral& quad)
+		{
+			func(quad.p1, normalVector({quad.p4, quad.p1, quad.p2}));
+			func(quad.p2, normalVector({quad.p1, quad.p2, quad.p3}));
+			func(quad.p3, normalVector({quad.p2, quad.p3, quad.p4}));
+			func(quad.p4, normalVector({quad.p3, quad.p4, quad.p1}));
+		},
+		[&func](const ConditionalEdge& cedge)
+		{
+			func(cedge.p1, glm::vec3{});
+			func(cedge.p2, glm::vec3{});
+		},
+		element);
+}
+
 void gl::buildShaders(
 	QOpenGLShaderProgram* shaderProgram,
 	const char* vertexShaderSource,
@@ -165,10 +195,8 @@
 
 void gl::initializeModelShaders(gl::ModelShaders *modelShaders)
 {
-	if (not modelShaders->initialized)
-	{
-		for (auto& shader : modelShaders->shaderObjects)
-		{
+	if (not modelShaders->initialized) {
+		for (auto& shader : modelShaders->shaderObjects) {
 			shader.program = std::make_unique<QOpenGLShaderProgram>();
 			gl::buildShaders(shader.program.get(), ::vertexShaderSource, ::fragmentShaderSource);
 			shader.program->bind();
@@ -177,8 +205,7 @@
 			shader.buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw);
 			shader.vertexArray.create();
 			shader.vertexArray.bind();
-			for (int k : {0, 1, 2, 3, 4})
-			{
+			for (int k : {0, 1, 2, 3, 4}) {
 				shader.program->enableAttributeArray(k);
 			}
 			using Vertex = ModelShaders::Vertex;
@@ -209,16 +236,11 @@
 template<typename Fn>
 void iterateModelPolygons(Model* model, DocumentManager* context, Fn&& fn)
 {
-	std::optional<ModelId> modelId = context->findIdForModel(model);
-	if (modelId.has_value())
-	{
-		PolygonCache* cache = context->getPolygonCacheForModel(modelId.value());
-		if (cache != nullptr)
-		{
-			for (const WithId<PolygonElement>& polygon : getCachedPolygons(cache, model, context))
-			{
-				fn(polygon);
-			}
+	PolygonCache* cache = findPolygonCacheForModel(model, context);
+	if (cache != nullptr) {
+		const PolygonCache::vector_type* polygons = getCachedPolygons(cache, model, context);
+		for (const WithId<PolygonElement>& polygon : *polygons) {
+			fn(polygon);
 		}
 	}
 }
@@ -255,9 +277,9 @@
 	BoundingBox result = emptyBoundingBox;
 	iterateModelPolygons(model, context, [&](const PolygonElement& polygon)
 	{
-		visitPoints(
-			[&result](const glm::vec3& p) { addPointToBox(result, p); },
-			polygon);
+		visitPoints([&result](const glm::vec3& p) {
+			addPointToBox(result, p);
+		}, polygon);
 	});
 	return result;
 }
@@ -275,24 +297,18 @@
 	for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) {
 		shader.cachedData.clear();
 	}
-	iterateModelPolygons(model, context, [&](const PolygonElement& polygon)
+	iterateModelPolygons(model, context, [&](const WithId<PolygonElement>& polygon)
 	{
 		const int index = static_cast<int>(classifyPolygon(polygon));
 		std::vector<gl::ModelShaders::Vertex>& vertexBuffer = shaders->shaderObjects[index].cachedData;
-		auto vertexRing = iter::ring(polygon.vertices, polygon.numPolygonVertices());
-		reserveMore(vertexBuffer, polygon.numPolygonVertices());
 		const QColor color = getColorForPolygon(polygon, preferences, colorTable);
-		for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
-		{
-			const glm::vec3& v1 = vertexRing[i - 1];
-			const glm::vec3& v2 = vertexRing[i];
-			const glm::vec3& v3 = vertexRing[i + 1];
+		pointsToRender(polygon, [&](const glm::vec3& point, const glm::vec3& normal){
 			gl::ModelShaders::Vertex& vertex = vertexBuffer.emplace_back();
-			vertex.position = polygon.vertices[i];
-			vertex.normal = glm::normalize(glm::cross(v1 - v2, v3 - v2));
+			vertex.position = point;
+			vertex.normal = normal;
 			vertex.color = glm::vec4{color.redF(), color.greenF(), color.blueF(), color.alphaF()};
 			vertex.id = polygon.id.value;
-		}
+		});
 	});
 	for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects)
 	{

mercurial