commit work on GL rendering

Sun, 19 Jan 2020 02:54:48 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 19 Jan 2020 02:54:48 +0200
changeset 22
6da867fa5429
parent 21
0133e565e072
child 23
3387a84ddaba

commit work on GL rendering

locale/fi.ts file | annotate | diff | comparison | revisions
locale/sv.ts file | annotate | diff | comparison | revisions
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/libraries.cpp file | annotate | diff | comparison | revisions
src/main.h file | annotate | diff | comparison | revisions
src/types/boundingbox.cpp file | annotate | diff | comparison | revisions
src/types/boundingbox.h file | annotate | diff | comparison | revisions
src/vertex.h file | annotate | diff | comparison | revisions
--- a/locale/fi.ts	Wed Jan 01 17:45:56 2020 +0200
+++ b/locale/fi.ts	Sun Jan 19 02:54:48 2020 +0200
@@ -103,12 +103,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/libraries.cpp" line="274"/>
+        <location filename="../src/libraries.cpp" line="273"/>
         <source>Path</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/libraries.cpp" line="276"/>
+        <location filename="../src/libraries.cpp" line="275"/>
         <source>Role</source>
         <translation type="unfinished"></translation>
     </message>
@@ -187,6 +187,14 @@
     </message>
 </context>
 <context>
+    <name>PartRenderer</name>
+    <message>
+        <location filename="../src/gl/partrenderer.cpp" line="155"/>
+        <source>Rendering error</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
     <name>SettingsEditor</name>
     <message>
         <location filename="../src/settingseditor/settingseditor.ui" line="14"/>
--- a/locale/sv.ts	Wed Jan 01 17:45:56 2020 +0200
+++ b/locale/sv.ts	Sun Jan 19 02:54:48 2020 +0200
@@ -210,6 +210,13 @@
     </message>
 </context>
 <context>
+    <name>PartRenderer</name>
+    <message>
+        <source>Rendering error</source>
+        <translation type="unfinished"></translation>
+    </message>
+</context>
+<context>
     <name>SettingsEditor</name>
     <message>
         <source>Dialog</source>
--- a/src/gl/common.h	Wed Jan 01 17:45:56 2020 +0200
+++ b/src/gl/common.h	Sun Jan 19 02:54:48 2020 +0200
@@ -60,7 +60,7 @@
 	/**
 	 * @return amount of vertices used for geometry
 	 */
-	inline int numPolygonVertices() const
+	inline unsigned int numPolygonVertices() const
 	{
 		if (type == Type::ConditionalEdge)
 			return 2;
@@ -71,7 +71,7 @@
 	/**
 	 * @return amount of vertices
 	 */
-	inline int numVertices() const
+	inline unsigned int numVertices() const
 	{
 		switch (type)
 		{
@@ -82,9 +82,8 @@
 		case Type::ConditionalEdge:
 		case Type::Quadrilateral:
 			return 4;
-		default:
-			return 0;
 		}
+		return 0;
 	}
 };
 
--- a/src/gl/compiler.cpp	Wed Jan 01 17:45:56 2020 +0200
+++ b/src/gl/compiler.cpp	Sun Jan 19 02:54:48 2020 +0200
@@ -40,6 +40,7 @@
 	{
 		this->initializeVbo();
 	}
+	this->boundingBox = {};
 	std::vector<GLfloat> vboData[gl::numVbos];
 	const std::vector<gl::Polygon> polygons = model->getPolygons(context);
 	for (const gl::Polygon& polygon : polygons)
@@ -80,9 +81,9 @@
 
 void writeVertex(std::vector<GLfloat>& data, const Point3D& point)
 {
-	data.push_back(point.x);
-	data.push_back(point.y);
-	data.push_back(point.z);
+	data.push_back(static_cast<GLfloat>(point.x));
+	data.push_back(static_cast<GLfloat>(point.y));
+	data.push_back(static_cast<GLfloat>(point.z));
 }
 
 void gl::Compiler::buildPolygon(gl::Polygon polygon, std::vector<GLfloat>* vboData)
@@ -93,7 +94,7 @@
 		return vboData[gl::vboIndex({vboClass, subclass})];
 	};
 	auto vertexRing = iter::ring(polygon.vertices, polygon.numPolygonVertices());
