src/glRenderer.h

changeset 706
d79083b9f74d
parent 655
b376645315ab
child 718
a2cbef633673
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/glRenderer.h	Sat Mar 29 05:38:03 2014 +0200
@@ -0,0 +1,333 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013, 2014 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
+ *  the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include <QGLWidget>
+#include "main.h"
+#include "macros.h"
+#include "ldObject.h"
+#include "ldDocument.h"
+#include "glShared.h"
+
+class GLCompiler;
+class MessageManager;
+class QDialogButtonBox;
+class RadioGroup;
+class QDoubleSpinBox;
+class QSpinBox;
+class QLineEdit;
+class QTimer;
+
+enum EditMode
+{
+	ESelectMode,
+	EDrawMode,
+	ECircleMode,
+};
+
+// Meta for overlays
+struct LDGLOverlay
+{
+	Vertex			v0,
+					v1;
+	int				ox,
+					oy;
+	double			lw,
+					lh;
+	QString			fname;
+	QImage*			img;
+	bool			invalid;
+};
+
+struct LDFixedCameraInfo
+{
+	const char		glrotate[3];
+	const Axis		axisX,
+					axisY;
+	const bool		negX,
+					negY;
+};
+
+// =============================================================================
+// Document-specific data
+//
+struct LDGLData
+{
+	double			rotX,
+					rotY,
+					rotZ,
+					panX[7],
+					panY[7],
+					zoom[7];
+	double			depthValues[6];
+	LDGLOverlay		overlays[6];
+	bool			init;
+
+	LDGLData()
+	{
+		for (int i = 0; i < 7; ++i)
+		{
+			if (i < 6)
+			{
+				overlays[i].img = null;
+				overlays[i].invalid = false;
+				depthValues[i] = 0.0f;
+			}
+
+			zoom[i] = 30.0;
+			panX[i] = 0.0;
+			panY[i] = 0.0;
+		}
+
+		rotX = 0;
+		rotY = 0;
+		rotZ = 0;
+		init = false;
+	}
+};
+
+// =============================================================================
+// The main renderer object, draws the brick on the screen, manages the camera
+// and selection picking. The instance of GLRenderer is accessible as
+// g_win->R()
+//
+class GLRenderer : public QGLWidget
+{
+	public:
+		enum EFixedCamera
+		{
+			ETopCamera,
+			EFrontCamera,
+			ELeftCamera,
+			EBottomCamera,
+			EBackCamera,
+			ERightCamera,
+			EFreeCamera
+		};
+
+		enum ListType
+		{
+			NormalList,
+			PickList,
+			BFCFrontList,
+			BFCBackList
+		};
+
+		// CameraIcon::img is a heap-allocated QPixmap because otherwise it gets
+		// initialized before program gets to main() and constructs a QApplication
+		// and Qt doesn't like that.
+		struct CameraIcon
+		{
+			QPixmap*		img;
+			QRect			srcRect,
+							destRect,
+							selRect;
+			EFixedCamera	cam;
+		};
+
+		Q_OBJECT
+		PROPERTY (public,	bool,				isDrawOnly,	setDrawOnly,	STOCK_WRITE)
+		PROPERTY (public,	MessageManager*,	messageLog, setMessageLog,	STOCK_WRITE)
+		PROPERTY (private,	bool,				isPicking,	setPicking,		STOCK_WRITE)
+		PROPERTY (public,	LDDocument*,		document,	setDocument,	CUSTOM_WRITE)
+		PROPERTY (public,	EditMode,			editMode,	setEditMode,	CUSTOM_WRITE)
+		PROPERTY (private,	GLCompiler*,		compiler,	setCompiler,	STOCK_WRITE)
+
+	public:
+		GLRenderer (QWidget* parent = null);
+		~GLRenderer();
+
+		inline EFixedCamera camera() const
+		{
+			return m_camera;
+		}
+
+		void           clearOverlay();
+		void           compileObject (LDObject* obj);
+		void           drawGLScene();
+		void           endDraw (bool accept);
+		void           forgetObject (LDObject* obj);
+		Axis           getCameraAxis (bool y, EFixedCamera camid = (EFixedCamera) - 1);
+		const char*    getCameraName() const;
+		double         getDepthValue() const;
+		LDGLOverlay&   getOverlay (int newcam);
+		uchar*         getScreencap (int& w, int& h);
+		void           hardRefresh();
+		void           initGLData();
+		void           initOverlaysFromObjects();
+		void           refresh();
+		void           resetAngles();
+		void           resetAllAngles();
+		void           setBackground();
+		void           setCamera (const EFixedCamera cam);
+		void           setDepthValue (double depth);
+		bool           setupOverlay (EFixedCamera cam, QString file, int x, int y, int w, int h);
+		void           updateOverlayObjects();
+		void           zoomNotch (bool inward);
+		void           zoomToFit();
+		void           zoomAllToFit();
+
+		static void    deleteLists (LDObject* obj);
+		static QColor  getMainColor();
+
+	protected:
+		void           contextMenuEvent (QContextMenuEvent* ev);
+		void           initializeGL();
+		void           keyPressEvent (QKeyEvent* ev);
+		void           keyReleaseEvent (QKeyEvent* ev);
+		void           leaveEvent (QEvent* ev);
+		void           mouseDoubleClickEvent (QMouseEvent* ev);
+		void           mousePressEvent (QMouseEvent* ev);
+		void           mouseMoveEvent (QMouseEvent* ev);
+		void           mouseReleaseEvent (QMouseEvent* ev);
+		void           paintEvent (QPaintEvent* ev);
+		void           resizeGL (int w, int h);
+		void           wheelEvent (QWheelEvent* ev);
+
+	private:
+		CameraIcon					m_cameraIcons[7];
+		QTimer*						m_toolTipTimer;
+		Qt::MouseButtons			m_lastButtons;
+		Qt::KeyboardModifiers		m_keymods;
+		Vertex						m_hoverpos;
+		double						m_virtWidth,
+									m_virtHeight;
+		bool						m_darkbg,
+									m_rangepick,
+									m_addpick,
+									m_drawToolTip,
+									m_screencap,
+									m_panning;
+		QPoint						m_pos,
+									m_globalpos,
+									m_rangeStart;
+		QPen						m_thickBorderPen,
+									m_thinBorderPen;
+		EFixedCamera				m_camera,
+									m_toolTipCamera;
+		GLuint						m_axeslist;
+		int							m_width,
+									m_height,
+									m_totalmove;
+		QList<Vertex>				m_drawedVerts;
+		bool						m_rectdraw;
+		Vertex						m_rectverts[4];
+		QColor						m_bgcolor;
+		QList<Vertex>				m_knownVerts;
+
+		void           addDrawnVertex (Vertex m_hoverpos);
+		LDOverlay*     findOverlayObject (EFixedCamera cam);
+		void           updateRectVerts();
+		void           getRelativeAxes (Axis& relX, Axis& relY) const;
+		Matrix         getCircleDrawMatrix (double scale);
+		void           drawBlip (QPainter& paint, QPoint pos) const;
+
+		// Compute geometry for camera icons
+		void           calcCameraIcons();
+
+		// How large is the circle we're drawing right now?
+		double         getCircleDrawDist (int pos) const;
+
+		// Clamps an angle to [0, 360]
+		void           clampAngle (double& angle) const;
+
+		// Compile one of the lists of an object
+		void           compileList (LDObject* obj, const ListType list);
+
+		// Sub-routine for object compiling
+		void           compileSubObject (LDObject* obj, const GLenum gltype);
+
+		// Compile a single vertex to a list
+		void           compileVertex (const Vertex& vrt);
+
+		// Convert a 2D point to a 3D point
+		Vertex         coordconv2_3 (const QPoint& pos2d, bool snap) const;
+
+		// Draw a VBO array
+		void           drawVBOs (EVBOSurface surface, EVBOComplement colors, GLenum type);
+
+		// Determine which color to draw text with
+		QColor         getTextPen() const;
+
+		// Convert a 3D point to a 2D point
+		QPoint         coordconv3_2 (const Vertex& pos3d) const;
+
+		// Perform object selection
+		void           pick (int mouseX, int mouseY);
+
+		// Set the color to an object list
+		void           setObjectColor (LDObject* obj, const ListType list);
+
+		LDGLData& currentDocumentData() const
+		{
+			return *document()->getGLData();
+		}
+
+		// Get a rotation value
+		inline double& rot (Axis ax)
+		{
+			return
+				(ax == X) ? currentDocumentData().rotX :
+				(ax == Y) ? currentDocumentData().rotY :
+				            currentDocumentData().rotZ;
+		}
+
+		// Get a panning value
+		inline double& pan (Axis ax)
+		{
+			return (ax == X) ? currentDocumentData().panX[camera()] :
+				currentDocumentData().panY[camera()];
+		}
+
+		// Same except const (can be used in const methods)
+		inline const double& pan (Axis ax) const
+		{
+			return (ax == X) ? currentDocumentData().panX[camera()] :
+				currentDocumentData().panY[camera()];
+		}
+
+		// Get the zoom value
+		inline double& zoom()
+		{
+			return currentDocumentData().zoom[camera()];
+		}
+
+		template<typename... Args>
+		inline QString format (QString fmtstr, Args... args)
+		{
+			return ::format (fmtstr, args...);
+		}
+
+	private slots:
+		void           slot_toolTipTimer();
+		void initializeAxes();
+};
+
+// Alias for short namespaces
+typedef GLRenderer GL;
+
+static const GLRenderer::ListType g_glListTypes[] =
+{
+	GL::NormalList,
+	GL::PickList,
+	GL::BFCFrontList,
+	GL::BFCBackList,
+};
+
+extern const GL::EFixedCamera g_Cameras[7];
+extern const char* g_CameraNames[7];

mercurial