From 4ee7ee44ccceea8a6925ea1152c1ec3e95fbcad0 Mon Sep 17 00:00:00 2001 From: Benjamin Kraft Date: Sun, 24 Sep 2023 00:12:30 +0200 Subject: [PATCH] maybe fixed for windows --- src/GLWidget.cpp | 9 +++++++++ src/MainWindow.cpp | 7 +++++-- src/MainWindow.h | 2 +- src/Simulation.cpp | 26 ++++++++++++++++---------- src/Simulation.h | 6 +++++- src/main.cpp | 3 +++ 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/GLWidget.cpp b/src/GLWidget.cpp index 32a6f1b..83d1be6 100644 --- a/src/GLWidget.cpp +++ b/src/GLWidget.cpp @@ -46,6 +46,7 @@ void GLWidget::initializeGL() { simulation->semaphore.acquire(); uploadStaticDataToGPU(); + makeCurrent(); overlay->init(); } @@ -102,6 +103,8 @@ bool GLWidget::AnyDialogOpen() { } void GLWidget::uploadStaticDataToGPU() { + makeCurrent(); + auto pendula = &simulation->pendula; size_t pointCount = std::transform_reduce(pendula->begin(), pendula->end(), 0, [](size_t prev, size_t curr){ @@ -183,10 +186,14 @@ void GLWidget::uploadStaticDataToGPU() { glBindVertexArray(0); + doneCurrent(); + simulation->semaphore.release(); } void GLWidget::changePosition() { + makeCurrent(); + auto t1 = system_clock::now(); glBindBuffer(GL_ARRAY_BUFFER, positionVBO); auto positions = (GLfloat*) glMapBufferRange(GL_ARRAY_BUFFER, 0, GLsizeiptr(positionCount * sizeof(float)), GL_MAP_WRITE_BIT); @@ -201,6 +208,8 @@ void GLWidget::changePosition() { } glUnmapBuffer(GL_ARRAY_BUFFER); // std::cout << duration_cast(system_clock::now() - t1).count() << std::endl; + + doneCurrent(); simulation->semaphore.release(); } diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 6c139b2..f2f4b62 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -18,13 +18,14 @@ #include #include "Overlay.h" #include "Slider.h" +#include MainWindow::MainWindow() { simulationThread = new QThread(this); simulationThread->setObjectName("Simulation"); simulation = new Simulation; simulation->moveToThread(simulationThread); - simulationThread->start(); + connect(simulationThread, &QThread::started, simulation, &Simulation::initialize); masses = std::vector(MaxSegments); lengths = std::vector(MaxSegments); @@ -36,7 +37,9 @@ MainWindow::MainWindow() { normalizeLengths(); - QMetaObject::invokeMethod(simulation, &Simulation::initialize); + auto offSurface = new QOffscreenSurface; + offSurface->create(); + simulation->offSurface = offSurface; } void MainWindow::buildUI() { diff --git a/src/MainWindow.h b/src/MainWindow.h index 0871550..0eedcda 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -15,12 +15,12 @@ class MainWindow : public QWidget { public: explicit MainWindow(); ~MainWindow() override; + QThread * simulationThread; private: void buildUI(); QWidget * buildAddUI(); QWidget * buildSimulationUI(); Simulation * simulation; - QThread * simulationThread; GLWidget * glWidget = nullptr; diff --git a/src/Simulation.cpp b/src/Simulation.cpp index 3b1df2f..bd7f8fb 100644 --- a/src/Simulation.cpp +++ b/src/Simulation.cpp @@ -23,15 +23,12 @@ void Simulation::initialize() { // OpenGL Offscreen functions { - auto context = new QOpenGLContext(this); - auto format = QSurfaceFormat::defaultFormat(); - format.setVersion(4, 3); + context = new QOpenGLContext; + auto format = QSurfaceFormat::defaultFormat(); + format.setVersion(4, 3); context->setFormat(format); context->create(); - auto surface = new QOffscreenSurface(nullptr, this); - surface->setFormat(context->format()); - surface->create(); - context->makeCurrent(surface); + context->makeCurrent(offSurface); f = new QOpenGLFunctions_4_3_Core; if (!f->initializeOpenGLFunctions()){ std::string message = "OpenGL 4.3 is required for Compute Shaders! Falling back to CPU-Multithreading."; @@ -46,8 +43,11 @@ void Simulation::initialize() { } } - if (!useGPUAcceleration) - return; + if (!useGPUAcceleration){ + context->doneCurrent(); + return; + } + // Read GPU Limits { @@ -77,10 +77,13 @@ void Simulation::initialize() { f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, SSBO.segmentCounts); } + context->doneCurrent(); } // When the layout changes void Simulation::updateGPUData() { + context->makeCurrent(offSurface); + std::vector positions; std::vector velocities; std::vector invMasses; @@ -122,6 +125,8 @@ void Simulation::updateGPUData() { f->glBufferData(GL_SHADER_STORAGE_BUFFER, indicesSize, indices.data(), GL_STATIC_DRAW); f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO.segmentCounts); f->glBufferData(GL_SHADER_STORAGE_BUFFER, segmentCountsSize, segmentCounts.data(), GL_STATIC_DRAW); + + context->doneCurrent(); } // Every few milliseconds @@ -139,6 +144,7 @@ void Simulation::update() { double newKineticEnergy = 0; if (useGPUAcceleration) { + context->makeCurrent(offSurface); program->bind(); f->glUniform1d(program->uniformLocation("h"), h); f->glUniform1d(program->uniformLocation("gravity"), gravity); @@ -184,7 +190,7 @@ void Simulation::update() { #pragma omp atomic newKineticEnergy += localKineticEnergy; } - + context->doneCurrent(); } else { // CPU-Multithreading #pragma omp parallel for diff --git a/src/Simulation.h b/src/Simulation.h index 73f947b..5a067d6 100644 --- a/src/Simulation.h +++ b/src/Simulation.h @@ -5,6 +5,7 @@ #include #include +class QOffscreenSurface; class QTimer; class FPS; class Pendulum; @@ -30,13 +31,16 @@ public: std::binary_semaphore semaphore = std::binary_semaphore(1); FPS * ups; - void initialize(); + QOffscreenSurface* offSurface; + QOpenGLContext* context; + void updateEnergy(); signals: void gpuNotSupported(const std::string &message); void layoutChanged(); void positionChanged(); public slots: + void initialize(); void clearPendula(); void addPendula(const std::vector &add); void useGPUChanged(int); diff --git a/src/main.cpp b/src/main.cpp index 3293be6..9a2c364 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,7 @@ #include #include "MainWindow.h" #include +#include int main(int argc, char* argv[]) { QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); @@ -19,5 +20,7 @@ int main(int argc, char* argv[]) { w.setWindowIcon(QIcon(":/icons/app_icon.ico")); w.show(); + w.simulationThread->start(); + return QApplication::exec(); }