Commit c19372354698f6689f50be839fdb27e4e8449e5c
Committed by
David Gräff
1 parent
0f3e1d63
Use OpenGL 3.2 instead of 3.3 to make it work on MacOSX
Fix: * Move all GL startup calls to GLScope::fixOpenGLversion * Depending on OpenGL or ES availability initialize the QSurfaceFormat * Don't crash if the shader compilation failed. Show a nice message instead. Optimize: * Don't write the markers to the GPU each frame update, only do this if they actually changed position. Code style: * LevelSlider: Don't return a value for set* Methods. * Don't rely on the LevelSliders step to calculate the marker position in the OpenGL view.
Showing
8 changed files
with
197 additions
and
136 deletions
openhantek/src/dsowidget.cpp
| @@ -5,8 +5,8 @@ | @@ -5,8 +5,8 @@ | ||
| 5 | #include <QFileDialog> | 5 | #include <QFileDialog> |
| 6 | #include <QGridLayout> | 6 | #include <QGridLayout> |
| 7 | #include <QLabel> | 7 | #include <QLabel> |
| 8 | -#include <QTimer> | ||
| 9 | #include <QSignalBlocker> | 8 | #include <QSignalBlocker> |
| 9 | +#include <QTimer> | ||
| 10 | 10 | ||
| 11 | #include "dsowidget.h" | 11 | #include "dsowidget.h" |
| 12 | 12 | ||
| @@ -37,11 +37,12 @@ DsoWidget::DsoWidget(DsoSettingsScope *scope, DsoSettingsView *view, const Dso:: | @@ -37,11 +37,12 @@ DsoWidget::DsoWidget(DsoSettingsScope *scope, DsoSettingsView *view, const Dso:: | ||
| 37 | setupSliders(mainSliders); | 37 | setupSliders(mainSliders); |
| 38 | setupSliders(zoomSliders); | 38 | setupSliders(zoomSliders); |
| 39 | 39 | ||
| 40 | - connect(mainScope, &GlScope::markerMoved, [this] (int marker, double position) { | ||
| 41 | - double step = this->mainSliders.markerSlider->step(marker); | 40 | + connect(mainScope, &GlScope::markerMoved, [this](int marker, double position) { |
| 41 | + double value = std::round(position / MARKER_STEP) * MARKER_STEP; | ||
| 42 | 42 | ||
| 43 | - this->scope->horizontal.marker[marker] = | ||
| 44 | - this->mainSliders.markerSlider->setValue(marker, std::round(position / step) * step); | 43 | + this->scope->horizontal.marker[marker] = value; |
| 44 | + this->mainSliders.markerSlider->setValue(marker, value); | ||
| 45 | + this->mainScope->markerUpdated(); | ||
| 45 | }); | 46 | }); |
| 46 | 47 | ||
| 47 | // The table for the settings | 48 | // The table for the settings |
| @@ -175,14 +176,6 @@ DsoWidget::DsoWidget(DsoSettingsScope *scope, DsoSettingsView *view, const Dso:: | @@ -175,14 +176,6 @@ DsoWidget::DsoWidget(DsoSettingsScope *scope, DsoSettingsView *view, const Dso:: | ||
| 175 | mainLayout->setRowMinimumHeight(row++, 8); | 176 | mainLayout->setRowMinimumHeight(row++, 8); |
| 176 | mainLayout->addLayout(measurementLayout, row++, 0, 1, 5); | 177 | mainLayout->addLayout(measurementLayout, row++, 0, 1, 5); |
| 177 | 178 | ||
| 178 | - // Apply settings and update measured values | ||
| 179 | - updateTriggerDetails(); | ||
| 180 | - updateRecordLength(scope->horizontal.recordLength); | ||
| 181 | - updateFrequencybase(scope->horizontal.frequencybase); | ||
| 182 | - updateSamplerate(scope->horizontal.samplerate); | ||
| 183 | - updateTimebase(scope->horizontal.timebase); | ||
| 184 | - updateZoom(view->zoom); | ||
| 185 | - | ||
| 186 | // The widget itself | 179 | // The widget itself |
| 187 | setPalette(palette); | 180 | setPalette(palette); |
| 188 | setBackgroundRole(QPalette::Background); | 181 | setBackgroundRole(QPalette::Background); |
| @@ -205,9 +198,6 @@ DsoWidget::DsoWidget(DsoSettingsScope *scope, DsoSettingsView *view, const Dso:: | @@ -205,9 +198,6 @@ DsoWidget::DsoWidget(DsoSettingsScope *scope, DsoSettingsView *view, const Dso:: | ||
| 205 | zoomScope->update(); | 198 | zoomScope->update(); |
| 206 | }); | 199 | }); |
| 207 | zoomSliders.markerSlider->setEnabled(false); | 200 | zoomSliders.markerSlider->setEnabled(false); |
| 208 | - | ||
| 209 | - updateTriggerSource(); | ||
| 210 | - adaptTriggerPositionSlider(); | ||
| 211 | } | 201 | } |
| 212 | 202 | ||
| 213 | void DsoWidget::setupSliders(DsoWidget::Sliders &sliders) { | 203 | void DsoWidget::setupSliders(DsoWidget::Sliders &sliders) { |
| @@ -242,11 +232,10 @@ void DsoWidget::setupSliders(DsoWidget::Sliders &sliders) { | @@ -242,11 +232,10 @@ void DsoWidget::setupSliders(DsoWidget::Sliders &sliders) { | ||
| 242 | sliders.triggerLevelSlider = new LevelSlider(Qt::LeftArrow); | 232 | sliders.triggerLevelSlider = new LevelSlider(Qt::LeftArrow); |
| 243 | for (ChannelID channel = 0; channel < spec->channels; ++channel) { | 233 | for (ChannelID channel = 0; channel < spec->channels; ++channel) { |
| 244 | sliders.triggerLevelSlider->addSlider((int)channel); | 234 | sliders.triggerLevelSlider->addSlider((int)channel); |
| 245 | - sliders.triggerLevelSlider->setColor( | ||
| 246 | - channel, | ||
| 247 | - (!scope->trigger.special && channel == scope->trigger.source) | ||
| 248 | - ? view->screen.voltage[channel] | ||
| 249 | - : view->screen.voltage[channel].darker()); | 235 | + sliders.triggerLevelSlider->setColor(channel, |
| 236 | + (!scope->trigger.special && channel == scope->trigger.source) | ||
| 237 | + ? view->screen.voltage[channel] | ||
| 238 | + : view->screen.voltage[channel].darker()); | ||
| 250 | adaptTriggerLevelSlider(sliders, channel); | 239 | adaptTriggerLevelSlider(sliders, channel); |
| 251 | sliders.triggerLevelSlider->setValue(channel, scope->voltage[channel].trigger); | 240 | sliders.triggerLevelSlider->setValue(channel, scope->voltage[channel].trigger); |
| 252 | sliders.triggerLevelSlider->setIndexVisible(channel, scope->voltage[channel].used); | 241 | sliders.triggerLevelSlider->setIndexVisible(channel, scope->voltage[channel].used); |
| @@ -257,7 +246,7 @@ void DsoWidget::setupSliders(DsoWidget::Sliders &sliders) { | @@ -257,7 +246,7 @@ void DsoWidget::setupSliders(DsoWidget::Sliders &sliders) { | ||
| 257 | for (int marker = 0; marker < MARKER_COUNT; ++marker) { | 246 | for (int marker = 0; marker < MARKER_COUNT; ++marker) { |
| 258 | sliders.markerSlider->addSlider(QString::number(marker + 1), marker); | 247 | sliders.markerSlider->addSlider(QString::number(marker + 1), marker); |
| 259 | sliders.markerSlider->setLimits(marker, -DIVS_TIME / 2, DIVS_TIME / 2); | 248 | sliders.markerSlider->setLimits(marker, -DIVS_TIME / 2, DIVS_TIME / 2); |
| 260 | - sliders.markerSlider->setStep(marker, DIVS_TIME / 100.0); | 249 | + sliders.markerSlider->setStep(marker, MARKER_STEP); |
| 261 | sliders.markerSlider->setValue(marker, scope->horizontal.marker[marker]); | 250 | sliders.markerSlider->setValue(marker, scope->horizontal.marker[marker]); |
| 262 | sliders.markerSlider->setIndexVisible(marker, true); | 251 | sliders.markerSlider->setIndexVisible(marker, true); |
| 263 | } | 252 | } |
| @@ -269,9 +258,9 @@ void DsoWidget::setExporterForNextFrame(std::unique_ptr<Exporter> exporter) { | @@ -269,9 +258,9 @@ void DsoWidget::setExporterForNextFrame(std::unique_ptr<Exporter> exporter) { | ||
| 269 | 258 | ||
| 270 | /// \brief Set the trigger level sliders minimum and maximum to the new values. | 259 | /// \brief Set the trigger level sliders minimum and maximum to the new values. |
| 271 | void DsoWidget::adaptTriggerLevelSlider(DsoWidget::Sliders &sliders, ChannelID channel) { | 260 | void DsoWidget::adaptTriggerLevelSlider(DsoWidget::Sliders &sliders, ChannelID channel) { |
| 272 | - sliders.triggerLevelSlider->setLimits( | ||
| 273 | - (int)channel, (-DIVS_VOLTAGE / 2 - scope->voltage[channel].offset) * scope->gain(channel), | ||
| 274 | - (DIVS_VOLTAGE / 2 - scope->voltage[channel].offset) * scope->gain(channel)); | 261 | + sliders.triggerLevelSlider->setLimits((int)channel, |
| 262 | + (-DIVS_VOLTAGE / 2 - scope->voltage[channel].offset) * scope->gain(channel), | ||
| 263 | + (DIVS_VOLTAGE / 2 - scope->voltage[channel].offset) * scope->gain(channel)); | ||
| 275 | sliders.triggerLevelSlider->setStep((int)channel, scope->gain(channel) * 0.05); | 264 | sliders.triggerLevelSlider->setStep((int)channel, scope->gain(channel) * 0.05); |
| 276 | } | 265 | } |
| 277 | 266 | ||
| @@ -292,14 +281,10 @@ void DsoWidget::setMeasurementVisible(ChannelID channel) { | @@ -292,14 +281,10 @@ void DsoWidget::setMeasurementVisible(ChannelID channel) { | ||
| 292 | } | 281 | } |
| 293 | 282 | ||
| 294 | measurementGainLabel[channel]->setVisible(scope->voltage[channel].used); | 283 | measurementGainLabel[channel]->setVisible(scope->voltage[channel].used); |
| 295 | - if (!scope->voltage[channel].used) { | ||
| 296 | - measurementGainLabel[channel]->setText(QString()); | ||
| 297 | - } | 284 | + if (!scope->voltage[channel].used) { measurementGainLabel[channel]->setText(QString()); } |
| 298 | 285 | ||
| 299 | measurementMagnitudeLabel[channel]->setVisible(scope->spectrum[channel].used); | 286 | measurementMagnitudeLabel[channel]->setVisible(scope->spectrum[channel].used); |
| 300 | - if (!scope->spectrum[channel].used) { | ||
| 301 | - measurementMagnitudeLabel[channel]->setText(QString()); | ||
| 302 | - } | 287 | + if (!scope->spectrum[channel].used) { measurementMagnitudeLabel[channel]->setText(QString()); } |
| 303 | } | 288 | } |
| 304 | 289 | ||
| 305 | /// \brief Update the label about the marker measurements | 290 | /// \brief Update the label about the marker measurements |
| @@ -411,16 +396,15 @@ void DsoWidget::updateTriggerSource() { | @@ -411,16 +396,15 @@ void DsoWidget::updateTriggerSource() { | ||
| 411 | if (scope->trigger.special || scope->trigger.source >= spec->channels) { | 396 | if (scope->trigger.special || scope->trigger.source >= spec->channels) { |
| 412 | mainSliders.triggerPositionSlider->setColor(0, view->screen.border); | 397 | mainSliders.triggerPositionSlider->setColor(0, view->screen.border); |
| 413 | zoomSliders.triggerPositionSlider->setColor(0, view->screen.border); | 398 | zoomSliders.triggerPositionSlider->setColor(0, view->screen.border); |
| 414 | - } | ||
| 415 | - else { | 399 | + } else { |
| 416 | mainSliders.triggerPositionSlider->setColor(0, view->screen.voltage[scope->trigger.source]); | 400 | mainSliders.triggerPositionSlider->setColor(0, view->screen.voltage[scope->trigger.source]); |
| 417 | zoomSliders.triggerPositionSlider->setColor(0, view->screen.voltage[scope->trigger.source]); | 401 | zoomSliders.triggerPositionSlider->setColor(0, view->screen.voltage[scope->trigger.source]); |
| 418 | } | 402 | } |
| 419 | 403 | ||
| 420 | for (ChannelID channel = 0; channel < spec->channels; ++channel) { | 404 | for (ChannelID channel = 0; channel < spec->channels; ++channel) { |
| 421 | QColor color = (!scope->trigger.special && channel == scope->trigger.source) | 405 | QColor color = (!scope->trigger.special && channel == scope->trigger.source) |
| 422 | - ? view->screen.voltage[channel] | ||
| 423 | - : view->screen.voltage[channel].darker(); | 406 | + ? view->screen.voltage[channel] |
| 407 | + : view->screen.voltage[channel].darker(); | ||
| 424 | mainSliders.triggerLevelSlider->setColor(channel, color); | 408 | mainSliders.triggerLevelSlider->setColor(channel, color); |
| 425 | zoomSliders.triggerLevelSlider->setColor(channel, color); | 409 | zoomSliders.triggerLevelSlider->setColor(channel, color); |
| 426 | } | 410 | } |
| @@ -484,8 +468,7 @@ void DsoWidget::updateZoom(bool enabled) { | @@ -484,8 +468,7 @@ void DsoWidget::updateZoom(bool enabled) { | ||
| 484 | zoomSliders.offsetSlider->show(); | 468 | zoomSliders.offsetSlider->show(); |
| 485 | zoomSliders.triggerPositionSlider->show(); | 469 | zoomSliders.triggerPositionSlider->show(); |
| 486 | zoomSliders.triggerLevelSlider->show(); | 470 | zoomSliders.triggerLevelSlider->show(); |
| 487 | - } | ||
| 488 | - else { | 471 | + } else { |
| 489 | zoomSliders.offsetSlider->hide(); | 472 | zoomSliders.offsetSlider->hide(); |
| 490 | zoomSliders.triggerPositionSlider->hide(); | 473 | zoomSliders.triggerPositionSlider->hide(); |
| 491 | zoomSliders.triggerLevelSlider->hide(); | 474 | zoomSliders.triggerLevelSlider->hide(); |
| @@ -535,6 +518,20 @@ void DsoWidget::showNew(std::shared_ptr<PPresult> data) { | @@ -535,6 +518,20 @@ void DsoWidget::showNew(std::shared_ptr<PPresult> data) { | ||
| 535 | } | 518 | } |
| 536 | } | 519 | } |
| 537 | 520 | ||
| 521 | +void DsoWidget::showEvent(QShowEvent *event) { | ||
| 522 | + QWidget::showEvent(event); | ||
| 523 | + // Apply settings and update measured values | ||
| 524 | + updateTriggerDetails(); | ||
| 525 | + updateRecordLength(scope->horizontal.recordLength); | ||
| 526 | + updateFrequencybase(scope->horizontal.frequencybase); | ||
| 527 | + updateSamplerate(scope->horizontal.samplerate); | ||
| 528 | + updateTimebase(scope->horizontal.timebase); | ||
| 529 | + updateZoom(view->zoom); | ||
| 530 | + | ||
| 531 | + updateTriggerSource(); | ||
| 532 | + adaptTriggerPositionSlider(); | ||
| 533 | +} | ||
| 534 | + | ||
| 538 | /// \brief Handles valueChanged signal from the offset sliders. | 535 | /// \brief Handles valueChanged signal from the offset sliders. |
| 539 | /// \param channel The channel whose offset was changed. | 536 | /// \param channel The channel whose offset was changed. |
| 540 | /// \param value The new offset for the channel. | 537 | /// \param value The new offset for the channel. |
| @@ -573,8 +570,7 @@ void DsoWidget::adaptTriggerPositionSlider() { | @@ -573,8 +570,7 @@ void DsoWidget::adaptTriggerPositionSlider() { | ||
| 573 | if (m1 != m2 && m1 <= value && value <= m2) { | 570 | if (m1 != m2 && m1 <= value && value <= m2) { |
| 574 | zoomSliders.triggerPositionSlider->setIndexVisible(0, true); | 571 | zoomSliders.triggerPositionSlider->setIndexVisible(0, true); |
| 575 | zoomSliders.triggerPositionSlider->setValue(0, (value - m1) / (m2 - m1)); | 572 | zoomSliders.triggerPositionSlider->setValue(0, (value - m1) / (m2 - m1)); |
| 576 | - } | ||
| 577 | - else { | 573 | + } else { |
| 578 | zoomSliders.triggerPositionSlider->setIndexVisible(0, false); | 574 | zoomSliders.triggerPositionSlider->setIndexVisible(0, false); |
| 579 | } | 575 | } |
| 580 | } | 576 | } |
openhantek/src/dsowidget.h
| @@ -42,6 +42,7 @@ class DsoWidget : public QWidget { | @@ -42,6 +42,7 @@ class DsoWidget : public QWidget { | ||
| 42 | void showNew(std::shared_ptr<PPresult> data); | 42 | void showNew(std::shared_ptr<PPresult> data); |
| 43 | 43 | ||
| 44 | protected: | 44 | protected: |
| 45 | + virtual void showEvent(QShowEvent *event); | ||
| 45 | void setupSliders(Sliders &sliders); | 46 | void setupSliders(Sliders &sliders); |
| 46 | void adaptTriggerLevelSlider(DsoWidget::Sliders &sliders, ChannelID channel); | 47 | void adaptTriggerLevelSlider(DsoWidget::Sliders &sliders, ChannelID channel); |
| 47 | void adaptTriggerPositionSlider(); | 48 | void adaptTriggerPositionSlider(); |
openhantek/src/glscope.cpp
| @@ -4,12 +4,16 @@ | @@ -4,12 +4,16 @@ | ||
| 4 | #include <iostream> | 4 | #include <iostream> |
| 5 | 5 | ||
| 6 | #include <QColor> | 6 | #include <QColor> |
| 7 | +#include <QCoreApplication> | ||
| 7 | #include <QDebug> | 8 | #include <QDebug> |
| 8 | #include <QMatrix4x4> | 9 | #include <QMatrix4x4> |
| 10 | +#include <QMessageBox> | ||
| 9 | #include <QMouseEvent> | 11 | #include <QMouseEvent> |
| 10 | #include <QOpenGLShaderProgram> | 12 | #include <QOpenGLShaderProgram> |
| 13 | +#include <QPainter> | ||
| 11 | 14 | ||
| 12 | -#include <QOpenGLFunctions_3_3_Core> | 15 | +// We can't be more modern than OpenGL 3.2 or ES2 because of MacOSX. |
| 16 | +#include <QOpenGLFunctions_3_2_Core> | ||
| 13 | #include <QOpenGLFunctions_ES2> | 17 | #include <QOpenGLFunctions_ES2> |
| 14 | 18 | ||
| 15 | #include "glscope.h" | 19 | #include "glscope.h" |
| @@ -23,7 +27,7 @@ | @@ -23,7 +27,7 @@ | ||
| 23 | #if defined(QT_OPENGL_ES_2) | 27 | #if defined(QT_OPENGL_ES_2) |
| 24 | typedef QOpenGLFunctions_ES2 OPENGL_VER; | 28 | typedef QOpenGLFunctions_ES2 OPENGL_VER; |
| 25 | #else | 29 | #else |
| 26 | -typedef QOpenGLFunctions_3_3_Core OPENGL_VER; | 30 | +typedef QOpenGLFunctions_3_2_Core OPENGL_VER; |
| 27 | #endif | 31 | #endif |
| 28 | 32 | ||
| 29 | GlScope *GlScope::createNormal(DsoSettingsScope *scope, DsoSettingsView *view, QWidget *parent) { | 33 | GlScope *GlScope::createNormal(DsoSettingsScope *scope, DsoSettingsView *view, QWidget *parent) { |
| @@ -38,6 +42,25 @@ GlScope *GlScope::createZoomed(DsoSettingsScope *scope, DsoSettingsView *view, Q | @@ -38,6 +42,25 @@ GlScope *GlScope::createZoomed(DsoSettingsScope *scope, DsoSettingsView *view, Q | ||
| 38 | return s; | 42 | return s; |
| 39 | } | 43 | } |
| 40 | 44 | ||
| 45 | +void GlScope::fixOpenGLversion() { | ||
| 46 | + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); | ||
| 47 | + | ||
| 48 | + // Prefer full desktop OpenGL without fixed pipeline | ||
| 49 | + QSurfaceFormat format; | ||
| 50 | + format.setSamples(4); // Antia-Aliasing, Multisampling | ||
| 51 | +#if defined(QT_OPENGL_ES_2) | ||
| 52 | + format.setVersion(2, 0); | ||
| 53 | + format.setProfile(QSurfaceFormat::CoreProfile); | ||
| 54 | + format.setRenderableType(QSurfaceFormat::OpenGLES); | ||
| 55 | + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true); | ||
| 56 | +#else | ||
| 57 | + format.setVersion(3, 2); | ||
| 58 | + format.setProfile(QSurfaceFormat::CoreProfile); | ||
| 59 | + format.setRenderableType(QSurfaceFormat::OpenGL); | ||
| 60 | +#endif | ||
| 61 | + QSurfaceFormat::setDefaultFormat(format); | ||
| 62 | +} | ||
| 63 | + | ||
| 41 | GlScope::GlScope(DsoSettingsScope *scope, DsoSettingsView *view, QWidget *parent) | 64 | GlScope::GlScope(DsoSettingsScope *scope, DsoSettingsView *view, QWidget *parent) |
| 42 | : QOpenGLWidget(parent), scope(scope), view(view) { | 65 | : QOpenGLWidget(parent), scope(scope), view(view) { |
| 43 | vaMarker.resize(MARKER_COUNT); | 66 | vaMarker.resize(MARKER_COUNT); |
| @@ -51,7 +74,7 @@ void GlScope::mousePressEvent(QMouseEvent *event) { | @@ -51,7 +74,7 @@ void GlScope::mousePressEvent(QMouseEvent *event) { | ||
| 51 | double distance = DIVS_TIME; | 74 | double distance = DIVS_TIME; |
| 52 | selectedMarker = NO_MARKER; | 75 | selectedMarker = NO_MARKER; |
| 53 | // Capture nearest marker located within snap area (+/- 1% of full scale). | 76 | // Capture nearest marker located within snap area (+/- 1% of full scale). |
| 54 | - for (int marker = 0; marker < MARKER_COUNT; ++marker) { | 77 | + for (unsigned marker = 0; marker < MARKER_COUNT; ++marker) { |
| 55 | if (!scope->horizontal.marker_visible[marker]) continue; | 78 | if (!scope->horizontal.marker_visible[marker]) continue; |
| 56 | if (fabs(scope->horizontal.marker[marker] - position) < std::min(distance, DIVS_TIME / 100.0)) { | 79 | if (fabs(scope->horizontal.marker[marker] - position) < std::min(distance, DIVS_TIME / 100.0)) { |
| 57 | distance = fabs(scope->horizontal.marker[marker] - position); | 80 | distance = fabs(scope->horizontal.marker[marker] - position); |
| @@ -89,13 +112,34 @@ void GlScope::mouseReleaseEvent(QMouseEvent *event) { | @@ -89,13 +112,34 @@ void GlScope::mouseReleaseEvent(QMouseEvent *event) { | ||
| 89 | event->accept(); | 112 | event->accept(); |
| 90 | } | 113 | } |
| 91 | 114 | ||
| 115 | +void GlScope::paintEvent(QPaintEvent *event) { | ||
| 116 | + // Draw error message if OpenGL failed | ||
| 117 | + if (!shaderCompileSuccess) { | ||
| 118 | + QPainter painter(this); | ||
| 119 | + painter.setRenderHint(QPainter::Antialiasing, true); | ||
| 120 | + QFont font = painter.font(); | ||
| 121 | + font.setPointSize(18); | ||
| 122 | + painter.setFont(font); | ||
| 123 | + painter.drawText(rect(), Qt::AlignCenter, errorMessage); | ||
| 124 | + event->accept(); | ||
| 125 | + } else | ||
| 126 | + QOpenGLWidget::paintEvent(event); | ||
| 127 | +} | ||
| 128 | + | ||
| 92 | void GlScope::initializeGL() { | 129 | void GlScope::initializeGL() { |
| 93 | - auto *gl = context()->versionFunctions<OPENGL_VER>(); | 130 | + if (!QOpenGLShaderProgram::hasOpenGLShaderPrograms(context())) { |
| 131 | + errorMessage = tr("System does not support OpenGL Shading Language (GLSL)"); | ||
| 132 | + return; | ||
| 133 | + } | ||
| 134 | + if (m_program) { | ||
| 135 | + qWarning() << "OpenGL init called twice!"; | ||
| 136 | + return; | ||
| 137 | + } | ||
| 94 | 138 | ||
| 95 | - m_program = std::unique_ptr<QOpenGLShaderProgram>(new QOpenGLShaderProgram(context())); | 139 | + auto program = std::unique_ptr<QOpenGLShaderProgram>(new QOpenGLShaderProgram(context())); |
| 96 | 140 | ||
| 97 | const char *vshaderES = R"( | 141 | const char *vshaderES = R"( |
| 98 | - #version 330 | 142 | + #version 100 |
| 99 | attribute highp vec3 vertex; | 143 | attribute highp vec3 vertex; |
| 100 | uniform mat4 matrix; | 144 | uniform mat4 matrix; |
| 101 | void main() | 145 | void main() |
| @@ -104,9 +148,14 @@ void GlScope::initializeGL() { | @@ -104,9 +148,14 @@ void GlScope::initializeGL() { | ||
| 104 | gl_PointSize = 1.0; | 148 | gl_PointSize = 1.0; |
| 105 | } | 149 | } |
| 106 | )"; | 150 | )"; |
| 151 | + const char *fshaderES = R"( | ||
| 152 | + #version 100 | ||
| 153 | + uniform highp vec4 colour; | ||
| 154 | + void main() { gl_FragColor = colour; } | ||
| 155 | + )"; | ||
| 107 | 156 | ||
| 108 | const char *vshaderCore = R"( | 157 | const char *vshaderCore = R"( |
| 109 | - #version 330 | 158 | + #version 150 |
| 110 | in highp vec3 vertex; | 159 | in highp vec3 vertex; |
| 111 | uniform mat4 matrix; | 160 | uniform mat4 matrix; |
| 112 | void main() | 161 | void main() |
| @@ -116,37 +165,39 @@ void GlScope::initializeGL() { | @@ -116,37 +165,39 @@ void GlScope::initializeGL() { | ||
| 116 | } | 165 | } |
| 117 | )"; | 166 | )"; |
| 118 | const char *fshaderCore = R"( | 167 | const char *fshaderCore = R"( |
| 119 | - #version 330 | 168 | + #version 150 |
| 120 | uniform highp vec4 colour; | 169 | uniform highp vec4 colour; |
| 121 | - void main() { gl_FragColor = colour; } | 170 | + out vec4 flatColor; |
| 171 | + void main() { flatColor = colour; } | ||
| 122 | )"; | 172 | )"; |
| 123 | 173 | ||
| 124 | qDebug() << "compile shaders"; | 174 | qDebug() << "compile shaders"; |
| 125 | // Compile vertex shader | 175 | // Compile vertex shader |
| 126 | bool coreShaders = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile; | 176 | bool coreShaders = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile; |
| 127 | - if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, coreShaders ? vshaderCore : vshaderES) || | ||
| 128 | - !m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fshaderCore)) { | ||
| 129 | - qWarning() << "Failed to compile OpenGL shader programs.\n" << m_program->log(); | 177 | + if (!program->addShaderFromSourceCode(QOpenGLShader::Vertex, coreShaders ? vshaderCore : vshaderES) || |
| 178 | + !program->addShaderFromSourceCode(QOpenGLShader::Fragment, coreShaders ? fshaderCore : fshaderES)) { | ||
| 179 | + errorMessage = "Failed to compile OpenGL shader programs.\n" + program->log(); | ||
| 130 | return; | 180 | return; |
| 131 | } | 181 | } |
| 132 | 182 | ||
| 133 | // Link shader pipeline | 183 | // Link shader pipeline |
| 134 | - if (!m_program->link() || !m_program->bind()) { | ||
| 135 | - qWarning() << "Failed to link/bind OpenGL shader programs"; | 184 | + if (!program->link() || !program->bind()) { |
| 185 | + errorMessage = "Failed to link/bind OpenGL shader programs\n" + program->log(); | ||
| 136 | return; | 186 | return; |
| 137 | } | 187 | } |
| 138 | 188 | ||
| 139 | - vertexLocation = m_program->attributeLocation("vertex"); | ||
| 140 | - matrixLocation = m_program->uniformLocation("matrix"); | ||
| 141 | - colorLocation = m_program->uniformLocation("colour"); | 189 | + vertexLocation = program->attributeLocation("vertex"); |
| 190 | + matrixLocation = program->uniformLocation("matrix"); | ||
| 191 | + colorLocation = program->uniformLocation("colour"); | ||
| 142 | 192 | ||
| 143 | if (vertexLocation == -1 || colorLocation == -1 || matrixLocation == -1) { | 193 | if (vertexLocation == -1 || colorLocation == -1 || matrixLocation == -1) { |
| 144 | qWarning() << "Failed to locate shader variable"; | 194 | qWarning() << "Failed to locate shader variable"; |
| 145 | return; | 195 | return; |
| 146 | } | 196 | } |
| 147 | 197 | ||
| 148 | - m_program->bind(); | 198 | + program->bind(); |
| 149 | 199 | ||
| 200 | + auto *gl = context()->versionFunctions<OPENGL_VER>(); | ||
| 150 | gl->glDisable(GL_DEPTH_TEST); | 201 | gl->glDisable(GL_DEPTH_TEST); |
| 151 | gl->glEnable(GL_BLEND); | 202 | gl->glEnable(GL_BLEND); |
| 152 | // Enable depth buffer | 203 | // Enable depth buffer |
| @@ -159,7 +210,7 @@ void GlScope::initializeGL() { | @@ -159,7 +210,7 @@ void GlScope::initializeGL() { | ||
| 159 | QColor bg = view->screen.background; | 210 | QColor bg = view->screen.background; |
| 160 | gl->glClearColor((GLfloat)bg.redF(), (GLfloat)bg.greenF(), (GLfloat)bg.blueF(), (GLfloat)bg.alphaF()); | 211 | gl->glClearColor((GLfloat)bg.redF(), (GLfloat)bg.greenF(), (GLfloat)bg.blueF(), (GLfloat)bg.alphaF()); |
| 161 | 212 | ||
| 162 | - generateGrid(); | 213 | + generateGrid(program.get()); |
| 163 | 214 | ||
| 164 | { | 215 | { |
| 165 | m_vaoMarker.create(); | 216 | m_vaoMarker.create(); |
| @@ -168,15 +219,18 @@ void GlScope::initializeGL() { | @@ -168,15 +219,18 @@ void GlScope::initializeGL() { | ||
| 168 | m_marker.bind(); | 219 | m_marker.bind(); |
| 169 | m_marker.setUsagePattern(QOpenGLBuffer::StaticDraw); | 220 | m_marker.setUsagePattern(QOpenGLBuffer::StaticDraw); |
| 170 | m_marker.allocate(int(vaMarker.size() * sizeof(Line))); | 221 | m_marker.allocate(int(vaMarker.size() * sizeof(Line))); |
| 171 | - m_program->enableAttributeArray(vertexLocation); | ||
| 172 | - m_program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0, 3, 0); | 222 | + program->enableAttributeArray(vertexLocation); |
| 223 | + program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0, 3, 0); | ||
| 173 | } | 224 | } |
| 174 | 225 | ||
| 175 | - m_program->release(); | 226 | + markerUpdated(); |
| 227 | + | ||
| 228 | + m_program = std::move(program); | ||
| 229 | + shaderCompileSuccess = true; | ||
| 176 | } | 230 | } |
| 177 | 231 | ||
| 178 | void GlScope::showData(PPresult *data) { | 232 | void GlScope::showData(PPresult *data) { |
| 179 | - if (!m_program || !m_program->isLinked()) return; | 233 | + if (!shaderCompileSuccess) return; |
| 180 | makeCurrent(); | 234 | makeCurrent(); |
| 181 | // Remove too much entries | 235 | // Remove too much entries |
| 182 | while (view->digitalPhosphorDraws() < m_GraphHistory.size()) m_GraphHistory.pop_back(); | 236 | while (view->digitalPhosphorDraws() < m_GraphHistory.size()) m_GraphHistory.pop_back(); |
| @@ -192,8 +246,23 @@ void GlScope::showData(PPresult *data) { | @@ -192,8 +246,23 @@ void GlScope::showData(PPresult *data) { | ||
| 192 | // doneCurrent(); | 246 | // doneCurrent(); |
| 193 | } | 247 | } |
| 194 | 248 | ||
| 249 | +void GlScope::markerUpdated() | ||
| 250 | +{ | ||
| 251 | + | ||
| 252 | + for (unsigned marker = 0; marker < vaMarker.size(); ++marker) { | ||
| 253 | + if (!scope->horizontal.marker_visible[marker]) continue; | ||
| 254 | + vaMarker[marker] = {QVector3D((GLfloat)scope->horizontal.marker[marker], -DIVS_VOLTAGE, 0.0f), | ||
| 255 | + QVector3D((GLfloat)scope->horizontal.marker[marker], DIVS_VOLTAGE, 0.0f)}; | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + // Write coordinates to GPU | ||
| 259 | + makeCurrent(); | ||
| 260 | + m_marker.bind(); | ||
| 261 | + m_marker.write(0, vaMarker.data(), vaMarker.size() * sizeof(Line)); | ||
| 262 | +} | ||
| 263 | + | ||
| 195 | void GlScope::paintGL() { | 264 | void GlScope::paintGL() { |
| 196 | - if (!m_program->isLinked()) return; | 265 | + if (!shaderCompileSuccess) return; |
| 197 | 266 | ||
| 198 | auto *gl = context()->versionFunctions<OPENGL_VER>(); | 267 | auto *gl = context()->versionFunctions<OPENGL_VER>(); |
| 199 | 268 | ||
| @@ -231,6 +300,7 @@ void GlScope::paintGL() { | @@ -231,6 +300,7 @@ void GlScope::paintGL() { | ||
| 231 | } | 300 | } |
| 232 | 301 | ||
| 233 | void GlScope::resizeGL(int width, int height) { | 302 | void GlScope::resizeGL(int width, int height) { |
| 303 | + if (!shaderCompileSuccess) return; | ||
| 234 | auto *gl = context()->versionFunctions<OPENGL_VER>(); | 304 | auto *gl = context()->versionFunctions<OPENGL_VER>(); |
| 235 | gl->glViewport(0, 0, (GLint)width, (GLint)height); | 305 | gl->glViewport(0, 0, (GLint)width, (GLint)height); |
| 236 | 306 | ||
| @@ -248,30 +318,7 @@ void GlScope::resizeGL(int width, int height) { | @@ -248,30 +318,7 @@ void GlScope::resizeGL(int width, int height) { | ||
| 248 | m_program->release(); | 318 | m_program->release(); |
| 249 | } | 319 | } |
| 250 | 320 | ||
| 251 | -void GlScope::drawGrid() { | ||
| 252 | - auto *gl = context()->versionFunctions<OPENGL_VER>(); | ||
| 253 | - gl->glLineWidth(1); | ||
| 254 | - | ||
| 255 | - // Grid | ||
| 256 | - m_vaoGrid[0].bind(); | ||
| 257 | - m_program->setUniformValue(colorLocation, view->screen.grid); | ||
| 258 | - gl->glDrawArrays(GL_POINTS, 0, gridDrawCounts[0]); | ||
| 259 | - m_vaoGrid[0].release(); | ||
| 260 | - | ||
| 261 | - // Axes | ||
| 262 | - m_vaoGrid[1].bind(); | ||
| 263 | - m_program->setUniformValue(colorLocation, view->screen.axes); | ||
| 264 | - gl->glDrawArrays(GL_LINES, 0, gridDrawCounts[1]); | ||
| 265 | - m_vaoGrid[1].release(); | ||
| 266 | - | ||
| 267 | - // Border | ||
| 268 | - m_vaoGrid[2].bind(); | ||
| 269 | - m_program->setUniformValue(colorLocation, view->screen.border); | ||
| 270 | - gl->glDrawArrays(GL_LINE_LOOP, 0, gridDrawCounts[2]); | ||
| 271 | - m_vaoGrid[2].release(); | ||
| 272 | -} | ||
| 273 | - | ||
| 274 | -void GlScope::generateGrid() { | 321 | +void GlScope::generateGrid(QOpenGLShaderProgram *program) { |
| 275 | gridDrawCounts[0] = 0; | 322 | gridDrawCounts[0] = 0; |
| 276 | gridDrawCounts[1] = 0; | 323 | gridDrawCounts[1] = 0; |
| 277 | gridDrawCounts[2] = 0; | 324 | gridDrawCounts[2] = 0; |
| @@ -286,8 +333,8 @@ void GlScope::generateGrid() { | @@ -286,8 +333,8 @@ void GlScope::generateGrid() { | ||
| 286 | m_vaoGrid[0].create(); | 333 | m_vaoGrid[0].create(); |
| 287 | QOpenGLVertexArrayObject::Binder b(&m_vaoGrid[0]); | 334 | QOpenGLVertexArrayObject::Binder b(&m_vaoGrid[0]); |
| 288 | m_grid.bind(); | 335 | m_grid.bind(); |
| 289 | - m_program->enableAttributeArray(vertexLocation); | ||
| 290 | - m_program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0, 3, 0); | 336 | + program->enableAttributeArray(vertexLocation); |
| 337 | + program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0, 3, 0); | ||
| 291 | } | 338 | } |
| 292 | 339 | ||
| 293 | // Draw vertical lines | 340 | // Draw vertical lines |
| @@ -318,8 +365,8 @@ void GlScope::generateGrid() { | @@ -318,8 +365,8 @@ void GlScope::generateGrid() { | ||
| 318 | m_vaoGrid[1].create(); | 365 | m_vaoGrid[1].create(); |
| 319 | QOpenGLVertexArrayObject::Binder b(&m_vaoGrid[1]); | 366 | QOpenGLVertexArrayObject::Binder b(&m_vaoGrid[1]); |
| 320 | m_grid.bind(); | 367 | m_grid.bind(); |
| 321 | - m_program->enableAttributeArray(vertexLocation); | ||
| 322 | - m_program->setAttributeBuffer(vertexLocation, GL_FLOAT, int(vaGrid.size() * sizeof(QVector3D)), 3); | 368 | + program->enableAttributeArray(vertexLocation); |
| 369 | + program->setAttributeBuffer(vertexLocation, GL_FLOAT, int(vaGrid.size() * sizeof(QVector3D)), 3); | ||
| 323 | } | 370 | } |
| 324 | 371 | ||
| 325 | // Axes | 372 | // Axes |
| @@ -353,8 +400,8 @@ void GlScope::generateGrid() { | @@ -353,8 +400,8 @@ void GlScope::generateGrid() { | ||
| 353 | m_vaoGrid[2].create(); | 400 | m_vaoGrid[2].create(); |
| 354 | QOpenGLVertexArrayObject::Binder b(&m_vaoGrid[2]); | 401 | QOpenGLVertexArrayObject::Binder b(&m_vaoGrid[2]); |
| 355 | m_grid.bind(); | 402 | m_grid.bind(); |
| 356 | - m_program->enableAttributeArray(vertexLocation); | ||
| 357 | - m_program->setAttributeBuffer(vertexLocation, GL_FLOAT, int(vaGrid.size() * sizeof(QVector3D)), 3); | 403 | + program->enableAttributeArray(vertexLocation); |
| 404 | + program->setAttributeBuffer(vertexLocation, GL_FLOAT, int(vaGrid.size() * sizeof(QVector3D)), 3); | ||
| 358 | } | 405 | } |
| 359 | 406 | ||
| 360 | // Border | 407 | // Border |
| @@ -368,6 +415,29 @@ void GlScope::generateGrid() { | @@ -368,6 +415,29 @@ void GlScope::generateGrid() { | ||
| 368 | m_grid.release(); | 415 | m_grid.release(); |
| 369 | } | 416 | } |
| 370 | 417 | ||
| 418 | +void GlScope::drawGrid() { | ||
| 419 | + auto *gl = context()->versionFunctions<OPENGL_VER>(); | ||
| 420 | + gl->glLineWidth(1); | ||
| 421 | + | ||
| 422 | + // Grid | ||
| 423 | + m_vaoGrid[0].bind(); | ||
| 424 | + m_program->setUniformValue(colorLocation, view->screen.grid); | ||
| 425 | + gl->glDrawArrays(GL_POINTS, 0, gridDrawCounts[0]); | ||
| 426 | + m_vaoGrid[0].release(); | ||
| 427 | + | ||
| 428 | + // Axes | ||
| 429 | + m_vaoGrid[1].bind(); | ||
| 430 | + m_program->setUniformValue(colorLocation, view->screen.axes); | ||
| 431 | + gl->glDrawArrays(GL_LINES, 0, gridDrawCounts[1]); | ||
| 432 | + m_vaoGrid[1].release(); | ||
| 433 | + | ||
| 434 | + // Border | ||
| 435 | + m_vaoGrid[2].bind(); | ||
| 436 | + m_program->setUniformValue(colorLocation, view->screen.border); | ||
| 437 | + gl->glDrawArrays(GL_LINE_LOOP, 0, gridDrawCounts[2]); | ||
| 438 | + m_vaoGrid[2].release(); | ||
| 439 | +} | ||
| 440 | + | ||
| 371 | void GlScope::drawMarkers() { | 441 | void GlScope::drawMarkers() { |
| 372 | auto *gl = context()->versionFunctions<OPENGL_VER>(); | 442 | auto *gl = context()->versionFunctions<OPENGL_VER>(); |
| 373 | QColor trColor = view->screen.markers; | 443 | QColor trColor = view->screen.markers; |
| @@ -375,23 +445,13 @@ void GlScope::drawMarkers() { | @@ -375,23 +445,13 @@ void GlScope::drawMarkers() { | ||
| 375 | 445 | ||
| 376 | m_vaoMarker.bind(); | 446 | m_vaoMarker.bind(); |
| 377 | 447 | ||
| 378 | - for (unsigned marker = 0; marker < vaMarker.size(); ++marker) { | ||
| 379 | - if (!scope->horizontal.marker_visible[marker]) continue; | ||
| 380 | - vaMarker[marker] = {QVector3D((GLfloat)scope->horizontal.marker[marker], -DIVS_VOLTAGE, 0.0f), | ||
| 381 | - QVector3D((GLfloat)scope->horizontal.marker[marker], DIVS_VOLTAGE, 0.0f)}; | ||
| 382 | - } | ||
| 383 | - | ||
| 384 | - // Write coordinates to GPU | ||
| 385 | - m_marker.bind(); | ||
| 386 | - m_marker.write(0, vaMarker.data(), vaMarker.size() * sizeof(Line)); | ||
| 387 | - | ||
| 388 | // Draw all | 448 | // Draw all |
| 389 | gl->glLineWidth(1); | 449 | gl->glLineWidth(1); |
| 390 | gl->glDrawArrays(GL_LINES, 0, (GLsizei)vaMarker.size() * 2); | 450 | gl->glDrawArrays(GL_LINES, 0, (GLsizei)vaMarker.size() * 2); |
| 391 | - m_marker.release(); | ||
| 392 | 451 | ||
| 393 | // Draw selected | 452 | // Draw selected |
| 394 | if (selectedMarker != NO_MARKER) { | 453 | if (selectedMarker != NO_MARKER) { |
| 454 | + qWarning() << selectedMarker; | ||
| 395 | gl->glLineWidth(3); | 455 | gl->glLineWidth(3); |
| 396 | gl->glDrawArrays(GL_LINES, selectedMarker * 2, (GLsizei)2); | 456 | gl->glDrawArrays(GL_LINES, selectedMarker * 2, (GLsizei)2); |
| 397 | } | 457 | } |
openhantek/src/glscope.h
| @@ -31,10 +31,16 @@ class GlScope : public QOpenGLWidget { | @@ -31,10 +31,16 @@ class GlScope : public QOpenGLWidget { | ||
| 31 | QWidget *parent = 0); | 31 | QWidget *parent = 0); |
| 32 | 32 | ||
| 33 | /** | 33 | /** |
| 34 | + * We need at least OpenGL 3.2 with shader version 150 or | ||
| 35 | + * OpenGL ES 2.0 with shader version 100. | ||
| 36 | + */ | ||
| 37 | + static void fixOpenGLversion(); | ||
| 38 | + /** | ||
| 34 | * Show new post processed data | 39 | * Show new post processed data |
| 35 | * @param data | 40 | * @param data |
| 36 | */ | 41 | */ |
| 37 | void showData(PPresult* data); | 42 | void showData(PPresult* data); |
| 43 | + void markerUpdated(); | ||
| 38 | 44 | ||
| 39 | protected: | 45 | protected: |
| 40 | /// \brief Initializes the scope widget. | 46 | /// \brief Initializes the scope widget. |
| @@ -42,21 +48,23 @@ class GlScope : public QOpenGLWidget { | @@ -42,21 +48,23 @@ class GlScope : public QOpenGLWidget { | ||
| 42 | /// \param parent The parent widget. | 48 | /// \param parent The parent widget. |
| 43 | GlScope(DsoSettingsScope *scope, DsoSettingsView *view, QWidget *parent = 0); | 49 | GlScope(DsoSettingsScope *scope, DsoSettingsView *view, QWidget *parent = 0); |
| 44 | virtual ~GlScope(); | 50 | virtual ~GlScope(); |
| 51 | + GlScope(const GlScope&) = delete; | ||
| 45 | 52 | ||
| 46 | /// \brief Initializes OpenGL output. | 53 | /// \brief Initializes OpenGL output. |
| 47 | - void initializeGL() override; | 54 | + virtual void initializeGL() override; |
| 48 | 55 | ||
| 49 | /// \brief Draw the graphs, marker and the grid. | 56 | /// \brief Draw the graphs, marker and the grid. |
| 50 | - void paintGL() override; | 57 | + virtual void paintGL() override; |
| 51 | 58 | ||
| 52 | /// \brief Resize the widget. | 59 | /// \brief Resize the widget. |
| 53 | /// \param width The new width of the widget. | 60 | /// \param width The new width of the widget. |
| 54 | /// \param height The new height of the widget. | 61 | /// \param height The new height of the widget. |
| 55 | - void resizeGL(int width, int height) override; | 62 | + virtual void resizeGL(int width, int height) override; |
| 56 | 63 | ||
| 57 | - void mousePressEvent(QMouseEvent *event) override; | ||
| 58 | - void mouseMoveEvent(QMouseEvent *event) override; | ||
| 59 | - void mouseReleaseEvent(QMouseEvent *event) override; | 64 | + virtual void mousePressEvent(QMouseEvent *event) override; |
| 65 | + virtual void mouseMoveEvent(QMouseEvent *event) override; | ||
| 66 | + virtual void mouseReleaseEvent(QMouseEvent *event) override; | ||
| 67 | + virtual void paintEvent(QPaintEvent *event) override; | ||
| 60 | 68 | ||
| 61 | /// \brief Draw the grid. | 69 | /// \brief Draw the grid. |
| 62 | void drawGrid(); | 70 | void drawGrid(); |
| @@ -91,13 +99,15 @@ class GlScope : public QOpenGLWidget { | @@ -91,13 +99,15 @@ class GlScope : public QOpenGLWidget { | ||
| 91 | QOpenGLBuffer m_grid; | 99 | QOpenGLBuffer m_grid; |
| 92 | QOpenGLVertexArrayObject m_vaoGrid[3]; | 100 | QOpenGLVertexArrayObject m_vaoGrid[3]; |
| 93 | GLsizei gridDrawCounts[3]; | 101 | GLsizei gridDrawCounts[3]; |
| 94 | - void generateGrid(); | 102 | + void generateGrid(QOpenGLShaderProgram *program); |
| 95 | 103 | ||
| 96 | // Graphs | 104 | // Graphs |
| 97 | std::list<Graph> m_GraphHistory; | 105 | std::list<Graph> m_GraphHistory; |
| 98 | unsigned currentGraphInHistory = 0; | 106 | unsigned currentGraphInHistory = 0; |
| 99 | 107 | ||
| 100 | // OpenGL shader, matrix, var-locations | 108 | // OpenGL shader, matrix, var-locations |
| 109 | + bool shaderCompileSuccess = false; | ||
| 110 | + QString errorMessage; | ||
| 101 | std::unique_ptr<QOpenGLShaderProgram> m_program; | 111 | std::unique_ptr<QOpenGLShaderProgram> m_program; |
| 102 | QMatrix4x4 pmvMatrix; ///< projection, view matrix | 112 | QMatrix4x4 pmvMatrix; ///< projection, view matrix |
| 103 | int colorLocation; | 113 | int colorLocation; |
openhantek/src/main.cpp
| @@ -24,6 +24,8 @@ | @@ -24,6 +24,8 @@ | ||
| 24 | #include "usb/usbdevice.h" | 24 | #include "usb/usbdevice.h" |
| 25 | #include "viewconstants.h" | 25 | #include "viewconstants.h" |
| 26 | 26 | ||
| 27 | +#include "glscope.h" | ||
| 28 | + | ||
| 27 | #ifndef VERSION | 29 | #ifndef VERSION |
| 28 | #error "You need to run the cmake buildsystem!" | 30 | #error "You need to run the cmake buildsystem!" |
| 29 | #endif | 31 | #endif |
| @@ -69,14 +71,8 @@ int main(int argc, char *argv[]) { | @@ -69,14 +71,8 @@ int main(int argc, char *argv[]) { | ||
| 69 | QCoreApplication::setApplicationName("OpenHantek"); | 71 | QCoreApplication::setApplicationName("OpenHantek"); |
| 70 | QCoreApplication::setApplicationVersion(VERSION); | 72 | QCoreApplication::setApplicationVersion(VERSION); |
| 71 | 73 | ||
| 72 | - QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true); | ||
| 73 | - QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); | 74 | + GlScope::fixOpenGLversion(); |
| 74 | 75 | ||
| 75 | - // Prefer full desktop OpenGL without fixed pipeline | ||
| 76 | - QSurfaceFormat format; | ||
| 77 | - format.setProfile(QSurfaceFormat::CoreProfile); | ||
| 78 | - format.setSamples(4); // Antia-Aliasing, Multisampling | ||
| 79 | - QSurfaceFormat::setDefaultFormat(format); | ||
| 80 | QApplication openHantekApplication(argc, argv); | 76 | QApplication openHantekApplication(argc, argv); |
| 81 | 77 | ||
| 82 | //////// Load translations //////// | 78 | //////// Load translations //////// |
| @@ -155,5 +151,10 @@ int main(int argc, char *argv[]) { | @@ -155,5 +151,10 @@ int main(int argc, char *argv[]) { | ||
| 155 | 151 | ||
| 156 | postProcessingThread.quit(); | 152 | postProcessingThread.quit(); |
| 157 | postProcessingThread.wait(10000); | 153 | postProcessingThread.wait(10000); |
| 154 | + | ||
| 155 | + if (context && device != nullptr) { | ||
| 156 | + libusb_exit(context); | ||
| 157 | + } | ||
| 158 | + | ||
| 158 | return res; | 159 | return res; |
| 159 | } | 160 | } |
openhantek/src/scopesettings.h
| @@ -11,6 +11,7 @@ | @@ -11,6 +11,7 @@ | ||
| 11 | #include <vector> | 11 | #include <vector> |
| 12 | 12 | ||
| 13 | #define MARKER_COUNT 2 ///< Number of markers | 13 | #define MARKER_COUNT 2 ///< Number of markers |
| 14 | +#define MARKER_STEP (DIVS_TIME / 100.0) | ||
| 14 | 15 | ||
| 15 | /// \brief Holds the settings for the horizontal axis. | 16 | /// \brief Holds the settings for the horizontal axis. |
| 16 | struct DsoSettingsScopeHorizontal { | 17 | struct DsoSettingsScopeHorizontal { |
openhantek/src/widgets/levelslider.cpp
| @@ -196,17 +196,14 @@ double LevelSlider::maximum(int index) const { | @@ -196,17 +196,14 @@ double LevelSlider::maximum(int index) const { | ||
| 196 | /// \param minimum The value a slider has at the bottommost/leftmost position. | 196 | /// \param minimum The value a slider has at the bottommost/leftmost position. |
| 197 | /// \param maximum The value a slider has at the topmost/rightmost position. | 197 | /// \param maximum The value a slider has at the topmost/rightmost position. |
| 198 | /// \return -1 on error, fixValue result on success. | 198 | /// \return -1 on error, fixValue result on success. |
| 199 | -int LevelSlider::setLimits(int index, double minimum, double maximum) { | ||
| 200 | - if (index < 0 || index >= this->slider.count()) return -1; | 199 | +void LevelSlider::setLimits(int index, double minimum, double maximum) { |
| 200 | + if (index < 0 || index >= this->slider.count()) return; | ||
| 201 | 201 | ||
| 202 | this->slider[index]->minimum = minimum; | 202 | this->slider[index]->minimum = minimum; |
| 203 | this->slider[index]->maximum = maximum; | 203 | this->slider[index]->maximum = maximum; |
| 204 | - int result = this->fixValue(index); | ||
| 205 | - | 204 | + this->fixValue(index); |
| 206 | this->calculateRect(index); | 205 | this->calculateRect(index); |
| 207 | this->repaint(); | 206 | this->repaint(); |
| 208 | - | ||
| 209 | - return result; | ||
| 210 | } | 207 | } |
| 211 | 208 | ||
| 212 | /// \brief Return the step width of the sliders. | 209 | /// \brief Return the step width of the sliders. |
| @@ -243,8 +240,8 @@ double LevelSlider::value(int index) const { | @@ -243,8 +240,8 @@ double LevelSlider::value(int index) const { | ||
| 243 | /// \param index The index of the slider whose value should be set. | 240 | /// \param index The index of the slider whose value should be set. |
| 244 | /// \param value The new value of the slider. | 241 | /// \param value The new value of the slider. |
| 245 | /// \return The new value of the slider. | 242 | /// \return The new value of the slider. |
| 246 | -double LevelSlider::setValue(int index, double value) { | ||
| 247 | - if (index < 0 || index >= this->slider.count()) return -1; | 243 | +void LevelSlider::setValue(int index, double value) { |
| 244 | + if (index < 0 || index >= this->slider.count()) return; | ||
| 248 | 245 | ||
| 249 | // Apply new value | 246 | // Apply new value |
| 250 | this->slider[index]->value = value; | 247 | this->slider[index]->value = value; |
| @@ -254,8 +251,6 @@ double LevelSlider::setValue(int index, double value) { | @@ -254,8 +251,6 @@ double LevelSlider::setValue(int index, double value) { | ||
| 254 | this->repaint(); | 251 | this->repaint(); |
| 255 | 252 | ||
| 256 | if (this->pressedSlider < 0) emit valueChanged(index, value); | 253 | if (this->pressedSlider < 0) emit valueChanged(index, value); |
| 257 | - | ||
| 258 | - return this->slider[index]->value; | ||
| 259 | } | 254 | } |
| 260 | 255 | ||
| 261 | /// \brief Return the direction of the sliders. | 256 | /// \brief Return the direction of the sliders. |
| @@ -563,17 +558,14 @@ int LevelSlider::calculateWidth() { | @@ -563,17 +558,14 @@ int LevelSlider::calculateWidth() { | ||
| 563 | /// \brief Fix the value if it's outside the limits. | 558 | /// \brief Fix the value if it's outside the limits. |
| 564 | /// \param index The index of the slider who should be fixed. | 559 | /// \param index The index of the slider who should be fixed. |
| 565 | /// \return 0 when ok, -1 on error, 1 when increased and 2 when decreased. | 560 | /// \return 0 when ok, -1 on error, 1 when increased and 2 when decreased. |
| 566 | -int LevelSlider::fixValue(int index) { | ||
| 567 | - if (index < 0 || index >= this->slider.count()) return -1; | 561 | +void LevelSlider::fixValue(int index) { |
| 562 | + if (index < 0 || index >= this->slider.count()) return; | ||
| 568 | 563 | ||
| 569 | double lowest = qMin(this->slider[index]->minimum, this->slider[index]->maximum); | 564 | double lowest = qMin(this->slider[index]->minimum, this->slider[index]->maximum); |
| 570 | double highest = qMax(this->slider[index]->minimum, this->slider[index]->maximum); | 565 | double highest = qMax(this->slider[index]->minimum, this->slider[index]->maximum); |
| 571 | if (this->slider[index]->value < lowest) { | 566 | if (this->slider[index]->value < lowest) { |
| 572 | this->slider[index]->value = lowest; | 567 | this->slider[index]->value = lowest; |
| 573 | - return 1; | ||
| 574 | } else if (this->slider[index]->value > highest) { | 568 | } else if (this->slider[index]->value > highest) { |
| 575 | this->slider[index]->value = highest; | 569 | this->slider[index]->value = highest; |
| 576 | - return 2; | ||
| 577 | } | 570 | } |
| 578 | - return 0; | ||
| 579 | } | 571 | } |
openhantek/src/widgets/levelslider.h
| @@ -51,11 +51,11 @@ class LevelSlider : public QWidget { | @@ -51,11 +51,11 @@ class LevelSlider : public QWidget { | ||
| 51 | 51 | ||
| 52 | double minimum(int index) const; | 52 | double minimum(int index) const; |
| 53 | double maximum(int index) const; | 53 | double maximum(int index) const; |
| 54 | - int setLimits(int index, double minimum, double maximum); | 54 | + void setLimits(int index, double minimum, double maximum); |
| 55 | double step(int index) const; | 55 | double step(int index) const; |
| 56 | double setStep(int index, double step); | 56 | double setStep(int index, double step); |
| 57 | double value(int index) const; | 57 | double value(int index) const; |
| 58 | - double setValue(int index, double value); | 58 | + void setValue(int index, double value); |
| 59 | 59 | ||
| 60 | // Parameters for all sliders | 60 | // Parameters for all sliders |
| 61 | Qt::ArrowType direction() const; | 61 | Qt::ArrowType direction() const; |
| @@ -71,7 +71,7 @@ class LevelSlider : public QWidget { | @@ -71,7 +71,7 @@ class LevelSlider : public QWidget { | ||
| 71 | 71 | ||
| 72 | QRect calculateRect(int sliderId); | 72 | QRect calculateRect(int sliderId); |
| 73 | int calculateWidth(); | 73 | int calculateWidth(); |
| 74 | - int fixValue(int index); | 74 | + void fixValue(int index); |
| 75 | 75 | ||
| 76 | QList<LevelSliderParameters *> slider; ///< The parameters for each slider | 76 | QList<LevelSliderParameters *> slider; ///< The parameters for each slider |
| 77 | int pressedSlider; ///< The currently pressed (moved) slider | 77 | int pressedSlider; ///< The currently pressed (moved) slider |