diff options
author | Eddie Hung <e.hung@imperial.ac.uk> | 2018-07-26 21:00:26 -0700 |
---|---|---|
committer | Eddie Hung <e.hung@imperial.ac.uk> | 2018-07-26 21:00:26 -0700 |
commit | d5c2332ebf5dd9b84e3a6fd2a99e8df70150bd33 (patch) | |
tree | 0f641516654085dd24bb69889ef466041234f684 /gui/fpgaviewwidget.h | |
parent | f45e688354c13f38bda3ba4064587880a25980fe (diff) | |
parent | e5acd80247264fed41dfc1e7e07efa8a10a67fae (diff) | |
download | nextpnr-d5c2332ebf5dd9b84e3a6fd2a99e8df70150bd33.tar.gz nextpnr-d5c2332ebf5dd9b84e3a6fd2a99e8df70150bd33.tar.bz2 nextpnr-d5c2332ebf5dd9b84e3a6fd2a99e8df70150bd33.zip |
Merge remote-tracking branch 'origin/master' into redist_slack
Diffstat (limited to 'gui/fpgaviewwidget.h')
-rw-r--r-- | gui/fpgaviewwidget.h | 236 |
1 files changed, 30 insertions, 206 deletions
diff --git a/gui/fpgaviewwidget.h b/gui/fpgaviewwidget.h index b87c5d0a..260ebf05 100644 --- a/gui/fpgaviewwidget.h +++ b/gui/fpgaviewwidget.h @@ -33,183 +33,10 @@ #include <QWaitCondition> #include "nextpnr.h" +#include "lineshader.h" NEXTPNR_NAMESPACE_BEGIN -// Vertex2DPOD is a structure of X, Y coordinates that can be passed to OpenGL -// directly. -NPNR_PACKED_STRUCT(struct Vertex2DPOD { - GLfloat x; - GLfloat y; - - Vertex2DPOD(GLfloat X, GLfloat Y) : x(X), y(Y) {} -}); - -// LineShaderData is a built set of vertices that can be rendered by the -// LineShader. -// Each LineShaderData can have its' own color and thickness. -struct LineShaderData -{ - std::vector<Vertex2DPOD> vertices; - std::vector<Vertex2DPOD> normals; - std::vector<GLfloat> miters; - std::vector<GLuint> indices; - - LineShaderData(void) {} - - void clear(void) - { - vertices.clear(); - normals.clear(); - miters.clear(); - indices.clear(); - } -}; - -// PolyLine is a set of segments defined by points, that can be built to a -// ShaderLine for GPU rendering. -class PolyLine -{ - private: - std::vector<QVector2D> points_; - bool closed_; - - void buildPoint(LineShaderData *building, const QVector2D *prev, const QVector2D *cur, const QVector2D *next) const; - - public: - // Create an empty PolyLine. - PolyLine(bool closed = false) : closed_(closed) {} - - // Create a non-closed polyline consisting of one segment. - PolyLine(float x0, float y0, float x1, float y1) : closed_(false) - { - point(x0, y0); - point(x1, y1); - } - - // Add a point to the PolyLine. - void point(float x, float y) { points_.push_back(QVector2D(x, y)); } - - // Built PolyLine to shader data. - void build(LineShaderData &target) const; - - // Set whether line is closed (ie. a loop). - void setClosed(bool closed) { closed_ = closed; } -}; - -// LineShader is an OpenGL shader program that renders LineShaderData on the -// GPU. -// The LineShader expects two vertices per line point. It will push those -// vertices along the given normal * miter. This is used to 'stretch' the line -// to be as wide as the given thickness. The normal and miter are calculated -// by the PolyLine build method in order to construct a constant thickness line -// with miter edge joints. -// -// +------+------+ -// -// | -// PolyLine.build() -// | -// V -// -// ^ ^ ^ -// | | | <--- normal vectors (x2, pointing in the same -// +/+----+/+----+/+ direction) -// -// | -// vertex shader -// | -// V -// -// +------+------+ ^ by normal * miter * thickness/2 -// | | | -// +------+------+ V by normal * miter * thickness/2 -// -// (miter is flipped for every second vertex generated) -class LineShader -{ - private: - QObject *parent_; - QOpenGLShaderProgram *program_; - - // GL attribute locations. - struct - { - // original position of line vertex - GLuint position; - // normal by which vertex should be translated - GLuint normal; - // scalar defining: - // - how stretched the normal vector should be to - // compensate for bends - // - which way the normal should be applied (+1 for one vertex, -1 - // for the other) - GLuint miter; - } attributes_; - - // GL buffers - struct - { - QOpenGLBuffer position; - QOpenGLBuffer normal; - QOpenGLBuffer miter; - QOpenGLBuffer index; - } buffers_; - - // GL uniform locations. - struct - { - // combines m/v/p matrix to apply - GLuint projection; - // desired thickness of line - GLuint thickness; - // color of line - GLuint color; - } uniforms_; - - QOpenGLVertexArrayObject vao_; - - public: - LineShader(QObject *parent) : parent_(parent), program_(nullptr) - { - buffers_.position = QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); - buffers_.position.setUsagePattern(QOpenGLBuffer::StaticDraw); - - buffers_.normal = QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); - buffers_.normal.setUsagePattern(QOpenGLBuffer::StaticDraw); - - buffers_.miter = QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); - buffers_.miter.setUsagePattern(QOpenGLBuffer::StaticDraw); - - buffers_.index = QOpenGLBuffer(QOpenGLBuffer::IndexBuffer); - buffers_.index.setUsagePattern(QOpenGLBuffer::StaticDraw); - } - - static constexpr const char *vertexShaderSource_ = - "#version 110\n" - "attribute highp vec2 position;\n" - "attribute highp vec2 normal;\n" - "attribute highp float miter;\n" - "uniform highp float thickness;\n" - "uniform highp mat4 projection;\n" - "void main() {\n" - " vec2 p = position.xy + vec2(normal * thickness/2.0 / miter);\n" - " gl_Position = projection * vec4(p, 0.0, 1.0);\n" - "}\n"; - - static constexpr const char *fragmentShaderSource_ = "#version 110\n" - "uniform lowp vec4 color;\n" - "void main() {\n" - " gl_FragColor = color;\n" - "}\n"; - - // Must be called on initialization. - bool compile(void); - - // Render a LineShaderData with a given M/V/P transformation. - void draw(const LineShaderData &data, const QColor &color, float thickness, const QMatrix4x4 &projection); -}; - class PeriodicRunner : public QThread { Q_OBJECT @@ -267,53 +94,43 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions FPGAViewWidget(QWidget *parent = 0); ~FPGAViewWidget(); - QSize minimumSizeHint() const override; - QSize sizeHint() const override; - - void setXTranslation(float t_x); - void setYTranslation(float t_y); - void setZoom(float t_z); - - void xRotationChanged(int angle); - void yRotationChanged(int angle); - void zRotationChanged(int angle); - protected: + // Qt callbacks. void initializeGL() Q_DECL_OVERRIDE; void paintGL() Q_DECL_OVERRIDE; void resizeGL(int width, int height) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - void drawDecal(LineShaderData &data, const DecalXY &decal); - void drawDecal(LineShaderData out[], const DecalXY &decal); + QSize minimumSizeHint() const override; + QSize sizeHint() const override; + + public Q_SLOTS: void newContext(Context *ctx); void onSelectedArchItem(std::vector<DecalXY> decals); void onHighlightGroupChanged(std::vector<DecalXY> decals, int group); void pokeRenderer(void); + void zoomIn(); + void zoomOut(); + void zoomSelected(); + void zoomOutbound(); private: - void renderLines(void); - - QPoint lastPos_; - LineShader lineShader_; - QMatrix4x4 viewMove_; - float zoom_; - QMatrix4x4 getProjection(void); - QVector4D mouseToWorldCoordinates(int x, int y); - const float zoomNear_ = 1.0f; // do not zoom closer than this const float zoomFar_ = 10000.0f; // do not zoom further than this - const float zoomLvl1_ = 100.0f; const float zoomLvl2_ = 50.0f; Context *ctx_; QTimer paintTimer_; - std::unique_ptr<PeriodicRunner> renderRunner_; + QPoint lastDragPos_; + LineShader lineShader_; + QMatrix4x4 viewMove_; + float zoom_; + struct { QColor background; @@ -328,22 +145,29 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions struct RendererData { - LineShaderData decals[4]; - LineShaderData selected; - LineShaderData highlighted[8]; + LineShaderData gfxByStyle[GraphicElement::STYLE_MAX]; + LineShaderData gfxSelected; + LineShaderData gfxHighlighted[8]; }; + std::unique_ptr<RendererData> rendererData_; + QMutex rendererDataLock_; struct RendererArgs { - std::vector<DecalXY> selectedItems; - std::vector<DecalXY> highlightedItems[8]; + std::vector<DecalXY> selectedDecals; + std::vector<DecalXY> highlightedDecals[8]; bool highlightedOrSelectedChanged; }; - - std::unique_ptr<RendererData> rendererData_; - QMutex rendererDataLock_; std::unique_ptr<RendererArgs> rendererArgs_; QMutex rendererArgsLock_; + + void zoom(int level); + void renderLines(void); + void drawGraphicElement(LineShaderData &out, const GraphicElement &el, float x, float y); + void drawDecal(LineShaderData &out, const DecalXY &decal); + void drawArchDecal(LineShaderData out[GraphicElement::STYLE_MAX], const DecalXY &decal); + QVector4D mouseToWorldCoordinates(int x, int y); + QMatrix4x4 getProjection(void); }; NEXTPNR_NAMESPACE_END |