gldraw.cpp

changeset 104
6e29bb0e83c5
parent 103
b0a345196435
child 105
53f95a6e351d
--- a/gldraw.cpp	Sat Apr 13 02:11:54 2013 +0300
+++ b/gldraw.cpp	Sun Apr 14 03:54:40 2013 +0300
@@ -1,6 +1,6 @@
 /*
  *  LDForge: LDraw parts authoring CAD
- *  Copyright (C) 2013 Santeri `arezey` Piippo
+ *  Copyright (C) 2013 Santeri Piippo
  *  
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -25,9 +25,11 @@
 #include "gldraw.h"
 #include "bbox.h"
 #include "colors.h"
+#include "gui.h"
 
 static double g_faObjectOffset[3];
 static double g_StoredBBoxSize;
+static bool g_bPicking = false;
 
 cfg (str, gl_bgcolor, "#CCCCD9");
 cfg (str, gl_maincolor, "#707078");
@@ -35,18 +37,18 @@
 cfg (int, gl_linethickness, 2);
 cfg (bool, gl_colorbfc, true);
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 renderer::renderer (QWidget* parent) {
 	parent = parent; // shhh, GCC
 	fRotX = fRotY = fRotZ = 0.0f;
 	fZoom = 1.0f;
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 void renderer::initializeGL () {
 	glLoadIdentity();
 	glMatrixMode (GL_MODELVIEW);
@@ -73,9 +75,9 @@
 	compileObjects ();
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 void renderer::setMainColor () {
 	QColor col (gl_maincolor.value.chars());
 	
@@ -89,7 +91,7 @@
 		gl_maincolor_alpha);
 }
 
-// -----------------------------------------------------------------------------
+// ------------------------------------------------------------------------- //
 void renderer::setBackground () {
 	QColor col (gl_bgcolor.value.chars());
 	
@@ -103,14 +105,40 @@
 		1.0f);
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 static vector<short> g_daWarnedColors;
-void renderer::setObjectColor (LDObject* obj, bool bBackSide) {
+void renderer::setObjectColor (LDObject* obj) {
+	if (g_bPicking) {
+		// Make the color by the object's index color if we're picking, so we can
+		// make the index from the color we get from the picking results.
+		long i = obj->getIndex (g_CurrentFile);
+		
+		// If we couldn't find the index, this object must not be from this file,
+		// therefore it must be an object inlined from another file through a
+		// subfile reference. Use the reference's index.
+		if (i == -1)
+			i = obj->topLevelParent ()->getIndex (g_CurrentFile);
+		
+		// We should have the index now.
+		assert (i != -1);
+		
+		// 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;
+		double g = (i / 256) % 256;
+		double b = (i / (256 * 256)) % 256;
+		
+		glColor3f (r / 255.f, g / 255.f, b / 255.f);
+		return;
+	}
+	
 	if (obj->dColor == -1)
 		return;
 	
+#if 0
 	if (gl_colorbfc &&
 		obj->getType () != OBJ_Line &&
 		obj->getType () != OBJ_CondLine)
@@ -121,6 +149,7 @@
 			glColor4f (0.0f, 0.8f, 0.0f, 1.0f);
 		return;
 	}
+#endif
 	
 	if (obj->dColor == dMainColor) {
 		setMainColor ();
@@ -139,7 +168,7 @@
 			if (obj->dColor == i)
 				return;
 		
-		printf ("setObjectColor Unknown color %d!\n", obj->dColor);
+		printf ("%s: Unknown color %d!\n", __func__, obj->dColor);
 		g_daWarnedColors.push_back (obj->dColor);
 		return;
 	}
@@ -151,9 +180,9 @@
 		((double)col->qColor.alpha()) / 255.0f);
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 void renderer::hardRefresh () {
 	compileObjects ();
 	paintGL ();
@@ -162,9 +191,9 @@
 	glLineWidth (gl_linethickness);
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 void renderer::resizeGL (int w, int h) {
 	glViewport (0, 0, w, h);
 	glLoadIdentity ();
@@ -172,9 +201,9 @@
 	gluPerspective (45.0f, (double)w / (double)h, 0.1f, 100.0f);
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 void renderer::paintGL () {
 	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 	glMatrixMode (GL_MODELVIEW);
@@ -189,25 +218,17 @@
 		glRotatef (fRotY, 0.0f, 1.0f, 0.0f);
 		glRotatef (fRotZ, 0.0f, 0.0f, 1.0f);
 		
-		if (gl_colorbfc) {
-			glEnable (GL_CULL_FACE);
-			
-			glCullFace (GL_FRONT);
-			glCallList (uObjList);
-			
-			glCullFace (GL_BACK);
-			glCallList (uObjListBack);
-			
-			glDisable (GL_CULL_FACE);
-		} else
-			glCallList (uObjList);
+		for (GLuint uList : uaObjLists)
+			glCallList (uList);
 	glPopMatrix ();
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 void renderer::compileObjects () {
+	uaObjLists.clear ();
+	
 	g_faObjectOffset[0] = -(g_BBox.v0.x + g_BBox.v1.x) / 2;
 	g_faObjectOffset[1] = -(g_BBox.v0.y + g_BBox.v1.y) / 2;
 	g_faObjectOffset[2] = -(g_BBox.v0.z + g_BBox.v1.z) / 2;
@@ -219,32 +240,17 @@
 		return;
 	}
 	
-	GLuint* upaLists[2] = {
-		&uObjList,
-		&uObjListBack,
-	};
-	
-	for (uchar i = 0; i < 2; ++i) {
-		if (i && !gl_colorbfc)
-			continue;
-		
-		*upaLists[i] = glGenLists (1);
-		glNewList (*upaLists[i], GL_COMPILE);
-		
-		for (LDObject* obj : g_CurrentFile->objects)
-			compileOneObject (obj, i);
-		
-		glEndList ();
-	}
+	for (LDObject* obj : g_CurrentFile->objects) 
+		compileOneObject (obj);
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 template<class T> void renderer::compileSubObject (LDObject* obj,
-	const bool bBackSide, const GLenum eGLType, const short dVerts)
+	const GLenum eGLType, const short dVerts)
 {
-	setObjectColor (obj, bBackSide);
+	setObjectColor (obj);
 	T* newobj = static_cast<T*> (obj);
 	glBegin (eGLType);
 	
@@ -254,33 +260,33 @@
 	glEnd ();
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-void renderer::compileOneObject (LDObject* obj, bool bBackSide) {
-	if (!obj)
-		return;
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
+void renderer::compileOneObject (LDObject* obj) {
+	GLuint uList = glGenLists (1);
+	glNewList (uList, GL_COMPILE);
 	
 	switch (obj->getType ()) {
 	case OBJ_Line:
-		compileSubObject<LDLine> (obj, bBackSide, GL_LINES, 2);
+		compileSubObject<LDLine> (obj, GL_LINES, 2);
 		break;
 	
 	case OBJ_CondLine:
 		glLineStipple (1, 0x6666);
 		glEnable (GL_LINE_STIPPLE);
 		
-		compileSubObject<LDCondLine> (obj, bBackSide, GL_LINES, 2);
+		compileSubObject<LDCondLine> (obj, GL_LINES, 2);
 		
 		glDisable (GL_LINE_STIPPLE);
 		break;
 	
 	case OBJ_Triangle:
-		compileSubObject<LDTriangle> (obj, bBackSide, GL_TRIANGLES, 3);
+		compileSubObject<LDTriangle> (obj, GL_TRIANGLES, 3);
 		break;
 	
 	case OBJ_Quad:
-		compileSubObject<LDQuad> (obj, bBackSide, GL_QUADS, 4);
+		compileSubObject<LDQuad> (obj, GL_QUADS, 4);
 		break;
 	
 	case OBJ_Subfile:
@@ -290,7 +296,7 @@
 			vector<LDObject*> objs = ref->inlineContents (true, true);
 			
 			for (LDObject* obj : objs) {
-				compileOneObject (obj, bBackSide);
+				compileOneObject (obj);
 				delete obj;
 			}
 		}
@@ -333,11 +339,15 @@
 	default:
 		break;
 	}
+	
+	glEndList ();
+	uaObjLists.push_back (uList);
+	obj->uGLList = uList;
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 void renderer::compileVertex (vertex& vrt) {
 	glVertex3d (
 		(vrt.x + g_faObjectOffset[0]) / g_StoredBBoxSize,
@@ -345,9 +355,9 @@
 		-(vrt.z + g_faObjectOffset[2]) / g_StoredBBoxSize);
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 void renderer::clampAngle (double& fAngle) {
 	while (fAngle < 0)
 		fAngle += 360.0;
@@ -355,12 +365,31 @@
 		fAngle -= 360.0;
 }
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
+void renderer::mouseReleaseEvent (QMouseEvent* event) {
+	if ((qMouseButtons & Qt::LeftButton) && !(event->buttons() & Qt::LeftButton)) {
+		if (ulTotalMouseMove < 10)
+			pick (event->x(), event->y());
+		
+		ulTotalMouseMove = 0;
+	}
+}
+
+void renderer::mousePressEvent (QMouseEvent* event) {
+	qMouseButtons = event->buttons();
+	if (event->buttons() & Qt::LeftButton)
+		ulTotalMouseMove = 0;
+}
+
+// ========================================================================= //
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// ========================================================================= //
 void renderer::mouseMoveEvent (QMouseEvent *event) {
 	int dx = event->x () - lastPos.x ();
 	int dy = event->y () - lastPos.y ();
+	ulTotalMouseMove += abs (dx) + abs (dy);
 	
 	if (event->buttons () & Qt::LeftButton) {
 		fRotX = fRotX + (dy);
@@ -383,4 +412,39 @@
 	
 	lastPos = event->pos();
 	updateGL ();
+}
+
+// ========================================================================= //
+void renderer::pick (uint mx, uint my) {
+	glDisable (GL_DITHER);
+	glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
+	
+	g_bPicking = true;
+	
+	compileObjects ();
+	paintGL ();
+	
+	GLubyte pixel[3];
+	GLint viewport[4];
+	glGetIntegerv (GL_VIEWPORT, viewport);
+	glReadPixels (mx, viewport[3] - my, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*> (pixel));
+	
+	if (pixel[0] != 255 || pixel[1] != 255 || pixel[2] != 255) {
+		ulong idx = pixel[0] + (pixel[1] * 256) + (pixel[2] * 256 * 256);
+		printf ("idx: %lu\n", idx);
+		
+		LDObject* obj = g_CurrentFile->object (idx);
+		
+		g_ForgeWindow->paSelection.clear ();
+		g_ForgeWindow->paSelection.push_back (obj);
+	}
+	
+	g_bPicking = false;
+	glEnable (GL_DITHER);
+	
+	setBackground ();
+	compileObjects ();
+	paintGL ();
+	
+	g_ForgeWindow->updateSelection ();
 }
\ No newline at end of file

mercurial