Cleaned up GLCompiler. Among other changes, the compiler no longer has to be told what to compile.

Thu, 09 Feb 2017 20:44:36 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Thu, 09 Feb 2017 20:44:36 +0200
changeset 1113
5f3139c802bf
parent 1112
d1d8be74275b
child 1114
ffd49a28f49e

Cleaned up GLCompiler. Among other changes, the compiler no longer has to be told what to compile.

src/glCompiler.cpp file | annotate | diff | comparison | revisions
src/glCompiler.h file | annotate | diff | comparison | revisions
src/glRenderer.cpp file | annotate | diff | comparison | revisions
src/glRenderer.h file | annotate | diff | comparison | revisions
src/ldDocument.cpp file | annotate | diff | comparison | revisions
src/ldDocument.h file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h file | annotate | diff | comparison | revisions
src/model.cpp file | annotate | diff | comparison | revisions
src/model.h file | annotate | diff | comparison | revisions
src/toolsets/filetoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/movetoolset.cpp file | annotate | diff | comparison | revisions
--- a/src/glCompiler.cpp	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/glCompiler.cpp	Thu Feb 09 20:44:36 2017 +0200
@@ -45,8 +45,6 @@
 
 ConfigOption (QString SelectColorBlend = "#0080FF")
 
-// static QMap<LDObject*, String> g_objectOrigins;
-
 void CheckGLErrorImpl (const char* file, int line)
 {
 	QString errmsg;
@@ -72,8 +70,14 @@
 	HierarchyElement (renderer),
 	m_renderer (renderer)
 {
-	needMerge();
-	memset (m_vboSizes, 0, sizeof m_vboSizes);
+	connect(renderer->model(), SIGNAL(objectAdded(LDObject*)), this, SLOT(compileObject(LDObject*)));
+	connect(renderer->model(), SIGNAL(objectModified(LDObject*)), this, SLOT(compileObject(LDObject*)));
+	connect(renderer->model(), SIGNAL(aboutToRemoveObject(LDObject*)), this, SLOT(forgetObject(LDObject*)), Qt::DirectConnection);
+	connect(renderer, SIGNAL(objectHighlightingChanged(LDObject*)), this, SLOT(compileObject(LDObject*)));
+	connect(m_window, SIGNAL(gridChanged()), this, SLOT(recompile()));
+
+	for (LDObject* object : renderer->model()->objects())
+		stageForCompilation(object);
 }
 
 
@@ -96,24 +100,23 @@
 {
 	// Calculate a color based from this index. This method caters for
 	// 16777216 objects. I don't think that will be exceeded anytime soon. :)
-	int r = (id / 0x10000) % 0x100,
-		g = (id / 0x100) % 0x100,
-		b = id % 0x100;
-
-	return QColor (r, g, b);
+	int r = (id / 0x10000) % 0x100;
+	int g = (id / 0x100) % 0x100;
+	int b = id % 0x100;
+	return {r, g, b};
 }
 
 
 QColor GLCompiler::getColorForPolygon (LDPolygon& poly, LDObject* topobj, ComplementVboType complement) const
 {
 	QColor qcol;
-	static const QColor bfcFrontColor (64, 192, 80);
-	static const QColor bfcBackColor (208, 64, 64);
+	static const QColor bfcFrontColor {64, 192, 80};
+	static const QColor bfcBackColor {208, 64, 64};
 
 	switch (complement)
 	{
 	case SurfacesVboComplement:
-		return QColor();
+		return {};
 
 	case BfcFrontColorsVboComplement:
 		qcol = bfcFrontColor;
@@ -124,7 +127,7 @@
 		break;
 
 	case PickColorsVboComplement:
-		return indexColorForID (topobj->id());
+		return indexColorForID(topobj->id());
 
 	case RandomColorsVboComplement:
 		qcol = topobj->randomColor();
@@ -140,7 +143,7 @@
 		}
 		else if (poly.color == EdgeColor)
 		{
-			qcol = luma (QColor (m_config->backgroundColor())) > 40 ? Qt::black : Qt::white;
+			qcol = luma(QColor (m_config->backgroundColor())) > 40 ? Qt::black : Qt::white;
 		}
 		else
 		{
@@ -152,7 +155,25 @@
 		break;
 	}
 
-	if (not qcol.isValid())
+	if (qcol.isValid())
+	{
+		double blendAlpha = 0.0;
+
+		if (topobj->isSelected())
+			blendAlpha = 1.0;
+		else if (topobj == m_renderer->objectAtCursor())
+			blendAlpha = 0.5;
+
+		if (blendAlpha != 0.0)
+		{
+			QColor selectedColor = m_config->selectColorBlend();
+			double denom = blendAlpha + 1.0;
+			qcol.setRed((qcol.red() + (selectedColor.red() * blendAlpha)) / denom);
+			qcol.setGreen((qcol.green() + (selectedColor.green() * blendAlpha)) / denom);
+			qcol.setBlue((qcol.blue() + (selectedColor.blue() * blendAlpha)) / denom);
+		}
+	}
+	else
 	{
 		// The color was unknown. Use main color to make the polygon at least
 		// not appear pitch-black.
@@ -162,30 +183,12 @@
 			qcol = Qt::black;
 
 		// Warn about the unknown color, but only once.
-		static QList<int> warnedColors;
-		if (not warnedColors.contains (poly.color))
+		static QSet<int> warnedColors;
+		if (not warnedColors.contains(poly.color))
 		{
-			print ("Unknown color %1!\n", poly.color);
-			warnedColors << poly.color;
+			print("Unknown color %1!\n", poly.color);
+			warnedColors.insert(poly.color);
 		}
-
-		return qcol;
-	}
-
-	double blendAlpha = 0.0;
-
-	if (topobj->isSelected())
-		blendAlpha = 1.0;
-	else if (topobj == m_renderer->objectAtCursor())
-		blendAlpha = 0.5;
-
-	if (blendAlpha != 0.0)
-	{
-		QColor selcolor (m_config->selectColorBlend());
-		double denom = blendAlpha + 1.0;
-		qcol.setRed ((qcol.red() + (selcolor.red() * blendAlpha)) / denom);
-		qcol.setGreen ((qcol.green() + (selcolor.green() * blendAlpha)) / denom);
-		qcol.setBlue ((qcol.blue() + (selcolor.blue() * blendAlpha)) / denom);
 	}
 
 	return qcol;
@@ -201,11 +204,6 @@
 
 void GLCompiler::stageForCompilation (LDObject* obj)
 {
-	/*
-	g_objectOrigins[obj] = format ("%1:%2 (%3)",
-		obj->document()->getDisplayName(), obj->lineNumber(), obj->typeName());
-	*/
-
 	m_staged << obj;
 }
 
@@ -216,20 +214,10 @@
 }
 
 
-void GLCompiler::compileModel (Model* model)
-{
-	if (model)
-	{
-		for (LDObject* obj : model->objects())
-			compileObject (obj);
-	}
-}
-
-
 void GLCompiler::compileStaged()
 {
-	for (QSetIterator<LDObject*> it (m_staged); it.hasNext();)
-		compileObject (it.next());
+	for (LDObject* object : m_staged)
+		compileObject(object);
 
 	m_staged.clear();
 }
@@ -268,15 +256,21 @@
 }
 
 
