diff options
Diffstat (limited to 'gui/fpgaviewwidget.cc')
-rw-r--r-- | gui/fpgaviewwidget.cc | 211 |
1 files changed, 0 insertions, 211 deletions
diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc index d87c26a3..de73e27b 100644 --- a/gui/fpgaviewwidget.cc +++ b/gui/fpgaviewwidget.cc @@ -31,217 +31,6 @@ NEXTPNR_NAMESPACE_BEGIN -void PolyLine::buildPoint(LineShaderData *building, const QVector2D *prev, const QVector2D *cur, - const QVector2D *next) const -{ - // buildPoint emits two vertices per line point, along with normals to move - // them the right directio when rendering and miter to compensate for - // bends. - - if (cur == nullptr) { - // BUG - return; - } - - if (prev == nullptr && next == nullptr) { - // BUG - return; - } - - // TODO(q3k): fast path for vertical/horizontal lines? - - // TODO(q3k): consider moving some of the linear algebra to the GPU, - // they're better at this than poor old CPUs. - - // Build two unit vectors pointing in the direction of the two segments - // defined by (prev, cur) and (cur, next) - QVector2D dprev, dnext; - if (prev == nullptr) { - dnext = *next - *cur; - dprev = dnext; - } else if (next == nullptr) { - dprev = *cur - *prev; - dnext = dprev; - } else { - dprev = *cur - *prev; - dnext = *next - *cur; - } - dprev.normalize(); - dnext.normalize(); - - // Calculate tangent unit vector. - QVector2D tangent(dprev + dnext); - tangent.normalize(); - - // Calculate normal to tangent - this is the line on which the vectors need - // to be pushed to build a thickened line. - const QVector2D tangent_normal = QVector2D(-tangent.y(), tangent.x()); - - // Calculate normal to one of the lines. - const QVector2D dprev_normal = QVector2D(-dprev.y(), dprev.x()); - // https://people.eecs.berkeley.edu/~sequin/CS184/IMGS/Sweep_PolyLine.jpg - // (the ^-1 is performed in the shader) - const float miter = QVector2D::dotProduct(tangent_normal, dprev_normal); - - const float x = cur->x(); - const float y = cur->y(); - const float mx = tangent_normal.x(); - const float my = tangent_normal.y(); - - // Push back 'left' vertex. - building->vertices.push_back(Vertex2DPOD(x, y)); - building->normals.push_back(Vertex2DPOD(mx, my)); - building->miters.push_back(miter); - - // Push back 'right' vertex. - building->vertices.push_back(Vertex2DPOD(x, y)); - building->normals.push_back(Vertex2DPOD(mx, my)); - building->miters.push_back(-miter); -} - -void PolyLine::build(LineShaderData &target) const -{ - if (points_.size() < 2) { - return; - } - const QVector2D *first = &points_.front(); - const QVector2D *last = &points_.back(); - - // Index number of vertices, used to build the index buffer. - unsigned int startIndex = target.vertices.size(); - unsigned int index = startIndex; - - // For every point on the line, call buildPoint with (prev, point, next). - // If we're building a closed line, prev/next wrap around. Otherwise - // they are passed as nullptr and buildPoint interprets that accordinglu. - const QVector2D *prev = nullptr; - - // Loop iterator used to ensure next is valid. - unsigned int i = 0; - for (const QVector2D &point : points_) { - const QVector2D *next = nullptr; - if (++i < points_.size()) { - next = (&point + 1); - } - - // If the line is closed, wrap around. Otherwise, pass nullptr. - if (prev == nullptr && closed_) { - buildPoint(&target, last, &point, next); - } else if (next == nullptr && closed_) { - buildPoint(&target, prev, &point, first); - } else { - buildPoint(&target, prev, &point, next); - } - - // If we have a prev point relative to cur, build a pair of triangles - // to render vertices into lines. - if (prev != nullptr) { - target.indices.push_back(index); - target.indices.push_back(index + 1); - target.indices.push_back(index + 2); - - target.indices.push_back(index + 2); - target.indices.push_back(index + 1); - target.indices.push_back(index + 3); - - index += 2; - } - prev = &point; - } - - // If we're closed, build two more vertices that loop the line around. - if (closed_) { - target.indices.push_back(index); - target.indices.push_back(index + 1); - target.indices.push_back(startIndex); - - target.indices.push_back(startIndex); - target.indices.push_back(index + 1); - target.indices.push_back(startIndex + 1); - } -} - -bool LineShader::compile(void) -{ - program_ = new QOpenGLShaderProgram(parent_); - program_->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource_); - program_->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource_); - if (!program_->link()) { - printf("could not link program: %s\n", program_->log().toStdString().c_str()); - return false; - } - - if (!vao_.create()) - log_abort(); - vao_.bind(); - - if (!buffers_.position.create()) - log_abort(); - if (!buffers_.normal.create()) - log_abort(); - if (!buffers_.miter.create()) - log_abort(); - if (!buffers_.index.create()) - log_abort(); - - attributes_.position = program_->attributeLocation("position"); - attributes_.normal = program_->attributeLocation("normal"); - attributes_.miter = program_->attributeLocation("miter"); - uniforms_.thickness = program_->uniformLocation("thickness"); - uniforms_.projection = program_->uniformLocation("projection"); - uniforms_.color = program_->uniformLocation("color"); - - vao_.release(); - return true; -} - -void LineShader::draw(const LineShaderData &line, const QColor &color, float thickness, const QMatrix4x4 &projection) -{ - auto gl = QOpenGLContext::currentContext()->functions(); - if (line.vertices.size() == 0) - return; - vao_.bind(); - program_->bind(); - - buffers_.position.bind(); - buffers_.position.allocate(&line.vertices[0], sizeof(Vertex2DPOD) * line.vertices.size()); - - buffers_.normal.bind(); - buffers_.normal.allocate(&line.normals[0], sizeof(Vertex2DPOD) * line.normals.size()); - - buffers_.miter.bind(); - buffers_.miter.allocate(&line.miters[0], sizeof(GLfloat) * line.miters.size()); - - buffers_.index.bind(); - buffers_.index.allocate(&line.indices[0], sizeof(GLuint) * line.indices.size()); - - program_->setUniformValue(uniforms_.projection, projection); - program_->setUniformValue(uniforms_.thickness, thickness); - program_->setUniformValue(uniforms_.color, color.redF(), color.greenF(), color.blueF(), color.alphaF()); - - buffers_.position.bind(); - program_->enableAttributeArray("position"); - gl->glVertexAttribPointer(attributes_.position, 2, GL_FLOAT, GL_FALSE, 0, (void *)0); - - buffers_.normal.bind(); - program_->enableAttributeArray("normal"); - gl->glVertexAttribPointer(attributes_.normal, 2, GL_FLOAT, GL_FALSE, 0, (void *)0); - - buffers_.miter.bind(); - program_->enableAttributeArray("miter"); - gl->glVertexAttribPointer(attributes_.miter, 1, GL_FLOAT, GL_FALSE, 0, (void *)0); - - buffers_.index.bind(); - gl->glDrawElements(GL_TRIANGLES, line.indices.size(), GL_UNSIGNED_INT, (void *)0); - - program_->disableAttributeArray("miter"); - program_->disableAttributeArray("normal"); - program_->disableAttributeArray("position"); - - program_->release(); - vao_.release(); -} - FPGAViewWidget::FPGAViewWidget(QWidget *parent) : QOpenGLWidget(parent), ctx_(nullptr), paintTimer_(this), lineShader_(this), zoom_(500.0f), |