-	for (int i = 0; i < polygon.numPolygonVertices(); i += 1)
+	for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
 	{
 		const Point3D& v1 = vertexRing[i - 1];
 		const Point3D& v2 = vertexRing[i];
@@ -105,18 +106,11 @@
 	}
 	vboBuffer(VboSubclass::Surfaces).reserve(vboBuffer(VboSubclass::Surfaces).size() + polygon.numPolygonVertices());
 	// Transform vertices so that they're suitable for GL rendering
-	for (int i = 0; i < polygon.numPolygonVertices(); i += 1)
+	for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
 	{
 		polygon.vertices[i].y = -polygon.vertices[i].y;
 		polygon.vertices[i].z = -polygon.vertices[i].z;
-#if 0
-		// Add these vertices to the bounding box (unless we're going to do it over
-		// from scratch afterwards anyway)
-		if (not this->needBoundingBoxRebuild)
-		{
-			this->boundingBox.consider(poly.vertices[i]);
-		}
-#endif
+		this->boundingBox.consider(polygon.vertices[i]);
 		writeVertex(vboBuffer(VboSubclass::Surfaces), polygon.vertices[i]);
 	}
 	this->writeColor(vboData, polygon, VboSubclass::RegularColors);
@@ -199,15 +193,25 @@
 	std::vector<GLfloat>& buffer = data[gl::vboIndex({classifyPolygon(polygon), subclass})];
 	const QColor color = this->getColorForPolygon(polygon, subclass);
 	buffer.reserve(data->size() + 4 * polygon.numPolygonVertices());
-	for (int i = 0; i < polygon.numPolygonVertices(); i += 1)
+	for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
 	{
-		buffer.push_back(color.redF() / 255.0f);
-		buffer.push_back(color.greenF() / 255.0f);
-		buffer.push_back(color.blueF() / 255.0f);
-		buffer.push_back(color.alphaF() / 255.0f);
+		buffer.push_back(static_cast<GLfloat>(color.redF()));
+		buffer.push_back(static_cast<GLfloat>(color.greenF()));
+		buffer.push_back(static_cast<GLfloat>(color.blueF()));
+		buffer.push_back(static_cast<GLfloat>(color.alphaF()));
 	}
 }
 
+Point3D gl::Compiler::modelCenter() const
+{
+	return boxCenter(this->boundingBox);
+}
+
+double gl::Compiler::modelDistance() const
+{
+	return longestMeasure(this->boundingBox);
+}
+
 void gl::Compiler::initializeVbo()
 {
 	this->initializeOpenGLFunctions();
@@ -223,7 +227,7 @@
 void gl::Compiler::upload(const int vboIndex, const std::vector<GLfloat>& data)
 {
 	glBindBuffer(GL_ARRAY_BUFFER, this->storedVbo[vboIndex]);
-	glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof data[0], data.data(), GL_STATIC_DRAW);
+	glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(data.size() * sizeof data[0]), data.data(), GL_STATIC_DRAW);
 	glBindBuffer(GL_ARRAY_BUFFER, 0);
 	this->storedVboSizes[vboIndex] = data.size();
 }
@@ -233,7 +237,7 @@
 	return this->storedVbo[gl::vboIndex(vboAddress)];
 }
 
-int gl::Compiler::vboSize(const VboAddress vboAddress) const
+std::size_t gl::Compiler::vboSize(const VboAddress vboAddress) const
 {
 	return this->storedVboSizes[gl::vboIndex(vboAddress)];
 }
--- a/src/gl/compiler.h	Wed Jan 01 17:45:56 2020 +0200
+++ b/src/gl/compiler.h	Sun Jan 19 02:54:48 2020 +0200
@@ -48,15 +48,18 @@
 	void buildPolygon(Polygon polygon, std::vector<GLfloat>* vboData);
 	void upload(const int vboIndex, const std::vector<GLfloat>& data);
 	GLuint vbo(const VboAddress vboAddress) const;
-	int vboSize(const VboAddress vboAddress) const;
+	std::size_t vboSize(const VboAddress vboAddress) const;
 	QColor getColorForPolygon(const gl::Polygon& polygon, VboSubclass subclass);
 	void writeColor(std::vector<GLfloat>* data, const gl::Polygon& polygon, VboSubclass subclass);
