BIG COMMIT -- Moving from display lists to VAOs.

Fri, 09 Aug 2013 03:09:08 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Fri, 09 Aug 2013 03:09:08 +0300
changeset 441
a958f6925088
parent 440
ce2009d50c61
child 442
4852e815df29

BIG COMMIT -- Moving from display lists to VAOs.

src/gldata.cpp file | annotate | diff | comparison | revisions
src/gldata.h file | annotate | diff | comparison | revisions
src/gldraw.cpp file | annotate | diff | comparison | revisions
src/gldraw.h file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gldata.cpp	Fri Aug 09 03:09:08 2013 +0300
@@ -0,0 +1,341 @@
+#include "gldata.h"
+#include "ldtypes.h"
+#include "colors.h"
+#include "file.h"
+#include "misc.h"
+#include "gldraw.h"
+
+cfg (bool, gl_blackedges, true);
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+VertexCompiler::Array::Array() :
+	m_data (null)
+{
+	clear();
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+VertexCompiler::Array::~Array() {
+	delete[] m_data;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void VertexCompiler::Array::clear() {
+	delete[] m_data;
+	
+	m_data = new DataType[64];
+	m_size = 64;
+	m_ptr = &m_data[0];
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void VertexCompiler::Array::resizeToFit (
+	VertexCompiler::Array::SizeType newSize
+) {
+	if (allocatedSize() >= newSize)
+		return;
+	
+	int32 cachedWriteSize = writtenSize();
+	
+	// Add some lee-way space to reduce the amount of resizing.
+	newSize += 256;
+	
+	const SizeType oldSize = allocatedSize();
+	
+	// We need to back up the data first
+	DataType* copy = new DataType[oldSize];
+	memcpy (copy, m_data, oldSize);
+	
+	// Re-create the buffer
+	delete[] m_data;
+	m_data = new DataType[newSize];
+	m_size = newSize;
+	m_ptr = &m_data[cachedWriteSize / sizeof (DataType)];
+	
+	// Copy the data back
+	memcpy (m_data, copy, oldSize);
+	delete[] copy;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+const VertexCompiler::Array::DataType* VertexCompiler::Array::data() const {
+	return m_data;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+const VertexCompiler::Array::SizeType& VertexCompiler::Array::allocatedSize() const {
+	return m_size;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+VertexCompiler::Array::SizeType VertexCompiler::Array::writtenSize() const {
+	return (m_ptr - m_data) * sizeof (DataType);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void VertexCompiler::Array::write (
+	VertexCompiler::Array::DataType f
+) {
+	// Ensure there's enoughspace for the new float
+	resizeToFit (writtenSize() + sizeof f);
+	
+	// Write the float in
+	*m_ptr++ = f;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void VertexCompiler::Array::merge (
+	Array* other
+) {
+	// Ensure there's room for both buffers
+	resizeToFit (writtenSize() + other->writtenSize());
+	
+	memcpy (m_ptr, other->data(), other->writtenSize());
+	m_ptr += other->writtenSize() / sizeof (DataType);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+VertexCompiler::VertexCompiler() :
+	m_file (null)
+{
+	for (int i = 0; i < NumArrays; ++i) {
+		m_mainArrays[i] = new Array;
+		m_changed[i] = false;
+	}
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+VertexCompiler::~VertexCompiler() {
+	for (Array* array : m_mainArrays)
+		delete array;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void VertexCompiler::compileVertex (
+	vertex v,
+	QColor col,
+	Array* array
+) {
+	VertexCompiler::Vertex glvertex;
+	glvertex.x = v.x();
+	glvertex.y = v.y();
+	glvertex.z = v.z();
+	glvertex.color =
+		(col.red()   & 0xFF) << 0x00 |
+		(col.green() & 0xFF) << 0x08 |
+		(col.blue()  & 0xFF) << 0x10 |
+		(col.alpha() & 0xFF) << 0x18;
+	
+	array->write (glvertex);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void VertexCompiler::compilePolygon (
+	LDObject* obj,
+	VertexCompiler::Array** arrays
+) {
+	LDObject::Type objtype = obj->getType();
+	bool isline = (objtype == LDObject::Line || objtype == LDObject::CondLine);
+	int verts = isline ? 2 : obj->vertices();
+	
+	for (int i = 0; i < verts; ++i) {
+		compileVertex (obj->getVertex (i), getObjectColor (obj, Normal),
+			arrays[isline ? EdgeArray : MainArray]);
+	}
+	
+	// For non-lines, compile BFC data
+	if (!isline) {
+		QColor col = getObjectColor (obj, BFCFront);
+		for (int i = 0; i < verts; ++i)
+			compileVertex (obj->getVertex(i), col, arrays[BFCArray]);
+		
+		col = getObjectColor (obj, BFCBack);
+		for (int i = verts - 1; i >= 0; --i)
+			compileVertex (obj->getVertex(i), col, arrays[BFCArray]);
+	}
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void VertexCompiler::compileObject (
+	LDObject* obj
+) {
+	if (m_objArrays.find (obj) == m_objArrays.end()) {
+		m_objArrays[obj] = new Array*[NumArrays];
+		
+		for (int i = 0; i < NumArrays; ++i)
+			m_objArrays[obj][i] = new Array;
+	} else {
+		for (int i = 0; i < NumArrays; ++i)
+			m_objArrays[obj][i]->clear();
+	}
+	
+	switch (obj->getType()) {
+	case LDObject::Triangle:
+		compilePolygon (obj, m_objArrays[obj]);
+		m_changed[MainArray] = true;
+		break;
+	
+	case LDObject::Quad:
+		for (LDTriangleObject* triangle : static_cast<LDQuadObject*> (obj)->splitToTriangles())
+			compilePolygon (triangle, m_objArrays[obj]);
+		m_changed[MainArray] = true;
+		break;
+	
+	case LDObject::Line:
+		compilePolygon (obj, m_objArrays[obj]);
+		break;
+	
+	default:
+		break;
+	}
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void VertexCompiler::compileFile() {
+	for (LDObject* obj : *m_file)
+		compileObject (obj);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void VertexCompiler::forgetObject (
+	LDObject* obj
+) {
+	for (int i = 0; i < NumArrays; ++i)
+		delete m_objArrays[obj][i];
+	
+	delete m_objArrays[obj];
+	m_objArrays.remove (obj);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void VertexCompiler::setFile (
+	LDFile* file
+) {
+	m_file = file;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+VertexCompiler::Array* VertexCompiler::getMergedBuffer (
+	VertexCompiler::MergedArrayType type
+) {
+	assert (type < NumArrays);
+	
+	if (m_changed) {
+		m_changed[type] = false;
+		m_mainArrays[type]->clear();
+		
+		for (LDObject* obj : *m_file) {
+			auto it = m_objArrays.find (obj);
+			
+			if (it != m_objArrays.end())
+				m_mainArrays[type]->merge ((*it)[type]);
+		}
+	}
+	
+	return m_mainArrays[type];
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+static List<short> g_warnedColors;
+QColor VertexCompiler::getObjectColor (
+	LDObject* obj,
+	ColorType colotype
+) const {
+	QColor qcol;
+	
+	if (!obj->isColored())
+		return QColor();
+	
+/*
+	if (list == GL::PickList) {
+		// Make the color by the object's ID if we're picking, so we can make the
+		// ID again from the color we get from the picking results. Be sure to use
+		// the top level parent's index since we want a subfile's children point
+		// to the subfile itself.
+		long i = obj->topLevelParent()->id();
+		
+		// Calculate a color based from this index. This method caters for
+		// 16777216 objects. I don't think that'll be exceeded anytime soon. :)
+		// ATM biggest is 53588.dat with 12600 lines.
+		double r = (i / (256 * 256)) % 256,
+			g = (i / 256) % 256,
+			b = i % 256;
+		
+		qglColor (QColor (r, g, b));
+		return;
+	}
+*/
+	
+	if ((colotype == BFCFront || colotype == BFCBack) &&
+		obj->getType() != LDObject::Line &&
+		obj->getType() != LDObject::CondLine) {
+		
+		if (colotype == BFCFront)
+			qcol = QColor (40, 192, 0);
+		else
+			qcol = QColor (224, 0, 0);
+	} else {
+		if (obj->color() == maincolor)
+			qcol = GL::getMainColor();
+		else {
+			LDColor* col = getColor (obj->color());
+			
+			if (col)
+				qcol = col->faceColor;
+		}
+		
+		if (obj->color() == edgecolor) {
+			qcol = QColor (32, 32, 32); // luma (m_bgcolor) < 40 ? QColor (64, 64, 64) : Qt::black;
+			LDColor* col;
+			
+			if (!gl_blackedges && obj->parent() && (col = getColor (obj->parent()->color())))
+				qcol = col->edgeColor;
+		}
+		
+		if (qcol.isValid() == false) {
+			// The color was unknown. Use main color to make the object at least
+			// not appear pitch-black.
+			if (obj->color() != edgecolor)
+				qcol = GL::getMainColor();
+			
+			// Warn about the unknown colors, but only once.
+			for (short i : g_warnedColors)
+				if (obj->color() == i)
+					return Qt::black;
+			
+			print ("%1: Unknown color %2!\n", __func__, obj->color());
+			g_warnedColors << obj->color();
+			return Qt::black;
+		}
+	}
+	
+	if (obj->topLevelParent()->selected()) {
+		// Brighten it up for the select list.
+		const uchar add = 51;
+		
+		qcol.setRed (min (qcol.red() + add, 255));
+		qcol.setGreen (min (qcol.green() + add, 255));
+		qcol.setBlue (min (qcol.blue() + add, 255));
+	}
+	
+	return qcol;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gldata.h	Fri Aug 09 03:09:08 2013 +0300
@@ -0,0 +1,74 @@
+#ifndef LDFORGE_GLDATA_H
+#define LDFORGE_GLDATA_H
+
+#include "types.h"
+#include <QMap>
+
+class QColor;
+class LDFile;
+
+class VertexCompiler {
+public:
+	enum ColorType {
+		Normal,
+		BFCFront,
+		BFCBack,
+	};
+	
+	enum MergedArrayType {
+		MainArray,
+		EdgeArray,
+		BFCArray,
+		NumArrays
+	};
+	
+	struct Vertex {
+		float x, y, z;
+		uint32 color;
+		float pad[4];
+	};
+	
+	class Array {
+	public:
+		typedef int32 SizeType;
+		typedef Vertex DataType;
+		
+		Array();
+		Array (const Array& other) = delete;
+		~Array();
+		
+		void clear();
+		void merge (Array* other);
+		void resizeToFit (SizeType newSize);
+		const SizeType& allocatedSize() const;
+		SizeType writtenSize() const;
+		const DataType* data() const;
+		void write (DataType f);
+		Array& operator= (const Array& other) = delete;
+		
+	private:
+		DataType* m_data;
+		DataType* m_ptr;
+		SizeType m_size;
+	};
+	
+	VertexCompiler();
+	~VertexCompiler();
+	void setFile (LDFile* file);
+	void compileFile();
+	void compileObject (LDObject* obj);
+	void forgetObject (LDObject* obj);
+	Array* getMergedBuffer (MergedArrayType type);
+	QColor getObjectColor (LDObject* obj, ColorType list) const;
+	
+private:
+	void compilePolygon (LDObject* obj, Array** arrays);
+	void compileVertex (vertex v, QColor col, VertexCompiler::Array* array);
+	
+	QMap<LDObject*, Array**> m_objArrays;
+	Array* m_mainArrays[NumArrays];
+	LDFile* m_file;
+	bool m_changed[NumArrays];
+};
+
+#endif // LDFORGE_GLDATA_H
\ No newline at end of file
--- a/src/gldraw.cpp	Wed Aug 07 20:50:53 2013 +0300
+++ b/src/gldraw.cpp	Fri Aug 09 03:09:08 2013 +0300
@@ -21,10 +21,9 @@
 #include <QMouseEvent>
 #include <QContextMenuEvent>
 #include <QInputDialog>
-#include <qtooltip.h>
+#include <QToolTip>
 #include <QTimer>
 #include <GL/glu.h>
-
 #include "common.h"
 #include "config.h"
 #include "file.h"
@@ -36,6 +35,8 @@
 #include "dialogs.h"
 #include "addObjectDialog.h"
 #include "messagelog.h"
+#include "gldata.h"
+#include "build/moc_gldraw.cpp"
 
 static const struct staticCameraMeta {
 	const char glrotate[3];
@@ -56,19 +57,18 @@
 cfg (int, gl_linethickness, 2);
 cfg (bool, gl_colorbfc, true);
 cfg (int, gl_camera, GLRenderer::Free);
-cfg (bool, gl_blackedges, true);
 cfg (bool, gl_axes, false);
 cfg (bool, gl_wireframe, false);
 
 // argh
 const char* g_CameraNames[7] = {
-	QT_TRANSLATE_NOOP ("GLRenderer",  "Top"),
-	QT_TRANSLATE_NOOP ("GLRenderer",  "Front"),
-	QT_TRANSLATE_NOOP ("GLRenderer",  "Left"),
-	QT_TRANSLATE_NOOP ("GLRenderer",  "Bottom"),
-	QT_TRANSLATE_NOOP ("GLRenderer",  "Back"),
-	QT_TRANSLATE_NOOP ("GLRenderer",  "Right"),
-	QT_TRANSLATE_NOOP ("GLRenderer",  "Free")
+	QT_TRANSLATE_NOOP ("GLRenderer", "Top"),
+	QT_TRANSLATE_NOOP ("GLRenderer", "Front"),
+	QT_TRANSLATE_NOOP ("GLRenderer", "Left"),
+	QT_TRANSLATE_NOOP ("GLRenderer", "Bottom"),
+	QT_TRANSLATE_NOOP ("GLRenderer", "Back"),
+	QT_TRANSLATE_NOOP ("GLRenderer", "Right"),
+	QT_TRANSLATE_NOOP ("GLRenderer", "Free")
 };
 
 const GL::Camera g_Cameras[7] = {
@@ -86,10 +86,13 @@
 	const vertex vert;
 } g_GLAxes[3] = {
 	{ QColor (255,   0,   0), vertex (10000, 0, 0) },
-	{ QColor (80, 192,   0), vertex (0, 10000, 0) },
+	{ QColor (80,  192,   0), vertex (0, 10000, 0) },
 	{ QColor (0,   160, 192), vertex (0, 0, 10000) },
 };
-	
+
+#warning this should be a member
+static VertexCompiler g_vertexCompiler;
+
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
@@ -190,7 +193,8 @@
 	setAutoFillBackground (false);
 	setMouseTracking (true);
 	setFocusPolicy (Qt::WheelFocus);
-	compileAllObjects();
+	
+	g_vertexCompiler.compileFile();
 }
 
 // =============================================================================
@@ -223,98 +227,6 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-static List<short> g_warnedColors;
-void GLRenderer::setObjectColor (LDObject* obj, const ListType list) {
-	QColor qcol;
-	
-	if (!obj->isColored())
-		return;
-	
-	if (list == GL::PickList) {
-		// Make the color by the object's ID if we're picking, so we can make the
-		// ID again from the color we get from the picking results. Be sure to use
-		// the top level parent's index since we want a subfile's children point
-		// to the subfile itself.
-		long i = obj->topLevelParent()->id();
-		
-		// Calculate a color based from this index. This method caters for
-		// 16777216 objects. I don't think that'll be exceeded anytime soon. :)
-		// ATM biggest is 53588.dat with 12600 lines.
-		double r = (i / (256 * 256)) % 256,
-			g = (i / 256) % 256,
-			b = i % 256;
-		
-		qglColor (QColor (r, g, b));
-		return;
-	}
-	
-	if ((list == BFCFrontList || list == BFCBackList) &&
-		obj->getType() != LDObject::Line &&
-		obj->getType() != LDObject::CondLine) {
-		
-		if (list == GL::BFCFrontList)
-			qcol = QColor (40, 192, 0);
-		else
-			qcol = QColor (224, 0, 0);
-	} else {
-		if (obj->color() == maincolor)
-			qcol = getMainColor();
-		else {
-			LDColor* col = getColor (obj->color());
-			
-			if (col)
-				qcol = col->faceColor;
-		}
-		
-		if (obj->color() == edgecolor) {
-			qcol = luma (m_bgcolor) < 40 ? QColor (64, 64, 64) : Qt::black;
-			LDColor* col;
-			
-			if (!gl_blackedges && obj->parent() && (col = getColor (obj->parent()->color())))
-				qcol = col->edgeColor;
-		}
-		
-		if (qcol.isValid() == false) {
-			// The color was unknown. Use main color to make the object at least
-			// not appear pitch-black.
-			if (obj->color() != edgecolor)
-				qcol = getMainColor();
-			
-			// Warn about the unknown colors, but only once.
-			for (short i : g_warnedColors)
-				if (obj->color() == i)
-					return;
-			
-			printf ("%s: Unknown color %d!\n", __func__, obj->color());
-			g_warnedColors << obj->color();
-			return;
-		}
-	}
-	
-	long r = qcol.red(),
-		g = qcol.green(),
-		b = qcol.blue(),
-		a = qcol.alpha();
-	
-	if (obj->topLevelParent()->selected()) {
-		// Brighten it up for the select list.
-		const uchar add = 51;
-		
-		r = min (r + add, 255l);
-		g = min (g + add, 255l);
-		b = min (b + add, 255l);
-	}
-	
-	glColor4f (
-		((double) r) / 255.0f,
-		((double) g) / 255.0f,
-		((double) b) / 255.0f,
-		((double) a) / 255.0f);
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
 void GLRenderer::refresh() {
 	update();
 	swapBuffers();
@@ -322,7 +234,7 @@
 
 // =============================================================================
 void GLRenderer::hardRefresh() {
-	compileAllObjects();
+	g_vertexCompiler.compileFile();
 	refresh();
 	
 	glLineWidth (gl_linethickness);
@@ -385,32 +297,28 @@
 	
 	const GL::ListType list = (!drawOnly() && m_picking) ? PickList : NormalList;
 	
-	if (gl_colorbfc && !m_picking && !drawOnly()) {
+	// Draw the polygons
+	glEnableClientState (GL_VERTEX_ARRAY);
+	glEnableClientState (GL_COLOR_ARRAY);
+	glDisableClientState (GL_NORMAL_ARRAY);
+	
+	if (gl_colorbfc) {
 		glEnable (GL_CULL_FACE);
-		
-		for (LDObject* obj : file()->objs()) {
-			if (obj->hidden())
-				continue;
-			
-			glCullFace (GL_BACK);
-			glCallList (obj->glLists[BFCFrontList]);
-			
-			glCullFace (GL_FRONT);
-			glCallList (obj->glLists[BFCBackList]);
-		}
-		
+		glCullFace (GL_CCW);
+	} else
 		glDisable (GL_CULL_FACE);
-	} else {
-		for (LDObject* obj : file()->objs()) {
-			if (obj->hidden())
-				continue;
-			
-			glCallList (obj->glLists[list]);
-		}
-	}
 	
-	if (gl_axes && !m_picking && !drawOnly())
-		glCallList (m_axeslist);
+	VertexCompiler::Array* array = g_vertexCompiler.getMergedBuffer (
+		(gl_colorbfc) ? VertexCompiler::BFCArray : VertexCompiler::MainArray);
+	glVertexPointer (3, GL_FLOAT, sizeof (VertexCompiler::Vertex), &array->data()[0].x);
+	glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (VertexCompiler::Vertex), &array->data()[0].color);
+	glDrawArrays (GL_TRIANGLES, 0, array->writtenSize() / sizeof (VertexCompiler::Vertex));
+	
+	// Draw edge lines
+	array = g_vertexCompiler.getMergedBuffer (VertexCompiler::EdgeArray);
+	glVertexPointer (3, GL_FLOAT, sizeof (VertexCompiler::Vertex), &array->data()[0].x);
+	glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (VertexCompiler::Vertex), &array->data()[0].color);
+	glDrawArrays (GL_LINES, 0, array->writtenSize() / sizeof (VertexCompiler::Vertex));
 	
 	glPopMatrix();
 	glMatrixMode (GL_MODELVIEW);
@@ -664,114 +572,7 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 void GLRenderer::compileAllObjects() {
-	if (!file())
-		return;
-	
-	m_knownVerts.clear();
-	
-	for (LDObject* obj : file()->objs())
-		compileObject (obj);
-	
-	// Compile axes
-	glDeleteLists (m_axeslist, 1);
-	m_axeslist = glGenLists (1);
-	glNewList (m_axeslist, GL_COMPILE);
-	glBegin (GL_LINES);
-	
-	for (const GLAxis& ax : g_GLAxes) {
-		qglColor (ax.col);
-		compileVertex (ax.vert);
-		compileVertex (-ax.vert);
-	}
-	
-	glEnd();
-	glEndList();
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-static bool g_glInvert = false;
-
-void GLRenderer::compileSubObject (LDObject* obj, const GLenum gltype) {
-	glBegin (gltype);
-	
-	const short numverts = (obj->getType() != LDObject::CondLine) ? obj->vertices() : 2;
-	
-	if (g_glInvert == false)
-		for (short i = 0; i < numverts; ++i)
-			compileVertex (obj->m_coords[i]);
-	else
-		for (short i = numverts - 1; i >= 0; --i)
-			compileVertex (obj->m_coords[i]);
-	
-	glEnd();
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void GLRenderer::compileList (LDObject* obj, const GLRenderer::ListType list) {
-	setObjectColor (obj, list);
-	
-	switch (obj->getType()) {
-	case LDObject::Line:
-		compileSubObject (obj, GL_LINES);
-		break;
-	
-	case LDObject::CondLine:
-		// Draw conditional lines with a dash pattern - however, use a full
-		// line when drawing a pick list to make selecting them easier.
-		if (list != GL::PickList) {
-			glLineStipple (1, 0x6666);
-			glEnable (GL_LINE_STIPPLE);
-		}
-		
-		compileSubObject (obj, GL_LINES);
-		
-		glDisable (GL_LINE_STIPPLE);
-		break;
-	
-	case LDObject::Triangle:
-		compileSubObject (obj, GL_TRIANGLES);
-		break;
-	
-	case LDObject::Quad:
-		compileSubObject (obj, GL_QUADS);
-		break;
-	
-	case LDObject::Subfile: {
-			LDSubfileObject* ref = static_cast<LDSubfileObject*> (obj);
-			List<LDObject*> objs = ref->inlineContents (true, true);
-			
-			bool oldinvert = g_glInvert;
-			
-			if (ref->transform().determinant() < 0)
-				g_glInvert = !g_glInvert;
-			
-			LDObject* prev = ref->prev();
-			if (prev && prev->getType() == LDObject::BFC && static_cast<LDBFCObject*> (prev)->type == LDBFCObject::InvertNext)
-				g_glInvert = !g_glInvert;
-			
-			for (LDObject* obj : objs) {
-				compileList (obj, list);
-				delete obj;
-			}
-			
-			g_glInvert = oldinvert;
-		}
-		break;
-	
-	default:
-		break;
-	}
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void GLRenderer::compileVertex (const vertex& vrt) {
-	glVertex3d (vrt[X], -vrt[Y], -vrt[Z]);
+	g_vertexCompiler.compileFile();
 }
 
 // =============================================================================
@@ -1184,6 +985,7 @@
 
 SET_ACCESSOR (LDFile*, GLRenderer::setFile) {
 	m_file = val;
+	g_vertexCompiler.setFile (val);
 	
 	if (val != null)
 		overlaysFromObjects();
@@ -1270,26 +1072,7 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 void GLRenderer::compileObject (LDObject* obj) {
-	deleteLists (obj);
-	
-	for (const GL::ListType listType : g_glListTypes) {
-		if (drawOnly() && listType != GL::NormalList)
-			continue;
-		
-		GLuint list = glGenLists (1);
-		glNewList (list, GL_COMPILE);
-		
-		obj->glLists[listType] = list;
-		compileList (obj, listType);
-		
-		glEndList();
-	}
-	
-	// Mark in known vertices of this object
-	List<vertex> verts = getVertices (obj);
-	m_knownVerts << verts;
-	m_knownVerts.makeUnique();
-	
+	g_vertexCompiler.compileObject (obj);
 	obj->m_glinit = true;
 }
 
@@ -1658,6 +1441,4 @@
 	
 	if (g_win->R() == this)
 		g_win->refresh();
-}
-
-#include "build/moc_gldraw.cpp"
\ No newline at end of file
+}
\ No newline at end of file
--- a/src/gldraw.h	Wed Aug 07 20:50:53 2013 +0300
+++ b/src/gldraw.h	Fri Aug 09 03:09:08 2013 +0300
@@ -79,7 +79,7 @@
 	double         depthValue() const;
 	void           drawGLScene();
 	void           endDraw (bool accept);
-	QColor         getMainColor();
+	static QColor  getMainColor();
 	overlayMeta&   getOverlay (int newcam);
 	void           hardRefresh();
 	void           initGLData();
@@ -145,15 +145,11 @@
 	void           addDrawnVertex (vertex m_hoverpos);
 	void           calcCameraIcons();                                      // Compute geometry for camera icons
 	void           clampAngle (double& angle) const;                       // Clamps an angle to [0, 360]
-	void           compileList (LDObject* obj, const ListType list);       // Compile one of the lists of an object
-	void           compileSubObject (LDObject* obj, const GLenum gltype);  // Sub-routine for object compiling
-	void           compileVertex (const vertex& vrt);                      // Compile a single vertex to a list
 	vertex         coordconv2_3 (const QPoint& pos2d, bool snap) const;    // Convert a 2D point to a 3D point
 	QPoint         coordconv3_2 (const vertex& pos3d) const;               // Convert a 3D point to a 2D point
 	LDOverlayObject* findOverlayObject (Camera cam);
 	void           updateRectVerts();
 	void           pick (uint mouseX, uint mouseY);                        // Perform object selection
-	void           setObjectColor (LDObject* obj, const ListType list);    // Set the color to an object list
 	
 private slots:
 	void           slot_toolTipTimer();

mercurial