Commit a36eccc6032ed9112072e426b1cb6ad8654000ea

Authored by David Graeff
Committed by David Gräff
1 parent f26fec83

Fix OpenGL problems

openhantek/src/glscope.cpp
... ... @@ -166,7 +166,7 @@ void GlScope::initializeGL() {
166 166 m_marker.create();
167 167 m_marker.bind();
168 168 m_marker.setUsagePattern(QOpenGLBuffer::StaticDraw);
169   - m_marker.allocate(4 * sizeof(QVector3D));
  169 + m_marker.allocate(int(vaMarker.size() * sizeof(Line)));
170 170 m_program->enableAttributeArray(vertexLocation);
171 171 m_program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0, 3, 0);
172 172 }
... ... @@ -177,10 +177,18 @@ void GlScope::initializeGL() {
177 177 void GlScope::showData(PPresult *data) {
178 178 if (!m_program || !m_program->isLinked()) return;
179 179 makeCurrent();
180   - m_GraphHistory.resize(view->digitalPhosphorDraws());
181   - m_GraphHistory[currentGraphInHistory].writeData(data, m_program.get(), vertexLocation);
182   - currentGraphInHistory = (currentGraphInHistory + 1) % m_GraphHistory.size();
183   - doneCurrent();
  180 + // Remove too much entries
  181 + while (view->digitalPhosphorDraws() < m_GraphHistory.size()) m_GraphHistory.pop_back();
  182 +
  183 + // Add if missing
  184 + if (view->digitalPhosphorDraws() > m_GraphHistory.size()) { m_GraphHistory.resize(m_GraphHistory.size() + 1); }
  185 +
  186 + // Move last item to front
  187 + m_GraphHistory.splice(m_GraphHistory.begin(), m_GraphHistory, std::prev(m_GraphHistory.end()));
  188 +
  189 + // Add new entry
  190 + m_GraphHistory.front().writeData(data, m_program.get(), vertexLocation);
  191 + // doneCurrent();
184 192 }
185 193  
186 194 void GlScope::paintGL() {
... ... @@ -210,13 +218,13 @@ void GlScope::paintGL() {
210 218 m_program->setUniformValue(matrixLocation, pmvMatrix * m);
211 219 }
212 220  
213   - for (unsigned historyIndex = 0; historyIndex < m_GraphHistory.size(); ++historyIndex) {
214   - unsigned graphID = (historyIndex + currentGraphInHistory) % m_GraphHistory.size();
215   - Graph &graph = m_GraphHistory[graphID];
  221 + unsigned historyIndex = 0;
  222 + for (Graph &graph : m_GraphHistory) {
216 223 for (ChannelID channel = 0; channel < scope->voltage.size(); ++channel) {
217 224 drawSpectrumChannelGraph(channel, graph, (int)historyIndex);
218 225 drawVoltageChannelGraph(channel, graph, (int)historyIndex);
219 226 }
  227 + ++historyIndex;
220 228 }
221 229  
222 230 gl->glDisable(GL_POINT_SMOOTH);
... ... @@ -377,18 +385,25 @@ void GlScope::drawMarkers() {
377 385  
378 386 m_vaoMarker.bind();
379 387  
380   - for (unsigned marker = 0; marker < MARKER_COUNT; ++marker) {
  388 + for (unsigned marker = 0; marker < vaMarker.size(); ++marker) {
381 389 if (!scope->horizontal.marker_visible[marker]) continue;
382 390 vaMarker[marker] = {QVector3D((GLfloat)scope->horizontal.marker[marker], -DIVS_VOLTAGE, 0.0f),
383 391 QVector3D((GLfloat)scope->horizontal.marker[marker], DIVS_VOLTAGE, 0.0f)};
  392 + }
384 393  
385   - m_marker.bind();
386   - auto ptr = m_marker.mapRange(0, sizeof(Line), QOpenGLBuffer::RangeInvalidateBuffer | QOpenGLBuffer::RangeWrite);
387   - memcpy(ptr, &vaMarker[marker], sizeof(Line));
388   - m_marker.unmap();
  394 + // Write coordinates to GPU
  395 + m_marker.bind();
  396 + m_marker.write(0, vaMarker.data(), vaMarker.size() * sizeof(Line));
  397 +
  398 + // Draw all
  399 + gl->glLineWidth(1);
  400 + gl->glDrawArrays(GL_LINES, 0, (GLsizei)vaMarker.size() * 2);
  401 + m_marker.release();
389 402  
390   - gl->glLineWidth((marker == selectedMarker) ? 3 : 1);
391   - gl->glDrawArrays(GL_LINES, 0, (GLsizei)2);
  403 + // Draw selected
  404 + if (selectedMarker != NO_MARKER) {
  405 + gl->glLineWidth(3);
  406 + gl->glDrawArrays(GL_LINES, selectedMarker * 2, (GLsizei)2);
392 407 }
393 408  
394 409 m_vaoMarker.release();
... ... @@ -398,7 +413,6 @@ void GlScope::drawVoltageChannelGraph(ChannelID channel, Graph &amp;graph, int histo
398 413 if (!scope->voltage[channel].used) return;
399 414  
400 415 m_program->setUniformValue(colorLocation, view->screen.voltage[channel].darker(100 + 10 * historyIndex));
401   -
402 416 Graph::VaoCount &v = graph.vaoVoltage[channel];
403 417  
404 418 QOpenGLVertexArrayObject::Binder b(v.first);
... ...
openhantek/src/glscope.h
... ... @@ -3,6 +3,7 @@
3 3 #pragma once
4 4  
5 5 #include <memory>
  6 +#include <list>
6 7  
7 8 #include <QtGlobal>
8 9 #include <QOpenGLBuffer>
... ... @@ -93,7 +94,7 @@ class GlScope : public QOpenGLWidget {
93 94 void generateGrid();
94 95  
95 96 // Graphs
96   - std::vector<Graph> m_GraphHistory;
  97 + std::list<Graph> m_GraphHistory;
97 98 unsigned currentGraphInHistory = 0;
98 99  
99 100 // OpenGL shader, matrix, var-locations
... ... @@ -102,4 +103,5 @@ class GlScope : public QOpenGLWidget {
102 103 int colorLocation;
103 104 int vertexLocation;
104 105 int matrixLocation;
  106 + int selectionLocation;
105 107 };
... ...
openhantek/src/glscopegraph.cpp
... ... @@ -13,6 +13,7 @@ void Graph::writeData(PPresult *data, QOpenGLShaderProgram *program, int vertexL
13 13 for (ChannelGraph &cg : data->vaChannelSpectrum) neededMemory += cg.size() * sizeof(QVector3D);
14 14  
15 15 buffer.bind();
  16 + program->bind();
16 17  
17 18 // Allocate space if necessary
18 19 if (neededMemory > allocatedMem) {
... ... @@ -32,7 +33,10 @@ void Graph::writeData(PPresult *data, QOpenGLShaderProgram *program, int vertexL
32 33 int dataSize;
33 34  
34 35 // Voltage channel
35   - if (!v.first) v.first = new QOpenGLVertexArrayObject;
  36 + if (!v.first) {
  37 + v.first = new QOpenGLVertexArrayObject;
  38 + if (!v.first->create()) throw new std::runtime_error("QOpenGLVertexArrayObject create failed");
  39 + }
36 40 ChannelGraph &gVoltage = data->vaChannelVoltage[channel];
37 41 v.first->bind();
38 42 dataSize = int(gVoltage.size() * sizeof(QVector3D));
... ... @@ -44,7 +48,10 @@ void Graph::writeData(PPresult *data, QOpenGLShaderProgram *program, int vertexL
44 48 offset += dataSize;
45 49  
46 50 // Spectrum channel
47   - if (!s.first) s.first = new QOpenGLVertexArrayObject;
  51 + if (!s.first) {
  52 + s.first = new QOpenGLVertexArrayObject;
  53 + if (!s.first->create()) throw new std::runtime_error("QOpenGLVertexArrayObject create failed");
  54 + }
48 55 ChannelGraph &gSpectrum = data->vaChannelSpectrum[channel];
49 56 s.first->bind();
50 57 dataSize = int(gSpectrum.size() * sizeof(QVector3D));
... ...
openhantek/src/glscopegraph.h
... ... @@ -12,10 +12,12 @@
12 12 #include "post/ppresult.h"
13 13  
14 14 struct Graph {
15   - Graph();
  15 + explicit Graph();
  16 + Graph(const Graph &) = delete;
  17 + Graph(const Graph &&) = delete;
16 18 ~Graph();
17   - void writeData(PPresult *data, QOpenGLShaderProgram* program, int vertexLocation);
18   - typedef std::pair<QOpenGLVertexArrayObject*, GLsizei> VaoCount;
  19 + void writeData(PPresult *data, QOpenGLShaderProgram *program, int vertexLocation);
  20 + typedef std::pair<QOpenGLVertexArrayObject *, GLsizei> VaoCount;
19 21  
20 22 public:
21 23 int allocatedMem = 0;
... ...
openhantek/src/post/graphgenerator.cpp
... ... @@ -62,7 +62,7 @@ void GraphGenerator::generateGraphsTYvoltage(PPresult *result) {
62 62 size_t neededSize = sampleCount * 2;
63 63  
64 64 // Set size directly to avoid reallocations
65   - target.resize(neededSize);
  65 + target.reserve(neededSize);
66 66  
67 67 // What's the horizontal distance between sampling points?
68 68 float horizontalFactor = (float)(samples.interval / scope->horizontal.timebase);
... ... @@ -104,7 +104,7 @@ void GraphGenerator::generateGraphsTYspectrum(PPresult *result) {
104 104 size_t neededSize = sampleCount * 2;
105 105  
106 106 // Set size directly to avoid reallocations
107   - target.resize(neededSize);
  107 + target.reserve(neededSize);
108 108  
109 109 // What's the horizontal distance between sampling points?
110 110 float horizontalFactor = (float)(samples.interval / scope->horizontal.frequencybase);
... ... @@ -160,7 +160,7 @@ void GraphGenerator::generateGraphsXY(PPresult *result, const DsoSettingsScope *
160 160 // Check if the sample count has changed
161 161 const size_t sampleCount = std::min(xSamples.sample.size(), ySamples.sample.size());
162 162 ChannelGraph &drawLines = result->vaChannelVoltage[channel];
163   - drawLines.resize(sampleCount * 2);
  163 + drawLines.reserve(sampleCount * 2);
164 164  
165 165 // Fill vector array
166 166 std::vector<double>::const_iterator xIterator = xSamples.sample.begin();
... ...