Split GL preferences that affect GL build to a new build preferences structure, modifying that requires rebuild, modifying render preferences does not

Tue, 11 Apr 2023 22:39:18 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Tue, 11 Apr 2023 22:39:18 +0300
changeset 376
3cef3b016330
parent 375
21a5ecbe34e4
child 377
e1c5e4310f8b

Split GL preferences that affect GL build to a new build preferences structure, modifying that requires rebuild, modifying render preferences does not

src/gl/common.h file | annotate | diff | comparison | revisions
src/gl/compiler.cpp file | annotate | diff | comparison | revisions
src/gl/compiler.h file | annotate | diff | comparison | revisions
src/gl/partrenderer.cpp file | annotate | diff | comparison | revisions
src/gl/partrenderer.h file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
--- a/src/gl/common.h	Tue Apr 11 20:27:04 2023 +0300
+++ b/src/gl/common.h	Tue Apr 11 22:39:18 2023 +0300
@@ -119,12 +119,17 @@
 		Black = 5,
 	};
 
+	// Options that affect GL polygon building
+	struct build_preferences
+	{
+		QColor mainColor{255, 255, 64};
+		QColor backgroundColor{48, 48, 48};
+	};
+
 	// User options for rendering
 	struct RenderPreferences
 	{
 		gl::RenderStyle style = gl::RenderStyle::Normal;
-		QColor mainColor{255, 255, 64};
-		QColor backgroundColor{48, 48, 48};
 		QColor selectedColor{32, 32, 255};
 		GLfloat lineThickness = 2.0f;
 		bool lineAntiAliasing = true;
--- a/src/gl/compiler.cpp	Tue Apr 11 20:27:04 2023 +0300
+++ b/src/gl/compiler.cpp	Tue Apr 11 22:39:18 2023 +0300
@@ -236,19 +236,19 @@
 
 static QColor getColorForPolygon(
 	const PolygonElement& polygon,
-	const gl::RenderPreferences& preferences,
+	const gl::build_preferences* preferences,
 	const ColorTable& colorTable)
 {
 	QColor color;
 	// For normal colors, use the polygon's color.
 	if (polygon.color == MAIN_COLOR)
 	{
-		color = preferences.mainColor;
+		color = preferences->mainColor;
 	}
 	else if (polygon.color == EDGE_COLOR)
 	{
 		// Edge color is black, unless we have a dark background, in which case lines need to be bright.
-		color = luma(preferences.backgroundColor) > (40.0 / 256.0) ? Qt::black : Qt::white;
+		color = luma(preferences->backgroundColor) > (40.0 / 256.0) ? Qt::black : Qt::white;
 	}
 	else
 	{
@@ -281,7 +281,7 @@
 	QTextDocument* model,
 	const ColorTable& colorTable,
 	DocumentManager* context,
-	const gl::RenderPreferences& preferences)
+	const gl::build_preferences* preferences)
 {
 	for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) {
 		shader.cachedData.clear();
--- a/src/gl/compiler.h	Tue Apr 11 20:27:04 2023 +0300
+++ b/src/gl/compiler.h	Tue Apr 11 22:39:18 2023 +0300
@@ -75,7 +75,7 @@
 		QTextDocument* model,
 		const ColorTable& colorTable,
 		DocumentManager* context,
-		const RenderPreferences& preferences);
+		const build_preferences* preferences);
 	void initializeModelShaders(ModelShaders* modelShaders);
 	void bindModelShaderVertexArray(gl::ModelShaders* shaders, gl::ArrayClass arrayClass);
 	void releaseModelShaderVertexArray(gl::ModelShaders* shaders, gl::ArrayClass arrayClass);
--- a/src/gl/partrenderer.cpp	Tue Apr 11 20:27:04 2023 +0300
+++ b/src/gl/partrenderer.cpp	Tue Apr 11 22:39:18 2023 +0300
@@ -33,6 +33,8 @@
 
 static constexpr double MIN_ZOOM = -3.0;
 static constexpr double MAX_ZOOM = 3.0;