-void GLCompiler::dropObjectInfo (LDObject* obj)
+void GLCompiler::dropObjectInfo(LDObject* object)
 {
-	if (m_objectInfo.contains (obj))
+	if (m_objectInfo.contains(object))
 	{
-		m_objectInfo.remove (obj);
+		m_objectInfo.remove(object);
 		needMerge();
 	}
 }
 
+void GLCompiler::forgetObject(LDObject* object)
+{
+	dropObjectInfo(object);
+	m_staged.remove(object);
+}
+
 
 void GLCompiler::compileObject (LDObject* obj)
 {
@@ -398,4 +392,11 @@
 int GLCompiler::vboSize (int vbonum) const
 {
 	return m_vboSizes[vbonum];
-}
\ No newline at end of file
+}
+
+
+void GLCompiler::recompile()
+{
+	for (LDObject* object : m_renderer->model()->objects())
+		compileObject(object);
+}
--- a/src/glCompiler.h	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/glCompiler.h	Thu Feb 09 20:44:36 2017 +0200
@@ -25,8 +25,10 @@
 
 // =============================================================================
 //
-class GLCompiler : public HierarchyElement, protected QOpenGLFunctions
+class GLCompiler : public QObject, public HierarchyElement, protected QOpenGLFunctions
 {
+	Q_OBJECT
+
 public:
 	struct ObjectVBOInfo
 	{
@@ -36,8 +38,6 @@
 
 	GLCompiler (GLRenderer* renderer);
 	~GLCompiler();
-	void compileModel (Model* model);
-	void dropObjectInfo (LDObject* obj);
 	QColor getColorForPolygon (LDPolygon& poly, LDObject* topobj, ComplementVboType complement) const;
 	QColor indexColorForID (int id) const;
 	void initialize();
@@ -53,14 +53,18 @@
 
 private:
 	void compileStaged();
-	void compileObject (LDObject* obj);
 	void compilePolygon (LDPolygon& poly, LDObject* topobj, ObjectVBOInfo* objinfo);
+	Q_SLOT void compileObject (LDObject* obj);
+	Q_SLOT void recompile();
+	void dropObjectInfo (LDObject* obj);
+	Q_SLOT void forgetObject(LDObject* object);
 
+private:
 	QMap<LDObject*, ObjectVBOInfo>	m_objectInfo;
 	QSet<LDObject*> m_staged; // Objects that need to be compiled
 	GLuint m_vbo[NumVbos];
-	bool m_vboChanged[NumVbos];
-	int m_vboSizes[NumVbos];
+	bool m_vboChanged[NumVbos] = {true};
+	int m_vboSizes[NumVbos] = {0};
 	GLRenderer* m_renderer;
 };
 
--- a/src/glRenderer.cpp	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/glRenderer.cpp	Thu Feb 09 20:44:36 2017 +0200
@@ -328,17 +328,6 @@
 
 // =============================================================================
 //
-void GLRenderer::hardRefresh()
-{
-	if (m_initialized)
-	{
-		compiler()->compileModel (currentDocument());
-		refresh();
-	}
-}
-
-// =============================================================================
-//
 void GLRenderer::resizeGL (int width, int height)
 {
 	calcCameraIcons();
@@ -785,18 +774,8 @@
 
 // =============================================================================
 //
-void GLRenderer::compileObject (LDObject* obj)
-{
-	compiler()->stageForCompilation (obj);
-}
-
-// =============================================================================
-//
 void GLRenderer::forgetObject(LDObject* obj)
 {
-	compiler()->dropObjectInfo(obj);
-	compiler()->unstage(obj);
-
 	if (m_objectAtCursor == obj)
 		m_objectAtCursor = nullptr;
 }
@@ -1002,10 +981,10 @@
 		m_objectAtCursor = newObject;
 
 		if (oldObject)
-			compileObject (oldObject);
+			emit objectHighlightingChanged(oldObject);
 
 		if (newObject)
-			compileObject (newObject);
+			emit objectHighlightingChanged(newObject);
 	}
 
 	update();
@@ -1085,3 +1064,8 @@
 {
 	return m_virtualWidth;
 }
+
+const Model* GLRenderer::model() const
+{
+	return m_model;
+}
\ No newline at end of file
--- a/src/glRenderer.h	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/glRenderer.h	Thu Feb 09 20:44:36 2017 +0200
@@ -80,18 +80,17 @@
 	const CameraInfo& cameraInfo(Camera camera) const;
 	QString cameraName(Camera camera) const;
 	QByteArray capturePixels();
-	void compileObject(LDObject* obj);
 	GLCompiler* compiler() const;
 	QString currentCameraName() const;
 	void drawGLScene();
 	void forgetObject(LDObject* obj);
 	Axis getCameraAxis(bool y, Camera camid = (Camera) -1);
-	void hardRefresh();
 	void highlightCursorObject();
 	void initGLData();
 	bool isDrawOnly() const;
 	bool isPicking() const;
 	Qt::KeyboardModifiers keyboardModifiers() const;
+	const Model* model() const;
 	bool mouseHasMoved() const;
 	QPoint const& mousePosition() const;
 	QPointF const& mousePositionF() const;
@@ -113,6 +112,9 @@
 
 	static const QPen thinBorderPen;
 
+signals:
+	void objectHighlightingChanged(LDObject* object);
+
 protected:
 	void initializeGL();
 	void keyPressEvent(QKeyEvent* event);
--- a/src/ldDocument.cpp	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/ldDocument.cpp	Thu Feb 09 20:44:36 2017 +0200
@@ -22,13 +22,11 @@
 #include "miscallenous.h"
 #include "mainwindow.h"
 #include "canvas.h"
-#include "glCompiler.h"
 #include "documentloader.h"
 #include "dialogs/openprogressdialog.h"
 #include "documentmanager.h"
 
 LDDocument::LDDocument (DocumentManager* parent) :
-	QObject (parent),
     Model {parent},
 	HierarchyElement (parent),
     m_history (new EditHistory (this)),
@@ -299,7 +297,6 @@
 {
 	Model::insertObject(pos, obj);
 	history()->add(new AddHistoryEntry {pos, obj});
-	m_window->renderer()->compileObject(obj);
 	connect(obj, SIGNAL(codeChanged(int,QString,QString)), this, SLOT(objectChanged(int,QString,QString)));
 
 #ifdef DEBUG
@@ -312,8 +309,8 @@
 {
 	LDObject* object = static_cast<LDObject*>(sender());
 	addToHistory(new EditHistoryEntry {position, before, after});
-	m_window->renderer()->compileObject(object);
-	m_window->currentDocument()->redoVertices();
+	redoVertices();
+	emit objectModified(object);
 }
 
 LDObject* LDDocument::withdrawAt(int position)
@@ -446,7 +443,7 @@
 	if (not m_selection.contains(obj) and obj->model() == this)
 	{
 		m_selection.insert(obj);
-		m_window->renderer()->compileObject (obj);
+		emit objectModified(obj);
 
 		// If this object is inverted with INVERTNEXT, select the INVERTNEXT as well.
 		LDBfc* invertnext;
@@ -463,7 +460,7 @@
 	if (m_selection.contains(obj))
 	{
 		m_selection.remove(obj);
-		m_window->renderer()->compileObject (obj);
+		emit objectModified(obj);
 
 		// If this object is inverted with INVERTNEXT, deselect the INVERTNEXT as well.
 		LDBfc* invertnext;
@@ -478,9 +475,7 @@
 void LDDocument::clearSelection()
 {
 	for (LDObject* object : m_selection)
-		m_window->renderer()->compileObject(object);
-
-	m_selection.clear();
+		removeFromSelection(object);
 }
 
 // =============================================================================
--- a/src/ldDocument.h	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/ldDocument.h	Thu Feb 09 20:44:36 2017 +0200
@@ -37,7 +37,7 @@
 // The default name is a placeholder, initially suggested name for a file. The
 // primitive generator uses this to give initial names to primitives.
 //
-class LDDocument : public QObject, public Model, public HierarchyElement
+class LDDocument : public Model, public HierarchyElement
 {
 	Q_OBJECT
 
--- a/src/mainwindow.cpp	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/mainwindow.cpp	Thu Feb 09 20:44:36 2017 +0200
@@ -280,10 +280,7 @@
 	ui.actionGridCoarse->setChecked (grid == Grid::Coarse);
 	ui.actionGridMedium->setChecked (grid == Grid::Medium);
 	ui.actionGridFine->setChecked (grid == Grid::Fine);
-
-	// Recompile all Bézier curves, the changing grid affects their precision.
-	for (LDObjectIterator<LDBezierCurve> it (m_currentDocument); it.isValid(); ++it)
-		renderer()->compileObject (it);
+	emit gridChanged();
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -437,11 +434,6 @@
 	// The select() method calls may have selected additional items (i.e. invertnexts)
 	// Update it all now.
 	updateSelection();
-
-	// Update the GL renderer
-	for (LDObject* obj : priorSelection + selectedObjects())
-		renderer()->compileObject (obj);
-
 	renderer()->update();
 }
 
@@ -478,7 +470,6 @@
 			continue; // uncolored object
 
 		obj->setColor (color);
-		renderer()->compileObject (obj);
 	}
 
 	endAction();
@@ -505,7 +496,7 @@
 void MainWindow::doFullRefresh()
 {
 	buildObjectList();
-	renderer()->hardRefresh();
+	renderer()->update();
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -1147,9 +1138,7 @@
 	{
 		document->setFrozen(false);
 		print ("Opened %1", document->name());
-
-		// Cache files are not compiled by the GL renderer. Now that this file is open for editing, it needs to be compiled.
-		getRendererForDocument(document)->compiler()->compileModel(document);
+		getRendererForDocument(document);
 		updateDocumentList();
 	}
 }
--- a/src/mainwindow.h	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/mainwindow.h	Thu Feb 09 20:44:36 2017 +0200
@@ -119,6 +119,9 @@
 	void updateSelection();
 	void updateTitle();
 
+signals:
+	void gridChanged();
+
 public slots:
 	void actionTriggered();
 	void circleToolSegmentsChanged();
--- a/src/model.cpp	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/model.cpp	Thu Feb 09 20:44:36 2017 +0200
@@ -21,6 +21,7 @@
 #include "documentmanager.h"
 
 Model::Model(DocumentManager* manager) :
+    QObject {manager},
     _manager {manager} {}
 
 Model::~Model()
@@ -65,6 +66,7 @@
 	_objects.insert(position, object);
 	_needsTriangleRecount = true;
 	object->setDocument(this);
+	emit objectAdded(object);
 }
 
 /*
@@ -248,6 +250,7 @@
 LDObject* Model::withdrawAt(int position)
 {
 	LDObject* object = _objects[position];
+	emit aboutToRemoveObject(object);
 	_objects.removeAt(position);
 	_needsTriangleRecount = true;
 	return object;
--- a/src/model.h	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/model.h	Thu Feb 09 20:44:36 2017 +0200
@@ -23,8 +23,10 @@
 /*
  * This class represents a LDraw model, consisting of a vector of objects. It manages LDObject ownership.
  */
-class Model
+class Model : public QObject
 {
+	Q_OBJECT
+
 public:
 	Model(DocumentManager* manager);
 	Model(const Model& other) = delete;
@@ -56,6 +58,11 @@
 	LDObject* addFromString(QString line);
 	LDObject* replaceWithFromString(LDObject* object, QString line);
 
+signals:
+	void objectAdded(LDObject* object);
+	void aboutToRemoveObject(LDObject* object);
+	void objectModified(LDObject* object);
+
 protected:
 	template<typename T, typename... Args> T* constructObject(Args&& ...args);
 	void withdraw(LDObject* object);
--- a/src/toolsets/filetoolset.cpp	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/toolsets/filetoolset.cpp	Thu Feb 09 20:44:36 2017 +0200
@@ -126,7 +126,6 @@
 			{
 				currentDocument()->insertObject (position, object);
 				currentDocument()->addToSelection(object);
-				m_window->renderer()->compileObject (object);
 				position++;
 			}
 
--- a/src/toolsets/movetoolset.cpp	Thu Feb 09 20:07:45 2017 +0200
+++ b/src/toolsets/movetoolset.cpp	Thu Feb 09 20:44:36 2017 +0200
@@ -63,11 +63,6 @@
 		obj->swap(model->getObject(target));
 	}
 
-	// The objects need to be recompiled, otherwise their pick lists are left with
-	// the wrong index colors which messes up selection.
-	for (LDObject* obj : objsToCompile)
-		m_window->renderer()->compileObject(obj);
-
 	m_window->buildObjectList();
 }
 

mercurial