+	Point3D modelCenter() const;
+	double modelDistance() const;
 private:
 	void initializeVbo();
 	GLuint storedVbo[gl::numVbos];
 	bool m_vboChanged[gl::numVbos] = {true};
-	int storedVboSizes[gl::numVbos] = {0};
+	std::size_t storedVboSizes[gl::numVbos] = {0_z};
 	bool initialized = false;
+	BoundingBox boundingBox;
 };
 
 #define CHECK_GL_ERROR() { checkGLError(__FILE__, __LINE__); }
--- a/src/gl/partrenderer.cpp	Wed Jan 01 17:45:56 2020 +0200
+++ b/src/gl/partrenderer.cpp	Sun Jan 19 02:54:48 2020 +0200
@@ -14,7 +14,7 @@
 void PartRenderer::initializeGL()
 {
 	this->initializeOpenGLFunctions();
-	if (this->glGetError() != GL_NO_ERROR)
+	if (glGetError() != GL_NO_ERROR)
 	{
 		abort();
 	}
@@ -23,6 +23,7 @@
 	this->rotation = QQuaternion::fromAxisAndAngle({1, 0, 0}, 30);
 	this->rotation *= QQuaternion::fromAxisAndAngle({0, 1, 0}, 330);
 	this->compiler->build(this->model, this->documents);
+	glLineWidth(2.0);
 }
 
 /*
@@ -57,16 +58,16 @@
 
 void PartRenderer::resizeGL(int width, int height)
 {
-	constexpr GLfloat near = 1.0f;
-	constexpr GLfloat far = 1e+05f;
+	constexpr GLdouble near = 1.0;
+	constexpr GLdouble far = 1e+05;
 	glViewport (0, 0, width, height);
 	glMatrixMode(GL_PROJECTION);
 	glLoadIdentity();
-	gluPerspective(45.0f, static_cast<double>(width) / static_cast<double>(height), near, far);
+	gluPerspective(45.0, static_cast<double>(width) / static_cast<double>(height), near, far);
 	glMatrixMode(GL_MODELVIEW);
 }
 
-static int getGlTypeForVboClass(const gl::VboClass vboClass)
+static GLenum getGlTypeForVboClass(const gl::VboClass vboClass)
 {
 	switch (vboClass)
 	{
@@ -85,6 +86,20 @@
 #include <QMessageBox>
 void PartRenderer::paintGL()
 {
+	glEnable (GL_BLEND);
+	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	glEnable (GL_POLYGON_OFFSET_FILL);
+	glPolygonOffset (1.0f, 1.0f);
+	glEnable (GL_DEPTH_TEST);
+	glShadeModel (GL_SMOOTH);
+	glEnable (GL_MULTISAMPLE);
+	glEnable (GL_LINE_SMOOTH);
+	glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
+	this->renderScene();
+}
+
+void PartRenderer::renderScene()
+{
 	switch (this->renderStyle)
 	{
 	case gl::RenderStyle::Normal:
@@ -95,6 +110,7 @@
 		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 		break;
 	}
+	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 	glMatrixMode(GL_MODELVIEW);
 	// clear the drawing buffer.
 	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
@@ -105,33 +121,32 @@
 	glLoadIdentity();
 	// traslate the draw by z = -4.0
 	// Note this when you decrease z like -8.0 the drawing will looks far , or smaller.
-	glTranslatef(0.0,0.0,-4.5);
-	// Red color used to draw.
-	glColor3f(0.8, 0.2, 0.1);
+	glTranslatef(0.0, 0.0, -4.5 * this->compiler->modelDistance());
 	glMultMatrixf(padMatrix(this->rotation.toRotationMatrix()).constData());
-	//glutSolidTeapot(1.0);
+	xyz(glTranslatef, -this->compiler->modelCenter());
+	glEnableClientState(GL_NORMAL_ARRAY);
 	glEnableClientState(GL_VERTEX_ARRAY);
 	glEnableClientState(GL_COLOR_ARRAY);
 	for (const gl::VboClass vboClass : {gl::VboClass::Lines, gl::VboClass::Triangles, gl::VboClass::Quads})
 	{
-		const int vboSurfaces = this->compiler->vbo({vboClass, gl::VboSubclass::Surfaces});
-		const int vboColors = this->compiler->vbo({vboClass, gl::VboSubclass::RegularColors});
-		const int vboNormals = this->compiler->vbo({vboClass, gl::VboSubclass::Normals});
-		const int count = this->compiler->vboSize({vboClass, gl::VboSubclass::Surfaces}) / 3;
+		const GLuint vboSurfaces = this->compiler->vbo({vboClass, gl::VboSubclass::Surfaces});
+		const GLuint vboColors = this->compiler->vbo({vboClass, gl::VboSubclass::RegularColors});
+		const GLuint vboNormals = this->compiler->vbo({vboClass, gl::VboSubclass::Normals});
+		const std::size_t count = this->compiler->vboSize({vboClass, gl::VboSubclass::Surfaces}) / 3_z;
 		glBindBuffer(GL_ARRAY_BUFFER, vboSurfaces);
 		glVertexPointer(3, GL_FLOAT, 0, nullptr);
 		glBindBuffer(GL_ARRAY_BUFFER, vboColors);
 		glColorPointer(4, GL_FLOAT, 0, nullptr);
-		//glBindBuffer(GL_ARRAY_BUFFER, vboNormals);
-		//glNormalPointer(GL_FLOAT, 0, nullptr);
-		glDrawArrays(getGlTypeForVboClass(vboClass), 0, count);
+		glBindBuffer(GL_ARRAY_BUFFER, vboNormals);
+		glNormalPointer(GL_FLOAT, 0, nullptr);
+		glDrawArrays(getGlTypeForVboClass(vboClass), 0, static_cast<GLsizei>(count));
 	}
 	glBindBuffer(GL_ARRAY_BUFFER, 0);
+	glDisableClientState(GL_NORMAL_ARRAY);
 	glDisableClientState(GL_VERTEX_ARRAY);
 	glDisableClientState(GL_COLOR_ARRAY);
-
 	//glFlush();
-	const int glError = this->glGetError();
+	const GLenum glError = this->glGetError();
 	if (glError != GL_NO_ERROR)
 	{
 		const QString glErrorString = QString::fromLatin1(reinterpret_cast<const char*>(::gluErrorString(glError)));
@@ -140,6 +155,7 @@
 			tr("Rendering error"),
 			QString{"Failed to render: %1"}.arg(glErrorString));
 	}
+	glDisable(GL_CULL_FACE);
 }
 
 static QPointF pointToPointF(const QPoint& point)
@@ -162,7 +178,7 @@
 	{
 		const QQuaternion versor = QQuaternion::fromAxisAndAngle(
 			QVector3D{static_cast<float>(move.y()), static_cast<float>(move.x()), 0.0f},
-			0.6 * std::hypot(move.x(), move.y())
+			0.6f * static_cast<float>(std::hypot(move.x(), move.y()))
 		);
 		this->rotation = versor * this->rotation;
 		this->update();
--- a/src/gl/partrenderer.h	Wed Jan 01 17:45:56 2020 +0200
+++ b/src/gl/partrenderer.h	Sun Jan 19 02:54:48 2020 +0200
@@ -20,12 +20,13 @@
 private slots:
 	void setRenderStyle(const gl::RenderStyle newStyle);
 private:
+	void renderScene();
 	Model* const model;
 	DocumentManager* const documents;
 	QPointF lastMousePosition;
-	bool initialized = false;
+	QQuaternion rotation;
+	gl::Compiler* compiler;
 	gl::RenderStyle renderStyle = gl::RenderStyle::Normal;
-	QQuaternion rotation;
+	bool initialized = false;
 	void initializeLighting();
-	gl::Compiler* compiler;
 };
--- a/src/libraries.cpp	Wed Jan 01 17:45:56 2020 +0200
+++ b/src/libraries.cpp	Sun Jan 19 02:54:48 2020 +0200
@@ -212,9 +212,8 @@
 		return LibraryManager::tr("Unofficial library");
 	case Library::WorkingLibrary:
 		return LibraryManager::tr("Working library");
-	default:
-		return "???";
 	}
+	return "???";
 }
 
 /**
--- a/src/main.h	Wed Jan 01 17:45:56 2020 +0200
+++ b/src/main.h	Sun Jan 19 02:54:48 2020 +0200
@@ -21,3 +21,8 @@
 		unsigned int value;
 	};
 }
+
+constexpr std::size_t operator""_z(const unsigned long long int x)
+{
+	return static_cast<std::size_t>(x);
+}
--- a/src/types/boundingbox.cpp	Wed Jan 01 17:45:56 2020 +0200
+++ b/src/types/boundingbox.cpp	Sun Jan 19 02:54:48 2020 +0200
@@ -39,24 +39,38 @@
  */
 double longestMeasure(const BoundingBox& box)
 {
-	double dx = box.minimum.x - box.maximum.x;
-	double dy = box.minimum.y - box.maximum.y;
-	double dz = box.minimum.z - box.maximum.z;
-	double size = std::max(std::max(dx, dy), dz);
-	return std::max(std::abs(size / 2.0), 1.0);
+	if (box != emptyBoundingBox)
+	{
+		double dx = box.minimum.x - box.maximum.x;
+		double dy = box.minimum.y - box.maximum.y;
+		double dz = box.minimum.z - box.maximum.z;
+		double size = std::max(std::max(dx, dy), dz);
+		return std::max(std::abs(size / 2.0), 1.0);
+	}
+	else
+	{
+		return 0.0;
+	}
 }
 
 
 /*
  * Yields the center of the bounding box.
  */