+const gl::RenderPreferences PartRenderer::default_render_preferences{};
+const gl::build_preferences PartRenderer::default_build_preferences{};
 
 PartRenderer::PartRenderer(
 	QTextDocument* model,
@@ -120,24 +122,22 @@
 {
 	if (this->needBuild)
 	{
-		gl::build(&this->shaders, this->model, this->colorTable, this->documents, this->renderPreferences);
+		gl::build(&this->shaders, this->model, this->colorTable, this->documents, this->build_preferences);
 		this->boundingBox = gl::boundingBoxForModel(this->model, this->documents);
 		this->needBuild = false;
 	}
 	this->checkForGLErrors();
-	if (true
-		and this->renderPreferences.lineAntiAliasing
-		and this->renderPreferences.style != gl::RenderStyle::PickScene
-	) {
+	if (this->render_preferences->lineAntiAliasing)
+	{
 		glEnable(GL_LINE_SMOOTH);
 		glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
 	}
 	else {
 		glDisable(GL_LINE_SMOOTH);
 	}
-	if (this->renderPreferences.style != gl::RenderStyle::PickScene)
+	if (this->render_preferences->style != gl::RenderStyle::PickScene)
 	{
-		const QColor& backgroundColor = this->renderPreferences.backgroundColor;
+		const QColor& backgroundColor = this->build_preferences->backgroundColor;
 		glClearColor(
 			static_cast<float>(backgroundColor.redF()),
 			static_cast<float>(backgroundColor.greenF()),
@@ -151,7 +151,7 @@
 		gl::setShaderUniform(&this->shaders, "useLighting", GL_FALSE);
 	}
 	this->checkForGLErrors();
-	const QColor qs = this->renderPreferences.selectedColor;
+	const QColor qs = this->render_preferences->selectedColor;
 	const glm::vec4 selectedColor{qs.redF(), qs.greenF(), qs.blueF(), 1.0f};
 	gl::setShaderUniformVector(&this->shaders, "selectedColor", selectedColor);
 	gl::setShaderUniform(&this->shaders, "highlighted", this->highlighted.value);
@@ -160,17 +160,18 @@
 	glEnable(GL_DEPTH_TEST);
 	glEnable(GL_POLYGON_OFFSET_FILL);
 	glPolygonOffset(1.0f, 1.0f);
-	glLineWidth(this->renderPreferences.lineThickness);
+	glLineWidth(this->render_preferences->lineThickness);
 	const auto renderAllArrays = [this](){
 		// Lines need to be rendered last so that anti-aliasing does not interfere with polygon rendering.
 		this->renderVao<gl::ArrayClass::Triangles>();
 		this->renderVao<gl::ArrayClass::Quads>();
 		this->renderVao<gl::ArrayClass::Lines>();
 	};
-	if (this->renderPreferences.wireframe and this->renderPreferences.style != gl::RenderStyle::PickScene) {
+	if (this->render_preferences->wireframe)
+	{
 		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 	}
-	switch (this->renderPreferences.style)
+	switch (this->render_preferences->style)
 	{
 	case gl::RenderStyle::Normal:
 		this->setFragmentStyle(gl::FragmentStyle::Normal);
@@ -195,7 +196,6 @@
 		renderAllArrays();
 		break;
 	case gl::RenderStyle::PickScene:
-		glLineWidth(3.0f);
 		this->setFragmentStyle(gl::FragmentStyle::Id);
 		renderAllArrays();
 		break;
@@ -395,7 +395,7 @@
 
 bool PartRenderer::isDark() const
 {
-	return luma(this->renderPreferences.backgroundColor) < 0.25;
+	return luma(this->build_preferences->backgroundColor) < 0.25;
 }
 
 Line<3> PartRenderer::cameraLine(const QPointF& point) const
@@ -433,8 +433,16 @@
 	// will be affected by High DPI scaling. We need to take this into account
 	// and multiply the pixel positions by the screen pixel scaling factor.
 	where *= this->devicePixelRatioF();
-	const gl::RenderStyle oldRenderStyle = this->renderPreferences.style;
-	this->renderPreferences.style = gl::RenderStyle::PickScene;
+	static const gl::RenderPreferences pick_scene_preferences {
+		.style = gl::RenderStyle::PickScene,
+		.selectedColor = {},
+		.lineThickness = 3.0f,
+		.lineAntiAliasing = false,
+		.drawAxes = false,
+		.wireframe = false,
+	};
+	const gl::RenderPreferences* old_render_preferences = this->render_preferences;
+	this->render_preferences = &pick_scene_preferences;
 	this->makeCurrent();
 	QOpenGLFramebufferObject fbo{this->width(), this->height(), QOpenGLFramebufferObject::CombinedDepthStencil};
 	fbo.bind();
@@ -444,7 +452,7 @@
 	glReadPixels(where.x(), where.y(), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &data[0]);
 	this->checkForGLErrors();
 	fbo.release();
-	this->renderPreferences.style = oldRenderStyle;
+	this->render_preferences = old_render_preferences;
 	return gl::idFromUcharColor(data);
 }
 
@@ -458,23 +466,6 @@
 }
 
 /**
- * @brief Changes the way the scene is rendered
- * @param newStyle new render style to use
- */
-void PartRenderer::setRenderPreferences(const gl::RenderPreferences& newPreferences)
-{
-	bool mainColorChanged = this->renderPreferences.mainColor != newPreferences.mainColor;
-	bool backgroundColorChanged = this->renderPreferences.backgroundColor != newPreferences.backgroundColor;
-	this->renderPreferences = newPreferences;
-	if (mainColorChanged or backgroundColorChanged)
-	{
-		this->build();
-	}
-	Q_EMIT this->renderPreferencesChanged();
-	this->update();
-}
-
-/**
  * @return the currently highlighted object
  */
 ModelId PartRenderer::getHighlightedObject() const
--- a/src/gl/partrenderer.h	Tue Apr 11 20:27:04 2023 +0300
+++ b/src/gl/partrenderer.h	Tue Apr 11 22:39:18 2023 +0300
@@ -23,7 +23,6 @@
 	glm::vec3 modelViewOrigin = {0, 0, 0};
 	QPoint lastMousePosition;
 	int totalMouseMove = 0;
-	gl::RenderPreferences renderPreferences;
 	double zoom = 1.0;
 	bool initialized = false;
 	bool needBuild = true;
@@ -32,13 +31,16 @@
 	std::chrono::time_point<std::chrono::steady_clock> lastClickTime;
 	bool frozen = false;
 public:
+	static const gl::RenderPreferences default_render_preferences;
+	static const gl::build_preferences default_build_preferences;
+	const gl::RenderPreferences* render_preferences = &PartRenderer::default_render_preferences;
+	const gl::build_preferences* build_preferences = &PartRenderer::default_build_preferences;
 	PartRenderer(
 		QTextDocument* model,
 		DocumentManager* documents,
 		const ColorTable& colorTable,
 		QWidget* parent = nullptr);
 	~PartRenderer() override;
-	void setRenderPreferences(const gl::RenderPreferences& newPreferences);
 	ModelId getHighlightedObject() const;
 	void addRenderLayer(RenderLayer* layer);
 	void setLayerEnabled(RenderLayer* layer, bool enabled);
@@ -50,11 +52,11 @@
 	glm::vec3 cameraVector(const QPointF& point) const;
 	Line<3> cameraLine(const QPointF& point) const;
 	Q_SLOT void setModelViewOrigin(const glm::vec3& newViewOrigin);
+	Q_SLOT void build();
 Q_SIGNALS:
 	void projectionMatrixChanged(const glm::mat4& newMatrix);
 	void modelMatrixChanged(const glm::mat4& newMatrix);
 	void viewMatrixChanged(const glm::mat4& newMatrix);
-	void renderPreferencesChanged();
 	void message(const Message& message);
 private:
 	void initializeGL() override;
@@ -70,7 +72,6 @@
 	void renderScene();
 	void updateViewMatrix();
 	void updateModelMatrix();
-	Q_SLOT void build();
 	void renderVao(const gl::ArrayClass arrayClass, const GLenum glType);
 	template<gl::ArrayClass arrayClass>
 	void renderVao();
--- a/src/main.cpp	Tue Apr 11 20:27:04 2023 +0300
+++ b/src/main.cpp	Tue Apr 11 22:39:18 2023 +0300
@@ -75,6 +75,7 @@
 	QStringList recentlyOpenedFiles;
 	ColorTable colorTable;
 	gl::RenderPreferences renderPreferences;
+	gl::build_preferences user_gl_build_preferences;
 	MessageLog messageLog;
 	ToolWidgets toolWidgets{
 		.circleToolOptions = new CircleToolOptionsWidget{&mainWindow},
@@ -176,12 +177,22 @@
 	});
 }
 
+static void rebuild_polygons_for_all_models(MainState* state)
+{
+	forEachModel(&state->documents, [](const void*, const ModelData* data){
+		if (data->canvas != nullptr) {
+			data->canvas->build();
+			data->canvas->update();
+		}
+	});
+}
+
 static void updateRenderPreferences(MainState* state)
 {
 	forEachModel(&state->documents, [state](const void*, const ModelData* data){
 		if (data->canvas != nullptr) {
-			data->canvas->setRenderPreferences(state->renderPreferences);
 			data->canvas->setLayerEnabled(data->axesLayer.get(), state->renderPreferences.drawAxes);
+			data->canvas->update();
 		}
 	});
 	state->mainWindow.setRenderStyle(state->renderPreferences.style);
@@ -189,12 +200,18 @@
 	state->mainWindow.actionWireframe->setChecked(state->renderPreferences.wireframe);
 }
 
+static gl::build_preferences load_gl_build_preferences_from_settings()
+{
+	return gl::build_preferences{
+		.mainColor = setting<Setting::MainColor>(),
+		.backgroundColor = setting<Setting::BackgroundColor>(),
+	};
+}
+
 static gl::RenderPreferences loadRenderPreferences()
 {
 	return gl::RenderPreferences{
 		.style = setting<Setting::RenderStyle>(),
-		.mainColor = setting<Setting::MainColor>(),
-		.backgroundColor = setting<Setting::BackgroundColor>(),
 		.selectedColor = setting<Setting::SelectedColor>(),
 		.lineThickness = setting<Setting::LineThickness>(),
 		.lineAntiAliasing = setting<Setting::LineAntiAliasing>(),
@@ -327,7 +344,8 @@
 			data->tools.get(),
 			&EditTools::modelAction,
 			std::bind(executeAction, model, std::placeholders::_1));
-		data->canvas->setRenderPreferences(state->renderPreferences);
+		data->canvas->render_preferences = &state->renderPreferences;
+		data->canvas->build_preferences = &state->user_gl_build_preferences;
 		QObject::connect(
 			data->tools.get(),
 			&EditTools::newStatusText,
@@ -388,10 +406,12 @@
 {
 	state->recentlyOpenedFiles = setting<Setting::RecentFiles>();
 	state->renderPreferences = loadRenderPreferences();
+	state->user_gl_build_preferences = load_gl_build_preferences_from_settings();
 	state->libraries.restoreFromSettings();
 	updateRecentlyOpenedDocumentsMenu(state);
 	state->colorTable = loadColors(&state->libraries);
 	updateRenderPreferences(state);
+	rebuild_polygons_for_all_models(state);
 	state->mainWindow.mdiArea->setViewMode(setting<Setting::ViewMode>());
 	state->mainWindow.retranslateUi(&state->mainWindow);
 	state->mainWindow.setToolButtonStyle(setting<Setting::ToolButtonStyle>());
@@ -731,7 +751,6 @@
 		}
 	);
 	restoreSettings(&state);
-	updateRenderPreferences(&state);
 	const int result = app.exec();
 	saveSettings(&state);
 	return result;

mercurial