From ce95a44564483abbe9bb32ea29a300902a599ca4 Mon Sep 17 00:00:00 2001 From: Samuli Vuorinen Date: Sat, 27 Feb 2021 13:52:40 +0200 Subject: [PATCH 1/5] Add more log messages to help troubleshoot crashes --- CHANGELOG.md | 6 ++++++ src/haloray-core/gui/openGLWidget.cpp | 1 + src/haloray-core/haloray-core.pro | 1 + src/haloray-core/opengl/textureRenderer.cpp | 6 +++++- src/haloray-core/simulation/simulationEngine.cpp | 7 +++++++ src/main/main.cpp | 11 ++++++++++- src/main/main.pro | 1 + 7 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20e71c9..760a014 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Improved logging and error handling + ## 3.1.0 - 2021-02-21 ### Changed diff --git a/src/haloray-core/gui/openGLWidget.cpp b/src/haloray-core/gui/openGLWidget.cpp index c42a2cd..f0f7b33 100644 --- a/src/haloray-core/gui/openGLWidget.cpp +++ b/src/haloray-core/gui/openGLWidget.cpp @@ -58,6 +58,7 @@ void OpenGLWidget::resizeGL(int w, int h) void OpenGLWidget::initializeGL() { + qInfo("Initializing OpenGL widget"); initializeOpenGLFunctions(); m_textureRenderer = std::make_unique(); diff --git a/src/haloray-core/haloray-core.pro b/src/haloray-core/haloray-core.pro index f74dc30..a97ec4b 100644 --- a/src/haloray-core/haloray-core.pro +++ b/src/haloray-core/haloray-core.pro @@ -5,6 +5,7 @@ QT += core gui widgets CONFIG += c++17 static win32:CONFIG += windows +DEFINES += QT_MESSAGELOGCONTEXT DEFINES += QT_DEPRECATED_WARNINGS GIT_COMMIT_HASH=$$system(git log -1 --format=%h) diff --git a/src/haloray-core/opengl/textureRenderer.cpp b/src/haloray-core/opengl/textureRenderer.cpp index 2367203..a40eb55 100644 --- a/src/haloray-core/opengl/textureRenderer.cpp +++ b/src/haloray-core/opengl/textureRenderer.cpp @@ -9,6 +9,7 @@ namespace OpenGL std::unique_ptr TextureRenderer::initializeTexDrawShaderProgram() { + qInfo("Initializing texture renderer vertex shader"); auto program = std::make_unique(); bool vertexShaderCompilationSucceeded = program->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Vertex, ":/shaders/renderer.vert"); @@ -17,20 +18,23 @@ std::unique_ptr TextureRenderer::initializeTexDrawShaderPr qWarning("Texture renderer vertex shader compilation failed"); throw std::runtime_error(program->log().toUtf8()); } + qInfo("Texture renderer vertex shader successfully initialized"); + qInfo("Initializing texture renderer fragment shader"); bool fragmentShaderCompilationSucceeded = program->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Fragment, ":/shaders/renderer.frag"); - if (fragmentShaderCompilationSucceeded == false) { qWarning("Texture renderer fragment shader compilation failed"); throw std::runtime_error(program->log().toUtf8()); } + qInfo("Texture renderer fragment shader successfully initialized"); if (program->link() == false) { qWarning("Texture renderer shader linking failed"); throw std::runtime_error(program->log().toUtf8()); } + qInfo("Texture renderer shader program linking successful"); return program; } diff --git a/src/haloray-core/simulation/simulationEngine.cpp b/src/haloray-core/simulation/simulationEngine.cpp index 31a8af2..ea694a9 100644 --- a/src/haloray-core/simulation/simulationEngine.cpp +++ b/src/haloray-core/simulation/simulationEngine.cpp @@ -261,6 +261,7 @@ void SimulationEngine::initialize() void SimulationEngine::initializeShaders() { + qInfo("Initializing raytracing shader"); m_simulationShader = std::make_unique(); bool raytraceShaderCompilationSucceeded = m_simulationShader->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Compute, ":/shaders/raytrace.glsl"); if (raytraceShaderCompilationSucceeded == false) @@ -268,13 +269,16 @@ void SimulationEngine::initializeShaders() qWarning("Compiling raytracing shader failed"); throw std::runtime_error(m_simulationShader->log().toUtf8()); } + qInfo("Raytracing shader successfully initialized"); if (m_simulationShader->link() == false) { qWarning("Linking raytracing shader failed"); throw std::runtime_error(m_simulationShader->log().toUtf8()); } + qInfo("Raytracing shader program linking successful"); + qInfo("Initializing sky shader"); m_skyShader = new QOpenGLShaderProgram(this); bool skyShaderCompilationSucceeded = m_skyShader->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Compute, ":/shaders/sky.glsl"); if (skyShaderCompilationSucceeded == false) @@ -282,11 +286,14 @@ void SimulationEngine::initializeShaders() qWarning("Compiling sky shader failed"); throw std::runtime_error(m_skyShader->log().toUtf8()); } + qInfo("Sky shader successfully initialized"); + if (m_skyShader->link() == false) { qWarning("Linking sky shader failed"); throw std::runtime_error(m_skyShader->log().toUtf8()); } + qInfo("Sky shader program linking successful"); } void SimulationEngine::initializeTextures() diff --git a/src/main/main.cpp b/src/main/main.cpp index 4e4264f..e0a0ea4 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -132,7 +132,10 @@ int main(int argc, char *argv[]) HaloRay::MainWindow mainWindow; mainWindow.showMaximized(); - return app.exec(); + qInfo("Starting event loop"); + int returnCode = app.exec(); + qInfo("Event loop exited with return code %i", returnCode); + return returnCode; } catch (const std::exception &e) { @@ -140,4 +143,10 @@ int main(int argc, char *argv[]) qFatal("Caught exception: %s", e.what()); return 1; } + catch (...) + { + QMessageBox::critical(nullptr, QObject::tr("Exception thrown"), QObject::tr("An unknown error occurred")); + qFatal("Caught non-standard exception"); + return 2; + } } diff --git a/src/main/main.pro b/src/main/main.pro index 661b19c..2b2e092 100644 --- a/src/main/main.pro +++ b/src/main/main.pro @@ -5,6 +5,7 @@ QT += core gui widgets CONFIG += c++17 win32:CONFIG += windows +DEFINES += QT_MESSAGELOGCONTEXT DEFINES += QT_DEPRECATED_WARNINGS GIT_COMMIT_HASH=$$system(git log -1 --format=%h) From a2eb88f92d79fafc86e789b676381ceb9b12acfe Mon Sep 17 00:00:00 2001 From: Samuli Vuorinen Date: Fri, 5 Mar 2021 18:19:54 +0200 Subject: [PATCH 2/5] Change shader compilation log messages addCacheableShaderFromSourceFile doesn't actually compile the shader. Compilation is deferred to link(). Changed log message to reflect this. --- src/haloray-core/opengl/textureRenderer.cpp | 16 +++++++-------- .../simulation/simulationEngine.cpp | 20 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/haloray-core/opengl/textureRenderer.cpp b/src/haloray-core/opengl/textureRenderer.cpp index a40eb55..5afc4a9 100644 --- a/src/haloray-core/opengl/textureRenderer.cpp +++ b/src/haloray-core/opengl/textureRenderer.cpp @@ -11,30 +11,30 @@ std::unique_ptr TextureRenderer::initializeTexDrawShaderPr { qInfo("Initializing texture renderer vertex shader"); auto program = std::make_unique(); - bool vertexShaderCompilationSucceeded = program->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Vertex, ":/shaders/renderer.vert"); + bool vertexShaderReadSucceeded = program->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Vertex, ":/shaders/renderer.vert"); - if (vertexShaderCompilationSucceeded == false) + if (vertexShaderReadSucceeded == false) { - qWarning("Texture renderer vertex shader compilation failed"); + qWarning("Texture renderer vertex shader read failed"); throw std::runtime_error(program->log().toUtf8()); } qInfo("Texture renderer vertex shader successfully initialized"); qInfo("Initializing texture renderer fragment shader"); - bool fragmentShaderCompilationSucceeded = program->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Fragment, ":/shaders/renderer.frag"); - if (fragmentShaderCompilationSucceeded == false) + bool fragmentShaderReadSucceeded = program->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Fragment, ":/shaders/renderer.frag"); + if (fragmentShaderReadSucceeded == false) { - qWarning("Texture renderer fragment shader compilation failed"); + qWarning("Texture renderer fragment shader read failed"); throw std::runtime_error(program->log().toUtf8()); } qInfo("Texture renderer fragment shader successfully initialized"); if (program->link() == false) { - qWarning("Texture renderer shader linking failed"); + qWarning("Texture renderer shader compilation and linking failed"); throw std::runtime_error(program->log().toUtf8()); } - qInfo("Texture renderer shader program linking successful"); + qInfo("Texture renderer shader program compilation and linking successful"); return program; } diff --git a/src/haloray-core/simulation/simulationEngine.cpp b/src/haloray-core/simulation/simulationEngine.cpp index ea694a9..b34c00c 100644 --- a/src/haloray-core/simulation/simulationEngine.cpp +++ b/src/haloray-core/simulation/simulationEngine.cpp @@ -263,37 +263,37 @@ void SimulationEngine::initializeShaders() { qInfo("Initializing raytracing shader"); m_simulationShader = std::make_unique(); - bool raytraceShaderCompilationSucceeded = m_simulationShader->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Compute, ":/shaders/raytrace.glsl"); - if (raytraceShaderCompilationSucceeded == false) + bool raytraceShaderReadSucceeded = m_simulationShader->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Compute, ":/shaders/raytrace.glsl"); + if (raytraceShaderReadSucceeded == false) { - qWarning("Compiling raytracing shader failed"); + qWarning("Reading raytracing shader failed"); throw std::runtime_error(m_simulationShader->log().toUtf8()); } qInfo("Raytracing shader successfully initialized"); if (m_simulationShader->link() == false) { - qWarning("Linking raytracing shader failed"); + qWarning("Compiling and linking raytracing shader failed"); throw std::runtime_error(m_simulationShader->log().toUtf8()); } - qInfo("Raytracing shader program linking successful"); + qInfo("Raytracing shader program compilation and linking successful"); qInfo("Initializing sky shader"); m_skyShader = new QOpenGLShaderProgram(this); - bool skyShaderCompilationSucceeded = m_skyShader->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Compute, ":/shaders/sky.glsl"); - if (skyShaderCompilationSucceeded == false) + bool skyShaderReadSucceeded = m_skyShader->addCacheableShaderFromSourceFile(QOpenGLShader::ShaderTypeBit::Compute, ":/shaders/sky.glsl"); + if (skyShaderReadSucceeded == false) { - qWarning("Compiling sky shader failed"); + qWarning("Reading sky shader failed"); throw std::runtime_error(m_skyShader->log().toUtf8()); } qInfo("Sky shader successfully initialized"); if (m_skyShader->link() == false) { - qWarning("Linking sky shader failed"); + qWarning("Compiling and linking sky shader failed"); throw std::runtime_error(m_skyShader->log().toUtf8()); } - qInfo("Sky shader program linking successful"); + qInfo("Sky shader program compilation and linking successful"); } void SimulationEngine::initializeTextures() From 94ae3173addeda67dfb1390d8b4982947cddf5d2 Mon Sep 17 00:00:00 2001 From: Samuli Vuorinen Date: Thu, 11 Mar 2021 12:42:55 +0200 Subject: [PATCH 3/5] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 59bad2b..04fba8b 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,12 @@ On Windows you can find it in `%LOCALAPPDATA%\Temp\haloray\haloray.log` where On Linux the log file is in `/tmp/haloray/haloray.log` +If the logs do not show any useful information and no error messages pop up, +it is possible the crash happens because of a GPU driver bug. This has +occasionally happened with some Intel GPUs, and there is not much HaloRay +can do about it. It is recommended to update to the latest GPU drivers if +problems like this are encountered. + ## Acknowledgments - [Lauri Kangas](https://github.com/lkangas) for providing tons of reading material and debugging help From 4b32b863cb2d7a505427a8be10a3dfc2f800cacb Mon Sep 17 00:00:00 2001 From: Samuli Vuorinen Date: Wed, 24 Mar 2021 00:09:06 +0200 Subject: [PATCH 4/5] Fix incorrect pyramid apex angle bug Apex angle of pyramid crystals was being calculated based on the angle between opposing edges in the pyramid, when it should have been based on opposing faces. --- CHANGELOG.md | 4 ++++ .../gui/crystalPreview/previewRenderArea.cpp | 15 ++++++++------- .../resources/shaders/raytrace.glsl | 17 ++++++++++------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 760a014..92c3763 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved logging and error handling +### Fixed + +- Fixed bug where pyramid apex angle was set incorrectly based on crystal edge angle rather than face angle + ## 3.1.0 - 2021-02-21 ### Changed diff --git a/src/haloray-core/gui/crystalPreview/previewRenderArea.cpp b/src/haloray-core/gui/crystalPreview/previewRenderArea.cpp index b5d577d..e1ddabb 100644 --- a/src/haloray-core/gui/crystalPreview/previewRenderArea.cpp +++ b/src/haloray-core/gui/crystalPreview/previewRenderArea.cpp @@ -123,6 +123,9 @@ void PreviewRenderArea::initializeGeometry(QVector3D *vertices, int numVertices) float deltaAngle = degToRad(60.0f); QVector2D hexagonCorners[6]; + /* The sqrt(3)/2 multiplier makes the default crystal such + that the distance of a vertex from the C axis is 1.0 */ + float sizeScaler = sqrt(3.0f) / 2.0f; for (int face = 0; face < 6; ++face) { int previousFace = face == 0 ? 5 : face - 1; @@ -132,11 +135,9 @@ void PreviewRenderArea::initializeGeometry(QVector3D *vertices, int numVertices) float currentAngle = previousAngle + deltaAngle; float nextAngle = previousAngle + 2.0 * deltaAngle; - /* The sqrt(3)/2 multiplier makes the default crystal such - that the distance of a vertex from the C axis is 1.0 */ - float previousDistance = 0.86602540378443864676372317075294 * prismFaceDistances[previousFace]; - float currentDistance = 0.86602540378443864676372317075294 * prismFaceDistances[face]; - float nextDistance = 0.86602540378443864676372317075294 * prismFaceDistances[nextFace]; + float previousDistance = sizeScaler * prismFaceDistances[previousFace]; + float currentDistance = sizeScaler * prismFaceDistances[face]; + float nextDistance = sizeScaler * prismFaceDistances[nextFace]; QVector2D previousLine = QVector2D(previousDistance, previousAngle); QVector2D currentLine = QVector2D(currentDistance, currentAngle); @@ -185,8 +186,8 @@ void PreviewRenderArea::initializeGeometry(QVector3D *vertices, int numVertices) } // Scale pyramid caps - float upperApexMaxHeight = 1.0 / tan(upperApexAngle / 2.0); - float lowerApexMaxHeight = 1.0 / tan(lowerApexAngle / 2.0); + float upperApexMaxHeight = sizeScaler / tan(upperApexAngle / 2.0); + float lowerApexMaxHeight = sizeScaler / tan(lowerApexAngle / 2.0); float upperApexHeight = upperApexHeightAverage; float lowerApexHeight = lowerApexHeightAverage; diff --git a/src/haloray-core/resources/shaders/raytrace.glsl b/src/haloray-core/resources/shaders/raytrace.glsl index abd38e7..20da1b8 100644 --- a/src/haloray-core/resources/shaders/raytrace.glsl +++ b/src/haloray-core/resources/shaders/raytrace.glsl @@ -497,6 +497,11 @@ void initializeCrystal() { float deltaAngle = radians(60.0); vec2 hexagonCorners[6]; + /* The sqrt(3)/2 multiplier makes the default crystal such + that the distance of a vertex from the C axis is 1.0. + sqrt(3)/2 equals cos(30deg), which is faster to calculate + on GPU */ + float sizeScaler = cos(radians(30.0)); for (int face = 0; face < 6; ++face) { int previousFace = face == 0 ? 5 : face - 1; @@ -506,11 +511,9 @@ void initializeCrystal() float currentAngle = previousAngle + deltaAngle; float nextAngle = previousAngle + 2.0 * deltaAngle; - /* The sqrt(3)/2 multiplier makes the default crystal such - that the distance of a vertex from the C axis is 1.0 */ - float previousDistance = 0.86602540378443864676372317075294 * crystalProperties.prismFaceDistances[previousFace]; - float currentDistance = 0.86602540378443864676372317075294 * crystalProperties.prismFaceDistances[face]; - float nextDistance = 0.86602540378443864676372317075294 * crystalProperties.prismFaceDistances[nextFace]; + float previousDistance = sizeScaler * crystalProperties.prismFaceDistances[previousFace]; + float currentDistance = sizeScaler * crystalProperties.prismFaceDistances[face]; + float nextDistance = sizeScaler * crystalProperties.prismFaceDistances[nextFace]; vec2 previousLine = vec2(previousDistance, previousAngle); vec2 currentLine = vec2(currentDistance, currentAngle); @@ -564,8 +567,8 @@ void initializeCrystal() } // Scale pyramid caps - float upperApexMaxHeight = 1.0 / tan(crystalProperties.upperApexAngle / 2.0); - float lowerApexMaxHeight = 1.0 / tan(crystalProperties.lowerApexAngle / 2.0); + float upperApexMaxHeight = sizeScaler / tan(crystalProperties.upperApexAngle / 2.0); + float lowerApexMaxHeight = sizeScaler / tan(crystalProperties.lowerApexAngle / 2.0); vec2 random = randn(); float upperApexHeight = clamp(crystalProperties.upperApexHeightAverage + crystalProperties.upperApexHeightStd * random.x, 0.0, 1.0); From 84dea3961e97d87279a1ed6f0fdf7df517d3d426 Mon Sep 17 00:00:00 2001 From: Samuli Vuorinen Date: Wed, 24 Mar 2021 00:15:00 +0200 Subject: [PATCH 5/5] Bump version number --- CHANGELOG.md | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92c3763..4d07576 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 3.2.0 - 2021-03-24 ### Changed diff --git a/appveyor.yml b/appveyor.yml index c352268..6da6a19 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: "3.1.0-{build}" +version: "3.2.0-{build}" branches: only: - master