Wed, 25 May 2022 20:36:34 +0300
Fix pick() picking from weird places on the screen with high DPI scaling
glReadPixels reads data from the frame buffer, which contains data after
high DPI scaling, so any reads to that need to take this scaling into account
#pragma once #include <QPainter> #include <QBrush> #include <QPen> #include "gl/partrenderer.h" #include "gl/gridprogram.h" #include "gl/axesprogram.h" #include "gl/vertexprogram.h" enum EditingMode { SelectMode, DrawMode }; struct DrawState { std::vector<glm::vec3> polygon; std::vector<glm::vec3> previewPolygon; glm::vec3 previewPoint; bool isconcave = false; EditingMode mode = SelectMode; }; class Canvas : public PartRenderer { Q_OBJECT public: using OverpaintCallback = std::function<void(Canvas*, QPainter*)>; Canvas( Model* model, Document* document, DocumentManager* documents, const ldraw::ColorTable& colorTable, QWidget* parent = nullptr); void setOverpaintCallback(OverpaintCallback fn); void drawWorldPoint(QPainter* painter, const glm::vec3& worldPoint) const; void drawWorldPolyline(QPainter* painter, const std::vector<glm::vec3>& points); void drawWorldPolygon(QPainter* painter, const std::vector<glm::vec3>& points); Winding worldPolygonWinding(const std::vector<glm::vec3>& points) const; const std::optional<glm::vec3>& getWorldPosition() const; const QSet<ldraw::id_t> selectedObjects() const; const glm::mat4& getGridMatrix() const; void closeShape(); glm::vec3 cameraVector() const; std::optional<glm::vec3> worldPosition; DrawState* drawState = nullptr; public Q_SLOTS: void handleSelectionChange(const QSet<ldraw::id_t>& selectedIds, const QSet<ldraw::id_t>& deselectedIds); void rebuildVertices(Document *document); void setGridMatrix(const glm::mat4 &newMatrix); protected: void mouseMoveEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; void initializeGL() override; void paintGL() override; Q_SIGNALS: void newStatusText(const QString& newStatusText); void mouseClick(QMouseEvent* event); void mouseMove(QMouseEvent* event); private: bool isGridPerpendicularToScreen(float threshold) const; QVector<QPointF> convertWorldPointsToScreenPoints(const std::vector<glm::vec3>& worldPoints) const; Q_SLOT void updateCanvasRenderPreferences(); void renderAxesLabels(QPainter& painter); std::optional<GridProgram> gridProgram; std::optional<AxesProgram> axesProgram; std::optional<VertexProgram> vertexProgram; glm::mat4 gridMatrix; geom::Plane gridPlane; int totalMouseMove = 0; bool isDark = true; QSet<ldraw::id_t> selection; OverpaintCallback overpaintCallback = nullptr; Document* document; }; void adjustGridToView(Canvas* canvas);