maybe fixed for windows

main
Benjamin Kraft 1 year ago
parent b9e00628f3
commit 4ee7ee44cc
  1. 9
      src/GLWidget.cpp
  2. 7
      src/MainWindow.cpp
  3. 2
      src/MainWindow.h
  4. 26
      src/Simulation.cpp
  5. 6
      src/Simulation.h
  6. 3
      src/main.cpp

@ -46,6 +46,7 @@ void GLWidget::initializeGL() {
simulation->semaphore.acquire(); simulation->semaphore.acquire();
uploadStaticDataToGPU(); uploadStaticDataToGPU();
makeCurrent();
overlay->init(); overlay->init();
} }
@ -102,6 +103,8 @@ bool GLWidget::AnyDialogOpen() {
} }
void GLWidget::uploadStaticDataToGPU() { void GLWidget::uploadStaticDataToGPU() {
makeCurrent();
auto pendula = &simulation->pendula; auto pendula = &simulation->pendula;
size_t pointCount = std::transform_reduce(pendula->begin(), pendula->end(), 0, [](size_t prev, size_t curr){ 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); glBindVertexArray(0);
doneCurrent();
simulation->semaphore.release(); simulation->semaphore.release();
} }
void GLWidget::changePosition() { void GLWidget::changePosition() {
makeCurrent();
auto t1 = system_clock::now(); auto t1 = system_clock::now();
glBindBuffer(GL_ARRAY_BUFFER, positionVBO); glBindBuffer(GL_ARRAY_BUFFER, positionVBO);
auto positions = (GLfloat*) glMapBufferRange(GL_ARRAY_BUFFER, 0, GLsizeiptr(positionCount * sizeof(float)), GL_MAP_WRITE_BIT); 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); glUnmapBuffer(GL_ARRAY_BUFFER);
// std::cout << duration_cast<microseconds>(system_clock::now() - t1).count() << std::endl; // std::cout << duration_cast<microseconds>(system_clock::now() - t1).count() << std::endl;
doneCurrent();
simulation->semaphore.release(); simulation->semaphore.release();
} }

