picking works now

Thu, 06 Feb 2020 23:41:20 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Thu, 06 Feb 2020 23:41:20 +0200
changeset 47
cd6704009eb9
parent 46
98645c8e7704
child 48
3c10f0e2fbe0

picking works now

CMakeLists.txt file | annotate | diff | comparison | revisions
locale/fi.ts file | annotate | diff | comparison | revisions
locale/sv.ts file | annotate | diff | comparison | revisions
src/document.cpp file | annotate | diff | comparison | revisions
src/document.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/mainwindow.cpp file | annotate | diff | comparison | revisions
src/ui/canvas.cpp file | annotate | diff | comparison | revisions
src/ui/canvas.h file | annotate | diff | comparison | revisions
--- a/CMakeLists.txt	Thu Feb 06 20:33:05 2020 +0200
+++ b/CMakeLists.txt	Thu Feb 06 23:41:20 2020 +0200
@@ -49,6 +49,7 @@
 	src/settingseditor/librarieseditor.cpp
 	src/settingseditor/settingseditor.cpp
 	src/types/boundingbox.cpp
+	src/ui/canvas.cpp
 	src/widgets/colorbutton.cpp
 )
 set (LDFORGE_HEADERS
@@ -85,6 +86,7 @@
 	src/settingseditor/librarieseditor.h
 	src/settingseditor/settingseditor.h
 	src/types/boundingbox.h
+	src/ui/canvas.h
 	src/widgets/colorbutton.h
 )
 set (LDFORGE_FORMS
--- a/locale/fi.ts	Thu Feb 06 20:33:05 2020 +0200
+++ b/locale/fi.ts	Thu Feb 06 23:41:20 2020 +0200
@@ -209,10 +209,20 @@
 <context>
     <name>PartRenderer</name>
     <message>
-        <location filename="../src/gl/partrenderer.cpp" line="206"/>
+        <location filename="../src/gl/partrenderer.cpp" line="201"/>
+        <source>Failed to render: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../src/gl/partrenderer.cpp" line="202"/>
         <source>Rendering error</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location filename="../src/gl/partrenderer.cpp" line="204"/>
+        <source>Damn it</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>SettingsEditor</name>
--- a/locale/sv.ts	Thu Feb 06 20:33:05 2020 +0200
+++ b/locale/sv.ts	Thu Feb 06 23:41:20 2020 +0200
@@ -231,6 +231,14 @@
         <source>Rendering error</source>
         <translation>Renderingsfel</translation>
     </message>
+    <message>
+        <source>Failed to render: %1</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Damn it</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>SettingsEditor</name>
--- a/src/document.cpp	Thu Feb 06 20:33:05 2020 +0200
+++ b/src/document.cpp	Thu Feb 06 23:41:20 2020 +0200
@@ -16,6 +16,7 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <QMouseEvent>
 #include "document.h"
 #include "ui_document.h"
 #include "model.h"
@@ -29,7 +30,7 @@
 	model{model},
 	documents{documents},
 	colorTable{colorTable},
-	renderer{new PartRenderer{model, documents, colorTable, this}},
+	renderer{new Canvas{model, documents, colorTable, this}},
 	ui{*new Ui::Document}
 {
 	this->ui.setupUi(this);
@@ -37,7 +38,9 @@
 	QVBoxLayout* layout = new QVBoxLayout;
 	layout->addWidget(this->renderer);
 	this->ui.viewportFrame->setLayout(layout);
+	this->setMouseTracking(true);
 	connect(this->ui.splitter, &QSplitter::splitterMoved, this, &Document::splitterChanged);
+	connect(this->renderer, &Canvas::newStatusText, this, &Document::newStatusText);
 }
 
 Document::~Document()
--- a/src/document.h	Thu Feb 06 20:33:05 2020 +0200
+++ b/src/document.h	Thu Feb 06 23:41:20 2020 +0200
@@ -19,7 +19,7 @@
 #pragma once
 #include <memory>
 #include <QWidget>
-#include "gl/partrenderer.h"
+#include "ui/canvas.h"
 
 namespace Ui
 {
@@ -37,16 +37,17 @@
 		DocumentManager* documents,
 		const ldraw::ColorTable& colorTable,
 		QWidget *parent = nullptr);
-	~Document();
+	~Document() override;
 	QByteArray saveSplitterState() const;
 	void restoreSplitterState(const QByteArray& state);
 	void setRenderPreferences(const gl::RenderPreferences& newPreferences);
 signals:
+	void newStatusText(const QString& newStatusText);
 	void splitterChanged();
 private:
 	Model* model;
 	DocumentManager* const documents;
 	const ldraw::ColorTable& colorTable;
-	PartRenderer* renderer;
+	Canvas* renderer;
 	Ui::Document& ui;
 };
