From ae9a54c612bdc0711a3b602140c58ae451f0a9d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Tue, 24 Nov 2015 20:08:49 +0100 Subject: [PATCH 1/2] Updated gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 178eef5..c7d78ba 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /output/ /perf.* /pic*.png +core *.pro.user *.pro.user.* qrc_*.cpp From c7e868ef112403220ec7150b3372d6e2580a2705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 3 Dec 2015 23:04:50 +0100 Subject: [PATCH 2/2] Better OpenGL error checking + opengl header refactoring --- Makefile | 5 ++ src/definition/DefinitionNode.cpp | 19 ++++--- src/definition/Layers.cpp | 2 +- src/definition/Scenery.cpp | 6 +- .../modeler/quickapp/MainModelerWindow.cpp | 5 ++ src/interface/modeler/quickapp/OpenGLView.cpp | 11 ++-- src/interface/modeler/quickapp/OpenGLView.h | 1 + src/render/opengl/ExplorerChunkTerrain.cpp | 2 +- src/render/opengl/OpenGLFunctions.h | 9 +++ src/render/opengl/OpenGLRenderer.cpp | 30 +++++++--- src/render/opengl/OpenGLRenderer.h | 7 +++ src/render/opengl/OpenGLShaderProgram.cpp | 57 ++++++++++--------- src/render/opengl/OpenGLShaderProgram.h | 2 +- src/render/opengl/OpenGLSharedState.cpp | 3 +- src/render/opengl/OpenGLSharedState.h | 2 +- src/render/opengl/OpenGLTerrain.cpp | 2 +- src/render/opengl/OpenGLVariable.cpp | 2 +- src/render/opengl/VertexArray.h | 2 +- src/render/opengl/opengl_global.h | 3 +- src/tests/Layers_Test.cpp | 2 +- 20 files changed, 111 insertions(+), 61 deletions(-) create mode 100644 src/render/opengl/OpenGLFunctions.h diff --git a/Makefile b/Makefile index 61156ac..4ded77d 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,11 @@ profile_cli:build LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g ${BUILDPATH}/interface/commandline/paysages-cli $(ARGS) perf report -g +gltrace:build + rm -f *.trace + LD_PRELOAD=/usr/lib/x86_64-linux-gnu/apitrace/wrappers/glxtrace.so LD_LIBRARY_PATH=$(LIBRARY_PATH) ${BUILDPATH}/interface/modeler/quickapp/paysages-modeler $(ARGS) + qapitrace paysages-modeler.trace + package:build rm -rf paysages3d-linux rm -f paysages3d-linux.tar.bz2 diff --git a/src/definition/DefinitionNode.cpp b/src/definition/DefinitionNode.cpp index 079e832..d6938eb 100644 --- a/src/definition/DefinitionNode.cpp +++ b/src/definition/DefinitionNode.cpp @@ -110,8 +110,8 @@ bool DefinitionNode::applyDiff(const DefinitionDiff *diff, bool) { if (diff->getTypeName() == type_name) { return true; } else { - Logs::error() << "Can't apply " << diff->getTypeName() << " diff to " << getName() << " " << type_name - << " node" << std::endl; + Logs::error() << "[Definition] Can't apply " << diff->getTypeName() << " diff to " << getName() << " " + << type_name << " node" << std::endl; return false; } } @@ -155,8 +155,8 @@ void DefinitionNode::save(PackStream *stream) const { child->save(stream); } else { // Child size not known, write it to a temporary stream to know it - Logs::debug() << "Unknown size for child " << child->name << ", unefficient writing to temporary stream" - << std::endl; + Logs::debug() << "[Definition] Unknown size for child " << child->name + << ", unefficient writing to temporary stream" << std::endl; PackStream substream; child->save(&substream); stream->writeFromBuffer(substream, true); @@ -183,7 +183,7 @@ void DefinitionNode::load(PackStream *stream) { // TODO Ask subclass if it can instanciate a child // Else skip length of unknown child stream->skipBytes(child_size); - Logs::warning() << "Skipped unknown child '" << child_name << "'" << std::endl; + Logs::warning() << "[Definition] Skipped unknown child '" << child_name << "'" << std::endl; } } } @@ -196,12 +196,13 @@ void DefinitionNode::copy(DefinitionNode *destination) const { if (dest_child) { child->copy(dest_child); } else { - Logs::warning() << "Can't copy to child " << child->name << " of " << destination->getTypeName() - << std::endl; + Logs::warning() << "[Definition] Can't copy to child " << child->name << " of " + << destination->getTypeName() << std::endl; } } } else { - Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl; + Logs::error() << "[Definition] Can't copy from " << getTypeName() << " to " << destination->getTypeName() + << std::endl; } } @@ -225,7 +226,7 @@ void DefinitionNode::removeChild(DefinitionNode *child) { child->parent = NULL; children.erase(it); } else { - Logs::warning() << "Trying to remove not found child '" << child->name << "' from '" << name << "'" + Logs::warning() << "[Definition] Trying to remove not found child '" << child->name << "' from '" << name << "'" << std::endl; } } diff --git a/src/definition/Layers.cpp b/src/definition/Layers.cpp index 3ace25a..4c31883 100644 --- a/src/definition/Layers.cpp +++ b/src/definition/Layers.cpp @@ -119,7 +119,7 @@ bool Layers::applyDiff(const DefinitionDiff *diff, bool backward) { void Layers::generateInitDiffs(std::vector *diffs) const { int i = 0; - for (auto layer: layers) { + for (auto layer : layers) { auto diff = new LayersDiff(this, LayersDiff::LAYER_ADDED, i++); diff->saveLayer(*layer); diffs->push_back(diff); diff --git a/src/definition/Scenery.cpp b/src/definition/Scenery.cpp index db08709..163ad0e 100644 --- a/src/definition/Scenery.cpp +++ b/src/definition/Scenery.cpp @@ -47,7 +47,7 @@ Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) co stream.write(&version_header); stream.write(&app_header); - Logs::debug() << "Scenery saved to file: " << filepath << std::endl; + Logs::debug() << "[Definition] Scenery saved to file: " << filepath << std::endl; return FILE_OPERATION_OK; } @@ -85,7 +85,7 @@ Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath) { return FILE_OPERATION_APP_MISMATCH; } - Logs::debug() << "Scenery loaded from file: " << filepath << std::endl; + Logs::debug() << "[Definition] Scenery loaded from file: " << filepath << std::endl; return FILE_OPERATION_OK; } @@ -110,7 +110,7 @@ void Scenery::autoPreset(int seed) { validate(); - Logs::debug() << "New scenery generated from seed " << seed << std::endl; + Logs::debug() << "[Definition] New scenery generated from seed " << seed << std::endl; } void Scenery::setAtmosphere(AtmosphereDefinition *atmosphere) { diff --git a/src/interface/modeler/quickapp/MainModelerWindow.cpp b/src/interface/modeler/quickapp/MainModelerWindow.cpp index 1d70530..80b64be 100644 --- a/src/interface/modeler/quickapp/MainModelerWindow.cpp +++ b/src/interface/modeler/quickapp/MainModelerWindow.cpp @@ -16,6 +16,11 @@ #include MainModelerWindow::MainModelerWindow() { + /*QSurfaceFormat new_format = format(); + new_format.setVersion(3, 3); + new_format.setProfile(QSurfaceFormat::CoreProfile); + setFormat(new_format);*/ + scenery = new Scenery(); scenery->autoPreset(); diff --git a/src/interface/modeler/quickapp/OpenGLView.cpp b/src/interface/modeler/quickapp/OpenGLView.cpp index 66cc116..39a47e0 100644 --- a/src/interface/modeler/quickapp/OpenGLView.cpp +++ b/src/interface/modeler/quickapp/OpenGLView.cpp @@ -20,7 +20,6 @@ OpenGLView::OpenGLView(QQuickItem *parent) : QQuickItem(parent) { connect(this, SIGNAL(windowChanged(QQuickWindow *)), this, SLOT(handleWindowChanged(QQuickWindow *))); connect(this, SIGNAL(widthChanged()), this, SLOT(handleResize())); connect(this, SIGNAL(heightChanged()), this, SLOT(handleResize())); - startTimer(50); } void OpenGLView::handleWindowChanged(QQuickWindow *win) { @@ -28,12 +27,11 @@ void OpenGLView::handleWindowChanged(QQuickWindow *win) { window = qobject_cast(win); if (window) { renderer = window->getRenderer(); - - connect(win, SIGNAL(beforeRendering()), this, SLOT(paint()), Qt::DirectConnection); + initialized = false; win->setClearBeforeRendering(false); - initialized = false; + connect(win, SIGNAL(sceneGraphInitialized()), this, SLOT(handleSceneGraphReady())); } } } @@ -66,6 +64,11 @@ void OpenGLView::handleResize() { resized = true; } +void OpenGLView::handleSceneGraphReady() { + connect(window, SIGNAL(beforeRendering()), this, SLOT(paint()), Qt::DirectConnection); + startTimer(50); +} + void OpenGLView::wheelEvent(QWheelEvent *event) { if (not acceptInputs()) { return; diff --git a/src/interface/modeler/quickapp/OpenGLView.h b/src/interface/modeler/quickapp/OpenGLView.h index 51a2dc8..d62fd14 100644 --- a/src/interface/modeler/quickapp/OpenGLView.h +++ b/src/interface/modeler/quickapp/OpenGLView.h @@ -17,6 +17,7 @@ class OpenGLView : public QQuickItem { void handleWindowChanged(QQuickWindow *win); void paint(); void handleResize(); + void handleSceneGraphReady(); protected: virtual void wheelEvent(QWheelEvent *event) override; diff --git a/src/render/opengl/ExplorerChunkTerrain.cpp b/src/render/opengl/ExplorerChunkTerrain.cpp index 0e9f86a..c1578ba 100644 --- a/src/render/opengl/ExplorerChunkTerrain.cpp +++ b/src/render/opengl/ExplorerChunkTerrain.cpp @@ -1,8 +1,8 @@ #include "ExplorerChunkTerrain.h" -#include OPENGL_FUNCTIONS_INCLUDE #include #include +#include "OpenGLFunctions.h" #include "ColorProfile.h" #include "CameraDefinition.h" #include "OpenGLRenderer.h" diff --git a/src/render/opengl/OpenGLFunctions.h b/src/render/opengl/OpenGLFunctions.h new file mode 100644 index 0000000..fba4f67 --- /dev/null +++ b/src/render/opengl/OpenGLFunctions.h @@ -0,0 +1,9 @@ +#ifndef OPENGLFUNCTIONS +#define OPENGLFUNCTIONS + +#include "opengl_global.h" + +#define _OPENGL_FUNCTIONS_INCLUDE +#include _OPENGL_FUNCTIONS_INCLUDE + +#endif // OPENGLFUNCTIONS diff --git a/src/render/opengl/OpenGLRenderer.cpp b/src/render/opengl/OpenGLRenderer.cpp index 25e15d7..075ac39 100644 --- a/src/render/opengl/OpenGLRenderer.cpp +++ b/src/render/opengl/OpenGLRenderer.cpp @@ -1,6 +1,6 @@ #include "OpenGLRenderer.h" -#include OPENGL_FUNCTIONS_INCLUDE +#include "OpenGLFunctions.h" #include "CameraDefinition.h" #include "OpenGLSharedState.h" #include "OpenGLSkybox.h" @@ -58,10 +58,20 @@ OpenGLRenderer::~OpenGLRenderer() { delete shared_state; } +void OpenGLRenderer::checkForErrors(const std::string &domain) { + int error_code; + while ((error_code = functions->glGetError()) != GL_NO_ERROR) { + Logs::warning() << "[OpenGL] Error in " << domain << " : " << error_code << std::endl; + } +} + void OpenGLRenderer::initialize() { ready = functions->initializeOpenGLFunctions(); if (ready) { + Logs::debug() << "[OpenGL] renderer started (version " << functions->glGetString(GL_VERSION) + << ", glsl version " << functions->glGetString(GL_SHADING_LANGUAGE_VERSION) << ")" << std::endl; + prepareOpenGLState(); prepare(); @@ -80,8 +90,10 @@ void OpenGLRenderer::initialize() { terrain->updateScenery(); cameraChangeEvent(render_camera); + + checkForErrors("initialize"); } else { - Logs::error() << "Failed to initialize OpenGL bindings" << std::endl; + Logs::error() << "[OpenGL] Failed to initialize api bindings" << std::endl; } } @@ -129,24 +141,28 @@ void OpenGLRenderer::resize(int width, int height) { cameraChangeEvent(render_camera); prepareOpenGLState(); + + checkForErrors("resize"); } } void OpenGLRenderer::paint() { if (ready and not paused) { + checkForErrors("before_paint"); functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); skybox->render(); + checkForErrors("skybox"); + terrain->render(); + checkForErrors("terrain"); + water->render(); + checkForErrors("water"); if (mouse_tracking) { updateMouseProjection(); - } - - int error_code; - while ((error_code = functions->glGetError()) != GL_NO_ERROR) { - Logs::warning() << "[OpenGL] ERROR : " << error_code << std::endl; + checkForErrors("mouse_tracking"); } displayed = true; diff --git a/src/render/opengl/OpenGLRenderer.h b/src/render/opengl/OpenGLRenderer.h index 0796303..dcd0250 100644 --- a/src/render/opengl/OpenGLRenderer.h +++ b/src/render/opengl/OpenGLRenderer.h @@ -31,6 +31,13 @@ class OPENGLSHARED_EXPORT OpenGLRenderer : public SoftwareRenderer { return displayed; } + /** + * Check for errors in OpenGL context. + * + * Will write the error on standard error output, with the *domain* specified. + */ + void checkForErrors(const std::string &domain); + void initialize(); void prepareOpenGLState(); void resize(int width, int height); diff --git a/src/render/opengl/OpenGLShaderProgram.cpp b/src/render/opengl/OpenGLShaderProgram.cpp index 817b97f..f6adc8a 100644 --- a/src/render/opengl/OpenGLShaderProgram.cpp +++ b/src/render/opengl/OpenGLShaderProgram.cpp @@ -1,8 +1,8 @@ #include "OpenGLShaderProgram.h" -#include OPENGL_FUNCTIONS_INCLUDE #include #include +#include "OpenGLFunctions.h" #include "OpenGLRenderer.h" #include "OpenGLSharedState.h" #include "Texture2D.h" @@ -27,7 +27,7 @@ void OpenGLShaderProgram::addVertexSource(QString path) { if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { source_vertex += QString(file.readAll()).toStdString(); } else { - Logs::error() << "Can't open vertex file " << file.fileName().toStdString() << std::endl; + Logs::error() << "[OpenGL] Can't open vertex file " << file.fileName().toStdString() << std::endl; } } @@ -36,7 +36,7 @@ void OpenGLShaderProgram::addFragmentSource(QString path) { if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { source_fragment += QString(file.readAll()).toStdString(); } else { - Logs::error() << "Can't open fragment file " << file.fileName().toStdString() << std::endl; + Logs::error() << "[OpenGL] Can't open fragment file " << file.fileName().toStdString() << std::endl; } } @@ -45,24 +45,29 @@ void OpenGLShaderProgram::compile() { program->addShaderFromSourceCode(QOpenGLShader::Fragment, QString::fromStdString(source_fragment)); if (not program->link()) { - Logs::warning() << "Error while compiling shader " << name << std::endl + Logs::warning() << "[OpenGL] Error while compiling shader " << name << std::endl << program->log().toStdString() << std::endl; } else if (program->log().length() > 0) { - Logs::debug() << "Shader " << name << " compilation output:" << std::endl + Logs::debug() << "[OpenGL] Shader " << name << " compilation output:" << std::endl << program->log().toStdString() << std::endl; + } else { + Logs::debug() << "[OpenGL] Shader " << name << " compiled" << std::endl; } } -void OpenGLShaderProgram::bind() { +bool OpenGLShaderProgram::bind() { if (not compiled) { compile(); compiled = true; } - program->bind(); - - int texture_unit = 0; - renderer->getSharedState()->apply(this, texture_unit); + if (program->bind()) { + int texture_unit = 0; + renderer->getSharedState()->apply(this, texture_unit); + return true; + } else { + return false; + } } void OpenGLShaderProgram::release() { @@ -70,29 +75,29 @@ void OpenGLShaderProgram::release() { } void OpenGLShaderProgram::drawTriangles(float *vertices, int triangle_count) { - bind(); + if (bind()) { + GLuint vertex = program->attributeLocation("vertex"); + program->setAttributeArray(vertex, GL_FLOAT, vertices, 3); + program->enableAttributeArray(vertex); - GLuint vertex = program->attributeLocation("vertex"); - program->setAttributeArray(vertex, GL_FLOAT, vertices, 3); - program->enableAttributeArray(vertex); + functions->glDrawArrays(GL_TRIANGLES, 0, triangle_count * 3); - functions->glDrawArrays(GL_TRIANGLES, 0, triangle_count * 3); + program->disableAttributeArray(vertex); - program->disableAttributeArray(vertex); - - release(); + release(); + } } void OpenGLShaderProgram::drawTriangleStrip(float *vertices, int vertex_count) { - bind(); + if (bind()) { + GLuint vertex = program->attributeLocation("vertex"); + program->setAttributeArray(vertex, GL_FLOAT, vertices, 3); + program->enableAttributeArray(vertex); - GLuint vertex = program->attributeLocation("vertex"); - program->setAttributeArray(vertex, GL_FLOAT, vertices, 3); - program->enableAttributeArray(vertex); + functions->glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count); - functions->glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count); + program->disableAttributeArray(vertex); - program->disableAttributeArray(vertex); - - release(); + release(); + } } diff --git a/src/render/opengl/OpenGLShaderProgram.h b/src/render/opengl/OpenGLShaderProgram.h index c833e5d..6ca2b84 100644 --- a/src/render/opengl/OpenGLShaderProgram.h +++ b/src/render/opengl/OpenGLShaderProgram.h @@ -21,7 +21,7 @@ class OPENGLSHARED_EXPORT OpenGLShaderProgram { void drawTriangles(float *vertices, int triangle_count); void drawTriangleStrip(float *vertices, int vertex_count); - void bind(); + bool bind(); void release(); inline QOpenGLShaderProgram *getProgram() const { diff --git a/src/render/opengl/OpenGLSharedState.cpp b/src/render/opengl/OpenGLSharedState.cpp index f5a9d8c..7cd27e9 100644 --- a/src/render/opengl/OpenGLSharedState.cpp +++ b/src/render/opengl/OpenGLSharedState.cpp @@ -3,8 +3,7 @@ OpenGLSharedState::OpenGLSharedState() { } -paysages::opengl::OpenGLSharedState::~OpenGLSharedState() -{ +paysages::opengl::OpenGLSharedState::~OpenGLSharedState() { for (const auto &pair : variables) { delete pair.second; } diff --git a/src/render/opengl/OpenGLSharedState.h b/src/render/opengl/OpenGLSharedState.h index 095448c..974e1d8 100644 --- a/src/render/opengl/OpenGLSharedState.h +++ b/src/render/opengl/OpenGLSharedState.h @@ -15,7 +15,7 @@ namespace opengl { class OPENGLSHARED_EXPORT OpenGLSharedState { public: OpenGLSharedState(); - ~OpenGLSharedState(); + ~OpenGLSharedState(); /*! * \brief Apply the stored variables to the bound program. diff --git a/src/render/opengl/OpenGLTerrain.cpp b/src/render/opengl/OpenGLTerrain.cpp index b0cf055..98cc06b 100644 --- a/src/render/opengl/OpenGLTerrain.cpp +++ b/src/render/opengl/OpenGLTerrain.cpp @@ -1,6 +1,6 @@ #include "OpenGLTerrain.h" -#include OPENGL_FUNCTIONS_INCLUDE +#include "OpenGLFunctions.h" #include "OpenGLRenderer.h" #include "OpenGLShaderProgram.h" #include "ParallelPool.h" diff --git a/src/render/opengl/OpenGLVariable.cpp b/src/render/opengl/OpenGLVariable.cpp index e1df6d6..bf4ab86 100644 --- a/src/render/opengl/OpenGLVariable.cpp +++ b/src/render/opengl/OpenGLVariable.cpp @@ -1,8 +1,8 @@ #include "OpenGLVariable.h" -#include OPENGL_FUNCTIONS_INCLUDE #include #include +#include "OpenGLFunctions.h" #include "OpenGLRenderer.h" #include "OpenGLShaderProgram.h" #include "Vector3.h" diff --git a/src/render/opengl/VertexArray.h b/src/render/opengl/VertexArray.h index 5c3a91d..cecd713 100644 --- a/src/render/opengl/VertexArray.h +++ b/src/render/opengl/VertexArray.h @@ -3,9 +3,9 @@ #include "opengl_global.h" -#include OPENGL_FUNCTIONS_INCLUDE #include #include +#include "OpenGLFunctions.h" namespace paysages { namespace opengl { diff --git a/src/render/opengl/opengl_global.h b/src/render/opengl/opengl_global.h index 1d1c56c..3c33a24 100644 --- a/src/render/opengl/opengl_global.h +++ b/src/render/opengl/opengl_global.h @@ -25,9 +25,8 @@ template class VertexArray; } using namespace paysages::opengl; -//#define OpenGLFunctions QOpenGLFunctions_3_2_Core #define OpenGLFunctions QOpenGLFunctions_3_0 -#define OPENGL_FUNCTIONS_INCLUDE +//#define OpenGLFunctions QOpenGLFunctions_3_3_Core class OpenGLFunctions; #endif // OPENGL_GLOBAL_H diff --git a/src/tests/Layers_Test.cpp b/src/tests/Layers_Test.cpp index 8c8c06c..8dc559a 100644 --- a/src/tests/Layers_Test.cpp +++ b/src/tests/Layers_Test.cpp @@ -187,7 +187,7 @@ TEST(Layers, generateInitDiffs) { EXPECT_EQ(3, (int)diffs.size()); Layers layers1(NULL, "layers", _construc1); - for (auto diff: diffs) { + for (auto diff : diffs) { layers1.applyDiff(diff); } ASSERT_EQ(3, layers1.getLayerCount());