@ -18,13 +18,14 @@
#include <QTimer> #include <QTimer>
#include "Overlay.h" #include "Overlay.h"
#include "Slider.h" #include "Slider.h"
#include <QOffscreenSurface>
MainWindow::MainWindow() { MainWindow::MainWindow() {
simulationThread = new QThread(this); simulationThread = new QThread(this);
simulationThread->setObjectName("Simulation"); simulationThread->setObjectName("Simulation");
simulation = new Simulation; simulation = new Simulation;
simulation->moveToThread(simulationThread); simulation->moveToThread(simulationThread);
simulationThread->start(); connect(simulationThread, &QThread::started, simulation, &Simulation::initialize);
masses = std::vector<double>(MaxSegments); masses = std::vector<double>(MaxSegments);
lengths = std::vector<double>(MaxSegments); lengths = std::vector<double>(MaxSegments);
@ -36,7 +37,9 @@ MainWindow::MainWindow() {
normalizeLengths(); normalizeLengths();
QMetaObject::invokeMethod(simulation, &Simulation::initialize); auto offSurface = new QOffscreenSurface;
offSurface->create();
simulation->offSurface = offSurface;
} }
void MainWindow::buildUI() { void MainWindow::buildUI() {

@ -15,12 +15,12 @@ class MainWindow : public QWidget {
public: public:
explicit MainWindow(); explicit MainWindow();
~MainWindow() override; ~MainWindow() override;
QThread * simulationThread;
private: private:
void buildUI(); void buildUI();
QWidget * buildAddUI(); QWidget * buildAddUI();
QWidget * buildSimulationUI(); QWidget * buildSimulationUI();
Simulation * simulation; Simulation * simulation;
QThread * simulationThread;
GLWidget * glWidget = nullptr; GLWidget * glWidget = nullptr;

@ -23,15 +23,12 @@ void Simulation::initialize() {
// OpenGL Offscreen functions // OpenGL Offscreen functions
{ {
auto context = new QOpenGLContext(this); context = new QOpenGLContext;
auto format = QSurfaceFormat::defaultFormat(); auto format = QSurfaceFormat::defaultFormat();
format.setVersion(4, 3); format.setVersion(4, 3);
context->setFormat(format); context->setFormat(format);
context->create(); context->create();
auto surface = new QOffscreenSurface(nullptr, this); context->makeCurrent(offSurface);
surface->setFormat(context->format());
surface->create();
context->makeCurrent(surface);
f = new QOpenGLFunctions_4_3_Core; f = new QOpenGLFunctions_4_3_Core;
if (!f->initializeOpenGLFunctions()){ if (!f->initializeOpenGLFunctions()){
std::string message = "OpenGL 4.3 is required for Compute Shaders! Falling back to CPU-Multithreading."; 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) if (!useGPUAcceleration){
return; context->doneCurrent();
return;
}
// Read GPU Limits // Read GPU Limits
{ {
@ -77,10 +77,13 @@ void Simulation::initialize() {
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, SSBO.segmentCounts); f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, SSBO.segmentCounts);
} }
context->doneCurrent();
} }
// When the layout changes // When the layout changes
void Simulation::updateGPUData() { void Simulation::updateGPUData() {
context->makeCurrent(offSurface);
std::vector<GLdouble> positions; std::vector<GLdouble> positions;
std::vector<GLdouble> velocities; std::vector<GLdouble> velocities;
std::vector<GLdouble> invMasses; std::vector<GLdouble> invMasses;
@ -122,6 +125,8 @@ void Simulation::updateGPUData() {
f->glBufferData(GL_SHADER_STORAGE_BUFFER, indicesSize, indices.data(), GL_STATIC_DRAW); f->glBufferData(GL_SHADER_STORAGE_BUFFER, indicesSize, indices.data(), GL_STATIC_DRAW);
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO.segmentCounts); f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO.segmentCounts);
f->glBufferData(GL_SHADER_STORAGE_BUFFER, segmentCountsSize, segmentCounts.data(), GL_STATIC_DRAW); f->glBufferData(GL_SHADER_STORAGE_BUFFER, segmentCountsSize, segmentCounts.data(), GL_STATIC_DRAW);
context->doneCurrent();
} }
// Every few milliseconds // Every few milliseconds
@ -139,6 +144,7 @@ void Simulation::update() {
double newKineticEnergy = 0; double newKineticEnergy = 0;
if (useGPUAcceleration) { if (useGPUAcceleration) {
context->makeCurrent(offSurface);
program->bind(); program->bind();
f->glUniform1d(program->uniformLocation("h"), h); f->glUniform1d(program->uniformLocation("h"), h);
f->glUniform1d(program->uniformLocation("gravity"), gravity); f->glUniform1d(program->uniformLocation("gravity"), gravity);
@ -184,7 +190,7 @@ void Simulation::update() {
#pragma omp atomic #pragma omp atomic
newKineticEnergy += localKineticEnergy; newKineticEnergy += localKineticEnergy;
} }
context->doneCurrent();
} else { } else {
// CPU-Multithreading // CPU-Multithreading
#pragma omp parallel for #pragma omp parallel for

@ -5,6 +5,7 @@
#include <semaphore> #include <semaphore>
#include <QOpenGLFunctions_4_3_Core> #include <QOpenGLFunctions_4_3_Core>
class QOffscreenSurface;
class QTimer; class QTimer;
class FPS; class FPS;
class Pendulum; class Pendulum;
@ -30,13 +31,16 @@ public:
std::binary_semaphore semaphore = std::binary_semaphore(1); std::binary_semaphore semaphore = std::binary_semaphore(1);
FPS * ups; FPS * ups;
void initialize(); QOffscreenSurface* offSurface;
QOpenGLContext* context;
void updateEnergy(); void updateEnergy();
signals: signals:
void gpuNotSupported(const std::string &message); void gpuNotSupported(const std::string &message);
void layoutChanged(); void layoutChanged();
void positionChanged(); void positionChanged();
public slots: public slots:
void initialize();
void clearPendula(); void clearPendula();
void addPendula(const std::vector<Pendulum *> &add); void addPendula(const std::vector<Pendulum *> &add);
void useGPUChanged(int); void useGPUChanged(int);

@ -2,6 +2,7 @@
#include <QSurfaceFormat> #include <QSurfaceFormat>
#include "MainWindow.h" #include "MainWindow.h"
#include <QIcon> #include <QIcon>
#include <QThread>
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); QSurfaceFormat fmt = QSurfaceFormat::defaultFormat();
@ -19,5 +20,7 @@ int main(int argc, char* argv[]) {
w.setWindowIcon(QIcon(":/icons/app_icon.ico")); w.setWindowIcon(QIcon(":/icons/app_icon.ico"));
w.show(); w.show();
w.simulationThread->start();
return QApplication::exec(); return QApplication::exec();
} }

Loading…
Cancel
Save