Sun, 06 Sep 2015 04:48:58 +0300
Refactor GLRenderer and GLCompiler
--- a/src/editmodes/abstractEditMode.cpp Sun Sep 06 03:17:29 2015 +0300 +++ b/src/editmodes/abstractEditMode.cpp Sun Sep 06 04:48:58 2015 +0300 @@ -96,7 +96,7 @@ // Find the closest vertex to our cursor double minimumDistance = 1024.0; const Vertex* closest = nullptr; - Vertex cursorPosition = renderer()->coordconv2_3 (data.ev->pos(), false); + Vertex cursorPosition = renderer()->convert2dTo3d (data.ev->pos(), false); QPoint cursorPosition2D (data.ev->pos()); const Axis relZ = renderer()->getRelativeZ(); QVector<Vertex> vertices = renderer()->document()->inlineVertices(); @@ -114,7 +114,7 @@ { // If the vertex in 2d space is very close to the cursor then we use // it regardless of depth. - QPoint vect2d = renderer()->coordconv3_2 (vrt) - cursorPosition2D; + QPoint vect2d = renderer()->convert3dTo2d (vrt) - cursorPosition2D; const double distance2DSquared = std::pow (vect2d.x(), 2) + std::pow (vect2d.y(), 2); if (distance2DSquared < 16.0 * 16.0) { @@ -192,7 +192,7 @@ // Convert to 2D for (int i = 0; i < poly3d.size(); ++i) - poly[i] = renderer()->coordconv3_2 (poly3d[i]); + poly[i] = renderer()->convert3dTo2d (poly3d[i]); // Draw the polygon-to-be painter.setBrush (m_polybrush);
--- a/src/editmodes/circleMode.cpp Sun Sep 06 03:17:29 2015 +0300 +++ b/src/editmodes/circleMode.cpp Sun Sep 06 04:48:58 2015 +0300 @@ -40,7 +40,7 @@ if (m_drawedVerts.size() >= pos + 1) { Vertex v1 = (m_drawedVerts.size() >= pos + 2) ? m_drawedVerts[pos + 1] : - renderer()->coordconv2_3 (renderer()->mousePosition(), false); + renderer()->convert2dTo3d (renderer()->mousePosition(), false); Axis localx, localy; renderer()->getRelativeAxes (localx, localy); double dx = m_drawedVerts[0][localx] - v1[localx]; @@ -187,7 +187,7 @@ return 0.0; const int divisions (m_window->ringToolHiRes() ? HighResolution : LowResolution); - QPointF originspot (renderer()->coordconv3_2 (m_drawedVerts.first())); + QPointF originspot (renderer()->convert3dTo2d (m_drawedVerts.first())); QLineF bearing (originspot, renderer()->mousePositionF()); QLineF bearing2 (originspot, QPointF (originspot.x(), 0.0)); double angleoffset (-bearing.angleTo (bearing2) + 90); @@ -205,7 +205,7 @@ // If we have not specified the center point of the circle yet, preview it on the screen. if (m_drawedVerts.isEmpty()) { - renderer()->drawBlip (painter, renderer()->coordconv3_2 (renderer()->position3D())); + renderer()->drawBlip (painter, renderer()->convert3dTo2d (renderer()->position3D())); return; } @@ -229,14 +229,14 @@ v.setCoordinate (relX, m_drawedVerts[0][relX] + (cosangle * innerdistance)); v.setCoordinate (relY, m_drawedVerts[0][relY] + (sinangle * innerdistance)); innerverts << v; - innerverts2d << renderer()->coordconv3_2 (v); + innerverts2d << renderer()->convert3dTo2d (v); if (outerdistance != -1) { v.setCoordinate (relX, m_drawedVerts[0][relX] + (cosangle * outerdistance)); v.setCoordinate (relY, m_drawedVerts[0][relY] + (sinangle * outerdistance)); outerverts << v; - outerverts2d << renderer()->coordconv3_2 (v); + outerverts2d << renderer()->convert3dTo2d (v); } } @@ -282,7 +282,7 @@ painter.drawLines (lines); // Draw the current radius in the middle of the circle. - QPoint origin = renderer()->coordconv3_2 (m_drawedVerts[0]); + QPoint origin = renderer()->convert3dTo2d (m_drawedVerts[0]); QString label = QString::number (innerdistance); painter.setPen (renderer()->textPen()); painter.drawText (origin.x() - (metrics.width (label) / 2), origin.y(), label);
--- a/src/editmodes/linePathMode.cpp Sun Sep 06 03:17:29 2015 +0300 +++ b/src/editmodes/linePathMode.cpp Sun Sep 06 04:48:58 2015 +0300 @@ -13,7 +13,7 @@ points3d << renderer()->position3D(); for (Vertex const& vrt : points3d) - points << renderer()->coordconv3_2 (vrt); + points << renderer()->convert3dTo2d (vrt); painter.setPen (renderer()->textPen());
--- a/src/glCompiler.cpp Sun Sep 06 03:17:29 2015 +0300 +++ b/src/glCompiler.cpp Sun Sep 06 04:48:58 2015 +0300 @@ -26,6 +26,7 @@ #include "miscallenous.h" #include "glRenderer.h" #include "dialogs.h" +#include "guiutilities.h" struct GLErrorInfo { @@ -47,10 +48,6 @@ ConfigOption (QString SelectColorBlend = "#0080FF") -static QList<int> g_warnedColors; -static const QColor g_BFCFrontColor (64, 192, 80); -static const QColor g_BFCBackColor (208, 64, 64); - // static QMap<LDObject*, String> g_objectOrigins; // ============================================================================= @@ -90,7 +87,7 @@ void GLCompiler::initialize() { initializeOpenGLFunctions(); - glGenBuffers (g_numVBOs, &m_vbo[0]); + glGenBuffers (NumVbos, &m_vbo[0]); CHECK_GL_ERROR(); } @@ -98,22 +95,8 @@ // GLCompiler::~GLCompiler() { - glDeleteBuffers (g_numVBOs, &m_vbo[0]); + glDeleteBuffers (NumVbos, &m_vbo[0]); CHECK_GL_ERROR(); - - if (m_renderer) - m_renderer->setCompiler (nullptr); -} - -// ============================================================================= -// -uint32 GLCompiler::colorToRGB (const QColor& color) -{ - return - (color.red() & 0xFF) << 0x00 | - (color.green() & 0xFF) << 0x08 | - (color.blue() & 0xFF) << 0x10 | - (color.alpha() & 0xFF) << 0x18; } // ============================================================================= @@ -131,52 +114,53 @@ // ============================================================================= // -QColor GLCompiler::getColorForPolygon (LDPolygon& poly, LDObject* topobj, - EVBOComplement complement) const +QColor GLCompiler::getColorForPolygon (LDPolygon& poly, LDObject* topobj, ComplementVboType complement) const { QColor qcol; + static const QColor bfcFrontColor (64, 192, 80); + static const QColor bfcBackColor (208, 64, 64); switch (complement) { - case VBOCM_Surfaces: - case VBOCM_NumComplements: - return QColor(); + case SurfacesVboComplement: + case NumVboComplements: + return QColor(); - case VBOCM_BFCFrontColors: - qcol = g_BFCFrontColor; - break; + case BfcFrontColorsVboComplement: + qcol = bfcFrontColor; + break; - case VBOCM_BFCBackColors: - qcol = g_BFCBackColor; - break; + case BfcBackColorsVboComplement: + qcol = bfcBackColor; + break; - case VBOCM_PickColors: - return indexColorForID (topobj->id()); + case PickColorsVboComplement: + return indexColorForID (topobj->id()); - case VBOCM_RandomColors: - qcol = topobj->randomColor(); - break; + case RandomColorsVboComplement: + qcol = topobj->randomColor(); + break; - case VBOCM_NormalColors: - if (poly.color == MainColor) - { - if (topobj->color() == MainColor) - qcol = m_renderer->getMainColor(); - else - qcol = topobj->color().faceColor(); - } - else if (poly.color == EdgeColor) - { - qcol = Luma (QColor (m_config->backgroundColor())) > 40 ? Qt::black : Qt::white; - } + case NormalColorsVboComplement: + if (poly.color == MainColor) + { + if (topobj->color() == MainColor) + qcol = guiUtilities()->mainColorRepresentation(); else - { - LDColor col = poly.color; + qcol = topobj->color().faceColor(); + } + else if (poly.color == EdgeColor) + { + qcol = Luma (QColor (m_config->backgroundColor())) > 40 ? Qt::black : Qt::white; + } + else + { + LDColor col = poly.color; - if (col.isValid()) - qcol = col.faceColor(); - } - break; + if (col.isValid()) + qcol = col.faceColor(); + } + break; } if (not qcol.isValid()) @@ -184,15 +168,16 @@ // The color was unknown. Use main color to make the polygon at least // not appear pitch-black. if (poly.num != 2 and poly.num != 5) - qcol = m_renderer->getMainColor(); + qcol = guiUtilities()->mainColorRepresentation(); else qcol = Qt::black; // Warn about the unknown color, but only once. - if (not g_warnedColors.contains (poly.color)) + static QList<int> warnedColors; + if (not warnedColors.contains (poly.color)) { print ("Unknown color %1!\n", poly.color); - g_warnedColors << poly.color; + warnedColors << poly.color; } return qcol; @@ -364,19 +349,19 @@ // void GLCompiler::compilePolygon (LDPolygon& poly, LDObject* topobj, ObjectVBOInfo* objinfo) { - EVBOSurface surface; + SurfaceVboType surface; int numverts; switch (poly.num) { - case 2: surface = VBOSF_Lines; numverts = 2; break; - case 3: surface = VBOSF_Triangles; numverts = 3; break; - case 4: surface = VBOSF_Quads; numverts = 4; break; - case 5: surface = VBOSF_CondLines; numverts = 2; break; + case 2: surface = LinesVbo; numverts = 2; break; + case 3: surface = TrianglesVbo; numverts = 3; break; + case 4: surface = QuadsVbo; numverts = 4; break; + case 5: surface = ConditionalLinesVbo; numverts = 2; break; default: return; } - for (EVBOComplement complement = VBOCM_First; complement < VBOCM_NumComplements; ++complement) + for (ComplementVboType complement = FirstVboComplement; complement < NumVboComplements; ++complement) { const int vbonum = vboNumber (surface, complement); QVector<GLfloat>& vbodata = objinfo->data[vbonum]; @@ -384,7 +369,7 @@ for (int vert = 0; vert < numverts; ++vert) { - if (complement == VBOCM_Surfaces) + if (complement == SurfacesVboComplement) { // Write coordinates. Apparently Z must be flipped too? vbodata << poly.vertices[vert].x() @@ -406,3 +391,18 @@ { m_renderer = renderer; } + +int GLCompiler::vboNumber (SurfaceVboType surface, ComplementVboType complement) +{ + return (surface * NumVboComplements) + complement; +} + +GLuint GLCompiler::vbo (int vbonum) const +{ + return m_vbo[vbonum]; +} + +int GLCompiler::vboSize (int vbonum) const +{ + return m_vboSizes[vbonum]; +} \ No newline at end of file
--- a/src/glCompiler.h Sun Sep 06 03:17:29 2015 +0300 +++ b/src/glCompiler.h Sun Sep 06 04:48:58 2015 +0300 @@ -30,52 +30,38 @@ public: struct ObjectVBOInfo { - QVector<GLfloat> data[g_numVBOs]; + QVector<GLfloat> data[NumVbos]; bool isChanged; }; GLCompiler (GLRenderer* renderer); ~GLCompiler(); - void compileDocument (LDDocument* doc); - void dropObjectInfo (LDObject* obj); - void initialize(); - QColor getColorForPolygon (LDPolygon& poly, LDObject* topobj, - EVBOComplement complement) const; - QColor indexColorForID (int id) const; - void needMerge(); - void prepareVBO (int vbonum); - void setRenderer (GLRenderer* compiler); - void stageForCompilation (LDObject* obj); - void unstage (LDObject* obj); - - static uint32 colorToRGB (const QColor& color); + void compileDocument (LDDocument* doc); + void dropObjectInfo (LDObject* obj); + QColor getColorForPolygon (LDPolygon& poly, LDObject* topobj, ComplementVboType complement) const; + QColor indexColorForID (int id) const; + void initialize(); + void needMerge(); + void prepareVBO (int vbonum); + void setRenderer (GLRenderer* compiler); + void stageForCompilation (LDObject* obj); + void unstage (LDObject* obj); + GLuint vbo (int vbonum) const; + int vboSize (int vbonum) const; - static inline int vboNumber (EVBOSurface surface, EVBOComplement complement) - { - return (surface * VBOCM_NumComplements) + complement; - } - - inline GLuint vbo (int vbonum) const - { - return m_vbo[vbonum]; - } - - inline int vboSize (int vbonum) const - { - return m_vboSizes[vbonum]; - } + static int vboNumber (SurfaceVboType surface, ComplementVboType complement); private: - void compileStaged(); - void compileObject (LDObject* obj); - void compilePolygon (LDPolygon& poly, LDObject* topobj, ObjectVBOInfo* objinfo); + void compileStaged(); + void compileObject (LDObject* obj); + void compilePolygon (LDPolygon& poly, LDObject* topobj, ObjectVBOInfo* objinfo); QMap<LDObject*, ObjectVBOInfo> m_objectInfo; - QSet<LDObject*> m_staged; // Objects that need to be compiled - GLuint m_vbo[g_numVBOs]; - bool m_vboChanged[g_numVBOs]; - int m_vboSizes[g_numVBOs]; - GLRenderer* m_renderer; + QSet<LDObject*> m_staged; // Objects that need to be compiled + GLuint m_vbo[NumVbos]; + bool m_vboChanged[NumVbos]; + int m_vboSizes[NumVbos]; + GLRenderer* m_renderer; }; #define CHECK_GL_ERROR() { CheckGLErrorImpl (__FILE__, __LINE__); }
--- a/src/glRenderer.cpp Sun Sep 06 03:17:29 2015 +0300 +++ b/src/glRenderer.cpp Sun Sep 06 04:48:58 2015 +0300 @@ -68,50 +68,24 @@ ConfigOption (bool DrawEdgeLines = true) ConfigOption (bool DrawConditionalLines = true) -// 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") -}; - -struct LDGLAxis -{ - const QColor col; - const Vertex vert; -}; - -// Definitions for visual axes, drawn on the screen -static const LDGLAxis g_GLAxes[3] = -{ - { QColor (192, 96, 96), Vertex (10000, 0, 0) }, // X - { QColor (48, 192, 48), Vertex (0, 10000, 0) }, // Y - { QColor (48, 112, 192), Vertex (0, 0, 10000) }, // Z -}; - -static bool RendererInitialized (false); - // ============================================================================= // GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent), HierarchyElement (parent), - m_document (nullptr) + m_document (nullptr), + m_initialized (false) { m_isPicking = false; m_camera = (ECamera) m_config->camera(); m_drawToolTip = false; - m_editmode = AbstractEditMode::createByType (this, EditModeType::Select); + m_currentEditMode = AbstractEditMode::createByType (this, EditModeType::Select); m_panning = false; m_compiler = new GLCompiler (this); m_objectAtCursor = nullptr; setDrawOnly (false); - setMessageLog (nullptr); + m_messageLog = new MessageManager (this); + m_messageLog->setRenderer (this); m_width = m_height = -1; m_position3D = Origin; m_toolTipTimer = new QTimer (this); @@ -125,9 +99,15 @@ // Init camera icons for (ECamera cam = EFirstCamera; cam < ENumCameras; ++cam) { - QString iconname = format ("camera-%1", tr (g_CameraNames[cam]).toLower()); + const char* cameraIconNames[ENumCameras] = + { + "camera-top", "camera-front", "camera-left", + "camera-bottom", "camera-back", "camera-right", + "camera-free" + }; + CameraIcon* info = &m_cameraIcons[cam]; - info->img = new QPixmap (GetIcon (iconname)); + info->image = new QPixmap (GetIcon (cameraIconNames[cam])); info->cam = cam; } @@ -138,21 +118,20 @@ // GLRenderer::~GLRenderer() { - for (int i = 0; i < 6; ++i) + for (int i = 0; i < countof (currentDocumentData().overlays); ++i) delete currentDocumentData().overlays[i].img; for (CameraIcon& info : m_cameraIcons) - delete info.img; + delete info.image; if (messageLog()) messageLog()->setRenderer (nullptr); m_compiler->setRenderer (nullptr); delete m_compiler; - delete m_editmode; - - glDeleteBuffers (1, &m_axesVBO); - glDeleteBuffers (1, &m_axesColorVBO); + delete m_currentEditMode; + glDeleteBuffers (1, &m_axesVbo); + glDeleteBuffers (1, &m_axesColorVbo); } // ============================================================================= @@ -166,16 +145,16 @@ for (CameraIcon& info : m_cameraIcons) { // MATH - const long x1 = (m_width - (info.cam != EFreeCamera ? 48 : 16)) + ((i % 3) * 16) - 1, - y1 = ((i / 3) * 16) + 1; + int x1 = (m_width - (info.cam != EFreeCamera ? 48 : 16)) + ((i % 3) * 16) - 1; + int y1 = ((i / 3) * 16) + 1; - info.srcRect = QRect (0, 0, 16, 16); - info.destRect = QRect (x1, y1, 16, 16); + info.sourceRect = QRect (0, 0, 16, 16); + info.targetRect = QRect (x1, y1, 16, 16); info.selRect = QRect ( - info.destRect.x(), - info.destRect.y(), - info.destRect.width() + 1, - info.destRect.height() + 1 + info.targetRect.x(), + info.targetRect.y(), + info.targetRect.width() + 1, + info.targetRect.height() + 1 ); ++i; @@ -190,7 +169,6 @@ 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); @@ -201,13 +179,49 @@ glEnable (GL_POLYGON_SMOOTH); glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST); - } else + } + else { glDisable (GL_LINE_SMOOTH); glDisable (GL_POLYGON_SMOOTH); } } +bool GLRenderer::isDrawOnly() const +{ + return m_isDrawOnly; +} + +void GLRenderer::setDrawOnly (bool value) +{ + m_isDrawOnly = value; +} + +MessageManager* GLRenderer::messageLog() const +{ + return m_messageLog; +} + +bool GLRenderer::isPicking() const +{ + return m_isPicking; +} + +LDDocument* GLRenderer::document() const +{ + return m_document; +} + +GLCompiler* GLRenderer::compiler() const +{ + return m_compiler; +} + +LDObject* GLRenderer::objectAtCursor() const +{ + return m_objectAtCursor; +} + // ============================================================================= // void GLRenderer::needZoomToFit() @@ -220,9 +234,9 @@ // void GLRenderer::resetAngles() { - rot (X) = 30.0f; - rot (Y) = 325.f; - pan (X) = pan (Y) = rot (Z) = 0.0f; + rotation (X) = 30.0f; + rotation (Y) = 325.f; + panning (X) = panning (Y) = rotation (Z) = 0.0f; needZoomToFit(); } @@ -256,57 +270,58 @@ setFocusPolicy (Qt::WheelFocus); compiler()->initialize(); initializeAxes(); - RendererInitialized = true; + m_initialized = true; } // ============================================================================= // void GLRenderer::initializeAxes() { - float axesdata[18]; + // Definitions for visual axes, drawn on the screen + struct AxisInfo + { + QColor color; + Vertex extrema; + }; + + static const AxisInfo axisinfo[3] = + { + { QColor (192, 96, 96), Vertex (10000, 0, 0) }, // X + { QColor (48, 192, 48), Vertex (0, 10000, 0) }, // Y + { QColor (48, 112, 192), Vertex (0, 0, 10000) }, // Z + }; + + float axisdata[18]; float colordata[18]; - memset (axesdata, 0, sizeof axesdata); + memset (axisdata, 0, sizeof axisdata); for (int i = 0; i < 3; ++i) { + const AxisInfo& data = axisinfo[i]; + for_axes (ax) { - axesdata[(i * 6) + ax] = g_GLAxes[i].vert[ax]; - axesdata[(i * 6) + 3 + ax] = -g_GLAxes[i].vert[ax]; + axisdata[(i * 6) + ax] = data.extrema[ax]; + axisdata[(i * 6) + 3 + ax] = -data.extrema[ax]; } - for (int j = 0; j < 2; ++j) - { - colordata[(i * 6) + (j * 3) + 0] = g_GLAxes[i].col.red(); - colordata[(i * 6) + (j * 3) + 1] = g_GLAxes[i].col.green(); - colordata[(i * 6) + (j * 3) + 2] = g_GLAxes[i].col.blue(); - } + int offset = i * 6; + colordata[offset + 0] = colordata[offset + 3] = data.color.red(); + colordata[offset + 1] = colordata[offset + 4] = data.color.green(); + colordata[offset + 2] = colordata[offset + 5] = data.color.blue(); } - glGenBuffers (1, &m_axesVBO); - glBindBuffer (GL_ARRAY_BUFFER, m_axesVBO); - glBufferData (GL_ARRAY_BUFFER, sizeof axesdata, axesdata, GL_STATIC_DRAW); - glGenBuffers (1, &m_axesColorVBO); - glBindBuffer (GL_ARRAY_BUFFER, m_axesColorVBO); + glGenBuffers (1, &m_axesVbo); + glBindBuffer (GL_ARRAY_BUFFER, m_axesVbo); + glBufferData (GL_ARRAY_BUFFER, sizeof axisdata, axisdata, GL_STATIC_DRAW); + glGenBuffers (1, &m_axesColorVbo); + glBindBuffer (GL_ARRAY_BUFFER, m_axesColorVbo); glBufferData (GL_ARRAY_BUFFER, sizeof colordata, colordata, GL_STATIC_DRAW); glBindBuffer (GL_ARRAY_BUFFER, 0); } // ============================================================================= // -QColor GLRenderer::getMainColor() -{ - QColor col (m_config->mainColor()); - - if (not col.isValid()) - return QColor (0, 0, 0); - - col.setAlpha (m_config->mainColorAlpha() * 255.f); - return col; -} - -// ============================================================================= -// void GLRenderer::setBackground() { if (isPicking()) @@ -321,8 +336,8 @@ return; color.setAlpha (255); - m_darkbg = Luma (color) < 80; - m_bgcolor = color; + m_useDarkBackground = Luma (color) < 80; + m_backgroundColor = color; qglClearColor (color); } @@ -340,11 +355,11 @@ // void GLRenderer::hardRefresh() { - if (not RendererInitialized) - return; - - compiler()->compileDocument (currentDocument()); - refresh(); + if (m_initialized) + { + compiler()->compileDocument (currentDocument()); + refresh(); + } } // ============================================================================= @@ -388,8 +403,8 @@ glPushMatrix(); glLoadIdentity(); - glOrtho (-m_virtWidth, m_virtWidth, -m_virtHeight, m_virtHeight, -100.0f, 100.0f); - glTranslatef (pan (X), pan (Y), 0.0f); + glOrtho (-m_virtualWidth, m_virtualWidth, -m_virtualHeight, m_virtualHeight, -100.0f, 100.0f); + glTranslatef (panning (X), panning (Y), 0.0f); if (camera() != EFrontCamera and camera() != EBackCamera) { @@ -412,10 +427,10 @@ glLoadIdentity(); glTranslatef (0.0f, 0.0f, -2.0f); - glTranslatef (pan (X), pan (Y), -zoom()); - glRotatef (rot (X), 1.0f, 0.0f, 0.0f); - glRotatef (rot (Y), 0.0f, 1.0f, 0.0f); - glRotatef (rot (Z), 0.0f, 0.0f, 1.0f); + glTranslatef (panning (X), panning (Y), -zoom()); + glRotatef (rotation (X), 1.0f, 0.0f, 0.0f); + glRotatef (rotation (Y), 0.0f, 1.0f, 0.0f); + glRotatef (rotation (Z), 0.0f, 0.0f, 1.0f); } glEnableClientState (GL_VERTEX_ARRAY); @@ -423,10 +438,10 @@ if (isPicking()) { - drawVBOs (VBOSF_Triangles, VBOCM_PickColors, GL_TRIANGLES); - drawVBOs (VBOSF_Quads, VBOCM_PickColors, GL_QUADS); - drawVBOs (VBOSF_Lines, VBOCM_PickColors, GL_LINES); - drawVBOs (VBOSF_CondLines, VBOCM_PickColors, GL_LINES); + drawVbos (TrianglesVbo, PickColorsVboComplement, GL_TRIANGLES); + drawVbos (QuadsVbo, PickColorsVboComplement, GL_QUADS); + drawVbos (LinesVbo, PickColorsVboComplement, GL_LINES); + drawVbos (ConditionalLinesVbo, PickColorsVboComplement, GL_LINES); } else { @@ -434,30 +449,36 @@ { glEnable (GL_CULL_FACE); glCullFace (GL_BACK); - drawVBOs (VBOSF_Triangles, VBOCM_BFCFrontColors, GL_TRIANGLES); - drawVBOs (VBOSF_Quads, VBOCM_BFCFrontColors, GL_QUADS); + drawVbos (TrianglesVbo, BfcFrontColorsVboComplement, GL_TRIANGLES); + drawVbos (QuadsVbo, BfcFrontColorsVboComplement, GL_QUADS); glCullFace (GL_FRONT); - drawVBOs (VBOSF_Triangles, VBOCM_BFCBackColors, GL_TRIANGLES); - drawVBOs (VBOSF_Quads, VBOCM_BFCBackColors, GL_QUADS); + drawVbos (TrianglesVbo, BfcBackColorsVboComplement, GL_TRIANGLES); + drawVbos (QuadsVbo, BfcBackColorsVboComplement, GL_QUADS); glDisable (GL_CULL_FACE); } else { - EVBOComplement colors = (m_config->randomColors()) ? VBOCM_RandomColors : VBOCM_NormalColors; - drawVBOs (VBOSF_Triangles, colors, GL_TRIANGLES); - drawVBOs (VBOSF_Quads, colors, GL_QUADS); + ComplementVboType colors; + + if (m_config->randomColors()) + colors = RandomColorsVboComplement; + else + colors = NormalColorsVboComplement; + + drawVbos (TrianglesVbo, colors, GL_TRIANGLES); + drawVbos (QuadsVbo, colors, GL_QUADS); } - drawVBOs (VBOSF_Lines, VBOCM_NormalColors, GL_LINES); + drawVbos (LinesVbo, NormalColorsVboComplement, GL_LINES); glEnable (GL_LINE_STIPPLE); - drawVBOs (VBOSF_CondLines, VBOCM_NormalColors, GL_LINES); + drawVbos (ConditionalLinesVbo, NormalColorsVboComplement, GL_LINES); glDisable (GL_LINE_STIPPLE); if (m_config->drawAxes()) { - glBindBuffer (GL_ARRAY_BUFFER, m_axesVBO); + glBindBuffer (GL_ARRAY_BUFFER, m_axesVbo); glVertexPointer (3, GL_FLOAT, 0, NULL); - glBindBuffer (GL_ARRAY_BUFFER, m_axesVBO); + glBindBuffer (GL_ARRAY_BUFFER, m_axesVbo); glColorPointer (3, GL_FLOAT, 0, NULL); glDrawArrays (GL_LINES, 0, 6); CHECK_GL_ERROR(); @@ -476,17 +497,17 @@ // ============================================================================= // -void GLRenderer::drawVBOs (EVBOSurface surface, EVBOComplement colors, GLenum type) +void GLRenderer::drawVbos (SurfaceVboType surface, ComplementVboType colors, GLenum type) { // Filter this through some configuration options - if ((isOneOf (surface, VBOSF_Quads, VBOSF_Triangles) and m_config->drawSurfaces() == false) or - (surface == VBOSF_Lines and m_config->drawEdgeLines() == false) or - (surface == VBOSF_CondLines and m_config->drawConditionalLines() == false)) + if ((isOneOf (surface, QuadsVbo, TrianglesVbo) and m_config->drawSurfaces() == false) + or (surface == LinesVbo and m_config->drawEdgeLines() == false) + or (surface == ConditionalLinesVbo and m_config->drawConditionalLines() == false)) { return; } - int surfacenum = m_compiler->vboNumber (surface, VBOCM_Surfaces); + int surfacenum = m_compiler->vboNumber (surface, SurfacesVboComplement); int colornum = m_compiler->vboNumber (surface, colors); m_compiler->prepareVBO (surfacenum); m_compiler->prepareVBO (colornum); @@ -508,24 +529,25 @@ } // ============================================================================= +// // This converts a 2D point on the screen to a 3D point in the model. If 'snap' // is true, the 3D point will snap to the current grid. // -Vertex GLRenderer::coordconv2_3 (const QPoint& pos2d, bool snap) const +Vertex GLRenderer::convert2dTo3d (const QPoint& pos2d, bool snap) const { if (camera() == EFreeCamera) return Origin; Vertex pos3d; const LDFixedCamera* cam = &g_FixedCameras[camera()]; - const Axis axisX = cam->axisX; - const Axis axisY = cam->axisY; - const int negXFac = cam->negX ? -1 : 1, - negYFac = cam->negY ? -1 : 1; + const Axis axisX = cam->localX; + const Axis axisY = cam->localY; + const int negXFac = cam->negatedX ? -1 : 1, + negYFac = cam->negatedY ? -1 : 1; // Calculate cx and cy - these are the LDraw unit coords the cursor is at. - double cx = (-m_virtWidth + ((2 * pos2d.x() * m_virtWidth) / m_width) - pan (X)); - double cy = (m_virtHeight - ((2 * pos2d.y() * m_virtHeight) / m_height) - pan (Y)); + double cx = (-m_virtualWidth + ((2 * pos2d.x() * m_virtualWidth) / m_width) - panning (X)); + double cy = (m_virtualHeight - ((2 * pos2d.y() * m_virtualHeight) / m_height) - panning (Y)); if (snap) { @@ -548,45 +570,44 @@ // ============================================================================= // -// Inverse operation for the above - convert a 3D position to a 2D screen -// position. Don't ask me how this code manages to work, I don't even know. +// Inverse operation for the above - convert a 3D position to a 2D screen position. Don't ask me how this code manages +// to work, I don't even know. // -QPoint GLRenderer::coordconv3_2 (const Vertex& pos3d) +QPoint GLRenderer::convert3dTo2d (const Vertex& pos3d) { - GLfloat m[16]; + if (camera() == EFreeCamera) + return QPoint (0, 0); + const LDFixedCamera* cam = &g_FixedCameras[camera()]; - const Axis axisX = cam->axisX; - const Axis axisY = cam->axisY; - const int negXFac = cam->negX ? -1 : 1, - negYFac = cam->negY ? -1 : 1; - - glGetFloatv (GL_MODELVIEW_MATRIX, m); - + const Axis axisX = cam->localX; + const Axis axisY = cam->localY; + const int negXFac = cam->negatedX ? -1 : 1; + const int negYFac = cam->negatedY ? -1 : 1; + GLfloat matrix[16]; const double x = pos3d.x(); const double y = pos3d.y(); const double z = pos3d.z(); + Vertex transformed; - Vertex transformed; - transformed.setX ((m[0] * x) + (m[1] * y) + (m[2] * z) + m[3]); - transformed.setY ((m[4] * x) + (m[5] * y) + (m[6] * z) + m[7]); - transformed.setZ ((m[8] * x) + (m[9] * y) + (m[10] * z) + m[11]); - - double rx = (((transformed[axisX] * negXFac) + m_virtWidth + pan (X)) * m_width) / (2 * m_virtWidth); - double ry = (((transformed[axisY] * negYFac) - m_virtHeight + pan (Y)) * m_height) / (2 * m_virtHeight); - + glGetFloatv (GL_MODELVIEW_MATRIX, matrix); + transformed.setX ((matrix[0] * x) + (matrix[1] * y) + (matrix[2] * z) + matrix[3]); + transformed.setY ((matrix[4] * x) + (matrix[5] * y) + (matrix[6] * z) + matrix[7]); + transformed.setZ ((matrix[8] * x) + (matrix[9] * y) + (matrix[10] * z) + matrix[11]); + double rx = (((transformed[axisX] * negXFac) + m_virtualWidth + panning (X)) * m_width) / (2 * m_virtualWidth); + double ry = (((transformed[axisY] * negYFac) - m_virtualHeight + panning (Y)) * m_height) / (2 * m_virtualHeight); return QPoint (rx, -ry); } QPen GLRenderer::textPen() const { - return QPen (m_darkbg ? Qt::white : Qt::black); + return QPen (m_useDarkBackground ? Qt::white : Qt::black); } QPen GLRenderer::linePen() const { QPen linepen (m_thinBorderPen); linepen.setWidth (2); - linepen.setColor (Luma (m_bgcolor) < 40 ? Qt::white : Qt::black); + linepen.setColor (Luma (m_backgroundColor) < 40 ? Qt::white : Qt::black); return linepen; } @@ -595,8 +616,8 @@ void GLRenderer::paintEvent (QPaintEvent*) { doMakeCurrent(); - m_virtWidth = zoom(); - m_virtHeight = (m_height * m_virtWidth) / m_width; + m_virtualWidth = zoom(); + m_virtualHeight = (m_height * m_virtualWidth) / m_width; initGLData(); drawGLScene(); @@ -612,7 +633,7 @@ if (not isPicking()) { QString text = format ("Rotation: (%1, %2, %3)\nPanning: (%4, %5), Zoom: %6", - rot(X), rot(Y), rot(Z), pan(X), pan(Y), zoom()); + rotation(X), rotation(Y), rotation(Z), panning(X), panning(Y), zoom()); QRect textSize = metrics.boundingRect (0, 0, m_width, m_height, Qt::AlignCenter, text); paint.setPen (textPen()); paint.drawText ((width() - textSize.width()) / 2, height() - textSize.height(), textSize.width(), @@ -627,12 +648,11 @@ if (overlay.img) { - QPoint v0 = coordconv3_2 (currentDocumentData().overlays[camera()].v0), - v1 = coordconv3_2 (currentDocumentData().overlays[camera()].v1); - - QRect targRect (v0.x(), v0.y(), qAbs (v1.x() - v0.x()), qAbs (v1.y() - v0.y())), - srcRect (0, 0, overlay.img->width(), overlay.img->height()); - paint.drawImage (targRect, *overlay.img, srcRect); + QPoint v0 = convert3dTo2d (currentDocumentData().overlays[camera()].v0); + QPoint v1 = convert3dTo2d (currentDocumentData().overlays[camera()].v1); + QRect targetRect (v0.x(), v0.y(), qAbs (v1.x() - v0.x()), qAbs (v1.y() - v0.y())); + QRect sourceRect (0, 0, overlay.img->width(), overlay.img->height()); + paint.drawImage (targetRect, *overlay.img, sourceRect); } // Paint the coordinates onto the screen. @@ -647,7 +667,7 @@ if (not isPicking()) { // Draw edit mode HUD - m_editmode->render (paint); + m_currentEditMode->render (paint); // Draw a background for the selected camera paint.setPen (m_thinBorderPen); @@ -657,35 +677,27 @@ // Draw the camera icons for (CameraIcon& info : m_cameraIcons) { - // Don't draw the free camera icon when in draw mode - if (&info == &m_cameraIcons[EFreeCamera] and not m_editmode->allowFreeCamera()) + // Don't draw the free camera icon when we can't use the free camera + if (&info == &m_cameraIcons[EFreeCamera] and not m_currentEditMode->allowFreeCamera()) continue; - paint.drawPixmap (info.destRect, *info.img, info.srcRect); + paint.drawPixmap (info.targetRect, *info.image, info.sourceRect); } - QString formatstr = tr ("%1 Camera"); - // Draw a label for the current camera in the bottom left corner { const int margin = 4; - - QString label; - label = format (formatstr, tr (g_CameraNames[camera()])); paint.setPen (textPen()); - paint.drawText (QPoint (margin, height() - (margin + metrics.descent())), label); + paint.drawText (QPoint (margin, height() - (margin + metrics.descent())), currentCameraName()); } // Tool tips if (m_drawToolTip) { - if (not m_cameraIcons[m_toolTipCamera].destRect.contains (m_mousePosition)) + if (not m_cameraIcons[m_toolTipCamera].targetRect.contains (m_mousePosition)) m_drawToolTip = false; else - { - QString label = format (formatstr, tr (g_CameraNames[m_toolTipCamera])); - QToolTip::showText (m_globalpos, label); - } + QToolTip::showText (m_globalpos, currentCameraName()); } } @@ -733,12 +745,9 @@ // void GLRenderer::mouseReleaseEvent (QMouseEvent* ev) { - const bool wasLeft = (m_lastButtons & Qt::LeftButton) and not (ev->buttons() & Qt::LeftButton); - + bool wasLeft = (m_lastButtons & Qt::LeftButton) and not (ev->buttons() & Qt::LeftButton); Qt::MouseButtons releasedbuttons = m_lastButtons & ~ev->buttons(); - - if (m_panning) - m_panning = false; + m_panning = false; if (wasLeft) { @@ -747,7 +756,7 @@ { for (CameraIcon & info : m_cameraIcons) { - if (info.destRect.contains (ev->pos())) + if (info.targetRect.contains (ev->pos())) { setCamera (info.cam); goto end; @@ -761,26 +770,26 @@ AbstractEditMode::MouseEventData data; data.ev = ev; data.mouseMoved = mouseHasMoved(); - data.keymods = m_keymods; + data.keymods = m_currentKeyboardModifiers; data.releasedButtons = releasedbuttons; - if (m_editmode->mouseReleased (data)) + if (m_currentEditMode->mouseReleased (data)) goto end; } end: update(); - m_totalmove = 0; + m_totalMouseMove = 0; } // ============================================================================= // void GLRenderer::mousePressEvent (QMouseEvent* ev) { - m_totalmove = 0; + m_totalMouseMove = 0; m_lastButtons = ev->buttons(); - if (m_editmode->mousePressed (ev)) + if (m_currentEditMode->mousePressed (ev)) ev->accept(); } @@ -790,10 +799,10 @@ { int dx = ev->x() - m_mousePosition.x(); int dy = ev->y() - m_mousePosition.y(); - m_totalmove += qAbs (dx) + qAbs (dy); - setCameraMoving (false); + m_totalMouseMove += qAbs (dx) + qAbs (dy); + m_isCameraMoving = false; - if (not m_editmode->mouseMoved (ev)) + if (not m_currentEditMode->mouseMoved (ev)) { const bool left = ev->buttons() & Qt::LeftButton, mid = ev->buttons() & Qt::MidButton, @@ -801,19 +810,18 @@ if (mid or (left and shift)) { - pan (X) += 0.03f * dx * (zoom() / 7.5f); - pan (Y) -= 0.03f * dy * (zoom() / 7.5f); + panning (X) += 0.03f * dx * (zoom() / 7.5f); + panning (Y) -= 0.03f * dy * (zoom() / 7.5f); m_panning = true; - setCameraMoving (true); + m_isCameraMoving = true; } else if (left and camera() == EFreeCamera) { - rot (X) = rot (X) + dy; - rot (Y) = rot (Y) + dx; - - clampAngle (rot (X)); - clampAngle (rot (Y)); - setCameraMoving (true); + rotation (X) = rotation (X) + dy; + rotation (Y) = rotation (Y) + dx; + clampAngle (rotation (X)); + clampAngle (rotation (Y)); + m_isCameraMoving = true; } } @@ -832,7 +840,7 @@ #endif // Calculate 3d position of the cursor - m_position3D = (camera() != EFreeCamera) ? coordconv2_3 (m_mousePosition, true) : Origin; + m_position3D = (camera() != EFreeCamera) ? convert2dTo3d (m_mousePosition, true) : Origin; highlightCursorObject(); update(); @@ -843,15 +851,15 @@ // void GLRenderer::keyPressEvent (QKeyEvent* ev) { - m_keymods = ev->modifiers(); + m_currentKeyboardModifiers = ev->modifiers(); } // ============================================================================= // void GLRenderer::keyReleaseEvent (QKeyEvent* ev) { - m_keymods = ev->modifiers(); - m_editmode->keyReleased (ev); + m_currentKeyboardModifiers = ev->modifiers(); + m_currentEditMode->keyReleased (ev); update(); } @@ -863,7 +871,7 @@ zoomNotch (ev->delta() > 0); zoom() = qBound (0.01, zoom(), 10000.0); - setCameraMoving (true); + m_isCameraMoving = true; update(); ev->accept(); } @@ -890,7 +898,7 @@ void GLRenderer::setCamera (const ECamera cam) { // The edit mode may forbid the free camera. - if (cam == EFreeCamera and not m_editmode->allowFreeCamera()) + if (cam == EFreeCamera and not m_currentEditMode->allowFreeCamera()) return; m_camera = cam; @@ -1023,14 +1031,14 @@ // void GLRenderer::setEditMode (EditModeType a) { - if (m_editmode and m_editmode->type() == a) + if (m_currentEditMode and m_currentEditMode->type() == a) return; - delete m_editmode; - m_editmode = AbstractEditMode::createByType (this, a); + delete m_currentEditMode; + m_currentEditMode = AbstractEditMode::createByType (this, a); // If we cannot use the free camera, use the top one instead. - if (camera() == EFreeCamera and not m_editmode->allowFreeCamera()) + if (camera() == EFreeCamera and not m_currentEditMode->allowFreeCamera()) setCamera (ETopCamera); m_window->updateEditModeActions(); @@ -1041,16 +1049,16 @@ // EditModeType GLRenderer::currentEditModeType() const { - return m_editmode->type(); + return m_currentEditMode->type(); } // ============================================================================= // -void GLRenderer::setDocument (LDDocument* const& a) +void GLRenderer::setDocument (LDDocument* document) { - m_document = a; + m_document = document; - if (a) + if (document) { initOverlaysFromObjects(); @@ -1066,9 +1074,9 @@ // ============================================================================= // -void GLRenderer::setPicking (const bool& a) +void GLRenderer::setPicking (bool value) { - m_isPicking = a; + m_isPicking = value; setBackground(); if (isPicking()) @@ -1092,8 +1100,8 @@ void GLRenderer::getRelativeAxes (Axis& relX, Axis& relY) const { const LDFixedCamera* cam = &g_FixedCameras[camera()]; - relX = cam->axisX; - relY = cam->axisY; + relX = cam->localX; + relY = cam->localY; } // ============================================================================= @@ -1101,30 +1109,7 @@ Axis GLRenderer::getRelativeZ() const { const LDFixedCamera* cam = &g_FixedCameras[camera()]; - return (Axis) (3 - cam->axisX - cam->axisY); -} - -// ============================================================================= -// -static QList<Vertex> GetVerticesOf (LDObject* obj) -{ - QList<Vertex> verts; - - if (obj->numVertices() >= 2) - { - for (int i = 0; i < obj->numVertices(); ++i) - verts << obj->vertex (i); - } - else if (obj->type() == OBJ_Subfile) - { - for (LDObject* obj : static_cast<LDSubfile*> (obj)->inlineContents (true, false)) - { - verts << GetVerticesOf (obj); - obj->destroy(); - } - } - - return verts; + return (Axis) (3 - cam->localX - cam->localY); } // ============================================================================= @@ -1147,20 +1132,15 @@ // ============================================================================= // -uchar* GLRenderer::getScreencap (int& w, int& h) +QByteArray GLRenderer::capturePixels() { - w = m_width; - h = m_height; - uchar* cap = new uchar[4 * w * h]; - - m_screencap = true; - update(); - m_screencap = false; - - // Capture the pixels - glReadPixels (0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, cap); - - return cap; + QByteArray result; + result.resize (4 * width() * height()); + m_takingScreenCapture = true; + update(); // Smile! + m_takingScreenCapture = false; + glReadPixels (0, 0, width(), height(), GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uchar*> (result.data())); + return result; } // ============================================================================= @@ -1172,7 +1152,7 @@ // a tooltip. for (CameraIcon & icon : m_cameraIcons) { - if (icon.destRect.contains (m_mousePosition)) + if (icon.targetRect.contains (m_mousePosition)) { m_toolTipCamera = icon.cam; m_drawToolTip = true; @@ -1190,7 +1170,7 @@ camid = camera(); const LDFixedCamera* cam = &g_FixedCameras[camid]; - return (y) ? cam->axisY : cam->axisX; + return (y) ? cam->localY : cam->localX; } // ============================================================================= @@ -1225,8 +1205,8 @@ const Axis x2d = getCameraAxis (false, cam), y2d = getCameraAxis (true, cam); - const double negXFac = g_FixedCameras[cam].negX ? -1 : 1, - negYFac = g_FixedCameras[cam].negY ? -1 : 1; + const double negXFac = g_FixedCameras[cam].negatedX ? -1 : 1, + negYFac = g_FixedCameras[cam].negatedY ? -1 : 1; info.v0 = info.v1 = Origin; info.v0.setCoordinate (x2d, -(info.ox * info.lw * negXFac) / img->width()); @@ -1280,9 +1260,26 @@ // ============================================================================= // -const char* GLRenderer::getCameraName() const +QString GLRenderer::cameraName (ECamera camera) const { - return g_CameraNames[camera()]; + switch (camera) + { + case ETopCamera: return tr ("Top Camera"); + case EFrontCamera: return tr ("Front Camera"); + case ELeftCamera: return tr ("Left Camera"); + case EBottomCamera: return tr ("Bottom Camera"); + case EBackCamera: return tr ("Back Camera"); + case ERightCamera: return tr ("Right Camera"); + case EFreeCamera: return tr ("Free Camera"); + default: break; + } + + return ""; +} + +QString GLRenderer::currentCameraName() const +{ + return cameraName (camera()); } // ============================================================================= @@ -1400,7 +1397,7 @@ // void GLRenderer::mouseDoubleClickEvent (QMouseEvent* ev) { - if (m_editmode->mouseDoubleClicked (ev)) + if (m_currentEditMode->mouseDoubleClicked (ev)) ev->accept(); } @@ -1538,7 +1535,7 @@ LDObject* oldObject = objectAtCursor(); qint32 newIndex; - if (isCameraMoving() or not m_config->highlightObjectBelowCursor()) + if (m_isCameraMoving or not m_config->highlightObjectBelowCursor()) { newIndex = 0; } @@ -1558,7 +1555,7 @@ if (newIndex != 0) newObject = LDObject::fromID (newIndex); - setObjectAtCursor (newObject); + m_objectAtCursor = newObject; if (oldObject) compileObject (oldObject); @@ -1580,10 +1577,11 @@ { if (m_window and ev->source() == m_window->getPrimitivesTree()) { - QString primName = static_cast<SubfileListItem*> (m_window->getPrimitivesTree()->currentItem())->primitive()->name; + SubfileListItem* item = static_cast<SubfileListItem*> (m_window->getPrimitivesTree()->currentItem()); + QString primitiveName = item->primitive()->name; LDSubfile* ref = LDSpawn<LDSubfile>(); ref->setColor (MainColor); - ref->setFileInfo (GetDocument (primName)); + ref->setFileInfo (GetDocument (primitiveName)); ref->setPosition (Origin); ref->setTransform (IdentityMatrix); currentDocument()->insertObj (m_window->suggestInsertPoint(), ref); @@ -1599,14 +1597,14 @@ return m_position3D; } -LDFixedCamera const& GLRenderer::getFixedCamera (ECamera cam) const +const LDFixedCamera& GLRenderer::getFixedCamera (ECamera cam) const { return g_FixedCameras[cam]; } bool GLRenderer::mouseHasMoved() const { - return m_totalmove >= 10; + return m_totalMouseMove >= 10; } QPoint const& GLRenderer::mousePosition() const @@ -1632,13 +1630,40 @@ Qt::KeyboardModifiers GLRenderer::keyboardModifiers() const { - return m_keymods; + return m_currentKeyboardModifiers; +} + +ECamera GLRenderer::camera() const +{ + return m_camera; +} + +LDGLData& GLRenderer::currentDocumentData() const +{ + return *document()->glData(); } -LDFixedCamera const& GetFixedCamera (ECamera cam) +double& GLRenderer::rotation (Axis ax) +{ + return + (ax == X) ? currentDocumentData().rotationX : + (ax == Y) ? currentDocumentData().rotationY : + currentDocumentData().rotationZ; +} + +double& GLRenderer::panning (Axis ax) { - if (cam != EFreeCamera) - return g_FixedCameras[cam]; - else - return g_FixedCameras[0]; + return (ax == X) ? currentDocumentData().panX[camera()] : + currentDocumentData().panY[camera()]; } + +double GLRenderer::panning (Axis ax) const +{ + return (ax == X) ? currentDocumentData().panX[camera()] : + currentDocumentData().panY[camera()]; +} + +double& GLRenderer::zoom() +{ + return currentDocumentData().zoom[camera()]; +}
--- a/src/glRenderer.h Sun Sep 06 03:17:29 2015 +0300 +++ b/src/glRenderer.h Sun Sep 06 04:48:58 2015 +0300 @@ -35,6 +35,16 @@ class QTimer; class MagicWandMode; +struct LDFixedCamera +{ + int glrotate[3]; + Axis localX; + Axis localY; + bool negatedX; + bool negatedY; + bool negatedDepth; // is greater depth value closer to camera? +}; + // // Meta for overlays // @@ -51,36 +61,26 @@ bool invalid; }; -struct LDFixedCamera -{ - const char glrotate[3]; - const Axis axisX, - axisY; - const bool negX, - negY, - negatedDepth; // is greater depth value closer to camera? -}; - // // Document-specific data // struct LDGLData { - double rotX, - rotY, - rotZ, - panX[7], - panY[7], - zoom[7]; + double rotationX; + double rotationY; + double rotationZ; + double panX[7]; + double panY[7]; + double zoom[7]; double depthValues[6]; LDGLOverlay overlays[6]; bool init; bool needZoomToFit; LDGLData() : - rotX (0.0), - rotY (0.0), - rotZ (0.0), + rotationX (0.0), + rotationY (0.0), + rotationZ (0.0), init (false), needZoomToFit (true) { @@ -117,144 +117,149 @@ MAKE_ITERABLE_ENUM (ECamera) // -// CameraIcon::img is a heap-allocated QPixmap because otherwise it gets +// CameraIcon::image 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; + QPixmap* image; + QRect sourceRect; + QRect targetRect; + QRect selRect; ECamera cam; }; -// -// 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() -// +// The main renderer object, draws the brick on the screen, manages the camera and selection picking. class GLRenderer : public QGLWidget, protected QOpenGLFunctions, public HierarchyElement { -public: Q_OBJECT - PROPERTY (public, bool, isDrawOnly, setDrawOnly, STOCK_WRITE) - PROPERTY (public, MessageManager*, messageLog, setMessageLog, STOCK_WRITE) - PROPERTY (private, bool, isPicking, setPicking, CUSTOM_WRITE) - PROPERTY (public, LDDocument*, document, setDocument, CUSTOM_WRITE) - PROPERTY (public, GLCompiler*, compiler, setCompiler, STOCK_WRITE) - PROPERTY (public, LDObject*, objectAtCursor, setObjectAtCursor, STOCK_WRITE) - PROPERTY (private, bool, isCameraMoving, setCameraMoving, STOCK_WRITE) public: GLRenderer (QWidget* parent = nullptr); ~GLRenderer(); - inline ECamera camera() const; - void clearOverlay(); - void compileObject (LDObject* obj); - Vertex coordconv2_3 (const QPoint& pos2d, bool snap) const; - QPoint coordconv3_2 (const Vertex& pos3d); - EditModeType currentEditModeType() const; - int depthNegateFactor() const; - void drawBlip (QPainter& paint, QPointF pos) const; - void drawGLScene(); - void forgetObject (LDObject* obj); - Axis getCameraAxis (bool y, ECamera camid = (ECamera) -1); - const char* getCameraName() const; - double getDepthValue() const; - LDFixedCamera const& getFixedCamera (ECamera cam) const; - void getRelativeAxes (Axis& relX, Axis& relY) const; - Axis getRelativeZ() const; - LDGLOverlay& getOverlay (int newcam); - uchar* getScreencap (int& w, int& h); - Qt::KeyboardModifiers keyboardModifiers() const; - void hardRefresh(); - void highlightCursorObject(); - void initGLData(); - void initOverlaysFromObjects(); - QPen linePen() const; - bool mouseHasMoved() const; - QPoint const& mousePosition() const; - QPointF const& mousePositionF() const; - void needZoomToFit(); - void pick (int mouseX, int mouseY, bool additive); - void pick (QRect const& range, bool additive); - LDObject* pickOneObject (int mouseX, int mouseY); - Vertex const& position3D() const; - void refresh(); - void resetAngles(); - void resetAllAngles(); - void setBackground(); - void setCamera (const ECamera cam); - void setDepthValue (double depth); - void setEditMode (EditModeType type); - bool setupOverlay (ECamera cam, QString file, int x, int y, int w, int h); - QPen textPen() const; - void updateOverlayObjects(); - void zoomNotch (bool inward); - - QColor getMainColor(); + ECamera camera() const; + QString cameraName (ECamera camera) const; + QByteArray capturePixels(); + void clearOverlay(); + void compileObject (LDObject* obj); + GLCompiler* compiler() const; + Vertex convert2dTo3d (const QPoint& pos2d, bool snap) const; + QPoint convert3dTo2d (const Vertex& pos3d); + QString currentCameraName() const; + EditModeType currentEditModeType() const; + int depthNegateFactor() const; + LDDocument* document() const; + void drawBlip (QPainter& paint, QPointF pos) const; + void drawGLScene(); + void forgetObject (LDObject* obj); + Axis getCameraAxis (bool y, ECamera camid = (ECamera) -1); + double getDepthValue() const; + const LDFixedCamera& getFixedCamera (ECamera cam) const; + LDGLOverlay& getOverlay (int newcam); + void getRelativeAxes (Axis& relX, Axis& relY) const; + Axis getRelativeZ() const; + void hardRefresh(); + void highlightCursorObject(); + void initGLData(); + void initOverlaysFromObjects(); + bool isDrawOnly() const; + bool isPicking() const; + Qt::KeyboardModifiers keyboardModifiers() const; + QPen linePen() const; + MessageManager* messageLog() const; + bool mouseHasMoved() const; + QPoint const& mousePosition() const; + QPointF const& mousePositionF() const; + void needZoomToFit(); + LDObject* objectAtCursor() const; + void pick (int mouseX, int mouseY, bool additive); + void pick (QRect const& range, bool additive); + LDObject* pickOneObject (int mouseX, int mouseY); + Vertex const& position3D() const; + void refresh(); + void resetAllAngles(); + void resetAngles(); + void setBackground(); + void setCamera (const ECamera cam); + void setDepthValue (double depth); + void setDocument (LDDocument* document); + void setDrawOnly (bool value); + void setEditMode (EditModeType type); + void setPicking (bool a); + bool setupOverlay (ECamera cam, QString file, int x, int y, int w, int h); + QPen textPen() const; + void updateOverlayObjects(); + void zoomNotch (bool inward); protected: - void contextMenuEvent (QContextMenuEvent* ev); - void dragEnterEvent (QDragEnterEvent* ev); - void dropEvent (QDropEvent* 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); + void contextMenuEvent (QContextMenuEvent* ev); + void dragEnterEvent (QDragEnterEvent* ev); + void dropEvent (QDropEvent* 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_position3D; - double m_virtWidth, - m_virtHeight; - bool m_darkbg, - m_drawToolTip, - m_screencap, - m_panning; - QPoint m_mousePosition, - m_globalpos; - QPointF m_mousePositionF; - QPen m_thinBorderPen; - ECamera m_camera, - m_toolTipCamera; - GLuint m_axeslist; - int m_width, - m_height, - m_totalmove; - QColor m_bgcolor; - AbstractEditMode* m_editmode; - GLuint m_axesVBO; - GLuint m_axesColorVBO; + MessageManager* m_messageLog; + LDDocument* m_document; + GLCompiler* m_compiler; + LDObject* m_objectAtCursor; - void calcCameraIcons(); - void clampAngle (double& angle) const; - inline LDGLData& currentDocumentData() const; - void drawVBOs (EVBOSurface surface, EVBOComplement colors, GLenum type); - void doMakeCurrent(); - LDOverlay* findOverlayObject (ECamera cam); - inline double& pan (Axis ax); - inline const double& pan (Axis ax) const; - inline double& rot (Axis ax); - inline double& zoom(); - void zoomToFit(); - void zoomAllToFit(); + CameraIcon m_cameraIcons[7]; + QTimer* m_toolTipTimer; + Qt::MouseButtons m_lastButtons; + Qt::KeyboardModifiers m_currentKeyboardModifiers; + Vertex m_position3D; + double m_virtualWidth; + double m_virtualHeight; + bool m_useDarkBackground; + bool m_drawToolTip; + bool m_takingScreenCapture; + bool m_panning; + bool m_initialized; + bool m_isDrawOnly; + bool m_isPicking; + bool m_isCameraMoving; + QPoint m_mousePosition; + QPoint m_globalpos; + QPointF m_mousePositionF; + QPen m_thinBorderPen; + ECamera m_camera; + ECamera m_toolTipCamera; + GLuint m_axeslist; + int m_width; + int m_height; + int m_totalMouseMove; + QColor m_backgroundColor; + AbstractEditMode* m_currentEditMode; + GLuint m_axesVbo; + GLuint m_axesColorVbo; + + void calcCameraIcons(); + void clampAngle (double& angle) const; + LDGLData& currentDocumentData() const; + void drawVbos (SurfaceVboType surface, ComplementVboType colors, GLenum type); + void doMakeCurrent(); + LDOverlay* findOverlayObject (ECamera cam); + double& panning (Axis ax); + double panning (Axis ax) const; + double& rotation (Axis ax); + double& zoom(); + void zoomToFit(); + void zoomAllToFit(); template<typename... Args> - inline QString format (QString fmtstr, Args... args) + QString format (QString fmtstr, Args... args) { return ::format (fmtstr, args...); } @@ -263,42 +268,3 @@ void slot_toolTipTimer(); void initializeAxes(); }; - -inline ECamera GLRenderer::camera() const -{ - return m_camera; -} - -inline LDGLData& GLRenderer::currentDocumentData() const -{ - return *document()->glData(); -} - -inline double& GLRenderer::rot (Axis ax) -{ - return - (ax == X) ? currentDocumentData().rotX : - (ax == Y) ? currentDocumentData().rotY : - currentDocumentData().rotZ; -} - -inline double& GLRenderer::pan (Axis ax) -{ - return (ax == X) ? currentDocumentData().panX[camera()] : - currentDocumentData().panY[camera()]; -} - -inline double const& GLRenderer::pan (Axis ax) const -{ - return (ax == X) ? currentDocumentData().panX[camera()] : - currentDocumentData().panY[camera()]; -} - -inline double& GLRenderer::zoom() -{ - return currentDocumentData().zoom[camera()]; -} - -LDFixedCamera const& GetFixedCamera (ECamera cam); - -extern const char* g_CameraNames[7];
--- a/src/glShared.h Sun Sep 06 03:17:29 2015 +0300 +++ b/src/glShared.h Sun Sep 06 04:48:58 2015 +0300 @@ -39,32 +39,37 @@ } }; -enum EVBOSurface +enum SurfaceVboType { - VBOSF_Lines, - VBOSF_Triangles, - VBOSF_Quads, - VBOSF_CondLines, + LinesVbo, + TrianglesVbo, + QuadsVbo, + ConditionalLinesVbo, - VBOSF_NumSurfaces, - VBOSF_First = VBOSF_Lines + NumSurfaceVbos, + FirstSurfaceVbo = LinesVbo }; -enum EVBOComplement +enum ComplementVboType { - VBOCM_Surfaces, - VBOCM_NormalColors, - VBOCM_PickColors, - VBOCM_BFCFrontColors, - VBOCM_BFCBackColors, - VBOCM_RandomColors, + SurfacesVboComplement, + NormalColorsVboComplement, + PickColorsVboComplement, + BfcFrontColorsVboComplement, + BfcBackColorsVboComplement, + RandomColorsVboComplement, - VBOCM_NumComplements, - VBOCM_First = VBOCM_Surfaces + NumVboComplements, + FirstVboComplement = SurfacesVboComplement }; -MAKE_ITERABLE_ENUM (EVBOSurface) -MAKE_ITERABLE_ENUM (EVBOComplement) +enum +{ + NumVbos = NumSurfaceVbos * NumVboComplements +}; + +MAKE_ITERABLE_ENUM (SurfaceVboType) +MAKE_ITERABLE_ENUM (ComplementVboType) #ifndef USE_QT5 // Placeholder QOpenGLFunctions for Qt 4.x support @@ -87,5 +92,3 @@ void glBufferData (GLuint, GLuint, void*, GLuint); void glBufferSubData (GLenum, GLint, GLsizei, void*); #endif - -static const int g_numVBOs = VBOSF_NumSurfaces * VBOCM_NumComplements;
--- a/src/guiutilities.cpp Sun Sep 06 03:17:29 2015 +0300 +++ b/src/guiutilities.cpp Sun Sep 06 04:48:58 2015 +0300 @@ -80,4 +80,15 @@ box->setItemData (row, it.key().index()); ++row; } -} \ No newline at end of file +} + +QColor GuiUtilities::mainColorRepresentation() +{ + QColor col (m_config->mainColor()); + + if (not col.isValid()) + return QColor (0, 0, 0); + + col.setAlpha (m_config->mainColorAlpha() * 255.f); + return col; +}
--- a/src/guiutilities.h Sun Sep 06 03:17:29 2015 +0300 +++ b/src/guiutilities.h Sun Sep 06 04:48:58 2015 +0300 @@ -28,4 +28,5 @@ QIcon makeColorIcon (LDColor ldcolor, int size); void fillUsedColorsToComboBox (class QComboBox* box); + QColor mainColorRepresentation(); };
--- a/src/mainwindow.cpp Sun Sep 06 03:17:29 2015 +0300 +++ b/src/mainwindow.cpp Sun Sep 06 04:48:58 2015 +0300 @@ -96,9 +96,6 @@ else updatePrimitives(); - m_msglog = new MessageManager; - m_msglog->setRenderer (renderer()); - m_renderer->setMessageLog (m_msglog); m_quickColors = LoadQuickColorList(); setStatusBar (new QStatusBar); updateActions(); @@ -448,7 +445,7 @@ case OBJ_Overlay: { LDOverlay* ovl = static_cast<LDOverlay*> (obj); - descr = format ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->camera()], + descr = format ("[%1] %2 (%3, %4), %5 x %6", renderer()->cameraName ((ECamera) ovl->camera()), Basename (ovl->fileName()), ovl->x(), ovl->y(), ovl->width(), ovl->height()); break; @@ -887,7 +884,7 @@ // Adds a message to the renderer's message manager. void MainWindow::addMessage (QString msg) { - m_msglog->addLine (msg); + m_renderer->messageLog()->addLine (msg); } // ============================================================================ @@ -1332,14 +1329,6 @@ // --------------------------------------------------------------------------------------------------------------------- // -QImage GetImageFromScreencap (uchar* data, int w, int h) -{ - // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well. - return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped().mirrored(); -} - -// --------------------------------------------------------------------------------------------------------------------- -// LDQuickColor::LDQuickColor (LDColor color, QToolButton* toolButton) : m_color (color), m_toolButton (toolButton) {}
--- a/src/mainwindow.h Sun Sep 06 03:17:29 2015 +0300 +++ b/src/mainwindow.h Sun Sep 06 04:48:58 2015 +0300 @@ -137,7 +137,6 @@ QList<LDQuickColor> m_quickColors; QList<QToolButton*> m_colorButtons; QList<QAction*> m_recentFiles; - MessageManager* m_msglog; class Ui_MainWindow& ui; QTabBar* m_tabs; bool m_updatingTabs; @@ -177,9 +176,6 @@ // Displays an error prompt with the given message void Critical (const QString& message); -// Returns a QImage from the given raw GL data -QImage GetImageFromScreencap (uchar* data, int w, int h); - // Takes in pairs of radio buttons and respective values and finds the first selected one. // Returns returns the value of the first found radio button that was checked by the user. template<class T>
--- a/src/toolsets/viewtoolset.cpp Sun Sep 06 03:17:29 2015 +0300 +++ b/src/toolsets/viewtoolset.cpp Sun Sep 06 04:48:58 2015 +0300 @@ -103,25 +103,24 @@ void ViewToolset::screenshot() { - setlocale (LC_ALL, "C"); - - int w, h; - uchar* imgdata = m_window->renderer()->getScreencap (w, h); - QImage img = GetImageFromScreencap (imgdata, w, h); - + const char* imageformats = "PNG images (*.png);;JPG images (*.jpg);;BMP images (*.bmp);;" + "PPM images (*.ppm);;X11 Bitmaps (*.xbm);;X11 Pixmaps (*.xpm);;All Files (*.*)"; + int width = m_window->renderer()->width(); + int height = m_window->renderer()->height(); + QByteArray capture = m_window->renderer()->capturePixels(); + const uchar* imagedata = reinterpret_cast<const uchar*> (capture.constData()); + // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well. + QImage image = QImage (imagedata, width, height, QImage::Format_ARGB32).rgbSwapped().mirrored(); QString root = Basename (currentDocument()->name()); if (root.right (4) == ".dat") root.chop (4); QString defaultname = (root.length() > 0) ? format ("%1.png", root) : ""; - QString fname = QFileDialog::getSaveFileName (m_window, "Save Screencap", defaultname, - "PNG images (*.png);;JPG images (*.jpg);;BMP images (*.bmp);;All Files (*.*)"); + QString filename = QFileDialog::getSaveFileName (m_window, "Save Screencap", defaultname, imageformats); - if (not fname.isEmpty() and not img.save (fname)) - Critical (format ("Couldn't open %1 for writing to save screencap: %2", fname, strerror (errno))); - - delete[] imgdata; + if (not filename.isEmpty() and not image.save (filename)) + Critical (format ("Couldn't open %1 for writing to save screencap: %2", filename, strerror (errno))); } void ViewToolset::axes() @@ -184,7 +183,7 @@ bool ok; double depth = QInputDialog::getDouble (m_window, "Set Draw Depth", - format ("Depth value for %1 Camera:", m_window->renderer()->getCameraName()), + format ("Depth value for %1:", m_window->renderer()->currentCameraName()), m_window->renderer()->getDepthValue(), -10000.0f, 10000.0f, 3, &ok); if (ok)