--- a/src/gl/compiler.cpp	Thu Feb 06 20:33:05 2020 +0200
+++ b/src/gl/compiler.cpp	Thu Feb 06 23:41:20 2020 +0200
@@ -205,6 +205,11 @@
 	return {r / 255.0f, g / 255.0f, b / 255.0f};
 }
 
+ldraw::Id gl::Compiler::idFromColor(const std::array<GLbyte, 3>& data)
+{
+	return {data[0] * std::int32_t{0x10000} + data[1] * std::int32_t{0x100} + data[2]};
+}
+
 void gl::Compiler::buildPolygon(
 	gl::Polygon polygon,
 	std::vector<gl::Vertex>* vboData,
--- a/src/gl/compiler.h	Thu Feb 06 20:33:05 2020 +0200
+++ b/src/gl/compiler.h	Thu Feb 06 23:41:20 2020 +0200
@@ -60,6 +60,8 @@
 	void releaseVertexArray(gl::ArrayClass arrayClass);
 	void buildShaders(int arrayId);
 
+	static ldraw::Id idFromColor(const std::array<GLbyte, 3>& data);
+
 	template<typename T>
 	void setUniform(const char* uniformName, T&& value)
 	{
--- a/src/gl/partrenderer.cpp	Thu Feb 06 20:33:05 2020 +0200
+++ b/src/gl/partrenderer.cpp	Thu Feb 06 23:41:20 2020 +0200
@@ -21,6 +21,7 @@
 #include <glm/ext/matrix_clip_space.hpp>
 #include <QMouseEvent>
 #include <QMessageBox>
+#include <QAbstractButton>
 #include "partrenderer.h"
 
 PartRenderer::PartRenderer(
@@ -85,13 +86,14 @@
 
 void PartRenderer::paintGL()
 {
-	/*
-	glEnable (GL_BLEND);
-	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-	*/
-	glEnable (GL_DEPTH_TEST);
-	glShadeModel (GL_SMOOTH);
-	glEnable (GL_MULTISAMPLE);
+	glEnable(GL_DEPTH_TEST);
+	glShadeModel(GL_SMOOTH);
+	glEnable(GL_MULTISAMPLE);
+	this->renderScene();
+}
+
+void PartRenderer::renderScene()
+{
 	if (this->renderPreferences.lineAntiAliasing && this->renderPreferences.style != gl::RenderStyle::PickScene)
 	{
 		glEnable(GL_LINE_SMOOTH);
@@ -100,14 +102,9 @@
 	else {
 		glDisable(GL_LINE_SMOOTH);
 	}
-	this->renderScene();
-}
-
-void PartRenderer::renderScene()
-{
-	const QColor& backgroundColor = this->renderPreferences.backgroundColor;
 	if (this->renderPreferences.style != gl::RenderStyle::PickScene)
 	{
+		const QColor& backgroundColor = this->renderPreferences.backgroundColor;
 		glClearColor(
 			static_cast<float>(backgroundColor.redF()),
 			static_cast<float>(backgroundColor.greenF()),
@@ -199,10 +196,13 @@
 	}
 	if (not errors.isEmpty())
 	{
-		QMessageBox::critical(
-			this,
-			tr("Rendering error"),
-			QString{"Failed to render.\n%1"}.arg(errors.join("\n")));
+		QMessageBox box{this};
+		box.setIcon(QMessageBox::Critical);
+		box.setText(tr("Failed to render: %1").arg(errors.join("\n")));
+		box.setWindowTitle(tr("Rendering error"));
+		box.setStandardButtons(QMessageBox::Close);
+		box.button(QMessageBox::Close)->setText(tr("Damn it"));
+		box.exec();
 	}
 }
 
@@ -236,6 +236,19 @@
 	this->update();
 }
 
+ldraw::Id PartRenderer::pick(const QPoint& where)
+{
+	const gl::RenderStyle oldRenderStyle = this->renderPreferences.style;
+	this->renderPreferences.style = gl::RenderStyle::PickScene;
+	this->makeCurrent();
+	this->renderScene();
+	std::array<GLbyte, 3> data;
+	glReadPixels(where.x(), this->height() - where.y(), 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &data[0]);
+	this->renderPreferences.style = oldRenderStyle;
+	this->update();
+	return gl::Compiler::idFromColor(data);
+}
+
 /**
  * @brief Changes the color of rendered fragments
  * @param newFragmentStyle new fragment style to use
--- a/src/gl/partrenderer.h	Thu Feb 06 20:33:05 2020 +0200
+++ b/src/gl/partrenderer.h	Thu Feb 06 23:41:20 2020 +0200
@@ -23,6 +23,7 @@
 	~PartRenderer() override;
 	void setRenderPreferences(const gl::RenderPreferences& newPreferences);
 protected:
+	ldraw::Id pick(const QPoint& where);
 	void initializeGL() override;
 	void resizeGL(int width, int height) override;
 	void paintGL() override;
--- a/src/mainwindow.cpp	Thu Feb 06 20:33:05 2020 +0200
+++ b/src/mainwindow.cpp	Thu Feb 06 23:41:20 2020 +0200
@@ -172,6 +172,10 @@
 {
 	Document* document = new Document{this->documents.findModelByName(modelName), &this->documents, this->colorTable};
 	document->setRenderPreferences(this->renderPreferences);
+	connect(document, &Document::newStatusText, [&](const QString& newStatusText)
+	{
+		this->statusBar()->showMessage(newStatusText);
+	});
 	this->ui->tabs->addTab(document, modelName);
 	this->ui->tabs->setCurrentWidget(document);
 	document->restoreSplitterState(this->documentSplitterState);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ui/canvas.cpp	Thu Feb 06 23:41:20 2020 +0200
@@ -0,0 +1,19 @@
+#include <QMouseEvent>
+#include "canvas.h"
+
+Canvas::Canvas(
+	Model* model,
+	DocumentManager* documents,
+	const ldraw::ColorTable& colorTable,
+	QWidget* parent) :
+	PartRenderer{model, documents, colorTable, parent}
+{
+	this->setMouseTracking(true);
+}
+
+void Canvas::mouseMoveEvent(QMouseEvent* event)
+{
+	const ldraw::Id id = this->pick(event->pos());
+	this->newStatusText("Selected: %1"_q.arg(id.value));
+	PartRenderer::mouseMoveEvent(event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ui/canvas.h	Thu Feb 06 23:41:20 2020 +0200
@@ -0,0 +1,17 @@
+#pragma once
+#include "gl/partrenderer.h"
+
+class Canvas : public PartRenderer
+{
+	Q_OBJECT
+public:
+	Canvas(
+		Model* model,
+		DocumentManager* documents,
+		const ldraw::ColorTable& colorTable,
+		QWidget* parent = nullptr);
+protected:
+	void mouseMoveEvent(QMouseEvent* event) override;
+signals:
+	void newStatusText(const QString& newStatusText);
+};

mercurial