diff --git a/basedevice.h b/basedevice.h index bb63e31..d14db8e 100644 --- a/basedevice.h +++ b/basedevice.h @@ -2,12 +2,7 @@ #include -template -struct SamplePairT { - T x, y; -}; - -typedef SamplePairT SamplePair; +#include "oscicommon.h" class BaseDevice : public QObject { diff --git a/fakedevice.cpp b/fakedevice.cpp index a7b448d..b354cdf 100644 --- a/fakedevice.cpp +++ b/fakedevice.cpp @@ -34,8 +34,8 @@ void FakeDevice::timerEvent(QTimerEvent *event) pair != m_buffer.get() + m_bufferSize; pair++) { - pair->x = std::sin(m_dingsDesHaltHochZaehlt) * std::numeric_limits::max(); - pair->y = std::cos(m_dingsDesHaltHochZaehlt) * std::numeric_limits::max(); + pair->first = std::sin(m_dingsDesHaltHochZaehlt) * std::numeric_limits::max(); + pair->second = std::cos(m_dingsDesHaltHochZaehlt) * std::numeric_limits::max(); m_dingsDesHaltHochZaehlt += 0.05; } diff --git a/mainwindow.cpp b/mainwindow.cpp index 99fe156..fe8fa54 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -46,14 +46,6 @@ MainWindow::MainWindow(QWidget *parent) : m_ui->widget->setFps(m_ui->comboBoxFps->currentData().toInt()); }); - m_ui->spinBoxBlend->setValue(m_ui->widget->blend()); - - connect(m_ui->spinBoxBlend, qOverload(&QSpinBox::valueChanged), m_ui->widget, &OsciWidget::setBlend); - - m_ui->spinBoxGlow->setValue(m_ui->widget->glow()); - - connect(m_ui->spinBoxGlow, qOverload(&QSpinBox::valueChanged), m_ui->widget, &OsciWidget::setGlow); - auto buttonGroup = new QButtonGroup; buttonGroup->setExclusive(true); for (auto factor : { .5f, 1.f, 2.f, 4.f, 8.f }) diff --git a/mainwindow.ui b/mainwindow.ui index 461ef30..73b5d8a 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -52,39 +52,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - blend - - - 255 - - - - - - - glow - - - 65535 - - - diff --git a/oscicommon.h b/oscicommon.h new file mode 100644 index 0000000..a02c40d --- /dev/null +++ b/oscicommon.h @@ -0,0 +1,11 @@ +#pragma once + +// Qt includes +#include + +template +struct SamplePairT { + T first, second; +}; + +using SamplePair = SamplePairT; diff --git a/oscilloscope.pro b/oscilloscope.pro index b9b6375..b8f279d 100644 --- a/oscilloscope.pro +++ b/oscilloscope.pro @@ -16,6 +16,7 @@ HEADERS += \ basedevice.h \ fakedevice.h \ mainwindow.h \ + oscicommon.h \ osciwidget.h OTHER_FILES += \ diff --git a/osciwidget.cpp b/osciwidget.cpp index 4d9fe34..f53965d 100644 --- a/osciwidget.cpp +++ b/osciwidget.cpp @@ -8,110 +8,26 @@ #include OsciWidget::OsciWidget(QWidget *parent) : - QWidget{parent}, + QOpenGLWidget{parent}, m_redrawTimerId(startTimer(1000/m_fps)) { - resizePixmap(); m_fpsTimer.start(); } -int OsciWidget::blend() const -{ - return m_blend; -} - -float OsciWidget::factor() const -{ - return m_factor; -} - -float OsciWidget::glow() const -{ - return m_glow; -} - -int OsciWidget::fps() const -{ - return m_fps; -} - -void OsciWidget::setBlend(int blend) -{ - if (blend == m_blend) - return; - - qDebug() << blend; - - m_blend = blend; -} - -void OsciWidget::setFactor(float factor) -{ - qDebug() << factor; - m_factor = factor; -} - -void OsciWidget::setGlow(float glow) -{ - qDebug() << glow; - m_glow = glow; -} - void OsciWidget::setFps(int fps) { - qDebug() << fps; killTimer(m_redrawTimerId); + m_fps = fps; + m_redrawTimerId = startTimer(1000/m_fps); } void OsciWidget::renderSamples(const SamplePair *begin, const SamplePair *end) { - QPainter painter; - painter.begin(&m_pixmap); - painter.setCompositionMode(QPainter::CompositionMode_Plus); + m_callbacksCounter++; - QPen pen; - pen.setWidth(2); - pen.setColor(QColor(0, 255, 0)); - painter.setPen(pen); - - // Paint from center - painter.translate(m_pixmap.width()/2, m_pixmap.height()/2); - - const auto pointToCoordinates = [width=m_pixmap.width()/2,height=m_pixmap.height()/2,factor=m_factor](const QPointF &point) - { - return QPoint{ - int(point.x() * factor * width), - int(point.y() * factor * height) - }; - }; - - for (auto i = begin; i < end; i++) - { - const QPointF p{ - float(i->x) / std::numeric_limits::max(), - float(-i->y) / std::numeric_limits::max() - }; - - const QLineF line(m_lastPoint, p); - - auto brightness = 1.f / line.length() / m_glow; - if (line.length() == 0.f || brightness > 255.f) - brightness = 255.f; - - painter.setOpacity(brightness); - - painter.drawLine(pointToCoordinates(m_lastPoint), pointToCoordinates(p)); - - m_lastPoint = p; - } - - painter.resetTransform(); - painter.setCompositionMode(QPainter::CompositionMode_Multiply); - painter.fillRect(m_pixmap.rect(), QColor(m_blend,m_blend,m_blend)); - - painter.end(); + m_buffer.insert(m_buffer.end(), begin, end); } void OsciWidget::paintEvent(QPaintEvent *event) @@ -121,25 +37,64 @@ void OsciWidget::paintEvent(QPaintEvent *event) m_frameCounter++; if (m_fpsTimer.hasExpired(1000)) { - m_displayFrameCounter = m_frameCounter; + m_statsDisplay = QString("%0FPS (%1 callbacks)").arg(m_frameCounter).arg(m_callbacksCounter); m_frameCounter = 0; + m_callbacksCounter = 0; m_fpsTimer.restart(); } QPainter painter; painter.begin(this); - painter.drawPixmap(0, 0, m_pixmap); + // draw background + painter.setBrush(Qt::black); + painter.drawRect(rect()); + + // drawing new lines ontop + QPen pen; + pen.setWidth(2); + pen.setColor(QColor(0, 255, 0)); + painter.setPen(pen); + painter.translate(width()/2, height()/2); + painter.setCompositionMode(QPainter::CompositionMode_Plus); + + const auto pointToCoordinates = [width=width()/2,height=height()/2,factor=m_factor](const QPointF &point) + { + return QPoint{ + int(point.x() * factor * width), + int(point.y() * factor * height) + }; + }; + + for (const auto &i : m_buffer) + { + const QPointF p{ + float(i.first) / std::numeric_limits::max(), + float(-i.second) / std::numeric_limits::max() + }; + + const QLineF line(m_lastPoint, p); + + painter.setOpacity(std::min(1.0, 1. / ((line.length() * 100) + 1))); + + painter.drawLine(pointToCoordinates(m_lastPoint), pointToCoordinates(p)); + + m_lastPoint = p; + } + + painter.resetTransform(); + painter.setOpacity(1); + + m_buffer.clear(); + + // draw stats painter.setPen(Qt::white); painter.setBrush(Qt::white); QFont font; font.setPixelSize(24); - painter.drawText(20, 20, QString("%0FPS").arg(m_displayFrameCounter)); + painter.drawText(20, 20, m_statsDisplay); painter.end(); - - if (m_pixmap.rect() != rect()) - qDebug() << m_pixmap.rect() << rect(); } void OsciWidget::timerEvent(QTimerEvent *event) @@ -148,15 +103,3 @@ void OsciWidget::timerEvent(QTimerEvent *event) if (event->timerId() == m_redrawTimerId) repaint(); } - -void OsciWidget::resizeEvent(QResizeEvent *event) -{ - QWidget::resizeEvent(event); - resizePixmap(); -} - -void OsciWidget::resizePixmap() -{ - m_pixmap = QPixmap(size()); - m_pixmap.fill(QColor{}); -} diff --git a/osciwidget.h b/osciwidget.h index cf141c2..ae2cc1c 100644 --- a/osciwidget.h +++ b/osciwidget.h @@ -1,52 +1,48 @@ #pragma once -#include +// Qt includes +#include #include #include #include -#include "audiodevice.h" +// system includes +#include -class OsciWidget : public QWidget +// local includes +#include "oscicommon.h" + +class OsciWidget : public QOpenGLWidget { Q_OBJECT public: explicit OsciWidget(QWidget *parent = nullptr); - int blend() const; - float factor() const; - float glow() const; - int fps() const; + float factor() const { return m_factor; } + int fps() const { return m_fps; } public slots: - void setBlend(int blend); - void setFactor(float factor); - void setGlow(float glow); + void setFactor(float factor) { m_factor = factor; } void setFps(int fps); void renderSamples(const SamplePair *begin, const SamplePair *end); protected: void paintEvent(QPaintEvent *event) override; - void resizeEvent(QResizeEvent *event) override; void timerEvent(QTimerEvent *event) override; private: - void resizePixmap(); - void createBlendPixmap(); - - int m_blend{150}; - float m_factor{4.f}; - float m_glow{512.f}; - - QPixmap m_pixmap; + float m_factor{2.f}; QPointF m_lastPoint; - int m_frameCounter{0}, m_displayFrameCounter{0}; + int m_frameCounter{0}, m_callbacksCounter{0}; + QString m_statsDisplay; QElapsedTimer m_fpsTimer; int m_fps{15}; int m_redrawTimerId; + + std::vector m_buffer; };