-Point3D center(const BoundingBox& box)
+Point3D boxCenter(const BoundingBox& box)
 {
-	return {
-		(box.minimum.x + box.maximum.x) / 2,
-		(box.minimum.y + box.maximum.y) / 2,
-		(box.minimum.z + box.maximum.z) / 2
-	};
+	if (box != emptyBoundingBox)
+	{
+		return {
+			(box.minimum.x + box.maximum.x) / 2,
+			(box.minimum.y + box.maximum.y) / 2,
+			(box.minimum.z + box.maximum.z) / 2
+		};
+	}
+	else
+	{
+		return origin;
+	}
 }
 
 /*
@@ -66,3 +80,13 @@
 {
 	return math::distance(box.minimum, box.maximum);
 }
+
+bool operator==(const BoundingBox &box_1, const BoundingBox &box_2)
+{
+	return box_1.minimum == box_2.minimum and box_1.maximum == box_2.maximum;
+}
+
+bool operator!=(const BoundingBox &box_1, const BoundingBox &box_2)
+{
+	return not (box_1 == box_2);
+}
--- a/src/types/boundingbox.h	Wed Jan 01 17:45:56 2020 +0200
+++ b/src/types/boundingbox.h	Sun Jan 19 02:54:48 2020 +0200
@@ -29,6 +29,9 @@
 };
 
 static constexpr BoundingBox emptyBoundingBox = {};
-Point3D center(const BoundingBox& box);
+Point3D boxCenter(const BoundingBox& box);
 double longestMeasure(const BoundingBox& box);
 double spaceDiagonal(const BoundingBox& box);
+
+bool operator==(const BoundingBox& box_1, const BoundingBox& box_2);
+bool operator!=(const BoundingBox& box_1, const BoundingBox& box_2);
--- a/src/vertex.h	Wed Jan 01 17:45:56 2020 +0200
+++ b/src/vertex.h	Sun Jan 19 02:54:48 2020 +0200
@@ -33,6 +33,8 @@
 	operator QVariant() const;
 };
 
+constexpr Point3D origin = {0, 0, 0};
+
 namespace math
 {
 	Point3D transform(const Point3D& point, const Matrix4x4& matrix);
@@ -63,3 +65,12 @@
 Point3D operator-(const Point3D& vertex);
 QDataStream& operator<<(QDataStream& out, const Point3D& vertex);
 QDataStream& operator>>(QDataStream& in, Point3D& vertex);
+
+/*
+ * Calls 'function' with the x, y and z coordinates of 'vertex'.
+ */
+template<typename Function>
+inline auto xyz(Function&& function, const Point3D& vertex)
+{
+	return function(vertex.x, vertex.y, vertex.z);
+}

mercurial