From 7db9bf0d98fdb9101e9cad49b8ee34c6e962401f Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Tue, 26 Apr 2016 10:20:54 +0200 Subject: [PATCH 01/61] start on experimental hybrid renderer --- include/openspace/rendering/abufferrenderer.h | 3 + shaders/abuffer/renderabuffer.frag | 39 ++++++----- shaders/abuffer/resolveabuffer.frag | 47 +++++++++++++- shaders/framebuffer/renderframebuffer.frag | 1 + src/rendering/abufferrenderer.cpp | 64 ++++++++++++++++++- src/rendering/framebufferrenderer.cpp | 3 + 6 files changed, 137 insertions(+), 20 deletions(-) diff --git a/include/openspace/rendering/abufferrenderer.h b/include/openspace/rendering/abufferrenderer.h index 1351643e8f..6f32ccd591 100644 --- a/include/openspace/rendering/abufferrenderer.h +++ b/include/openspace/rendering/abufferrenderer.h @@ -110,6 +110,9 @@ private: ghoul::Dictionary _resolveDictionary; + GLuint _mainColorTexture; + GLuint _mainDepthTexture; + GLuint _mainFramebuffer; GLuint _screenQuad; GLuint _anchorPointerTexture; GLuint _anchorPointerTextureInitializer; diff --git a/shaders/abuffer/renderabuffer.frag b/shaders/abuffer/renderabuffer.frag index 6c05208a3b..46f646f469 100644 --- a/shaders/abuffer/renderabuffer.frag +++ b/shaders/abuffer/renderabuffer.frag @@ -31,24 +31,31 @@ out vec4 _out_color_; void main() { Fragment frag = getFragment(); - int sampleMask = gl_SampleMaskIn[0]; - uint newHead = atomicCounterIncrement(atomicCounterBuffer); - if (newHead >= #{rendererData.maxTotalFragments}) { - discard; // ABuffer is full! - } - uint prevHead = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), newHead); + + // todo: calculate full sample mask from nAaSamples instead of hardcoded 255. + if (frag.color.a < 1.0 || sampleMask != 255) { + uint newHead = atomicCounterIncrement(atomicCounterBuffer); + if (newHead >= #{rendererData.maxTotalFragments}) { + discard; // ABuffer is full! + } + uint prevHead = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), newHead); - ABufferFragment aBufferFrag; - _color_(aBufferFrag, frag.color); - _depth_(aBufferFrag, frag.depth); - _blend_(aBufferFrag, frag.blend); + ABufferFragment aBufferFrag; + _color_(aBufferFrag, frag.color); + _depth_(aBufferFrag, frag.depth); + _blend_(aBufferFrag, frag.blend); + + _type_(aBufferFrag, 0); // 0 = geometry type + _msaa_(aBufferFrag, gl_SampleMaskIn[0]); + _next_(aBufferFrag, prevHead); + + storeFragment(newHead, aBufferFrag); + discard; + } else { + _out_color_ = frag.color; + gl_FragDepth = normalizeFloat(frag.depth); + } - _type_(aBufferFrag, 0); // 0 = geometry type - _msaa_(aBufferFrag, gl_SampleMaskIn[0]); - _next_(aBufferFrag, prevHead); - - storeFragment(newHead, aBufferFrag); - discard; } diff --git a/shaders/abuffer/resolveabuffer.frag b/shaders/abuffer/resolveabuffer.frag index 93329d3b65..40a0d80e70 100644 --- a/shaders/abuffer/resolveabuffer.frag +++ b/shaders/abuffer/resolveabuffer.frag @@ -35,6 +35,8 @@ layout (location = 0) out vec4 finalColor; uniform float blackoutFactor; uniform int nAaSamples; +uniform sampler2DMS mainColorTexture; +uniform sampler2DMS mainDepthTexture; #define RAYCASTING_ENABLED #{raycastingEnabled} #define N_RAYCASTERS #{nRaycasters} @@ -86,6 +88,18 @@ uint countSamples(uint mask) { + ((mask >> 7) & 1); } +uint depthFilterFragments(uint nFrags, float depthThreshold) { + uint j = 0; + for (uint i = 0; i < nFrags; i++) { + if (_depth_(fragments[i]) < depthThreshold) { + fragments[j] = fragments[i]; + j++; + } + } + return j; +} + + uint reduceFragments(uint nFrags) { uint outputIndex = 0; for (uint inputIndex = 0; inputIndex < nFrags; inputIndex++, outputIndex++) { @@ -216,14 +230,33 @@ void raycast(float raycastDepth, uint raycasterMask, inout vec4 finalColor) { #endif // RAYCASTING_ENABLED void main() { + //vec4 opaqueColor = vec4(0.0); finalColor = vec4(0.0); + float maxOpaqueDepth = 0; + + vec4 opaqueColor = vec4(0.0); + + for (int i = 0; i < nAaSamples; i++) { + float depth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), i).x); + // finalColor += color; + if (depth > maxOpaqueDepth) { + maxOpaqueDepth = depth; + + } + opaqueColor += texelFetch(mainColorTexture, ivec2(gl_FragCoord), i); + //finalColor.r += depth; + //finalColor += vec4(0.120); + } + + opaqueColor /= nAaSamples; uint nOriginalFrags = loadFragments(); uint raycasterMask = 0; - sortFragments(nOriginalFrags); + uint nFilteredFrags = depthFilterFragments(nOriginalFrags, maxOpaqueDepth); + sortFragments(nFilteredFrags); - uint nFrags = reduceFragments(nOriginalFrags); + uint nFrags = reduceFragments(nFilteredFrags); #if RAYCASTING_ENABLED retrieveRaycasterData(nFrags); #endif @@ -261,10 +294,18 @@ void main() { } #endif } - + + normalBlend(finalColor, opaqueColor); + // finalColor is expressed with premultiplied alpha finalColor.rgb *= blackoutFactor; + + // Render everything on a black background finalColor.a = 1.0; + + + //finalColor.rgb = vec3(float(nFrags) * 0.25); + } diff --git a/shaders/framebuffer/renderframebuffer.frag b/shaders/framebuffer/renderframebuffer.frag index 88540a28c9..98905b9952 100644 --- a/shaders/framebuffer/renderframebuffer.frag +++ b/shaders/framebuffer/renderframebuffer.frag @@ -22,6 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include "PowerScaling/powerScalingMath.hglsl" #include <#{fragmentPath}> out vec4 _out_color_; diff --git a/src/rendering/abufferrenderer.cpp b/src/rendering/abufferrenderer.cpp index 5be6bb75b1..6c991102c7 100644 --- a/src/rendering/abufferrenderer.cpp +++ b/src/rendering/abufferrenderer.cpp @@ -35,6 +35,7 @@ #include +#include #include #include @@ -97,7 +98,15 @@ void ABufferRenderer::initialize() { glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY); glGenBuffers(1, &_fragmentBuffer); glGenTextures(1, &_fragmentTexture); - + + glGenTextures(1, &_mainColorTexture); + glGenTextures(1, &_mainDepthTexture); + glGenFramebuffers(1, &_mainFramebuffer); + + GLint defaultFbo; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo); + + _nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); if (_nAaSamples == 0) { _nAaSamples = 1; @@ -112,6 +121,18 @@ void ABufferRenderer::initialize() { updateRaycastData(); updateResolveDictionary(); + glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture, 0); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + LERROR("Main framebuffer is not complete"); + } + + glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo); + + try { _resolveProgram = ghoul::opengl::ProgramObject::Build("ABuffer Resolve", "${SHADERS}/abuffer/resolveabuffer.vert", @@ -201,6 +222,13 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement if (_scene == nullptr) return; if (_camera == nullptr) return; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + GLint defaultFbo; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo); + glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // Reset clear(); glEnable(GL_DEPTH_TEST); @@ -219,6 +247,9 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement _scene->render(data, tasks); + glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo); + + // Step 2: Perform raycasting tasks requested by the scene for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) { VolumeRaycaster* raycaster = raycasterTask.raycaster; @@ -238,6 +269,16 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement // Step 3: Resolve the buffer _resolveProgram->activate(); + ghoul::opengl::TextureUnit mainColorTextureUnit; + mainColorTextureUnit.activate(); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); + + ghoul::opengl::TextureUnit mainDepthTextureUnit; + mainDepthTextureUnit.activate(); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture); + + _resolveProgram->setUniform("mainColorTexture", mainColorTextureUnit); + _resolveProgram->setUniform("mainDepthTexture", mainDepthTextureUnit); // 3a: Perform the pre-raycast step for all raycaster tasks. for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) { @@ -293,6 +334,7 @@ void ABufferRenderer::clear() { glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(zero), &zero); glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0); + } void ABufferRenderer::updateResolution() { @@ -320,6 +362,26 @@ void ABufferRenderer::updateResolution() { glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); + int nSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); + + glTexImage2DMultisample( + GL_TEXTURE_2D_MULTISAMPLE, + nSamples, + GL_RGBA, + GLsizei(_resolution.x), + GLsizei(_resolution.y), + true); + + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture); + glTexImage2DMultisample( + GL_TEXTURE_2D_MULTISAMPLE, + nSamples, + GL_DEPTH_COMPONENT32F, + GLsizei(_resolution.x), + GLsizei(_resolution.y), + true); + _dirtyResolution = false; } diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index b2e6d7f809..096de78beb 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -246,6 +246,8 @@ void FramebufferRenderer::updateResolution() { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + _dirtyResolution = false; } void FramebufferRenderer::updateRaycastData() { @@ -393,6 +395,7 @@ void FramebufferRenderer::setCamera(Camera* camera) { void FramebufferRenderer::setResolution(glm::ivec2 res) { _resolution = res; + _dirtyResolution = true; } void FramebufferRenderer::updateRendererData() { From 7e7d27446c3e302c788d23b1d039e8704b0fa2a6 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Fri, 20 May 2016 11:01:01 +0200 Subject: [PATCH 02/61] volumetric galaxy rendering --- CMakeLists.txt | 2 + data/scene/default.scene | 27 +- ext/ghoul | 2 +- modules/galaxy/CMakeLists.txt | 45 +++ modules/galaxy/galaxymodule.cpp | 41 +++ modules/galaxy/galaxymodule.h | 40 +++ modules/galaxy/include.cmake | 4 + modules/galaxy/rendering/galaxyraycaster.cpp | 146 +++++++++ modules/galaxy/rendering/galaxyraycaster.h | 83 ++++++ modules/galaxy/rendering/renderablegalaxy.cpp | 279 ++++++++++++++++++ modules/galaxy/rendering/renderablegalaxy.h | 73 +++++ modules/galaxy/shaders/galaxyraycast.glsl | 92 ++++++ modules/galaxy/shaders/points.fs | 41 +++ modules/galaxy/shaders/points.vs | 55 ++++ modules/galaxy/shaders/raycasterbounds.fs | 43 +++ modules/galaxy/shaders/raycasterbounds.vs | 47 +++ modules/multiresvolume/include.cmake | 3 - shaders/abuffer/renderabuffer.frag | 10 +- shaders/abuffer/resolveabuffer.frag | 87 +++--- shaders/fragment.glsl | 1 + 20 files changed, 1060 insertions(+), 61 deletions(-) create mode 100644 modules/galaxy/CMakeLists.txt create mode 100644 modules/galaxy/galaxymodule.cpp create mode 100644 modules/galaxy/galaxymodule.h create mode 100644 modules/galaxy/include.cmake create mode 100644 modules/galaxy/rendering/galaxyraycaster.cpp create mode 100644 modules/galaxy/rendering/galaxyraycaster.h create mode 100644 modules/galaxy/rendering/renderablegalaxy.cpp create mode 100644 modules/galaxy/rendering/renderablegalaxy.h create mode 100644 modules/galaxy/shaders/galaxyraycast.glsl create mode 100644 modules/galaxy/shaders/points.fs create mode 100644 modules/galaxy/shaders/points.vs create mode 100644 modules/galaxy/shaders/raycasterbounds.fs create mode 100644 modules/galaxy/shaders/raycasterbounds.vs diff --git a/CMakeLists.txt b/CMakeLists.txt index c08556a2d1..978a00258a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,8 @@ cmake_minimum_required (VERSION 3.0 FATAL_ERROR) project (OpenSpace) message(STATUS "Generating OpenSpace project") +set(BOOST_ROOT "G:/deps/bin/boost_1_60_0") + set(OPENSPACE_BASE_DIR "${PROJECT_SOURCE_DIR}") set(OPENSPACE_APPS_DIR "${OPENSPACE_BASE_DIR}/apps") set(OPENSPACE_EXT_DIR "${OPENSPACE_BASE_DIR}/ext") diff --git a/data/scene/default.scene b/data/scene/default.scene index 65c7e3b609..cb1577e4c8 100644 --- a/data/scene/default.scene +++ b/data/scene/default.scene @@ -35,22 +35,23 @@ return { ScenePath = ".", CommonFolder = "common", Camera = { - Focus = "Earth", - Position = {1, 0, 0, 5}, + Focus = "Root", + Position = {1, 0, 0, 2}, }, Modules = { - "sun", - "mercury", - "venus", - "earth", - "mars", - "jupiter", - "saturn", - "uranus", - "neptune", - "stars", + --"sun", + --"mercury", + --"venus", + --"earth", + --"mars", + --"jupiter", + --"saturn", + --"uranus", + --"neptune", + --"stars", -- "stars-denver", - "milkyway", + --"milkyway", + "volumetricmilkyway", -- "milkyway-eso", --"constellationbounds", -- "fieldlines", diff --git a/ext/ghoul b/ext/ghoul index 3ef4b9e9e4..5c9f358af8 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 3ef4b9e9e40910a2f7860a39d6b6f1f62c9c448f +Subproject commit 5c9f358af8056944d09b48c23cb9633aa5e533ff diff --git a/modules/galaxy/CMakeLists.txt b/modules/galaxy/CMakeLists.txt new file mode 100644 index 0000000000..afb55cfbb3 --- /dev/null +++ b/modules/galaxy/CMakeLists.txt @@ -0,0 +1,45 @@ +######################################################################################### +# # +# OpenSpace # +# # +# Copyright (c) 2014-2015 # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy of this # +# software and associated documentation files (the "Software"), to deal in the Software # +# without restriction, including without limitation the rights to use, copy, modify, # +# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the following # +# conditions: # +# # +# The above copyright notice and this permission notice shall be included in all copies # +# or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, # +# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A # +# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # +# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE # +# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +######################################################################################### + +include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake) + +set(HEADER_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/galaxymodule.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/galaxyraycaster.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablegalaxy.h +) +source_group("Header Files" FILES ${HEADER_FILES}) + +set(SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/galaxymodule.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/galaxyraycaster.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablegalaxy.cpp +) +source_group("Source Files" FILES ${SOURCE_FILES}) + +create_new_module( + "Galaxy" + galaxy + ${HEADER_FILES} ${SOURCE_FILES} +) diff --git a/modules/galaxy/galaxymodule.cpp b/modules/galaxy/galaxymodule.cpp new file mode 100644 index 0000000000..714818604e --- /dev/null +++ b/modules/galaxy/galaxymodule.cpp @@ -0,0 +1,41 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include +#include +#include +#include + +namespace openspace { + +GalaxyModule::GalaxyModule() : OpenSpaceModule("Galaxy") {} + +void GalaxyModule::internalInitialize() { + auto fRenderable = FactoryManager::ref().factory(); + ghoul_assert(fRenderable, "No renderable factory existed"); + fRenderable->registerClass("RenderableGalaxy"); +} + +} // namespace openspace diff --git a/modules/galaxy/galaxymodule.h b/modules/galaxy/galaxymodule.h new file mode 100644 index 0000000000..26b4341b30 --- /dev/null +++ b/modules/galaxy/galaxymodule.h @@ -0,0 +1,40 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2015 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __GALAXYMODULE_H__ +#define __GALAXYMODULE_H__ + +#include + +namespace openspace { + +class GalaxyModule : public OpenSpaceModule { +public: + GalaxyModule(); + void internalInitialize() override; +}; + +} // namespace openspace + +#endif // __GALAXYMODULE_H__ diff --git a/modules/galaxy/include.cmake b/modules/galaxy/include.cmake new file mode 100644 index 0000000000..163c5a64bf --- /dev/null +++ b/modules/galaxy/include.cmake @@ -0,0 +1,4 @@ +set (DEFAULT_MODULE ON) +set (OPENSPACE_DEPENDENCIES + volume +) \ No newline at end of file diff --git a/modules/galaxy/rendering/galaxyraycaster.cpp b/modules/galaxy/rendering/galaxyraycaster.cpp new file mode 100644 index 0000000000..60eef87721 --- /dev/null +++ b/modules/galaxy/rendering/galaxyraycaster.cpp @@ -0,0 +1,146 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +namespace { + const std::string GlslRaycastPath = "${MODULES}/galaxy/shaders/galaxyraycast.glsl"; + const std::string GlslBoundsVsPath = "${MODULES}/galaxy/shaders/raycasterbounds.vs"; + const std::string GlslBoundsFsPath = "${MODULES}/galaxy/shaders/raycasterbounds.fs"; +} + +namespace openspace { + +GalaxyRaycaster::GalaxyRaycaster(ghoul::opengl::Texture& texture) + : _boundingBox(glm::vec3(1.0)) + , _texture(texture) + , _textureUnit(nullptr) {} + +GalaxyRaycaster::~GalaxyRaycaster() {} + +void GalaxyRaycaster::initialize() { + _boundingBox.initialize(); +} + +void GalaxyRaycaster::deinitialize() { +} + +void GalaxyRaycaster::renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) { + program.setUniform("modelTransform", _modelTransform); + program.setUniform("viewProjection", data.camera.viewProjectionMatrix()); + program.setUniform("blendMode", static_cast(1)); + + Renderable::setPscUniforms(program, data.camera, data.position); + + // Cull back face + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + // Render bounding geometry + _boundingBox.render(); +} + +void GalaxyRaycaster::renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) { + // Uniforms + program.setUniform("modelTransform", _modelTransform); + program.setUniform("viewProjection", data.camera.viewProjectionMatrix()); + program.setUniform("blendMode", static_cast(1)); + Renderable::setPscUniforms(program, data.camera, data.position); + + // Cull front face + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + + // Render bounding geometry + _boundingBox.render(); + + // Restore defaults + glCullFace(GL_BACK); +} + +void GalaxyRaycaster::preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) { + std::string colorUniformName = "color" + std::to_string(data.id); + std::string stepSizeUniformName = "maxStepSize" + std::to_string(data.id); + std::string galaxyTextureUniformName = "galaxyTexture" + std::to_string(data.id); + std::string volumeAspectUniformName = "aspect" + std::to_string(data.id); + + program.setUniform(volumeAspectUniformName, _aspect); + program.setUniform(stepSizeUniformName, _stepSize); + + _textureUnit = std::make_unique(); + _textureUnit->activate(); + _texture.bind(); + program.setUniform(galaxyTextureUniformName, *_textureUnit); + +} + +void GalaxyRaycaster::postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) { + _textureUnit = nullptr; // release texture unit. +} + +std::string GalaxyRaycaster::getBoundsVsPath() const { + return GlslBoundsVsPath; +} + +std::string GalaxyRaycaster::getBoundsFsPath() const { + return GlslBoundsFsPath; +} + +std::string GalaxyRaycaster::getRaycastPath() const { + return GlslRaycastPath; +} + +std::string GalaxyRaycaster::getHelperPath() const { + return ""; // no helper file +} + +void GalaxyRaycaster::setAspect(const glm::vec3& aspect) { + _aspect = aspect / std::max(std::max(aspect.x, aspect.y), aspect.z); +} + +void GalaxyRaycaster::setModelTransform(glm::mat4 transform) { + _modelTransform = transform; +} + +void GalaxyRaycaster::setTime(double time) { + _time = time; +} + +void GalaxyRaycaster::setStepSize(float stepSize) { + _stepSize = stepSize; +} + +} diff --git a/modules/galaxy/rendering/galaxyraycaster.h b/modules/galaxy/rendering/galaxyraycaster.h new file mode 100644 index 0000000000..5d93e7d028 --- /dev/null +++ b/modules/galaxy/rendering/galaxyraycaster.h @@ -0,0 +1,83 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __GALAXYRAYCASTER_H__ +#define __GALAXYRAYCASTER_H__ + +#include +#include +#include +#include +#include +#include + +namespace ghoul { + namespace opengl { + class Texture; + class TextureUnit; + class ProgramObject; + } +} + +namespace openspace { + +class RenderData; +class RaycastData; + +class GalaxyRaycaster : public VolumeRaycaster { +public: + + GalaxyRaycaster(ghoul::opengl::Texture& texture); + + virtual ~GalaxyRaycaster(); + void initialize(); + void deinitialize(); + void renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override; + void renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override; + void preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override; + void postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override; + + std::string getBoundsVsPath() const override; + std::string getBoundsFsPath() const override; + std::string getRaycastPath() const override; + std::string getHelperPath() const override; + + void setAspect(const glm::vec3& aspect); + void setModelTransform(glm::mat4 transform); + void setTime(double time); + void setStepSize(float stepSize); +private: + BoxGeometry _boundingBox; + float _stepSize; + glm::mat4 _modelTransform; + glm::vec3 _aspect; + double _time; + ghoul::opengl::Texture& _texture; + std::unique_ptr _textureUnit; + +}; // GalaxyRaycaster + +} // openspace + +#endif // __GALAXYRRAYCASTER_H__ diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp new file mode 100644 index 0000000000..e66742afa7 --- /dev/null +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -0,0 +1,279 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include + +#include + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + + +namespace { + const std::string GlslRayCastPath = "${MODULES}/toyvolume/shaders/rayCast.glsl"; + const std::string GlslBoundsVsPath = "${MODULES}/toyvolume/shaders/boundsVs.glsl"; + const std::string GlslBoundsFsPath = "${MODULES}/toyvolume/shaders/boundsFs.glsl"; + const std::string _loggerCat = "Renderable Galaxy"; +} + +namespace openspace { + + RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) + , _scalingExponent("scalingExponent", "Scaling Exponent", 1, -10, 20) + , _stepSize("stepSize", "Step Size", 0.002, 0.001, 0.05) + , _scaling("scaling", "Scaling", glm::vec3(1.0, 1.0, 1.0), glm::vec3(0.0), glm::vec3(10.0)) + , _translation("translation", "Translation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0), glm::vec3(10.0)) + , _rotation("rotation", "Euler rotation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0), glm::vec3(6.28)) { + + float scalingExponent, stepSize; + glm::vec3 scaling, translation, rotation; + glm::vec4 color; + ghoul::Dictionary volumeDictionary, pointsDictionary; + + if (dictionary.getValue("ScalingExponent", scalingExponent)) { + _scalingExponent = scalingExponent; + } + if (dictionary.getValue("Scaling", scaling)) { + _scaling = scaling; + } + if (dictionary.getValue("Translation", translation)) { + _translation = translation; + } + if (dictionary.getValue("Rotation", rotation)) { + _rotation = rotation; + } + if (dictionary.getValue("StepSize", stepSize)) { + _stepSize = stepSize; + } + if (dictionary.getValue("Volume", volumeDictionary)) { + std::string volumeFilename; + if (volumeDictionary.getValue("Filename", volumeFilename)) { + _volumeFilename = absPath(volumeFilename); + } else { + LERROR("No volume filename specified."); + } + glm::vec3 volumeDimensions; + if (volumeDictionary.getValue("Dimensions", volumeDimensions)) { + _volumeDimensions = static_cast(volumeDimensions); + } else { + LERROR("No volume dimensions specified."); + } + } else { + LERROR("No volume dictionary specified."); + } + if (dictionary.getValue("Points", pointsDictionary)) { + std::string pointsFilename; + if (pointsDictionary.getValue("Filename", pointsFilename)) { + _pointsFilename = absPath(pointsFilename); + } else { + LERROR("No points filename specified."); + } + } else { + LERROR("No points dictionary specified."); + } + +} + +RenderableGalaxy::~RenderableGalaxy() {} + +bool RenderableGalaxy::initialize() { + // Aspect is currently hardcoded to cubic voxels. + _aspect = static_cast(_volumeDimensions); + _aspect = _aspect / std::max(std::max(_aspect.x, _aspect.y), _aspect.z); + + RawVolumeReader> reader(_volumeFilename, _volumeDimensions); + _volume = reader.read(); + + _texture = std::make_unique( + _volumeDimensions, + ghoul::opengl::Texture::Format::RGBA, + GL_RGBA32F, + GL_FLOAT, + ghoul::opengl::Texture::FilterMode::Linear, + ghoul::opengl::Texture::WrappingMode::Clamp); + + _texture->setPixelData(reinterpret_cast(_volume->data()), ghoul::opengl::Texture::TakeOwnership::No); + _texture->setDimensions(_volume->dimensions()); + _texture->uploadTexture(); + + _raycaster = std::make_unique(*_texture); + _raycaster->initialize(); + + OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get()); + + std::function onChange = [&](bool enabled) { + if (enabled) { + OsEng.renderEngine().raycasterManager().attachRaycaster(*_raycaster.get()); + } + else { + OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get()); + } + }; + + onEnabledChange(onChange); + + addProperty(_scaling); + addProperty(_scalingExponent); + addProperty(_stepSize); + addProperty(_translation); + addProperty(_rotation); + + // initialize points. + std::ifstream pointFile(_pointsFilename, std::ios::in); + + std::vector pointPositions; + std::vector pointColors; + + std::string format; + pointFile >> format >> _nPoints; + + // temporarily decrease number of points. + _nPoints = std::min(static_cast(100000), _nPoints); + + float x, y, z, r, g, b, a; + for (size_t i = 0; i < _nPoints; ++i) { + pointFile >> x >> y >> z >> r >> g >> b >> a; + if (pointFile.good()) { + pointPositions.push_back(glm::vec3(x, y, z)); + pointColors.push_back(glm::vec3(r, g, b)); + } + else { + LERROR("Could not read points."); + break; + } + } + pointFile.close(); + + glGenVertexArrays(1, &_pointsVao); + glGenBuffers(1, &_positionVbo); + glGenBuffers(1, &_colorVbo); + + glBindVertexArray(_pointsVao); + glBindBuffer(GL_ARRAY_BUFFER, _positionVbo); + glBufferData(GL_ARRAY_BUFFER, + pointPositions.size()*sizeof(glm::vec3), + pointPositions.data(), + GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, _colorVbo); + glBufferData(GL_ARRAY_BUFFER, + pointColors.size()*sizeof(glm::vec3), + pointColors.data(), + GL_STATIC_DRAW); + + + RenderEngine& renderEngine = OsEng.renderEngine(); + _pointsProgram = renderEngine.buildRenderProgram("Galaxy points", + "${MODULE_GALAXY}/shaders/points.vs", + "${MODULE_GALAXY}/shaders/points.fs"); + + GLint positionAttrib = _pointsProgram->attributeLocation("inPosition"); + GLint colorAttrib = _pointsProgram->attributeLocation("inColor"); + + glBindBuffer(GL_ARRAY_BUFFER, _positionVbo); + glEnableVertexAttribArray(positionAttrib); + glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0); + + glBindBuffer(GL_ARRAY_BUFFER, _colorVbo); + glEnableVertexAttribArray(colorAttrib); + glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + return true; +} + +bool RenderableGalaxy::deinitialize() { + if (_raycaster) { + OsEng.renderEngine().raycasterManager().detachRaycaster(*_raycaster.get()); + _raycaster = nullptr; + } + return true; +} + +bool RenderableGalaxy::isReady() const { + return true; +} + +void RenderableGalaxy::update(const UpdateData& data) { + if (_raycaster) { + + glm::mat4 transform = glm::translate(glm::mat4(1.0), static_cast(_translation) * std::powf(10.0, static_cast(_scalingExponent))); + glm::vec3 eulerRotation = static_cast(_rotation); + transform = glm::rotate(transform, eulerRotation.x, glm::vec3(1, 0, 0)); + transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0, 1, 0)); + transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0, 0, 1)); + transform = glm::scale(transform, _aspect * static_cast(_scaling) * std::powf(10.0, static_cast(_scalingExponent))); + + _raycaster->setStepSize(_stepSize); + _raycaster->setAspect(_aspect); + _raycaster->setModelTransform(transform); + _raycaster->setTime(data.time); + } +} + +void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) { + RaycasterTask task{ _raycaster.get(), data }; + tasks.raycasterTasks.push_back(task); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + _pointsProgram->activate(); + setPscUniforms(*_pointsProgram.get(), data.camera, data.position); + + + glm::mat4 modelMatrix = glm::mat4(1.0); + glm::mat4 viewMatrix = data.camera.viewMatrix(); + glm::mat4 projectionMatrix = data.camera.projectionMatrix(); + + _pointsProgram->setUniform("model", modelMatrix); + _pointsProgram->setUniform("view", viewMatrix); + _pointsProgram->setUniform("projection", projectionMatrix); + + glBindVertexArray(_pointsVao); + glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glDrawArrays(GL_POINTS, 0, _nPoints); + glBindVertexArray(0); + glDepthMask(true); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + +} + +} diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h new file mode 100644 index 0000000000..0ba5be2b07 --- /dev/null +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -0,0 +1,73 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __RENDERABLEGALAXY_H__ +#define __RENDERABLEGALAXY_H__ + +#include +#include +#include +#include +#include + +namespace openspace { + +struct RenderData; + +class RenderableGalaxy : public Renderable { +public: + RenderableGalaxy(const ghoul::Dictionary& dictionary); + ~RenderableGalaxy(); + + bool initialize() override; + bool deinitialize() override; + bool isReady() const override; + void render(const RenderData& data, RendererTasks& tasks) override; + void update(const UpdateData& data) override; + +private: + properties::Vec3Property _scaling; + properties::IntProperty _scalingExponent; + properties::FloatProperty _stepSize; + properties::Vec3Property _translation; + properties::Vec3Property _rotation; + + std::string _volumeFilename; + glm::ivec3 _volumeDimensions; + std::string _pointsFilename; + + std::unique_ptr _raycaster; + std::unique_ptr>> _volume; + std::unique_ptr _texture; + glm::vec3 _aspect; + + std::unique_ptr _pointsProgram; + size_t _nPoints; + GLuint _pointsVao; + GLuint _positionVbo; + GLuint _colorVbo; +}; +} + +#endif // __RENDERABLEGALAXY_H__ diff --git a/modules/galaxy/shaders/galaxyraycast.glsl b/modules/galaxy/shaders/galaxyraycast.glsl new file mode 100644 index 0000000000..dcc1021610 --- /dev/null +++ b/modules/galaxy/shaders/galaxyraycast.glsl @@ -0,0 +1,92 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +uniform float maxStepSize#{id} = 0.1; +uniform vec3 aspect#{id} = vec3(1.0); + +uniform sampler3D galaxyTexture#{id}; + +void sample#{id}(vec3 samplePos, + vec3 dir, + inout vec3 accumulatedColor, + inout vec3 accumulatedAlpha, + inout float maxStepSize) { + + vec3 aspect = aspect#{id}; + maxStepSize = maxStepSize#{id} * length(dir * 1.0/aspect); + vec4 sampledColor = texture(galaxyTexture#{id}, samplePos.xyz); + + float STEP_SIZE = maxStepSize#{id}; + + vec3 alphaTint = vec3(0.3, 0.54, 0.85); + //alphaTint = vec3(0.0, 0.5, 1.0); + + sampledColor = sampledColor*sampledColor; + sampledColor.a = pow(sampledColor.a, 0.7); + //sampledColor.rgba = min(vec4(1.0), sampledColor.rgba); + + //sampledColor.a = clamp(sampledColor.a * 10000000000.0, 0.0, 1.0); + //sampledColor.a = exp(-sampledColor.a); + // + + //sampledColor.rgb = pow(sampledColor.rgb, vec3(10.0)); + //sampledColor.a = pow(sampledColor.a, 10.0); + //sampledColor.a = pow(sampledColor.a, 100000000.0); + sampledColor.rgb *= 4000.0; + sampledColor.a *= 1; + + + //float emissionCoefficient = 80; + //float absorptionCoefficient = 1; +// sampledColor = clamp(sampledColor, 0.0, 1.0); + + //backColor = vec3(1.0) - pow(vec3(1.0) - backColor, vec3(STEP_SIZE)); + /*if (sampledColor.a > 1.0) { + sampledColor.a = 1.0; + //accumulatedColor = vec3(1.0, 0.0, 0.0); + //accumulatedAlpha = vec3(1.0, 1.0, 1.0); + //return; + }*/ + //sampledColor.a = 1.2; + + //sampledColor.a *= 0.00001; + + vec3 backColor = sampledColor.rgb; + vec3 backAlpha = sampledColor.a * alphaTint; + + backColor *= STEP_SIZE; + backAlpha *= STEP_SIZE; + + backColor = clamp(backColor, 0.0, 1.0); + backAlpha = clamp(backAlpha, 0.0, 1.0); + + vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha; + accumulatedColor += oneMinusFrontAlpha * backColor; + accumulatedAlpha += oneMinusFrontAlpha * backAlpha; + +} + +float stepSize#{id}(vec3 samplePos, vec3 dir) { + return maxStepSize#{id} * length(dir * 1.0/aspect#{id}); +} diff --git a/modules/galaxy/shaders/points.fs b/modules/galaxy/shaders/points.fs new file mode 100644 index 0000000000..5f87714048 --- /dev/null +++ b/modules/galaxy/shaders/points.fs @@ -0,0 +1,41 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +in vec3 vsPosition; +in vec3 vsColor; + +#include "fragment.glsl" +#include "PowerScaling/powerScaling_fs.hglsl" + +Fragment getFragment() { + vec4 color = vec4(vsColor, 1.0); + + Fragment frag; + frag.color = vec4(vsColor.rgb * 0.1, 1.0); + frag.depth = pscDepth(vec4(vsPosition, 0.0)); + frag.forceFboRendering = true; + + + return frag; +} diff --git a/modules/galaxy/shaders/points.vs b/modules/galaxy/shaders/points.vs new file mode 100644 index 0000000000..90d1547718 --- /dev/null +++ b/modules/galaxy/shaders/points.vs @@ -0,0 +1,55 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +in vec3 inPosition; +in vec3 inColor; + +out vec3 vsPosition; +out vec3 vsColor; + + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() { + vec4 p = vec4(inPosition, 0.0); + + vec4 tmp = p; + vec4 position = pscTransform(tmp, mat4(1.0)); + vsPosition = position.xyz; + position = projection * view * model * position; + gl_Position = z_normalization(position); + + + //float distThreshold = 0.0001; + + //gl_PointSize = min(1.0, position.z); + gl_PointSize = 1.0; + vsColor = inColor; +} diff --git a/modules/galaxy/shaders/raycasterbounds.fs b/modules/galaxy/shaders/raycasterbounds.fs new file mode 100644 index 0000000000..a335c00b51 --- /dev/null +++ b/modules/galaxy/shaders/raycasterbounds.fs @@ -0,0 +1,43 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +in vec3 vPosition; +in vec4 worldPosition; + +uniform uint blendMode; + +#include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" + +Fragment getFragment() { + vec4 fragColor = vec4((vPosition+0.5), 1.0); + vec4 position = worldPosition; + float depth = pscDepth(position); + + Fragment frag; + frag.color = fragColor; + frag.depth = depth; + frag.blend = blendMode; + return frag; +} diff --git a/modules/galaxy/shaders/raycasterbounds.vs b/modules/galaxy/shaders/raycasterbounds.vs new file mode 100644 index 0000000000..fc328f30df --- /dev/null +++ b/modules/galaxy/shaders/raycasterbounds.vs @@ -0,0 +1,47 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +layout(location = 0) in vec4 vertPosition; + +uniform mat4 viewProjection; +uniform mat4 modelTransform; + +out vec3 vPosition; +out vec4 worldPosition; + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() { + vPosition = vertPosition.xyz; + worldPosition = modelTransform*vertPosition; + + vec4 position = pscTransform(worldPosition, mat4(1.0)); + + // project the position to view space + gl_Position = viewProjection * position; + + gl_Position.z = 1.0; +} diff --git a/modules/multiresvolume/include.cmake b/modules/multiresvolume/include.cmake index 163c5a64bf..3ccace7c97 100644 --- a/modules/multiresvolume/include.cmake +++ b/modules/multiresvolume/include.cmake @@ -1,4 +1 @@ set (DEFAULT_MODULE ON) -set (OPENSPACE_DEPENDENCIES - volume -) \ No newline at end of file diff --git a/shaders/abuffer/renderabuffer.frag b/shaders/abuffer/renderabuffer.frag index 46f646f469..481836a029 100644 --- a/shaders/abuffer/renderabuffer.frag +++ b/shaders/abuffer/renderabuffer.frag @@ -33,29 +33,27 @@ void main() { Fragment frag = getFragment(); int sampleMask = gl_SampleMaskIn[0]; - // todo: calculate full sample mask from nAaSamples instead of hardcoded 255. - if (frag.color.a < 1.0 || sampleMask != 255) { + if (!frag.forceFboRendering && (frag.color.a < 1.0 || sampleMask != 255)) { uint newHead = atomicCounterIncrement(atomicCounterBuffer); if (newHead >= #{rendererData.maxTotalFragments}) { discard; // ABuffer is full! } uint prevHead = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), newHead); - + ABufferFragment aBufferFrag; _color_(aBufferFrag, frag.color); _depth_(aBufferFrag, frag.depth); _blend_(aBufferFrag, frag.blend); - + _type_(aBufferFrag, 0); // 0 = geometry type _msaa_(aBufferFrag, gl_SampleMaskIn[0]); _next_(aBufferFrag, prevHead); - + storeFragment(newHead, aBufferFrag); discard; } else { _out_color_ = frag.color; gl_FragDepth = normalizeFloat(frag.depth); } - } diff --git a/shaders/abuffer/resolveabuffer.frag b/shaders/abuffer/resolveabuffer.frag index 40a0d80e70..9d6019cdc3 100644 --- a/shaders/abuffer/resolveabuffer.frag +++ b/shaders/abuffer/resolveabuffer.frag @@ -100,7 +100,7 @@ uint depthFilterFragments(uint nFrags, float depthThreshold) { } -uint reduceFragments(uint nFrags) { +uint mergeFragments(uint nFrags) { uint outputIndex = 0; for (uint inputIndex = 0; inputIndex < nFrags; inputIndex++, outputIndex++) { @@ -170,7 +170,7 @@ void retrieveRaycasterData(uint nFrags) { /** * Perform raycasting */ -void raycast(float raycastDepth, uint raycasterMask, inout vec4 finalColor) { +void raycast(float raycastDepth, uint raycasterMask, inout vec3 accumulatedColor, inout vec3 accumulatedAlpha) { float nextStepSize = raycastDepth; float currentStepSize = 0.0; float jitterFactor = 0.5 + 0.5 * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0 @@ -186,7 +186,12 @@ void raycast(float raycastDepth, uint raycasterMask, inout vec4 finalColor) { float currentDepth = 0.0; - for (int steps = 0; finalColor.a < ALPHA_LIMIT && steps < RAYCAST_MAX_STEPS; ++steps) { + for (int steps = 0; + (accumulatedAlpha.x < ALPHA_LIMIT || + accumulatedAlpha.y < ALPHA_LIMIT || + accumulatedAlpha.z < ALPHA_LIMIT) && + steps < RAYCAST_MAX_STEPS; + ++steps) { bool exceededDepth = currentDepth + nextStepSize * jitterFactor > raycastDepth; bool shortStepSize = nextStepSize < raycastDepth / 10000000000.0; @@ -210,15 +215,22 @@ void raycast(float raycastDepth, uint raycasterMask, inout vec4 finalColor) { float maxStepSizeLocal; - vec4 raycasterContribution = sample#{raycaster.id}(jitteredPosition, data.direction, finalColor, maxStepSizeLocal); + sample#{raycaster.id}(jitteredPosition, + data.direction, + accumulatedColor, + accumulatedAlpha, + maxStepSizeLocal); + float sampleDistance = jitteredStepSizeLocal + data.previousJitterDistance; uint blend = raycasterData[#{raycaster.id}].blend; + /* if (blend == BLEND_MODE_NORMAL) { normalBlendStep(finalColor, raycasterContribution, sampleDistance); } else if (blend == BLEND_MODE_ADDITIVE) { additiveBlendStep(finalColor, raycasterContribution, sampleDistance); - } + }*/ + //finalColor = raycasterContribution; raycasterData[#{raycaster.id}].previousJitterDistance = stepSizeLocal - jitteredStepSizeLocal; float maxStepSize = maxStepSizeLocal/data.scale; @@ -230,33 +242,32 @@ void raycast(float raycastDepth, uint raycasterMask, inout vec4 finalColor) { #endif // RAYCASTING_ENABLED void main() { - //vec4 opaqueColor = vec4(0.0); - finalColor = vec4(0.0); - float maxOpaqueDepth = 0; + // TODO: disable multisampling for main fbo. + float fboDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x); + vec4 fboRgba = texelFetch(mainColorTexture, ivec2(gl_FragCoord), 0); - vec4 opaqueColor = vec4(0.0); - - for (int i = 0; i < nAaSamples; i++) { - float depth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), i).x); - // finalColor += color; - if (depth > maxOpaqueDepth) { - maxOpaqueDepth = depth; - - } - opaqueColor += texelFetch(mainColorTexture, ivec2(gl_FragCoord), i); - //finalColor.r += depth; - //finalColor += vec4(0.120); - } - - opaqueColor /= nAaSamples; + // RGB color values, premultiplied with alpha channels. + vec3 accumulatedColor = vec3(0.0); + // One alpha channel per color channel to allow for + // absorption of different wavelengths. + // Always within the interval [0, 1] + vec3 accumulatedAlpha = vec3(0.0); uint nOriginalFrags = loadFragments(); uint raycasterMask = 0; - uint nFilteredFrags = depthFilterFragments(nOriginalFrags, maxOpaqueDepth); + uint nFilteredFrags = nOriginalFrags; + + // discard all fragments in abuffer with higher depth value than the fbo + depthFilterFragments(nOriginalFrags, fboDepth); + + // sort remaining fragments from front to back sortFragments(nFilteredFrags); - uint nFrags = reduceFragments(nFilteredFrags); + // merge fragments whose sample masks don't intersect + // to get the correct alpha for fragments on borders between triangles + uint nFrags = mergeFragments(nFilteredFrags); + #if RAYCASTING_ENABLED retrieveRaycasterData(nFrags); #endif @@ -270,9 +281,12 @@ void main() { if (type == 0) { // geometry fragment vec4 color = _color_(frag); if (blend == BLEND_MODE_NORMAL) { - normalBlend(finalColor, color); + accumulatedColor += (1 - accumulatedAlpha) * color.rgb; + accumulatedAlpha += (1 - accumulatedAlpha) * color.aaa; + //normalBlend(finalColor, color); } else if (blend == BLEND_MODE_ADDITIVE) { - additiveBlend(finalColor, color); + accumulatedColor += (1 - accumulatedAlpha) * color.rgb; + //additiveBlend(finalColor, color); } } #if RAYCASTING_ENABLED @@ -290,22 +304,19 @@ void main() { if (i + 1 < nFrags && raycasterMask != 0) { float startDepth = _depth_(fragments[i]); float endDepth = _depth_(fragments[i + 1]); - raycast(endDepth - startDepth, raycasterMask, finalColor); + raycast(endDepth - startDepth, raycasterMask, accumulatedColor, accumulatedAlpha); } #endif } - normalBlend(finalColor, opaqueColor); + // Always blend in fbo content behind a buffer data. + accumulatedColor += (1 - accumulatedAlpha) * fboRgba.rgb; + //accumulatedAlpha += (1 - accumulatedAlpha) * fboRgba.aaa; - // finalColor is expressed with premultiplied alpha - finalColor.rgb *= blackoutFactor; - - - // Render everything on a black background - finalColor.a = 1.0; - - - //finalColor.rgb = vec3(float(nFrags) * 0.25); + finalColor = vec4(accumulatedColor.rgb * blackoutFactor, 1.0); + + // Gamma correction. + finalColor.rgb = pow(finalColor.rgb, vec3(1.0 / 2.2));// sqrt(finalColor.rgb); } diff --git a/shaders/fragment.glsl b/shaders/fragment.glsl index 5064fb4e95..c409fbd073 100644 --- a/shaders/fragment.glsl +++ b/shaders/fragment.glsl @@ -32,6 +32,7 @@ struct Fragment { vec4 color; float depth; uint blend; + bool forceFboRendering; }; #endif From 432a29314c44d82391f5047768efeb34fecd1671 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Fri, 20 May 2016 14:34:03 +0200 Subject: [PATCH 03/61] fix bugs in galaxy rendering --- modules/galaxy/rendering/renderablegalaxy.cpp | 4 +--- shaders/abuffer/resolveabuffer.frag | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index e66742afa7..d57b840fde 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -55,7 +55,7 @@ namespace openspace { RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _scalingExponent("scalingExponent", "Scaling Exponent", 1, -10, 20) - , _stepSize("stepSize", "Step Size", 0.002, 0.001, 0.05) + , _stepSize("stepSize", "Step Size", 0.001, 0.0005, 0.05) , _scaling("scaling", "Scaling", glm::vec3(1.0, 1.0, 1.0), glm::vec3(0.0), glm::vec3(10.0)) , _translation("translation", "Translation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0), glm::vec3(10.0)) , _rotation("rotation", "Euler rotation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0), glm::vec3(6.28)) { @@ -252,8 +252,6 @@ void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) { RaycasterTask task{ _raycaster.get(), data }; tasks.raycasterTasks.push_back(task); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - _pointsProgram->activate(); setPscUniforms(*_pointsProgram.get(), data.camera, data.position); diff --git a/shaders/abuffer/resolveabuffer.frag b/shaders/abuffer/resolveabuffer.frag index 9d6019cdc3..dd84d05283 100644 --- a/shaders/abuffer/resolveabuffer.frag +++ b/shaders/abuffer/resolveabuffer.frag @@ -259,7 +259,7 @@ void main() { uint nFilteredFrags = nOriginalFrags; // discard all fragments in abuffer with higher depth value than the fbo - depthFilterFragments(nOriginalFrags, fboDepth); + nFilteredFrags = depthFilterFragments(nOriginalFrags, fboDepth); // sort remaining fragments from front to back sortFragments(nFilteredFrags); @@ -281,7 +281,7 @@ void main() { if (type == 0) { // geometry fragment vec4 color = _color_(frag); if (blend == BLEND_MODE_NORMAL) { - accumulatedColor += (1 - accumulatedAlpha) * color.rgb; + accumulatedColor += (1 - accumulatedAlpha) * color.rgb * color.a; accumulatedAlpha += (1 - accumulatedAlpha) * color.aaa; //normalBlend(finalColor, color); } else if (blend == BLEND_MODE_ADDITIVE) { From 78c0ed902f71031f285f3186502e88b2a1c67250 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 30 May 2016 11:41:14 +0200 Subject: [PATCH 04/61] Correct displacement factor for planetary heightmap Correctly bind F8 key for clearing rosetta projections --- modules/newhorizons/shaders/projectiveTexture_vs.glsl | 2 +- scripts/bind_keys_rosetta.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/newhorizons/shaders/projectiveTexture_vs.glsl b/modules/newhorizons/shaders/projectiveTexture_vs.glsl index fbf40345e0..67075f0830 100644 --- a/modules/newhorizons/shaders/projectiveTexture_vs.glsl +++ b/modules/newhorizons/shaders/projectiveTexture_vs.glsl @@ -68,7 +68,7 @@ void main() { float height = texture(heightTex, in_st).r; // float height = 0.00005; vec3 displacementDirection = (normalize(tmp.xyz)); - float displacementFactor = height * _heightExaggeration / 2500.0; + float displacementFactor = height * _heightExaggeration / 750.0; tmp.xyz = tmp.xyz + displacementDirection * displacementFactor; } diff --git a/scripts/bind_keys_rosetta.lua b/scripts/bind_keys_rosetta.lua index 3c353c3b16..8b420b1f4e 100644 --- a/scripts/bind_keys_rosetta.lua +++ b/scripts/bind_keys_rosetta.lua @@ -31,7 +31,7 @@ openspace.bindKey("SHIFT+5", "openspace.time.setDeltaTime(460800)") openspace.bindKey("i", "local b = openspace.getPropertyValue('ImagePlaneRosetta.renderable.enabled'); openspace.setPropertyValue('ImagePlaneRosetta.renderable.enabled', not b)") -openspace.bindKey("F8", "openspace.setPropertyValue('PlutoProjection.renderable.clearAllProjections', true); openspace.setPropertyValue('Charon.renderable.clearAllProjections', true);") +openspace.bindKey("F8", "openspace.setPropertyValue('67P.renderable.clearAllProjections', true"); openspace.bindKey("a", "openspace.setPropertyValue('Interaction.origin', '67P')") openspace.bindKey("s", "openspace.setPropertyValue('Interaction.origin', 'Rosetta')") From 00d84458250e497e49145c1b58094250238a704c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 30 May 2016 12:26:06 +0200 Subject: [PATCH 05/61] Increase the Syncbuffer to deal with larger scripts --- src/engine/openspaceengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 8fafb203e4..699bf15b3f 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -124,7 +124,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, , _globalPropertyNamespace(new properties::PropertyOwner) , _isMaster(false) , _runTime(0.0) - , _syncBuffer(new SyncBuffer(1024)) + , _syncBuffer(new SyncBuffer(4096)) { _interactionHandler->setPropertyOwner(_globalPropertyNamespace.get()); _globalPropertyNamespace->addPropertySubOwner(_interactionHandler.get()); From 52c5d3a4069521154cc24310551233bbec2eaa0c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 30 May 2016 13:25:31 +0200 Subject: [PATCH 06/61] Add common Lua functions for scene definitions Adapt New Horizons scene to use new common.lua file --- scripts/bind_keys_newhorizons.lua | 97 +++++++++++++------------------ scripts/common.lua | 61 +++++++++++++++++++ 2 files changed, 101 insertions(+), 57 deletions(-) create mode 100644 scripts/common.lua diff --git a/scripts/bind_keys_newhorizons.lua b/scripts/bind_keys_newhorizons.lua index e20d5cf4b8..ca436024f9 100644 --- a/scripts/bind_keys_newhorizons.lua +++ b/scripts/bind_keys_newhorizons.lua @@ -1,30 +1,20 @@ --[[ OpenSpace keybinding script ]]-- --- This script sets the default keybindings and is executed at startup + +-- Load the common helper functions +dofile(openspace.absPath('${SCRIPTS}/common.lua')) openspace.clearKeys() -openspace.bindKey("F1", "openspace.gui.toggle()") -openspace.bindKey("F2", "openspace.setPerformanceMeasurement(true)") -openspace.bindKey("F3", "openspace.setPerformanceMeasurement(false)") +helper.setCommonKeys() + +helper.setDeltaTimeKeys({ + 1, 5, 10, 20, 40, 60, 120, 360, 540, 1080, + 2160, 4320, 8640 +}) + openspace.bindKey("F5", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun'); openspace.printInfo('Changing Viewpoint to Sun-in-center');"); openspace.bindKey("F6", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Jupiter'); openspace.printInfo('Changing Viewpoint to Jupiter-in-center');"); openspace.bindKey("F7", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Pluto'); openspace.printInfo('Changing Viewpoint to Pluto-in-center');"); -openspace.bindKey("PRINT_SCREEN", "openspace.takeScreenshot()") - -openspace.bindKey("SPACE", "openspace.time.togglePause()") - --- Bookmarks for the New Horizons encounter -openspace.bindKey("1", "openspace.time.setDeltaTime(1)") -openspace.bindKey("2", "openspace.time.setDeltaTime(5)") -openspace.bindKey("3", "openspace.time.setDeltaTime(10)") -openspace.bindKey("4", "openspace.time.setDeltaTime(20)") -openspace.bindKey("5", "openspace.time.setDeltaTime(40)") -openspace.bindKey("6", "openspace.time.setDeltaTime(60)") -openspace.bindKey("7", "openspace.time.setDeltaTime(120)") -openspace.bindKey("8", "openspace.time.setDeltaTime(360)") -openspace.bindKey("9", "openspace.time.setDeltaTime(540)") -openspace.bindKey("9", "openspace.time.setDeltaTime(1080)") - openspace.bindKey("F8", "openspace.setPropertyValue('PlutoProjection.renderable.clearAllProjections', true); openspace.setPropertyValue('Charon.renderable.clearAllProjections', true);") -- Quickfix backjumps in pluto sequence @@ -33,7 +23,7 @@ openspace.bindKey("F10", "openspace.time.setTime('2015-07-14T10:00:00.00'); open openspace.bindKey("F11", "openspace.time.setTime('2015-07-14T11:17:00.00'); openspace.setPropertyValue('PlutoProjection.renderable.clearAllProjections', true); openspace.setPropertyValue('Charon.renderable.clearAllProjections', true);") openspace.bindKey("F12", "openspace.time.setTime('2015-07-14T12:45:00.00'); openspace.setPropertyValue('PlutoProjection.renderable.clearAllProjections', true); openspace.setPropertyValue('Charon.renderable.clearAllProjections', true);") -openspace.bindKey("r", "local b = openspace.getPropertyValue('PlutoProjection.renderable.fk'); openspace.setPropertyValue('PlutoProjection.renderable.fk', not b)") +openspace.bindKey("r", helper.property.invert('PlutoProjection.renderable.fk')) openspace.bindKey("a", "openspace.setPropertyValue('Interaction.origin', 'NewHorizons')") openspace.bindKey("s", "openspace.setPropertyValue('Interaction.origin', 'PlutoProjection')") @@ -41,51 +31,44 @@ openspace.bindKey("d", "openspace.setPropertyValue('Interaction.origin', 'Charon openspace.bindKey("z", "openspace.setPropertyValue('Interaction.origin', 'JupiterProjection')") openspace.bindKey("x", "openspace.setPropertyValue('Interaction.origin', 'Europa')") +openspace.bindKey("KP_8", helper.property.increment('PlutoProjection.renderable.heightExaggeration', 2)) +openspace.bindKey("KP_2", helper.property.decrement('PlutoProjection.renderable.heightExaggeration', 2)) + +openspace.bindKey("KP_9", helper.property.increment('Charon.renderable.heightExaggeration', 2)) +openspace.bindKey("KP_3", helper.property.decrement('Charon.renderable.heightExaggeration', 2)) + openspace.bindKey("g", "openspace.time.setTime('2007-02-28T11:40:00.00'); openspace.time.setDeltaTime(1);") openspace.bindKey("h", "openspace.time.setTime('2015-07-14T10:00:00.00'); openspace.time.setDeltaTime(1); openspace.setPropertyValue('Interaction.coordinateSystem', 'Pluto');openspace.setPropertyValue('Interaction.origin', 'PlutoProjection'); openspace.printInfo('Changing Viewpoint to Pluto-in-center');") -openspace.bindKey("i", "local b = openspace.getPropertyValue('PlutoTexture.renderable.enabled'); openspace.setPropertyValue('PlutoTexture.renderable.enabled', not b)") +openspace.bindKey("q", helper.property.invert('SunMarker.renderable.enabled')) +openspace.bindKey("e", helper.property.invert('EarthMarker.renderable.enabled')) +openspace.bindKey("o", helper.property.invert('PlutoTrail.renderable.enabled')) -openspace.bindKey("q", "local b = openspace.getPropertyValue('SunMarker.renderable.enabled'); openspace.setPropertyValue('SunMarker.renderable.enabled', not b)") -openspace.bindKey("e", "local b = openspace.getPropertyValue('EarthMarker.renderable.enabled'); openspace.setPropertyValue('EarthMarker.renderable.enabled', not b)") +openspace.bindKey("k", + helper.renderable.toggle('HydraText') .. helper.renderable.toggle('NixText') .. helper.renderable.toggle('KerberosText') .. helper.renderable.toggle('StyxText') +) +openspace.bindKey("j", helper.renderable.toggle('PlutoText')) -openspace.bindKey("o", "local b = openspace.getPropertyValue('PlutoTrail.renderable.enabled'); openspace.setPropertyValue('PlutoTrail.renderable.enabled', not b)") +openspace.bindKey("l", helper.property.invert('Labels.renderable.performFading')) -openspace.bindKey("k", "local b = openspace.getPropertyValue('HydraText.renderable.enabled'); openspace.setPropertyValue('HydraText.renderable.enabled', not b)") -openspace.bindKey("k", "local b = openspace.getPropertyValue('CharonText.renderable.enabled'); openspace.setPropertyValue('CharonText.renderable.enabled', not b)") -openspace.bindKey("k", "local b = openspace.getPropertyValue('NixText.renderable.enabled'); openspace.setPropertyValue('NixText.renderable.enabled', not b)") -openspace.bindKey("k", "local b = openspace.getPropertyValue('KerberosText.renderable.enabled'); openspace.setPropertyValue('KerberosText.renderable.enabled', not b)") -openspace.bindKey("k", "local b = openspace.getPropertyValue('StyxText.renderable.enabled'); openspace.setPropertyValue('StyxText.renderable.enabled', not b)") -openspace.bindKey("j", "local b = openspace.getPropertyValue('PlutoText.renderable.enabled'); openspace.setPropertyValue('PlutoText.renderable.enabled', not b)") +openspace.bindKey("m", + helper.property.invert('NH_LORRI.renderable.solidDraw') .. helper.property.invert('NH_RALPH_LEISA.renderable.solidDraw') .. + helper.property.invert('NH_RALPH_MVIC_PAN1.renderable.solidDraw') .. helper.property.invert('NH_RALPH_MVIC_PAN2.renderable.solidDraw') .. + helper.property.invert('NH_RALPH_MVIC_RED.renderable.solidDraw') .. helper.property.invert('NH_RALPH_MVIC_BLUE.renderable.solidDraw') .. + helper.property.invert('NH_RALPH_MVIC_FT.renderable.solidDraw') .. helper.property.invert('NH_RALPH_MVIC_METHANE.renderable.solidDraw') .. + helper.property.invert('NH_RALPH_MVIC_NIR.renderable.solidDraw') .. helper.property.invert('NH_ALICE_AIRGLOW.renderable.solidDraw') .. + helper.property.invert('NH_ALICE_SOC.renderable.solidDraw') +) -openspace.bindKey("l", "local b = openspace.getPropertyValue('Labels.renderable.performFading'); openspace.setPropertyValue('Labels.renderable.performFading', not b)") +openspace.bindKey("t", helper.renderable.toggle('PlutoShadow') .. helper.renderable.toggle('CharonShadow')) -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_LORRI.renderable.solidDraw'); openspace.setPropertyValue('NH_LORRI.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_LEISA.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_LEISA.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_PAN1.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_PAN1.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_PAN2.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_PAN2.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_RED.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_RED.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_BLUE.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_BLUE.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_FT.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_FT.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_METHANE.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_METHANE.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_NIR.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_NIR.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_ALICE_AIRGLOW.renderable.solidDraw'); openspace.setPropertyValue('NH_ALICE_AIRGLOW.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_ALICE_SOC.renderable.solidDraw'); openspace.setPropertyValue('NH_ALICE_SOC.renderable.solidDraw', not b)") - -openspace.bindKey("t", "local b = openspace.getPropertyValue('PlutoShadow.renderable.enabled'); openspace.setPropertyValue('PlutoShadow.renderable.enabled', not b)") -openspace.bindKey("t", "local b = openspace.getPropertyValue('CharonShadow.renderable.enabled'); openspace.setPropertyValue('CharonShadow.renderable.enabled', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('JupiterProjection.renderable.performProjection'); openspace.setPropertyValue('JupiterProjection.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('Io.renderable.performProjection'); openspace.setPropertyValue('Io.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('Ganymede.renderable.performProjection'); openspace.setPropertyValue('Ganymede.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('Europa.renderable.performProjection'); openspace.setPropertyValue('Europa.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('Callisto.renderable.performProjection'); openspace.setPropertyValue('Callisto.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('PlutoProjection.renderable.performProjection'); openspace.setPropertyValue('PlutoProjection.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('Charon.renderable.performProjection'); openspace.setPropertyValue('Charon.renderable.performProjection', not b)") +openspace.bindKey("p", + helper.property.invert('JupiterProjection.renderable.performProjection') .. helper.property.invert('Io.renderable.performProjection') .. + helper.property.invert('Ganymede.renderable.performProjection') .. helper.property.invert('Europa.renderable.performProjection') .. + helper.property.invert('Callisto.renderable.performProjection') .. helper.property.invert('PlutoProjection.renderable.performProjection') .. + helper.property.invert('Charon.renderable.performProjection') +) openspace.bindKey("c", "openspace.parallel.setAddress('130.236.142.51');openspace.parallel.setPassword('newhorizons-20150714');openspace.parallel.connect();") - - -openspace.bindKey("COMMA", "openspace.setRenderer('Framebuffer');") -openspace.bindKey("PERIOD", "openspace.setRenderer('ABuffer');") \ No newline at end of file diff --git a/scripts/common.lua b/scripts/common.lua new file mode 100644 index 0000000000..cef02c1794 --- /dev/null +++ b/scripts/common.lua @@ -0,0 +1,61 @@ +--[[ Commonly used OpenSpace configuration functions ]]-- + +helper = {} +helper.renderable = {} +helper.property = {} + +-- Function that sets the most common key bindings that are common to most (all?) +-- scenes +helper.setCommonKeys = function() + openspace.bindKey("F1", "openspace.gui.toggle()") + openspace.bindKey("F2", "openspace.setPerformanceMeasurement(true)") + openspace.bindKey("F3", "openspace.setPerformanceMeasurement(false)") + + openspace.bindKey("PRINT_SCREEN", "openspace.takeScreenshot()") + openspace.bindKey("SPACE", "openspace.time.togglePause()") + + openspace.bindKey("COMMA", "openspace.setRenderer('Framebuffer');") + openspace.bindKey("PERIOD", "openspace.setRenderer('ABuffer');") +end + +helper.setDeltaTimeKeys = function(t) + local Keys = { + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', + 'Shift+1', 'Shift+2', 'Shift+3', 'Shift+4', 'Shift+5', 'Shift+6', 'Shift+7', 'Shift+8', 'Shift+9', 'Shift+0', + 'Ctrl+1', 'Ctrl+2', 'Ctrl+3', 'Ctrl+4', 'Ctrl+5', 'Ctrl+6', 'Ctrl+7', 'Ctrl+8', 'Ctrl+9', 'Ctrl+0', + 'Alt+1', 'Alt+2', 'Alt+3', 'Alt+4', 'Alt+5', 'Alt+6', 'Alt+7', 'Alt+8', 'Alt+9', 'Alt+0' + } + + if #t > #Keys then + openspace.printError("Error settings delta time keys: Too many delta times (" .. #t .. ")") + return + end + + for i, v in ipairs(t) do + openspace.bindKey(Keys[i], 'openspace.time.setDeltaTime(' .. v .. ")") + end +end + +-- Function that returns the string that inverts the fully qualified boolean property 'property' +helper.property.invert = function(property) + local escaped_property = "'" .. property .. "'" + return "openspace.setPropertyValue(" .. escaped_property .. ", not openspace.getPropertyValue(" .. escaped_property .. "));" +end + +-- Function that returns the string that increments the 'property' by the 'value' +helper.property.increment = function(property, value) + local v = value or 1 + local escaped_property = "'" .. property .. "'" + return "openspace.setPropertyValue(" .. escaped_property .. ", openspace.getPropertyValue(" .. escaped_property .. ") + " .. v .. ")" +end + +-- Function that returns the string that decrements the 'property' by the 'value' +helper.property.decrement = function(property, value) + return helper.property.increment(property, -value) +end + +-- Function that returns the string that enables/disables the renderable 'renderable' +helper.renderable.toggle = function(renderable) + return helper.property.invert(renderable .. ".renderable.enabled") +end + From 884324c467777c05898771977419c774c0d9b10f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 30 May 2016 13:32:34 +0200 Subject: [PATCH 07/61] Cleanup of default.scene and keybindings --- data/scene/default.scene | 14 +---- scripts/bind_keys.lua | 112 +++++---------------------------------- 2 files changed, 14 insertions(+), 112 deletions(-) diff --git a/data/scene/default.scene b/data/scene/default.scene index 65c7e3b609..3469171d1f 100644 --- a/data/scene/default.scene +++ b/data/scene/default.scene @@ -20,9 +20,7 @@ function postInitialization() openspace.setPropertyValue("Sun.renderable.enabled", false) openspace.setPropertyValue("SunMarker.renderable.enabled", true) openspace.setPropertyValue("EarthMarker.renderable.enabled", true) - --openspace.setPropertyValue("Constellation Bounds.renderable.enabled", false) - openspace.setPropertyValue("PlutoTrail.renderable.enabled", false) - openspace.setPropertyValue("PlutoTexture.renderable.enabled", false) + openspace.setPropertyValue("Constellation Bounds.renderable.enabled", false) openspace.setPropertyValue("MilkyWay.renderable.transparency", 0.55) openspace.setPropertyValue("MilkyWay.renderable.segments", 50) @@ -52,14 +50,6 @@ return { -- "stars-denver", "milkyway", -- "milkyway-eso", - --"constellationbounds", - -- "fieldlines", - --"io", - --"europa", - --"ganymede", - --"callisto", - --"gridGalactic", - --"gridEcliptic", - --"gridEquatorial", + "constellationbounds", } } diff --git a/scripts/bind_keys.lua b/scripts/bind_keys.lua index d173ab32a4..be68aeff20 100644 --- a/scripts/bind_keys.lua +++ b/scripts/bind_keys.lua @@ -1,106 +1,18 @@ --[[ OpenSpace keybinding script ]]-- --- This script sets the default keybindings and is executed at startup + +-- Load the common helper functions +dofile(openspace.absPath('${SCRIPTS}/common.lua')) openspace.clearKeys() -openspace.bindKey("F1", "openspace.gui.toggle()") -openspace.bindKey("F2", "openspace.setPerformanceMeasurement(true)") -openspace.bindKey("F3", "openspace.setPerformanceMeasurement(false)") -openspace.bindKey("F5", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun'); openspace.printInfo('Changing Viewpoint to Sun-in-center');"); -openspace.bindKey("F6", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Jupiter'); openspace.printInfo('Changing Viewpoint to Jupiter-in-center');"); -openspace.bindKey("F7", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Pluto'); openspace.printInfo('Changing Viewpoint to Pluto-in-center');"); +helper.setCommonKeys() +helper.setDeltaTimeKeys({ + 1, 5, 10, 20, 40, 60, 120, 360, 720, 1440, + 2880, 5760, 11520, 23040, 46080, 92160, 184320, 368640, 737280, 1474560, + 2949120, 5898240, 11796480, 23592960, 47185920, 94371840, 188743680, 377487360 +}) -openspace.bindKey("PRINT_SCREEN", "openspace.takeScreenshot()") - -openspace.bindKey("SPACE", "openspace.time.togglePause()") - --- Bookmarks for the New Horizons encounter -openspace.bindKey("1", "openspace.time.setDeltaTime(1)") -openspace.bindKey("2", "openspace.time.setDeltaTime(5)") -openspace.bindKey("3", "openspace.time.setDeltaTime(10)") -openspace.bindKey("4", "openspace.time.setDeltaTime(20)") -openspace.bindKey("5", "openspace.time.setDeltaTime(40)") -openspace.bindKey("6", "openspace.time.setDeltaTime(60)") -openspace.bindKey("7", "openspace.time.setDeltaTime(120)") -openspace.bindKey("8", "openspace.time.setDeltaTime(360)") -openspace.bindKey("9", "openspace.time.setDeltaTime(540)") - ---[[openspace.bindKey("2", "openspace.time.setDeltaTime(30)") -openspace.bindKey("3", "openspace.time.setDeltaTime(180)") -- 3m -openspace.bindKey("4", "openspace.time.setDeltaTime(900)") -- 15m -openspace.bindKey("5", "openspace.time.setDeltaTime(3600)") -- 1h -openspace.bindKey("6", "openspace.time.setDeltaTime(14400)") -- 3h -openspace.bindKey("7", "openspace.time.setDeltaTime(43200)") -- 12h -openspace.bindKey("8", "openspace.time.setDeltaTime(86400)") -- 1d -openspace.bindKey("9", "openspace.time.setDeltaTime(172800)") -- 2d - -openspace.bindKey("v", "openspace.time.setTime('2014 AUG 22 03:45:00'); openspace.time.setDeltaTime(1);") -openspace.bindKey("b", "openspace.time.setTime('2014 SEP 02 11:30:30'); openspace.time.setDeltaTime(1);") -openspace.bindKey("n", "openspace.time.setTime('2014 SEP 14 17:55:00'); openspace.time.setDeltaTime(1);") - -openspace.bindKey("i", "local b = openspace.getPropertyValue('ImagePlaneRosetta.renderable.enabled'); openspace.setPropertyValue('ImagePlaneRosetta.renderable.enabled', not b)") ---]] - -openspace.bindKey("F8", "openspace.setPropertyValue('PlutoProjection.renderable.clearAllProjections', true); openspace.setPropertyValue('Charon.renderable.clearAllProjections', true);") - --- Quickfix backjumps in pluto sequence -openspace.bindKey("F9", "openspace.time.setTime('2015-07-14T09:00:00.00'); openspace.setPropertyValue('PlutoProjection.renderable.clearAllProjections', true); openspace.setPropertyValue('Charon.renderable.clearAllProjections', true);") -openspace.bindKey("F10", "openspace.time.setTime('2015-07-14T10:00:00.00'); openspace.setPropertyValue('PlutoProjection.renderable.clearAllProjections', true); openspace.setPropertyValue('Charon.renderable.clearAllProjections', true);") -openspace.bindKey("F11", "openspace.time.setTime('2015-07-14T11:17:00.00'); openspace.setPropertyValue('PlutoProjection.renderable.clearAllProjections', true); openspace.setPropertyValue('Charon.renderable.clearAllProjections', true);") -openspace.bindKey("F12", "openspace.time.setTime('2015-07-14T12:45:00.00'); openspace.setPropertyValue('PlutoProjection.renderable.clearAllProjections', true); openspace.setPropertyValue('Charon.renderable.clearAllProjections', true);") - -openspace.bindKey("r", "local b = openspace.getPropertyValue('PlutoProjection.renderable.fk'); openspace.setPropertyValue('PlutoProjection.renderable.fk', not b)") - -openspace.bindKey("a", "openspace.setPropertyValue('Interaction.origin', 'NewHorizons')") -openspace.bindKey("s", "openspace.setPropertyValue('Interaction.origin', 'PlutoProjection')") -openspace.bindKey("d", "openspace.setPropertyValue('Interaction.origin', 'Charon')") -openspace.bindKey("z", "openspace.setPropertyValue('Interaction.origin', 'JupiterProjection')") -openspace.bindKey("x", "openspace.setPropertyValue('Interaction.origin', 'Europa')") - - -openspace.bindKey("g", "openspace.time.setTime('2007-02-28T11:40:00.00'); openspace.time.setDeltaTime(1);") - -openspace.bindKey("h", "openspace.time.setTime('2015-07-14T10:00:00.00'); openspace.time.setDeltaTime(1); openspace.setPropertyValue('Interaction.coordinateSystem', 'Pluto');openspace.setPropertyValue('Interaction.origin', 'PlutoProjection'); openspace.printInfo('Changing Viewpoint to Pluto-in-center');") - -openspace.bindKey("i", "local b = openspace.getPropertyValue('PlutoTexture.renderable.enabled'); openspace.setPropertyValue('PlutoTexture.renderable.enabled', not b)") - -openspace.bindKey("q", "local b = openspace.getPropertyValue('SunMarker.renderable.enabled'); openspace.setPropertyValue('SunMarker.renderable.enabled', not b)") -openspace.bindKey("e", "local b = openspace.getPropertyValue('EarthMarker.renderable.enabled'); openspace.setPropertyValue('EarthMarker.renderable.enabled', not b)") - -openspace.bindKey("o", "local b = openspace.getPropertyValue('PlutoTrail.renderable.enabled'); openspace.setPropertyValue('PlutoTrail.renderable.enabled', not b)") - -openspace.bindKey("k", "local b = openspace.getPropertyValue('HydraText.renderable.enabled'); openspace.setPropertyValue('HydraText.renderable.enabled', not b)") -openspace.bindKey("k", "local b = openspace.getPropertyValue('CharonText.renderable.enabled'); openspace.setPropertyValue('CharonText.renderable.enabled', not b)") -openspace.bindKey("k", "local b = openspace.getPropertyValue('NixText.renderable.enabled'); openspace.setPropertyValue('NixText.renderable.enabled', not b)") -openspace.bindKey("k", "local b = openspace.getPropertyValue('KerberosText.renderable.enabled'); openspace.setPropertyValue('KerberosText.renderable.enabled', not b)") -openspace.bindKey("k", "local b = openspace.getPropertyValue('StyxText.renderable.enabled'); openspace.setPropertyValue('StyxText.renderable.enabled', not b)") -openspace.bindKey("j", "local b = openspace.getPropertyValue('PlutoText.renderable.enabled'); openspace.setPropertyValue('PlutoText.renderable.enabled', not b)") - -openspace.bindKey("l", "local b = openspace.getPropertyValue('Labels.renderable.performFading'); openspace.setPropertyValue('Labels.renderable.performFading', not b)") - -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_LORRI.renderable.solidDraw'); openspace.setPropertyValue('NH_LORRI.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_LEISA.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_LEISA.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_PAN1.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_PAN1.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_PAN2.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_PAN2.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_RED.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_RED.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_BLUE.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_BLUE.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_FT.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_FT.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_METHANE.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_METHANE.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_NIR.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_NIR.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_ALICE_AIRGLOW.renderable.solidDraw'); openspace.setPropertyValue('NH_ALICE_AIRGLOW.renderable.solidDraw', not b)") -openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_ALICE_SOC.renderable.solidDraw'); openspace.setPropertyValue('NH_ALICE_SOC.renderable.solidDraw', not b)") - -openspace.bindKey("t", "local b = openspace.getPropertyValue('PlutoShadow.renderable.enabled'); openspace.setPropertyValue('PlutoShadow.renderable.enabled', not b)") -openspace.bindKey("t", "local b = openspace.getPropertyValue('CharonShadow.renderable.enabled'); openspace.setPropertyValue('CharonShadow.renderable.enabled', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('JupiterProjection.renderable.performProjection'); openspace.setPropertyValue('JupiterProjection.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('Io.renderable.performProjection'); openspace.setPropertyValue('Io.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('Ganymede.renderable.performProjection'); openspace.setPropertyValue('Ganymede.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('Europa.renderable.performProjection'); openspace.setPropertyValue('Europa.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('Callisto.renderable.performProjection'); openspace.setPropertyValue('Callisto.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('PlutoProjection.renderable.performProjection'); openspace.setPropertyValue('PlutoProjection.renderable.performProjection', not b)") -openspace.bindKey("p", "local b = openspace.getPropertyValue('Charon.renderable.performProjection'); openspace.setPropertyValue('Charon.renderable.performProjection', not b)") +openspace.bindKey("q", helper.renderable.toggle('SunMarker')) +openspace.bindKey("e", helper.renderable.toggle('EarthMarker')) +openspace.bindKey("x", helper.renderable.toggle('Constellation Bounds')) openspace.bindKey("c", "openspace.parallel.setAddress('130.236.142.51');openspace.parallel.setPassword('newhorizons-20150714');openspace.parallel.connect();") - - -openspace.bindKey("COMMA", "openspace.setRenderer('Framebuffer');") -openspace.bindKey("PERIOD", "openspace.setRenderer('ABuffer');") \ No newline at end of file From d3ab18ec93cae61a650db841fd82164634aa563f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 30 May 2016 13:54:33 +0200 Subject: [PATCH 08/61] Clean keybindings of Rosetta scene --- scripts/bind_keys_newhorizons.lua | 18 ++++++------ scripts/bind_keys_rosetta.lua | 49 ++++++++++--------------------- 2 files changed, 24 insertions(+), 43 deletions(-) diff --git a/scripts/bind_keys_newhorizons.lua b/scripts/bind_keys_newhorizons.lua index ca436024f9..7d82119ab0 100644 --- a/scripts/bind_keys_newhorizons.lua +++ b/scripts/bind_keys_newhorizons.lua @@ -11,9 +11,15 @@ helper.setDeltaTimeKeys({ 2160, 4320, 8640 }) -openspace.bindKey("F5", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun'); openspace.printInfo('Changing Viewpoint to Sun-in-center');"); -openspace.bindKey("F6", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Jupiter'); openspace.printInfo('Changing Viewpoint to Jupiter-in-center');"); -openspace.bindKey("F7", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Pluto'); openspace.printInfo('Changing Viewpoint to Pluto-in-center');"); +openspace.bindKey("a", "openspace.setPropertyValue('Interaction.origin', 'NewHorizons')") +openspace.bindKey("s", "openspace.setPropertyValue('Interaction.origin', 'PlutoProjection')") +openspace.bindKey("d", "openspace.setPropertyValue('Interaction.origin', 'Charon')") +openspace.bindKey("z", "openspace.setPropertyValue('Interaction.origin', 'JupiterProjection')") +openspace.bindKey("x", "openspace.setPropertyValue('Interaction.origin', 'Europa')") + +openspace.bindKey("F5", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun'); openspace.printInfo('Changing Viewpoint to Sun');"); +openspace.bindKey("F6", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Jupiter'); openspace.printInfo('Changing Viewpoint to Jupiter');"); +openspace.bindKey("F7", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Pluto'); openspace.printInfo('Changing Viewpoint to Pluto');"); openspace.bindKey("F8", "openspace.setPropertyValue('PlutoProjection.renderable.clearAllProjections', true); openspace.setPropertyValue('Charon.renderable.clearAllProjections', true);") @@ -25,12 +31,6 @@ openspace.bindKey("F12", "openspace.time.setTime('2015-07-14T12:45:00.00'); open openspace.bindKey("r", helper.property.invert('PlutoProjection.renderable.fk')) -openspace.bindKey("a", "openspace.setPropertyValue('Interaction.origin', 'NewHorizons')") -openspace.bindKey("s", "openspace.setPropertyValue('Interaction.origin', 'PlutoProjection')") -openspace.bindKey("d", "openspace.setPropertyValue('Interaction.origin', 'Charon')") -openspace.bindKey("z", "openspace.setPropertyValue('Interaction.origin', 'JupiterProjection')") -openspace.bindKey("x", "openspace.setPropertyValue('Interaction.origin', 'Europa')") - openspace.bindKey("KP_8", helper.property.increment('PlutoProjection.renderable.heightExaggeration', 2)) openspace.bindKey("KP_2", helper.property.decrement('PlutoProjection.renderable.heightExaggeration', 2)) diff --git a/scripts/bind_keys_rosetta.lua b/scripts/bind_keys_rosetta.lua index 8b420b1f4e..2806c022be 100644 --- a/scripts/bind_keys_rosetta.lua +++ b/scripts/bind_keys_rosetta.lua @@ -1,45 +1,26 @@ --[[ OpenSpace keybinding script ]]-- -- This script sets the default keybindings and is executed at startup +-- Load the common helper functions +dofile(openspace.absPath('${SCRIPTS}/common.lua')) + openspace.clearKeys() -openspace.bindKey("F1", "openspace.gui.toggle()") -openspace.bindKey("F2", "openspace.setPerformanceMeasurement(true)") -openspace.bindKey("F3", "openspace.setPerformanceMeasurement(false)") -openspace.bindKey("F5", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun'); openspace.printInfo('Changing Viewpoint to Sun-in-center');"); -openspace.bindKey("F6", "openspace.setPropertyValue('Interaction.coordinateSystem', '67P'); openspace.printInfo('Changing Viewpoint to 67P-in-center');"); +helper.setCommonKeys() -openspace.bindKey("PRINT_SCREEN", "openspace.takeScreenshot()") - -openspace.bindKey("SPACE", "openspace.time.togglePause()") - --- Bookmarks for the New Horizons encounter -openspace.bindKey("1", "openspace.time.setDeltaTime(1)") -openspace.bindKey("2", "openspace.time.setDeltaTime(5)") -openspace.bindKey("3", "openspace.time.setDeltaTime(10)") -openspace.bindKey("4", "openspace.time.setDeltaTime(20)") -openspace.bindKey("5", "openspace.time.setDeltaTime(40)") -openspace.bindKey("6", "openspace.time.setDeltaTime(90)") -openspace.bindKey("7", "openspace.time.setDeltaTime(360)") -openspace.bindKey("8", "openspace.time.setDeltaTime(720)") -openspace.bindKey("9", "openspace.time.setDeltaTime(2880)") -openspace.bindKey("0", "openspace.time.setDeltaTime(14400)") -openspace.bindKey("SHIFT+1", "openspace.time.setDeltaTime(28800)") -openspace.bindKey("SHIFT+2", "openspace.time.setDeltaTime(57600)") -openspace.bindKey("SHIFT+3", "openspace.time.setDeltaTime(115200)") -openspace.bindKey("SHIFT+4", "openspace.time.setDeltaTime(230400)") -openspace.bindKey("SHIFT+5", "openspace.time.setDeltaTime(460800)") - -openspace.bindKey("i", "local b = openspace.getPropertyValue('ImagePlaneRosetta.renderable.enabled'); openspace.setPropertyValue('ImagePlaneRosetta.renderable.enabled', not b)") - -openspace.bindKey("F8", "openspace.setPropertyValue('67P.renderable.clearAllProjections', true"); +helper.setDeltaTimeKeys({ + 1, 5, 10, 20, 40, 90, 360, 720, 2880, 14400, + 28800, 57600, 115200, 230400, 460800 +}) openspace.bindKey("a", "openspace.setPropertyValue('Interaction.origin', '67P')") openspace.bindKey("s", "openspace.setPropertyValue('Interaction.origin', 'Rosetta')") -openspace.bindKey("q", "local b = openspace.getPropertyValue('SunMarker.renderable.enabled'); openspace.setPropertyValue('SunMarker.renderable.enabled', not b)") -openspace.bindKey("e", "local b = openspace.getPropertyValue('EarthMarker.renderable.enabled'); openspace.setPropertyValue('EarthMarker.renderable.enabled', not b)") +openspace.bindKey("F5", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun'); openspace.printInfo('Changing Viewpoint to Sun');"); +openspace.bindKey("F6", "openspace.setPropertyValue('Interaction.coordinateSystem', '67P'); openspace.printInfo('Changing Viewpoint to 67P');"); +openspace.bindKey("F8", "openspace.setPropertyValue('67P.renderable.clearAllProjections', true"); + +openspace.bindKey("i", helper.renderable.toggle('ImagePlaneRosetta')) +openspace.bindKey("q", helper.renderable.toggle('SunMarker')) +openspace.bindKey("e", helper.renderable.toggle('EarthMarker')) openspace.bindKey("c", "openspace.parallel.setAddress('130.236.142.51');openspace.parallel.setPassword('newhorizons-20150714');openspace.parallel.connect();") - -openspace.bindKey("COMMA", "openspace.setRenderer('Framebuffer');") -openspace.bindKey("PERIOD", "openspace.setRenderer('ABuffer');") \ No newline at end of file From fde537681fe18179bc46c1d9018d454d9d67a734 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 30 May 2016 15:26:47 +0200 Subject: [PATCH 09/61] Some work on fixing 67P projections for all available times --- data/scene/rosetta/67P/67P.mod | 24 +++--------------------- data/scene/rosetta/rosetta/rosetta.mod | 21 +++++++++++++++++++++ scripts/bind_keys_rosetta.lua | 6 +++--- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/data/scene/rosetta/67P/67P.mod b/data/scene/rosetta/67P/67P.mod index bb37f7b630..e5c1e2962b 100644 --- a/data/scene/rosetta/67P/67P.mod +++ b/data/scene/rosetta/67P/67P.mod @@ -87,32 +87,14 @@ return { '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/CORL_DL_006_01____H__00156.BSP', --Jan 2014 - May 2015 (version match with 00162 ck files) - "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/CORB_DV_211_01_______00288.BSP", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/RORB_DV_211_01_______00288.BSP", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/LORB_DV_211_01_______00288.BSP", "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/CORB_DV_097_01_______00162.BSP", "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/RORB_DV_097_01_______00162.BSP", "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/LORB_DV_097_01_______00162.BSP", - --SCLK - -- "${OPENSPACE_DATA}/spice/RosettaKernels/SCLK/ROS_150227_STEP.TSC", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/SCLK/ROS_160425_STEP.TSC", - - -- FK + "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/CORB_DV_211_01_______00288.BSP", + "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/RORB_DV_211_01_______00288.BSP", + "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/LORB_DV_211_01_______00288.BSP", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/FK/ROS_CHURYUMOV_V01.TF", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/FK/ROS_V26.TF", - -- "${OPENSPACE_DATA}/spice/RosettaKernels/FK/ROS_V24.TF", - -- CK - "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/RATT_DV_211_01_01____00288.BC", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/CATT_DV_211_01_______00288.BC", - '${OPENSPACE_DATA}/spice/RosettaKernels/CK/RATT_DV_097_01_01____00162.BC', - "${OPENSPACE_DATA}/spice/RosettaKernels/CK/CATT_DV_097_01_______00162.BC", - - -- PCK - "${OPENSPACE_DATA}/spice/RosettaKernels_New/PCK/ROS_CGS_RSOC_V03.TPC", - -- "${OPENSPACE_DATA}/spice/RosettaKernels/PCK/ROS_CGS_RSOC_V03.TPC", - } }, diff --git a/data/scene/rosetta/rosetta/rosetta.mod b/data/scene/rosetta/rosetta/rosetta.mod index dffa3b30f6..9dd867355b 100644 --- a/data/scene/rosetta/rosetta/rosetta.mod +++ b/data/scene/rosetta/rosetta/rosetta.mod @@ -54,6 +54,27 @@ return { -- '${OPENSPACE_DATA}/spice/RosettaKernels/CK/RATT_DV_097_01_01____00162.BC', -- "${OPENSPACE_DATA}/spice/RosettaKernels/CK/CATT_DV_097_01_______00162.BC", + --SCLK + -- "${OPENSPACE_DATA}/spice/RosettaKernels/SCLK/ROS_150227_STEP.TSC", + "${OPENSPACE_DATA}/spice/RosettaKernels_New/SCLK/ROS_160425_STEP.TSC", + + -- FK + + "${OPENSPACE_DATA}/spice/RosettaKernels_New/FK/ROS_CHURYUMOV_V01.TF", + "${OPENSPACE_DATA}/spice/RosettaKernels_New/FK/ROS_V26.TF", + -- "${OPENSPACE_DATA}/spice/RosettaKernels/FK/ROS_V24.TF", + -- CK + "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/RATT_DV_211_01_01____00288.BC", + "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/CATT_DV_211_01_______00288.BC", + '${OPENSPACE_DATA}/spice/RosettaKernels/CK/RATT_DV_097_01_01____00162.BC', + "${OPENSPACE_DATA}/spice/RosettaKernels/CK/CATT_DV_097_01_______00162.BC", + + -- PCK + "${OPENSPACE_DATA}/spice/RosettaKernels_New/PCK/ROS_CGS_RSOC_V03.TPC", + -- "${OPENSPACE_DATA}/spice/RosettaKernels/PCK/ROS_CGS_RSOC_V03.TPC", + + + "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/ROS_SA_2014_V0047.BC", "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/ROS_SA_2015_V0042.BC", "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/ROS_SA_2016_V0019.BC", diff --git a/scripts/bind_keys_rosetta.lua b/scripts/bind_keys_rosetta.lua index 2806c022be..d6184966bc 100644 --- a/scripts/bind_keys_rosetta.lua +++ b/scripts/bind_keys_rosetta.lua @@ -9,15 +9,15 @@ helper.setCommonKeys() helper.setDeltaTimeKeys({ 1, 5, 10, 20, 40, 90, 360, 720, 2880, 14400, - 28800, 57600, 115200, 230400, 460800 + 28800, 57600, 115200, 230400, 460800, 921600, 1843200, 3686400, 7372800, 14745600 }) openspace.bindKey("a", "openspace.setPropertyValue('Interaction.origin', '67P')") openspace.bindKey("s", "openspace.setPropertyValue('Interaction.origin', 'Rosetta')") -openspace.bindKey("F5", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun'); openspace.printInfo('Changing Viewpoint to Sun');"); +-- openspace.bindKey("F5", "openspace.setPropertyValue('Interaction.coordinateSystem', 'Sun'); openspace.printInfo('Changing Viewpoint to Sun');"); openspace.bindKey("F6", "openspace.setPropertyValue('Interaction.coordinateSystem', '67P'); openspace.printInfo('Changing Viewpoint to 67P');"); -openspace.bindKey("F8", "openspace.setPropertyValue('67P.renderable.clearAllProjections', true"); +openspace.bindKey("F8", "openspace.setPropertyValue('67P.renderable.clearAllProjections', true);"); openspace.bindKey("i", helper.renderable.toggle('ImagePlaneRosetta')) openspace.bindKey("q", helper.renderable.toggle('SunMarker')) From a9a99a51e88a8185660d6f5e27ee490547a6e4e9 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 31 May 2016 14:40:15 +0200 Subject: [PATCH 10/61] Prevent 67P model from disappearing during projections (closing #83) --- .../rendering/renderablemodelprojection.cpp | 13 +++++++++---- .../rendering/renderablemodelprojection.h | 1 - 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 529a1438dd..a75d034bf5 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -343,7 +343,6 @@ void RenderableModelProjection::render(const RenderData& data) { if (_clearAllProjections) clearAllProjections(); - _programObject->activate(); _frameCount++; _camScaling = data.camera.scaling(); @@ -352,6 +351,9 @@ void RenderableModelProjection::render(const RenderData& data) { if (_capture && _performProjection) project(); + _programObject->activate(); + + attitudeParameters(_time); _imageTimes.clear(); @@ -370,8 +372,7 @@ void RenderableModelProjection::render(const RenderData& data) { _programObject->setUniform("boresight", _boresight); _programObject->setUniform("_performShading", _performShading); _programObject->setUniform("sun_pos", _sunPosition.vec3()); - _viewProjection = data.camera.viewProjectionMatrix(); - _programObject->setUniform("ViewProjection", _viewProjection); + _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform", _transform); setPscUniforms(*_programObject, data.camera, data.position); @@ -425,6 +426,8 @@ void RenderableModelProjection::imageProjectGPU() { glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ZERO); glViewport(0, 0, static_cast(_texture->width()), static_cast(_texture->height())); + + _fboProgramObject->activate(); ghoul::opengl::TextureUnit unitFboProject; @@ -449,7 +452,9 @@ void RenderableModelProjection::imageProjectGPU() { glBindVertexArray(0); _fboProgramObject->deactivate(); - //glDisable(GL_BLEND); + + + glDisable(GL_BLEND); //bind back to default glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); glViewport(m_viewport[0], m_viewport[1], diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index 926b61c597..73e817ff53 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -119,7 +119,6 @@ namespace openspace { glm::vec2 _camScaling; glm::vec3 _up; glm::mat4 _transform; - glm::mat4 _viewProjection; glm::mat4 _projectorMatrix; glm::vec3 _boresight; From 46107e94927e6b7e8b20ea20ff9323c923913bc3 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 31 May 2016 18:25:34 +0200 Subject: [PATCH 11/61] Add anti-aliasing to stereo configuration file --- config/sgct/single_stereo.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/sgct/single_stereo.xml b/config/sgct/single_stereo.xml index 30188156b0..71f83845c3 100644 --- a/config/sgct/single_stereo.xml +++ b/config/sgct/single_stereo.xml @@ -1,7 +1,7 @@ - + From 592c2d41b5642b781f46f3b0e0dcb61f54b12196 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 31 May 2016 18:25:57 +0200 Subject: [PATCH 12/61] First fix for reenabling Jupiter projections --- data/scene/newhorizons.scene | 2 ++ data/scene/newhorizons/jupiter/jupiter/jupiter.mod | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/data/scene/newhorizons.scene b/data/scene/newhorizons.scene index 114070e22a..c4277637c3 100644 --- a/data/scene/newhorizons.scene +++ b/data/scene/newhorizons.scene @@ -8,6 +8,8 @@ function preInitialization() critical objects. ]]-- + -- openspace.time.setTime("2007-02-28T11:40:00.000") + -- openspace.time.setTime("2015-07-08T15:57:45.00") -- openspace.time.setTime("2015-07-12T07:41:00.00") -- openspace.time.setTime("2015-07-12T15:43:00.00") diff --git a/data/scene/newhorizons/jupiter/jupiter/jupiter.mod b/data/scene/newhorizons/jupiter/jupiter/jupiter.mod index 5853649995..03e8f46b12 100644 --- a/data/scene/newhorizons/jupiter/jupiter/jupiter.mod +++ b/data/scene/newhorizons/jupiter/jupiter/jupiter.mod @@ -39,7 +39,7 @@ return { }, Projection = { --Sequence = "F:/JupiterFullSequence", - Sequence = "${OPENSPACE_DATA}/scene/newhorizons/jupiter/jupiterprojection/ProjectionsOfInterest", + Sequence = "${OPENSPACE_DATA}/scene/newhorizons/jupiter/jupiter/ProjectionsOfInterest", SequenceType = "image-sequence", Observer = "NEW HORIZONS", Target = "JUPITER", From c84972dee090f9a69e57f51ef9cb026d04931527 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 31 May 2016 18:26:20 +0200 Subject: [PATCH 13/61] Updating versioning number to prerelease-9 (IPS) --- include/openspace/openspace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/openspace/openspace.h b/include/openspace/openspace.h index c6640e989d..75fb83e1c8 100644 --- a/include/openspace/openspace.h +++ b/include/openspace/openspace.h @@ -32,10 +32,10 @@ namespace openspace { std::string licenseText(); const int OPENSPACE_VERSION_MAJOR = 0; -const int OPENSPACE_VERSION_MINOR = 3; +const int OPENSPACE_VERSION_MINOR = 4; const int OPENSPACE_VERSION_PATCH = 0; -const std::string OPENSPACE_VERSION_STRING = "prerelease-8"; +const std::string OPENSPACE_VERSION_STRING = "prerelease-9 (IPS)"; } // namespace openspace From 469358a8d6545f1228c7840fe34586b9adcd54d5 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 31 May 2016 18:34:49 +0200 Subject: [PATCH 14/61] Enable easy toggling of high v low resolution Pluto+Charon textures --- data/scene/newhorizons.scene | 1 + .../scene/newhorizons/pluto/charon/charon.mod | 13 +++++++------ data/scene/newhorizons/pluto/pluto/pluto.mod | 19 ++++++++----------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/data/scene/newhorizons.scene b/data/scene/newhorizons.scene index c4277637c3..bc0d07db16 100644 --- a/data/scene/newhorizons.scene +++ b/data/scene/newhorizons.scene @@ -1,4 +1,5 @@ UseAccurateNewHorizonsKernels = false +UseHighResolutionTextures = false function preInitialization() --[[ diff --git a/data/scene/newhorizons/pluto/charon/charon.mod b/data/scene/newhorizons/pluto/charon/charon.mod index 70ba1533aa..212760d979 100644 --- a/data/scene/newhorizons/pluto/charon/charon.mod +++ b/data/scene/newhorizons/pluto/charon/charon.mod @@ -8,6 +8,11 @@ else } end +if UseHighResolutionTextures then + ColorTexture = "textures/cpmap_cyl_HR_0e.jpg" +else + ColorTexture = "textures/charon_highres.jpg" +end return { -- CharonProjection module @@ -25,15 +30,11 @@ return { }, Textures = { Type = "simple", - Color = "textures/charon_highres.jpg", + Color = ColorTexture, + Height = "textures/cpdem-Mcolor2-MLorriCA-lr-5_ZMfs-cyl.jpg", Project = "textures/defaultProj.png", Sequencing = "true", }, - Atmosphere = { - Type = "Nishita", -- for example, values missing etc etc - MieFactor = 1.0, - MieColor = {1.0, 1.0, 1.0} - }, Projection = { Observer = "NEW HORIZONS", Target = "CHARON", diff --git a/data/scene/newhorizons/pluto/pluto/pluto.mod b/data/scene/newhorizons/pluto/pluto/pluto.mod index 735f3356aa..66d3d96c55 100644 --- a/data/scene/newhorizons/pluto/pluto/pluto.mod +++ b/data/scene/newhorizons/pluto/pluto/pluto.mod @@ -9,6 +9,12 @@ else } end +if UseHighResolutionTextures then + ColorTexture = "textures/pmap_cyl_HR_LOR_lowres.jpg" +else + ColorTexture = "textures/Shenk_180.jpg" +end + return { -- Pluto barycenter module { @@ -37,20 +43,11 @@ return { }, Textures = { Type = "simple", - -- Color = "textures/pluto_highres_180.jpg", - Color = "textures/Shenk_180.jpg", - -- Color = "textures/pluto_large.jpg", - -- Color = "textures/white.png", + Color = ColorTexture, + Height = "textures/pluto_shenk_heightmap.jpg", Project = "textures/3.jpg", - -- Height = "textures/pluto_shenk_heightmap.jpg", - -- NormalMap = "textures/pluto_shenk_normalmap.png", Sequencing = "true" }, - Atmosphere = { - Type = "Nishita", -- for example, values missing etc etc - MieFactor = 1.0, - MieColor = {1.0, 1.0, 1.0} - }, Projection = { Sequence = "${OPENSPACE_DATA}/scene/newhorizons/pluto/pluto/images", EventFile = "${OPENSPACE_DATA}/scene/newhorizons/pluto/pluto/assets/core_v9h_obs_getmets_v8_time_fix_nofrcd_mld.txt", From 8bfdf8db0dd15c0199c63651d4f3b615b5725cc2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 31 May 2016 18:35:13 +0200 Subject: [PATCH 15/61] Add more interesting times to rosetta scene files --- data/scene/rosetta.scene | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/data/scene/rosetta.scene b/data/scene/rosetta.scene index 2c3d8268b2..903362699b 100644 --- a/data/scene/rosetta.scene +++ b/data/scene/rosetta.scene @@ -6,7 +6,10 @@ function preInitialization() critical objects. ]]-- - openspace.time.setTime("2014 AUG 21 18:00:00") + openspace.time.setTime("2014-08-15T03:05:18.101") + -- openspace.time.setTime("2014-11-17T03:05:18.101") + -- openspace.time.setTime("2015-07-29T06:02:10.000") + -- openspace.time.setTime("2014 AUG 21 18:00:00") -- openspace.time.setTime("2015 SEP 10 19:39:00") dofile(openspace.absPath('${SCRIPTS}/bind_keys_rosetta.lua')) end From 0508faf7ce4860cd02ef25a0fd1e6530e39f7e6d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 1 Jun 2016 23:14:50 +0200 Subject: [PATCH 16/61] Some changes to make GUI optional --- include/openspace/engine/openspaceengine.h | 5 ++++ .../rendering/renderablemodelprojection.cpp | 1 - src/engine/openspaceengine.cpp | 27 ++++++++++++++++--- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 6aa13c20a4..ee36f2f0f8 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -83,7 +83,10 @@ public: properties::PropertyOwner& globalPropertyOwner(); WindowWrapper& windowWrapper(); ghoul::fontrendering::FontManager& fontManager(); + +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED gui::GUI& gui(); +#endif // SGCT callbacks bool initialize(); @@ -127,7 +130,9 @@ private: std::unique_ptr _commandlineParser; std::unique_ptr _console; std::unique_ptr _moduleEngine; +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED std::unique_ptr _gui; +#endif std::unique_ptr _parallelConnection; std::unique_ptr _windowWrapper; std::unique_ptr _fontManager; diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index a75d034bf5..1ebec0fd96 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -35,7 +35,6 @@ #include #include -#include "imgui.h" #define _USE_MATH_DEFINES #include diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 0cecb26abb..c48d12cae1 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -123,7 +123,9 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, )) , _console(new LuaConsole) , _moduleEngine(new ModuleEngine) +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED , _gui(new gui::GUI) +#endif , _parallelConnection(new network::ParallelConnection) , _windowWrapper(std::move(windowWrapper)) , _globalPropertyNamespace(new properties::PropertyOwner) @@ -147,7 +149,9 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, } OpenSpaceEngine::~OpenSpaceEngine() { +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED _gui->deinitializeGL(); +#endif _renderEngine->deinitialize(); _globalPropertyNamespace = nullptr; @@ -161,7 +165,9 @@ OpenSpaceEngine::~OpenSpaceEngine() { _commandlineParser = nullptr; _console = nullptr; _moduleEngine = nullptr; +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED _gui = nullptr; +#endif _syncBuffer = nullptr; } @@ -417,8 +423,10 @@ bool OpenSpaceEngine::initialize() { // Load a light and a monospaced font loadFonts(); +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED LINFO("Initializing GUI"); _gui->initialize(); +#endif #ifdef OPENSPACE_MODULE_ISWA_ENABLED IswaManager::initialize(); @@ -659,6 +667,7 @@ void OpenSpaceEngine::configureLogging() { bool OpenSpaceEngine::initializeGL() { LINFO("Initializing Rendering Engine"); bool success = _renderEngine->initializeGL(); +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED LINFO("Initializing OnScreen GUI GL"); try { _gui->initializeGL(); @@ -666,6 +675,7 @@ bool OpenSpaceEngine::initializeGL() { catch (const ghoul::RuntimeError& e) { LERROR(e.what()); } +#endif LINFO("Finished initializing OpenGL"); return success; } @@ -707,6 +717,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { _scriptEngine->postSynchronizationPreDraw(); _renderEngine->postSynchronizationPreDraw(); +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED if (_isMaster && _gui->isEnabled() && _windowWrapper->isRegularRendering()) { glm::vec2 mousePosition = _windowWrapper->mousePosition(); glm::ivec2 drawBufferResolution = _windowWrapper->currentDrawBufferResolution(); @@ -716,6 +727,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { _gui->startFrame(static_cast(dt), glm::vec2(drawBufferResolution), mousePosition, mouseButtons); } +#endif // Testing this every frame has minimal impact on the performance --- abock // Debug build: 1-2 us ; Release build: <= 1 us @@ -740,8 +752,10 @@ void OpenSpaceEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 if (_isMaster && _windowWrapper->isRegularRendering()) { if (_console->isVisible()) _console->render(); +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED if (_gui->isEnabled()) _gui->endFrame(); +#endif } } @@ -751,11 +765,13 @@ void OpenSpaceEngine::postDraw() { void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction action) { if (_isMaster) { +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED if (_gui->isEnabled()) { bool isConsumed = _gui->keyCallback(key, mod, action); if (isConsumed) return; } +#endif if (key == _console->commandInputButton() && (action == KeyAction::Press || action == KeyAction::Repeat)) _console->toggleVisibility(); @@ -771,12 +787,13 @@ void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction actio void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier) { if (_isMaster) { +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED if (_gui->isEnabled()) { const bool isConsumed = _gui->charCallback(codepoint, modifier); if (isConsumed) return; } - +#endif if (_console->isVisible()) { _console->charCallback(codepoint, modifier); } @@ -785,12 +802,13 @@ void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier) void OpenSpaceEngine::mouseButtonCallback(MouseButton button, MouseAction action) { if (_isMaster) { +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED if (_gui->isEnabled()) { const bool isConsumed = _gui->mouseButtonCallback(button, action); if (isConsumed && action != MouseAction::Release) return; } - +#endif _interactionHandler->mouseButtonCallback(button, action); } } @@ -803,12 +821,13 @@ void OpenSpaceEngine::mousePositionCallback(double x, double y) { void OpenSpaceEngine::mouseScrollWheelCallback(double pos) { if (_isMaster) { +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED if (_gui->isEnabled()) { const bool isConsumed = _gui->mouseWheelCallback(pos); if (isConsumed) return; } - +#endif _interactionHandler->mouseScrollWheelCallback(pos); } } @@ -887,10 +906,12 @@ LuaConsole& OpenSpaceEngine::console() { return *_console; } +#ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED gui::GUI& OpenSpaceEngine::gui() { ghoul_assert(_gui, "GUI must not be nullptr"); return *_gui; } +#endif network::ParallelConnection& OpenSpaceEngine::parallelConnection() { ghoul_assert(_parallelConnection, "ParallelConnection must not be nullptr"); From 03e0ac4067d82f3bd1d1f362e4e107be873e09c0 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 1 Jun 2016 23:15:25 +0200 Subject: [PATCH 17/61] Fix error with close near plane in cases of angled image planes --- shaders/PowerScaling/powerScalingMath.hglsl | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/shaders/PowerScaling/powerScalingMath.hglsl b/shaders/PowerScaling/powerScalingMath.hglsl index b14e15db60..742122a37f 100644 --- a/shaders/PowerScaling/powerScalingMath.hglsl +++ b/shaders/PowerScaling/powerScalingMath.hglsl @@ -76,15 +76,16 @@ vec2 psc_subtraction(vec2 v1, vec2 v2) { vec4 z_normalization(vec4 v_in) { vec4 v_out = v_in; - if(v_out.z > 0.0) { - v_out.z = 1; - } else if(v_out.z < 0.0) { - v_out.z = 1; - } else { - float tmp = max(max(abs(v_out.x), abs(v_out.y)),0); - if(tmp == 0.0) - v_out.s = FLT_MAX; - } + v_out.z = 0.0; + // if(v_out.z > 0.0) { + // v_out.z = 1; + // } else if(v_out.z < 0.0) { + // v_out.z = 1; + // } else { + // float tmp = max(max(abs(v_out.x), abs(v_out.y)),0); + // if(tmp == 0.0) + // v_out.s = FLT_MAX; + // } return v_out; } From de3edd5022ca53432c4565d613f9fcc5c8862fa2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 1 Jun 2016 23:15:46 +0200 Subject: [PATCH 18/61] Do not clear Framebuffer in FramebufferRenderer so that multiviewport rendering works --- src/rendering/framebufferrenderer.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index b2e6d7f809..c7c3418d43 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -293,12 +293,10 @@ void FramebufferRenderer::updateRaycastData() { } void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurements) { - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - if (_scene == nullptr) return; - if (_camera == nullptr) return; + if (!_scene) + return; + if (!_camera) + return; glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); From 1e8d329e3dd88d4fe50dbd1e9b33e147675b77f0 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 2 Jun 2016 13:12:28 +0200 Subject: [PATCH 19/61] Add a correction factor for ImGui that converts between window coordinates and fbo coordinates (closing #95) --- modules/onscreengui/include/gui.h | 2 +- modules/onscreengui/src/gui.cpp | 14 +++++++++----- src/engine/openspaceengine.cpp | 14 +++++++++++++- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/modules/onscreengui/include/gui.h b/modules/onscreengui/include/gui.h index 10b3f4452d..7bd37b0f85 100644 --- a/modules/onscreengui/include/gui.h +++ b/modules/onscreengui/include/gui.h @@ -60,7 +60,7 @@ public: // bool keyCallback(int key, int action); bool charCallback(unsigned int character, KeyModifier modifier); - void startFrame(float deltaTime, const glm::vec2& windowSize, const glm::vec2& mousePos, uint32_t mouseButtons); + void startFrame(float deltaTime, const glm::vec2& windowSize, const glm::vec2& mousePosCorrectionFactor, const glm::vec2& mousePos, uint32_t mouseButtons); void endFrame(); void renderMainWindow(); diff --git a/modules/onscreengui/src/gui.cpp b/modules/onscreengui/src/gui.cpp index a954288048..4353468086 100644 --- a/modules/onscreengui/src/gui.cpp +++ b/modules/onscreengui/src/gui.cpp @@ -273,6 +273,7 @@ void GUI::deinitializeGL() { } void GUI::startFrame(float deltaTime, const glm::vec2& windowSize, + const glm::vec2& mousePosCorrectionFactor, const glm::vec2& mousePos, uint32_t mouseButtonsPressed) { @@ -280,11 +281,14 @@ void GUI::startFrame(float deltaTime, const glm::vec2& windowSize, ImGuiIO& io = ImGui::GetIO(); io.DisplaySize = ImVec2(windowSize.x, windowSize.y); io.DeltaTime = deltaTime; -#ifdef __APPLE__ - io.MousePos = ImVec2(mousePos.x * 2, mousePos.y * 2); -#else - io.MousePos = ImVec2(mousePos.x, mousePos.y); -#endif + + io.MousePos = ImVec2(mousePos.x * mousePosCorrectionFactor.x, mousePos.y * mousePosCorrectionFactor.y); + +//#ifdef __APPLE__ +// io.MousePos = ImVec2(mousePos.x * 2, mousePos.y * 2); +//#else +// io.MousePos = ImVec2(mousePos.x, mousePos.y); +//#endif io.MouseDown[0] = mouseButtonsPressed & (1 << 0); io.MouseDown[1] = mouseButtonsPressed & (1 << 1); diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index c48d12cae1..29b1a9071c 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -721,11 +721,23 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { if (_isMaster && _gui->isEnabled() && _windowWrapper->isRegularRendering()) { glm::vec2 mousePosition = _windowWrapper->mousePosition(); glm::ivec2 drawBufferResolution = _windowWrapper->currentDrawBufferResolution(); + glm::ivec2 windowSize = _windowWrapper->currentWindowSize(); uint32_t mouseButtons = _windowWrapper->mouseButtons(2); + + glm::vec2 windowBufferCorrectionFactor = glm::vec2( + static_cast(drawBufferResolution.x) / static_cast(windowSize.x), + static_cast(drawBufferResolution.y) / static_cast(windowSize.y) + ); double dt = _windowWrapper->averageDeltaTime(); - _gui->startFrame(static_cast(dt), glm::vec2(drawBufferResolution), mousePosition, mouseButtons); + _gui->startFrame( + static_cast(dt), + glm::vec2(drawBufferResolution), + windowBufferCorrectionFactor, + mousePosition, + mouseButtons + ); } #endif From 4c679c15ea5446db30ecd39ec83cbdb859824f71 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 2 Jun 2016 13:25:05 +0200 Subject: [PATCH 20/61] Allow the disabling of ISWA components --- include/openspace/util/transformationmanager.h | 11 +++++++++-- modules/iswa/util/iswamanager.h | 2 ++ modules/onscreengui/src/guiiswacomponent.cpp | 6 +++++- src/util/transformationmanager.cpp | 4 +++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/include/openspace/util/transformationmanager.h b/include/openspace/util/transformationmanager.h index 9dd3c2f9e4..2443004852 100644 --- a/include/openspace/util/transformationmanager.h +++ b/include/openspace/util/transformationmanager.h @@ -27,11 +27,16 @@ #include #include +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED #include +#endif + +#include namespace openspace { +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED class ccmc::Kameleon; - +#endif class TransformationManager : public ghoul::Singleton { friend class ghoul::Singleton; @@ -42,7 +47,9 @@ public: glm::dmat3 frameTransformationMatrix(std::string from, std::string to, double ephemerisTime) const; private: - std::shared_ptr _kameleon; +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED + std::shared_ptr _kameleon; +#endif std::set _kameleonFrames; std::set _dipoleFrames; }; diff --git a/modules/iswa/util/iswamanager.h b/modules/iswa/util/iswamanager.h index cd862711bc..ce7e313298 100644 --- a/modules/iswa/util/iswamanager.h +++ b/modules/iswa/util/iswamanager.h @@ -31,7 +31,9 @@ #include #include #include +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED #include +#endif #include #include #include diff --git a/modules/onscreengui/src/guiiswacomponent.cpp b/modules/onscreengui/src/guiiswacomponent.cpp index 43a8dafdbf..0dfbcee8d9 100644 --- a/modules/onscreengui/src/guiiswacomponent.cpp +++ b/modules/onscreengui/src/guiiswacomponent.cpp @@ -116,6 +116,7 @@ void GuiIswaComponent::render() { } } +#ifdef OPENSPACE_MODULE_ISWA_ENABLED if(ImGui::CollapsingHeader("Cdf files")){ auto cdfInfo = IswaManager::ref().cdfInformation(); @@ -151,6 +152,7 @@ void GuiIswaComponent::render() { } } } +#endif for (const auto& p : _propertiesByOwner) { if (ImGui::CollapsingHeader(p.first.c_str())) { @@ -209,6 +211,7 @@ void GuiIswaComponent::render() { } +#ifdef OPENSPACE_MODULE_ISWA_ENABLED if (ImGui::CollapsingHeader("iSWA screen space cygntes")) { auto map = IswaManager::ref().cygnetInformation(); @@ -237,7 +240,8 @@ void GuiIswaComponent::render() { } } - +#endif + ImGui::End(); } diff --git a/src/util/transformationmanager.cpp b/src/util/transformationmanager.cpp index 6fd9207e5b..3da4d3fe06 100644 --- a/src/util/transformationmanager.cpp +++ b/src/util/transformationmanager.cpp @@ -45,13 +45,16 @@ } TransformationManager::~TransformationManager(){ +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED _kameleon = nullptr; +#endif } glm::dmat3 TransformationManager::frameTransformationMatrix(std::string from, std::string to, double ephemerisTime) const { +#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED auto fromit = _dipoleFrames.find(from); auto toit = _dipoleFrames.find(to); @@ -77,7 +80,6 @@ return SpiceManager::ref().frameTransformationMatrix(from, to, ephemerisTime); } -#ifdef OPENSPACE_MODULE_KAMELEON_ENABLED if(fromKameleon && toKameleon){ _kameleon->_cxform(from.c_str(), to.c_str(), ephemerisTime, &in0, &out0); _kameleon->_cxform(from.c_str(), to.c_str(), ephemerisTime, &in1, &out1); From 7908d8a8b0777edacc23a513c5d38e82545e8435 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 2 Jun 2016 17:38:33 +0200 Subject: [PATCH 21/61] Premultiply fieldline colors and use fully opaque transparency instead --- modules/fieldlines/shaders/fieldline_fs.glsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/fieldlines/shaders/fieldline_fs.glsl b/modules/fieldlines/shaders/fieldline_fs.glsl index 084f3bd3b6..1bbaf74cba 100644 --- a/modules/fieldlines/shaders/fieldline_fs.glsl +++ b/modules/fieldlines/shaders/fieldline_fs.glsl @@ -40,9 +40,9 @@ Fragment getFragment() float alpha = 1-length(gs_normal)*length(gs_normal); vec4 fragColor; if (classification) - fragColor = vec4(gs_color.rgb, alpha); + fragColor = vec4(gs_color.rgb * alpha, 1.0); else - fragColor = vec4(fieldLineColor.rgb, fieldLineColor.a * alpha); + fragColor = vec4(fieldLineColor.rgb * fieldLineColor.a * alpha, 1.0); float depth = pscDepth(gs_position); From 273713aaaa7ab9871474b26c56b848d3affbcb8e Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 3 Jun 2016 11:16:10 +0200 Subject: [PATCH 22/61] Started cleanup of RenderablePlanetProjection --- ext/ghoul | 2 +- .../rendering/renderableplanetprojection.cpp | 88 ++++--------------- .../rendering/renderableplanetprojection.h | 7 +- modules/newhorizons/shaders/fboPass_fs.glsl | 29 +++--- modules/newhorizons/shaders/fboPass_vs.glsl | 10 +-- .../shaders/projectiveTexture_fs.glsl | 81 +++-------------- .../shaders/projectiveTexture_vs.glsl | 24 ++--- 7 files changed, 53 insertions(+), 188 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index f3420c0b5c..8e2fe2b626 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit f3420c0b5c40cb0819e9b67a85c3ab51fce6be8f +Subproject commit 8e2fe2b62604e88356e5e41a8be3be3f5557343f diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 8b1f3c53fb..b2ee2f1207 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -88,7 +88,6 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& : Renderable(dictionary) , _colorTexturePath("planetTexture", "RGB Texture") , _heightMapTexturePath("heightMap", "Heightmap Texture") - , _normalMapTexturePath("normalMap", "Normalmap Texture") , _projectionTexturePath("projectionTexture", "RGB Texture") , _rotation("rotation", "Rotation", 0, 0, 360) //, _fadeProjection("fadeProjections", "Image Fading Factor", 0.f, 0.f, 1.f) @@ -101,21 +100,16 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& , _texture(nullptr) , _textureOriginal(nullptr) , _textureProj(nullptr) - , _textureWhiteSquare(nullptr) , _heightMapTexture(nullptr) - , _normalMapTexture(nullptr) , _geometry(nullptr) , _capture(false) , _hasHeightMap(false) - , _hasNormalMap(false) , _clearingImage(absPath("${OPENSPACE_DATA}/scene/common/textures/clear.png")) { std::string name; bool success = dictionary.getValue(SceneGraphNode::KeyName, name); ghoul_assert(success, ""); - _defaultProjImage = absPath("textures/defaultProj.png"); - ghoul::Dictionary geometryDictionary; success = dictionary.getValue( keyGeometry, geometryDictionary); @@ -180,13 +174,6 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& _hasHeightMap = true; } - std::string normalMapPath = ""; - success = dictionary.getValue("Textures.NormalMap", normalMapPath); - if (success) { - _normalMapTexturePath = absPath(normalMapPath); - _hasNormalMap = true; - } - addPropertySubOwner(_geometry); addProperty(_rotation); //addProperty(_fadeProjection); @@ -200,9 +187,6 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& addProperty(_heightMapTexturePath); _heightMapTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this)); - addProperty(_normalMapTexturePath); - _normalMapTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this)); - addProperty(_projectionTexturePath); _projectionTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadProjectionTexture, this)); @@ -296,7 +280,6 @@ bool RenderablePlanetProjection::initialize() { completeSuccess &= (_texture != nullptr); completeSuccess &= (_textureOriginal != nullptr); completeSuccess &= (_textureProj != nullptr); - completeSuccess &= (_textureWhiteSquare != nullptr); completeSuccess &= _geometry->initialize(this); @@ -308,7 +291,8 @@ bool RenderablePlanetProjection::initialize() { bool RenderablePlanetProjection::auxiliaryRendertarget() { bool completeSuccess = true; - if (!_texture) return false; + if (!_texture) + return false; GLint defaultFBO; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); @@ -355,7 +339,6 @@ bool RenderablePlanetProjection::deinitialize() { _texture = nullptr; _textureProj = nullptr; _textureOriginal = nullptr; - _textureWhiteSquare = nullptr; delete _geometry; _geometry = nullptr; @@ -368,7 +351,7 @@ bool RenderablePlanetProjection::deinitialize() { return true; } bool RenderablePlanetProjection::isReady() const { - return _geometry && _programObject && _texture && _textureWhiteSquare; + return _geometry && _programObject && _texture; } void RenderablePlanetProjection::imageProjectGPU() { @@ -393,13 +376,12 @@ void RenderablePlanetProjection::imageProjectGPU() { ghoul::opengl::TextureUnit unitFbo; unitFbo.activate(); _textureProj->bind(); - _fboProgramObject->setUniform("texture1" , unitFbo); + _fboProgramObject->setUniform("projectionTexture", unitFbo); ghoul::opengl::TextureUnit unitFbo2; unitFbo2.activate(); _textureOriginal->bind(); - _fboProgramObject->setUniform("texture2", unitFbo2); - //_fboProgramObject->setUniform("projectionFading", _fadeProjection); + _fboProgramObject->setUniform("baseTexture", unitFbo2); _fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix); _fboProgramObject->setUniform("ModelTransform" , _transform); @@ -498,32 +480,7 @@ void RenderablePlanetProjection::attitudeParameters(double time) { _projectorMatrix = computeProjectorMatrix(cpos, bs, _up); } - -void RenderablePlanetProjection::textureBind() { - ghoul::opengl::TextureUnit unit[4]; - unit[0].activate(); - _texture->bind(); - _programObject->setUniform("texture1", unit[0]); - unit[1].activate(); - _textureWhiteSquare->bind(); - _programObject->setUniform("texture2", unit[1]); - - if (_hasHeightMap) { - unit[2].activate(); - _heightMapTexture->bind(); - _programObject->setUniform("heightTex", unit[2]); - } - - if (_hasNormalMap) { - unit[3].activate(); - _normalMapTexture->bind(); - _programObject->setUniform("normalTex", unit[3]); - } - - -} - -void RenderablePlanetProjection::project(){ +void RenderablePlanetProjection::project() { // If high dt -> results in GPU queue overflow // switching to using a simple queue to distribute // images 1 image / frame -> projections appear slower @@ -591,18 +548,24 @@ void RenderablePlanetProjection::render(const RenderData& data) { _programObject->activate(); // setup the data to the shader _programObject->setUniform("sun_pos", sun_pos.vec3()); - _programObject->setUniform("ProjectorMatrix", _projectorMatrix); _programObject->setUniform("ViewProjection" , data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform" , _transform); - _programObject->setUniform("boresight" , _boresight); _programObject->setUniform("_hasHeightMap", _hasHeightMap); _programObject->setUniform("_heightExaggeration", _heightExaggeration); - _programObject->setUniform("_enableNormalMapping", _enableNormalMapping && _hasNormalMap); setPscUniforms(*_programObject.get(), data.camera, data.position); - textureBind(); + ghoul::opengl::TextureUnit unit[2]; + unit[0].activate(); + _texture->bind(); + _programObject->setUniform("baseTexture", unit[0]); + + if (_hasHeightMap) { + unit[1].activate(); + _heightMapTexture->bind(); + _programObject->setUniform("heightTexture", unit[1]); + } // render geometry _geometry->render(); @@ -679,14 +642,6 @@ void RenderablePlanetProjection::loadTexture() { _textureOriginal->setFilter(Texture::FilterMode::Linear); } } - _textureWhiteSquare = nullptr; - if (_colorTexturePath.value() != "") { - _textureWhiteSquare = ghoul::io::TextureReader::ref().loadTexture(_defaultProjImage); - if (_textureWhiteSquare) { - _textureWhiteSquare->uploadTexture(); - _textureWhiteSquare->setFilter(Texture::FilterMode::Linear); - } - } _heightMapTexture = nullptr; if (_heightMapTexturePath.value() != "") { @@ -697,15 +652,6 @@ void RenderablePlanetProjection::loadTexture() { _heightMapTexture->setFilter(Texture::FilterMode::Linear); } } - - _normalMapTexture = nullptr; - if (_normalMapTexturePath.value() != "") { - _normalMapTexture = ghoul::io::TextureReader::ref().loadTexture(_normalMapTexturePath); - if (_normalMapTexture) { - _normalMapTexture->uploadTexture(); - _normalMapTexture->setFilter(Texture::FilterMode::Linear); - } - } - } + } // namespace openspace diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index 941664d9bb..94762f86b2 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -80,9 +80,9 @@ protected: glm::mat4 computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up); void attitudeParameters(double time); - void textureBind(); void project(); void clearAllProjections(); + private: void imageProjectGPU(); @@ -90,7 +90,6 @@ private: properties::StringProperty _colorTexturePath; properties::StringProperty _heightMapTexturePath; - properties::StringProperty _normalMapTexturePath; properties::StringProperty _projectionTexturePath; properties::IntProperty _rotation; @@ -104,9 +103,7 @@ private: std::unique_ptr _texture; std::unique_ptr _textureOriginal; std::unique_ptr _textureProj; - std::unique_ptr _textureWhiteSquare; std::unique_ptr _heightMapTexture; - std::unique_ptr _normalMapTexture; properties::FloatProperty _heightExaggeration; properties::BoolProperty _enableNormalMapping; @@ -150,7 +147,6 @@ private: std::string _target; std::string _frame; - std::string _defaultProjImage; std::string _clearingImage; std::string _next; @@ -162,7 +158,6 @@ private: GLuint _vertexPositionBuffer; bool _hasHeightMap; - bool _hasNormalMap; std::queue imageQueue; }; diff --git a/modules/newhorizons/shaders/fboPass_fs.glsl b/modules/newhorizons/shaders/fboPass_fs.glsl index 8c2ba35b04..6f673c134a 100644 --- a/modules/newhorizons/shaders/fboPass_fs.glsl +++ b/modules/newhorizons/shaders/fboPass_fs.glsl @@ -24,22 +24,23 @@ #version __CONTEXT__ -uniform sampler2D texture1; -uniform sampler2D texture2; +#include "PowerScaling/powerScaling_vs.hglsl" + +in vec4 vs_position; +out vec4 color; + +uniform sampler2D projectionTexture; +uniform sampler2D baseTexture; + uniform mat4 ProjectorMatrix; uniform mat4 ModelTransform; + uniform vec2 _scaling; uniform vec4 _radius; uniform int _segments; -uniform float projectionFading; - -in vec4 vs_position; - uniform vec3 boresight; -out vec4 color; - #define M_PI 3.14159265358979323846 vec4 uvToModel(vec2 uv, vec4 radius, float segments){ @@ -58,8 +59,6 @@ vec4 uvToModel(vec2 uv, vec4 radius, float segments){ return vec4(0.0); } -#include "PowerScaling/powerScaling_vs.hglsl" - bool inRange(float x, float a, float b){ return (x >= a && x <= b); } @@ -85,11 +84,9 @@ void main() { { // The 1-x is in this texture call because of flipped textures // to be fixed soon ---abock - color = texture(texture1, vec2(projected.x, 1-projected.y)); - }else{ - color = texture(texture2, uv); - color.a = projectionFading; + color = texture(projectionTexture, vec2(projected.x, 1-projected.y)); + } else { + color = texture(baseTexture, uv); + color.a = 0.0; } - - // color.a = 0.1f;//1.f - abs(uv.x - 0.55) / (0.6 - 0.5); // blending } \ No newline at end of file diff --git a/modules/newhorizons/shaders/fboPass_vs.glsl b/modules/newhorizons/shaders/fboPass_vs.glsl index c75d6ac106..6db9f30f55 100644 --- a/modules/newhorizons/shaders/fboPass_vs.glsl +++ b/modules/newhorizons/shaders/fboPass_vs.glsl @@ -24,21 +24,13 @@ #version __CONTEXT__ -uniform mat4 ProjectorMatrix; -uniform mat4 ModelTransform; -uniform vec2 _scaling; +#include "PowerScaling/powerScaling_vs.hglsl" layout(location = 0) in vec4 in_position; -uniform vec3 boresight; -uniform vec2 radius; - out vec4 vs_position; -#include "PowerScaling/powerScaling_vs.hglsl" - void main() { vs_position = in_position; gl_Position = vec4(in_position.xy, 0.0, 1.0); - } diff --git a/modules/newhorizons/shaders/projectiveTexture_fs.glsl b/modules/newhorizons/shaders/projectiveTexture_fs.glsl index 8a5613a1dc..221c59b171 100644 --- a/modules/newhorizons/shaders/projectiveTexture_fs.glsl +++ b/modules/newhorizons/shaders/projectiveTexture_fs.glsl @@ -22,95 +22,42 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -uniform vec4 campos; -uniform vec4 objpos; -//uniform vec3 camdir; // add this for specular - - -uniform float time; -uniform sampler2D texture1; -uniform sampler2D texture2; -uniform sampler2D heightTex; -uniform sampler2D normalTex; - -uniform bool _enableNormalMapping; - -in vec2 vs_st; -in vec4 vs_normal; -in vec4 vs_position; - -in vec4 ProjTexCoord; - -uniform vec3 boresight; -uniform vec3 sun_pos; - #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" +in vec4 vs_position; +in vec2 vs_st; +in vec4 vs_normal; +in vec4 ProjTexCoord; + +uniform sampler2D baseTexture; + +uniform vec4 objpos; +uniform vec3 sun_pos; + Fragment getFragment() { vec4 position = vs_position; float depth = pscDepth(position); - vec4 diffuse = texture(texture1, vs_st); - // vec4 diffuse = texture(heightTex, vs_st); // directional lighting vec3 origin = vec3(0.0); vec4 spec = vec4(0.0); - // vec3 n = normalize(texture(normalTex, vs_st).xyz); - vec3 n = normalize(vs_normal.xyz); - // n = vec3(0); - // vec3 n = vec3(0); - if (_enableNormalMapping) { - n = n + normalize(texture(normalTex, vs_st).xyz); - } - //vec3 e = normalize(camdir); vec3 l_pos = sun_pos; // sun. vec3 l_dir = normalize(l_pos-objpos.xyz); - float terminatorBright = 0.4; - float intensity = min(max(5*dot(n,l_dir), terminatorBright), 1); + float terminatorBrightness = 0.4; + float intensity = min(max(5*dot(n,l_dir), terminatorBrightness), 1); float shine = 0.0001; vec4 specular = vec4(0.1); vec4 ambient = vec4(0.f,0.f,0.f,1); - /* Specular - if(intensity > 0.f){ - // halfway vector - vec3 h = normalize(l_dir + e); - // specular factor - float intSpec = max(dot(h,n),0.0); - spec = specular * pow(intSpec, shine); - } - */ - //diffuse = max(intensity * diffuse, ambient); - - // PROJECTIVE TEXTURE - vec4 projTexColor = textureProj(texture2, ProjTexCoord); - vec4 shaded = max(intensity * diffuse, ambient); - if (ProjTexCoord[0] > 0.0 || - ProjTexCoord[1] > 0.0 || - ProjTexCoord[0] < ProjTexCoord[2] || - ProjTexCoord[1] < ProjTexCoord[2]){ - diffuse = shaded; - } else if (dot(n,boresight) < 0 && - (projTexColor.w != 0)) {// frontfacing - diffuse = projTexColor;//*0.5f + 0.5f*shaded; - } else { - diffuse = shaded; - } Fragment frag; - frag.color = diffuse; -// frag.color = vec4(normalize(vs_position.xyz), 1.0); - - // frag.color = vec4(vec3(texture(heightTex, vs_st).r), 1.0); - // frag.color = texture(heightTex, vs_st); -// frag.color = vec4(n, 1.0); - // frag.color = test; + frag.color = max(intensity * texture(baseTexture, vs_st), ambient); frag.depth = depth; - //frag.color = vec4(vs_st, 0.0, 1.0); + return frag; } diff --git a/modules/newhorizons/shaders/projectiveTexture_vs.glsl b/modules/newhorizons/shaders/projectiveTexture_vs.glsl index 67075f0830..9a73ade8ee 100644 --- a/modules/newhorizons/shaders/projectiveTexture_vs.glsl +++ b/modules/newhorizons/shaders/projectiveTexture_vs.glsl @@ -27,37 +27,25 @@ #include "PowerScaling/powerScaling_vs.hglsl" layout(location = 0) in vec4 in_position; -//in vec3 in_position; layout(location = 1) in vec2 in_st; layout(location = 2) in vec3 in_normal; -uniform vec3 boresight; - +out vec4 vs_position; out vec2 vs_st; out vec4 vs_normal; -out vec4 vs_position; -out float s; out vec4 ProjTexCoord; -uniform mat4 ViewProjection; uniform mat4 ModelTransform; - -//texture projection matrix - +uniform mat4 ViewProjection; uniform mat4 ProjectorMatrix; uniform bool _hasHeightMap; uniform float _heightExaggeration; -uniform sampler2D heightTex; - +uniform sampler2D heightTexture; void main() { - // Radius = 0.71492 *10^8; - // set variables vs_st = in_st; - //vs_stp = in_position.xyz; - // vs_position = in_position; - vec4 tmp = in_position; + vec4 tmp = in_position; // this is wrong for the normal. // The normal transform is the transposed inverse of the model transform @@ -65,8 +53,7 @@ void main() { if (_hasHeightMap) { - float height = texture(heightTex, in_st).r; - // float height = 0.00005; + float height = texture(heightTexture, in_st).r; vec3 displacementDirection = (normalize(tmp.xyz)); float displacementFactor = height * _heightExaggeration / 750.0; tmp.xyz = tmp.xyz + displacementDirection * displacementFactor; @@ -78,6 +65,7 @@ void main() { vec4 raw_pos = psc_to_meter(tmp, scaling); ProjTexCoord = ProjectorMatrix * ModelTransform * raw_pos; + position = ViewProjection * position; gl_Position = z_normalization(position); From 1901166640eaab14f9a5784d95b982ede02c9045 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Fri, 3 Jun 2016 11:16:57 +0200 Subject: [PATCH 23/61] improved galaxy rendering --- apps/DataConverter/CMakeLists.txt | 6 +- apps/DataConverter/main.cpp | 10 +- .../milkywaypointsconversiontask.cpp | 62 ++++ .../milkywaypointsconversiontask.h | 35 +++ data/scene/enlilnh/enlilnh.mod | 1 + data/scene/milkyway/milkyway.mod | 2 +- include/openspace/rendering/abufferrenderer.h | 12 + include/openspace/rendering/renderable.h | 1 + include/openspace/rendering/renderengine.h | 34 ++- include/openspace/rendering/renderer.h | 12 + include/openspace/rendering/volumeraycaster.h | 5 + include/openspace/scene/scene.h | 5 + include/openspace/scene/scenegraphnode.h | 1 + modules/base/shaders/sphere_vs.glsl | 2 +- modules/galaxy/rendering/galaxyraycaster.cpp | 31 ++ modules/galaxy/rendering/galaxyraycaster.h | 4 + modules/galaxy/rendering/renderablegalaxy.cpp | 152 +++++++--- modules/galaxy/rendering/renderablegalaxy.h | 10 +- modules/galaxy/shaders/galaxyraycast.glsl | 17 +- modules/galaxy/shaders/points.fs | 14 +- modules/galaxy/shaders/points.vs | 9 +- modules/galaxy/shaders/raycasterbounds.vs | 13 +- .../rendering/multiresvolumeraycaster.cpp | 27 ++ .../rendering/multiresvolumeraycaster.h | 1 + .../rendering/renderablemultiresvolume.cpp | 16 +- .../rendering/renderablemultiresvolume.h | 4 + modules/multiresvolume/shaders/boundsVs.glsl | 14 +- modules/multiresvolume/shaders/raycast.glsl | 25 +- shaders/PowerScaling/powerScalingMath.hglsl | 10 +- shaders/PowerScaling/powerScaling_fs.hglsl | 6 +- shaders/abuffer/abufferresources.glsl | 21 ++ shaders/abuffer/boundsabuffer.frag | 5 + shaders/abuffer/postrenderabuffer.frag | 135 +++++++++ shaders/abuffer/raycasterdata.glsl | 4 +- shaders/abuffer/renderabuffer.frag | 11 +- shaders/abuffer/resolveabuffer.frag | 280 ++++-------------- shaders/abuffer/resolveconstants.glsl | 7 + shaders/abuffer/resolvehelpers.glsl | 260 ++++++++++++++++ .../framebuffer/postrenderframebuffer.frag | 34 +++ shaders/framebuffer/raycastframebuffer.frag | 15 +- shaders/postRender.frag | 2 + src/rendering/abufferrenderer.cpp | 114 ++++--- src/rendering/framebufferrenderer.cpp | 4 +- src/rendering/renderable.cpp | 4 + src/rendering/renderengine.cpp | 54 +++- src/scene/scene.cpp | 6 + src/scene/scenegraphnode.cpp | 12 + 47 files changed, 1156 insertions(+), 353 deletions(-) create mode 100644 apps/DataConverter/milkywaypointsconversiontask.cpp create mode 100644 apps/DataConverter/milkywaypointsconversiontask.h create mode 100644 shaders/abuffer/postrenderabuffer.frag create mode 100644 shaders/abuffer/resolveconstants.glsl create mode 100644 shaders/abuffer/resolvehelpers.glsl create mode 100644 shaders/framebuffer/postrenderframebuffer.frag create mode 100644 shaders/postRender.frag diff --git a/apps/DataConverter/CMakeLists.txt b/apps/DataConverter/CMakeLists.txt index 54ebfe6ac3..24bfdc7968 100644 --- a/apps/DataConverter/CMakeLists.txt +++ b/apps/DataConverter/CMakeLists.txt @@ -31,11 +31,13 @@ set(application_path ${OPENSPACE_APPS_DIR}/DataConverter) set(SOURCE_FILES ${application_path}/main.cpp - ${application_path}/milkywayconversiontask.cpp + ${application_path}/milkywayconversiontask.cpp + ${application_path}/milkywaypointsconversiontask.cpp ) set(HEADER_FILES ${application_path}/conversiontask.h - ${application_path}/milkywayconversiontask.h + ${application_path}/milkywayconversiontask.h + ${application_path}/milkywaypointsconversiontask.h ) add_executable(${APPLICATION_NAME} MACOSX_BUNDLE diff --git a/apps/DataConverter/main.cpp b/apps/DataConverter/main.cpp index 9f4cdb418d..d0f8579a0a 100644 --- a/apps/DataConverter/main.cpp +++ b/apps/DataConverter/main.cpp @@ -36,6 +36,7 @@ #include #include +#include int main(int argc, char** argv) { using namespace openspace; @@ -61,14 +62,19 @@ int main(int argc, char** argv) { // or at the very least: a command line interface. MilkyWayConversionTask mwConversionTask( - "F:/milky-way/cam2_main.", + "F:/mw_june2016/volumeslices/img/comp/v003/frames/primary/0100/cam2_main.", ".exr", 1385, 512, - "F:/milky-way/mw_512_512_64.rawvolume", + "F:/mw_june2016/mw_512_512_64_june.rawvolume", glm::vec3(512, 512, 64)); + //MilkyWayPointsConversionTask mwpConversionTask("F:/mw_june2016/points.off", "F:/mw_june2016/points.off.binary"); + + mwConversionTask.perform(onProgress); + //mwpConversionTask.perform(onProgress); + std::cout << "Done." << std::endl; diff --git a/apps/DataConverter/milkywaypointsconversiontask.cpp b/apps/DataConverter/milkywaypointsconversiontask.cpp new file mode 100644 index 0000000000..0287bbf80b --- /dev/null +++ b/apps/DataConverter/milkywaypointsconversiontask.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include + +namespace openspace { +namespace dataconverter { + + + +MilkyWayPointsConversionTask::MilkyWayPointsConversionTask( + const std::string& inFilename, + const std::string& outFilename) + : _inFilename(inFilename) + , _outFilename(outFilename) {} + + +void MilkyWayPointsConversionTask::perform(const std::function& onProgress) { + std::ifstream in(_inFilename, std::ios::in); + std::ofstream out(_outFilename, std::ios::out | std::ios::binary); + + std::string format; + int64_t nPoints; + in >> format >> nPoints; + + + + size_t nFloats = nPoints * 7; + + float* pointData = new float[nFloats]; + + float x, y, z, r, g, b, a; + for (size_t i = 0; i < nPoints; ++i) { + in >> x >> y >> z >> r >> g >> b >> a; + if (in.good()) { + pointData[i * 7 + 0] = x; + pointData[i * 7 + 1] = y; + pointData[i * 7 + 2] = z; + pointData[i * 7 + 3] = r; + pointData[i * 7 + 4] = g; + pointData[i * 7 + 5] = b; + pointData[i * 7 + 6] = a; + onProgress(static_cast(i + 1) / nPoints); + } else { + std::cout << "Failed to convert point data."; + return; + } + } + + out.write(reinterpret_cast(&nPoints), sizeof(int64_t)); + out.write(reinterpret_cast(pointData), nFloats * sizeof(float)); + + in.close(); + out.close(); +} + + + +} +} diff --git a/apps/DataConverter/milkywaypointsconversiontask.h b/apps/DataConverter/milkywaypointsconversiontask.h new file mode 100644 index 0000000000..3b5e8abb15 --- /dev/null +++ b/apps/DataConverter/milkywaypointsconversiontask.h @@ -0,0 +1,35 @@ +#ifndef __MILKYWAYPOINTSCONVERSIONTASK_H__ +#define __MILKYWAYPOINTSCONVERSIONTASK_H__ + +#include +#include +#include +#include +#include +#include + + +namespace openspace { +namespace dataconverter { + +/** + * Converts ascii based point data + * int64_t n + * (float x, float y, float z, float r, float g, float b) * n + * to a binary (floating point) representation with the same layout. + */ +class MilkyWayPointsConversionTask : public ConversionTask { +public: + MilkyWayPointsConversionTask(const std::string& inFilename, + const std::string& outFilename); + + void perform(const std::function& onProgress) override; +private: + std::string _inFilename; + std::string _outFilename; +}; + +} +} + +#endif diff --git a/data/scene/enlilnh/enlilnh.mod b/data/scene/enlilnh/enlilnh.mod index 497a9d4439..d6e31699be 100644 --- a/data/scene/enlilnh/enlilnh.mod +++ b/data/scene/enlilnh/enlilnh.mod @@ -14,6 +14,7 @@ return { Scaling = {1.1, 1.1, 1.1}, ScalingExponent = 12, Source = "tsp/enlil_nh_128_128_16.tsp", + ErrorHistogramsSource = "tsp/enlil_nh_128_128_16.errorHistograms", TransferFunction = "transferfunctions/fire.txt", BrickSelector = "tf", }, diff --git a/data/scene/milkyway/milkyway.mod b/data/scene/milkyway/milkyway.mod index 99ac4f1a89..b616119cf9 100644 --- a/data/scene/milkyway/milkyway.mod +++ b/data/scene/milkyway/milkyway.mod @@ -7,7 +7,7 @@ return { }, Renderable = { Type = "RenderableSphere", - Size = {10, 20}, + Size = {10, 30}, Segments = 40, Texture = "textures/DarkUniverse_mellinger_8k.jpg", Orientation = "Inside/Outside" diff --git a/include/openspace/rendering/abufferrenderer.h b/include/openspace/rendering/abufferrenderer.h index 6f32ccd591..d6af2088d1 100644 --- a/include/openspace/rendering/abufferrenderer.h +++ b/include/openspace/rendering/abufferrenderer.h @@ -35,6 +35,7 @@ #include +#include #include #include #include @@ -69,6 +70,9 @@ public: void setScene(Scene* scene) override; void setResolution(glm::ivec2 res) override; + void preRaycast(ghoul::opengl::ProgramObject& programObject); + void postRaycast(ghoul::opengl::ProgramObject& programObject); + void update(); void render(float blackoutFactor, bool doPerformanceMeasurements) override; @@ -112,6 +116,9 @@ private: GLuint _mainColorTexture; GLuint _mainDepthTexture; + std::unique_ptr _mainColorTextureUnit; + std::unique_ptr _mainDepthTextureUnit; + GLuint _mainFramebuffer; GLuint _screenQuad; GLuint _anchorPointerTexture; @@ -122,6 +129,11 @@ private: GLuint _vertexPositionBuffer; int _nAaSamples; + + std::unique_ptr _rendererTasks; + std::unique_ptr _renderData; + float _blackoutFactor; + ghoul::Dictionary _rendererData; }; // ABufferRenderer } // openspace diff --git a/include/openspace/rendering/renderable.h b/include/openspace/rendering/renderable.h index 7193f8e1e7..0e701ac610 100644 --- a/include/openspace/rendering/renderable.h +++ b/include/openspace/rendering/renderable.h @@ -68,6 +68,7 @@ public: virtual void render(const RenderData& data); virtual void render(const RenderData& data, RendererTasks& rendererTask); + virtual void postRender(const RenderData& data); virtual void update(const UpdateData& data); bool isVisible() const; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 27f0acc6b4..7c4f1a48ab 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -60,6 +60,12 @@ public: Invalid }; + enum class RenderProgramType { + Default = 0, + Post + }; + + static const std::string PerformanceMeasurementSharedData; static const std::string KeyFontMono; @@ -104,24 +110,43 @@ public: std::string name, std::string vsPath, std::string fsPath, - const ghoul::Dictionary& dictionary = ghoul::Dictionary()); + const ghoul::Dictionary& dictionary = ghoul::Dictionary(), + RenderEngine::RenderProgramType type = RenderEngine::RenderProgramType::Default); std::unique_ptr buildRenderProgram( std::string name, std::string vsPath, std::string fsPath, std::string csPath, - const ghoul::Dictionary& dictionary = ghoul::Dictionary()); + const ghoul::Dictionary& dictionary = ghoul::Dictionary(), + RenderEngine::RenderProgramType type = RenderEngine::RenderProgramType::Default); void removeRenderProgram(const std::unique_ptr& program); + /** + * Set raycasting uniforms on the program object, and setup raycasting. + */ + void preRaycast(ghoul::opengl::ProgramObject& programObject); + + /** + * Tear down raycasting for the specified program object. + */ + void postRaycast(ghoul::opengl::ProgramObject& programObject); + + void setRendererFromString(const std::string& method); /** - * Let's the renderer update the data to be brought into the rendererer programs + * Lets the renderer update the data to be brought into the rendererer programs * as a 'rendererData' variable in the dictionary. */ - void setRendererData(const ghoul::Dictionary& renderer); + void setRendererData(const ghoul::Dictionary& rendererData); + + /** + * Lets the renderer update the data to be brought into the post rendererer programs + * as a 'resolveData' variable in the dictionary. + */ + void setResolveData(const ghoul::Dictionary& resolveData); /** * Returns the Lua library that contains all Lua functions available to affect the @@ -156,6 +181,7 @@ private: std::unique_ptr _renderer; RendererImplementation _rendererImplementation; ghoul::Dictionary _rendererData; + ghoul::Dictionary _resolveData; ScreenLog* _log; bool _showInfo; diff --git a/include/openspace/rendering/renderer.h b/include/openspace/rendering/renderer.h index 0a3113a3b1..5835b4f8b8 100644 --- a/include/openspace/rendering/renderer.h +++ b/include/openspace/rendering/renderer.h @@ -59,6 +59,18 @@ public: virtual void setScene(Scene* scene) = 0; virtual void setResolution(glm::ivec2 res) = 0; + + /** + * Set raycasting uniforms on the program object, and setup raycasting. + */ + virtual void preRaycast(ghoul::opengl::ProgramObject& programObject) {}; + + /** + * Tear down raycasting for the specified program object. + */ + virtual void postRaycast(ghoul::opengl::ProgramObject& programObject) {}; + + virtual void update() = 0; virtual void render(float blackoutFactor, bool doPerformanceMeasurements) = 0; /** diff --git a/include/openspace/rendering/volumeraycaster.h b/include/openspace/rendering/volumeraycaster.h index 5dfb480df8..dc4bbcee57 100644 --- a/include/openspace/rendering/volumeraycaster.h +++ b/include/openspace/rendering/volumeraycaster.h @@ -70,6 +70,11 @@ public: */ virtual void postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) {}; + /** + * Return true if the camera is inside the volume. + * Also set localPosition to the camera position in the volume's local coordainte system. + */ + virtual bool cameraIsInside(const RenderData& data, glm::vec3& localPosition) { return false; }; /** * Return a path the file to use as vertex shader * diff --git a/include/openspace/scene/scene.h b/include/openspace/scene/scene.h index ae5efd1511..b9a6245b47 100644 --- a/include/openspace/scene/scene.h +++ b/include/openspace/scene/scene.h @@ -84,6 +84,11 @@ public: */ void render(const RenderData& data, RendererTasks& tasks); + /* + * Post-Render visible SceneGraphNodes using the provided camera + */ + void postRender(const RenderData& data); + /* * Returns the root SceneGraphNode */ diff --git a/include/openspace/scene/scenegraphnode.h b/include/openspace/scene/scenegraphnode.h index bb577fdd99..687c68ebad 100644 --- a/include/openspace/scene/scenegraphnode.h +++ b/include/openspace/scene/scenegraphnode.h @@ -67,6 +67,7 @@ public: void update(const UpdateData& data); void evaluate(const Camera* camera, const psc& parentPosition = psc()); void render(const RenderData& data, RendererTasks& tasks); + void postRender(const RenderData& data); void updateCamera(Camera* camera) const; //void addNode(SceneGraphNode* child); diff --git a/modules/base/shaders/sphere_vs.glsl b/modules/base/shaders/sphere_vs.glsl index 11c4f4c2db..7c64455d68 100644 --- a/modules/base/shaders/sphere_vs.glsl +++ b/modules/base/shaders/sphere_vs.glsl @@ -49,7 +49,7 @@ void main() vec4 position = pscTransform(tmp, mt); - vs_position = in_position; + vs_position = tmp; vs_st = in_st; position = ViewProjection * position; diff --git a/modules/galaxy/rendering/galaxyraycaster.cpp b/modules/galaxy/rendering/galaxyraycaster.cpp index 60eef87721..91a6689f35 100644 --- a/modules/galaxy/rendering/galaxyraycaster.cpp +++ b/modules/galaxy/rendering/galaxyraycaster.cpp @@ -96,9 +96,11 @@ void GalaxyRaycaster::preRaycast(const RaycastData& data, ghoul::opengl::Program std::string stepSizeUniformName = "maxStepSize" + std::to_string(data.id); std::string galaxyTextureUniformName = "galaxyTexture" + std::to_string(data.id); std::string volumeAspectUniformName = "aspect" + std::to_string(data.id); + std::string opacityCoefficientUniformName = "opacityCoefficient" + std::to_string(data.id); program.setUniform(volumeAspectUniformName, _aspect); program.setUniform(stepSizeUniformName, _stepSize); + program.setUniform(opacityCoefficientUniformName, _opacityCoefficient); _textureUnit = std::make_unique(); _textureUnit->activate(); @@ -110,7 +112,32 @@ void GalaxyRaycaster::preRaycast(const RaycastData& data, ghoul::opengl::Program void GalaxyRaycaster::postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) { _textureUnit = nullptr; // release texture unit. } + +bool GalaxyRaycaster::cameraIsInside(const RenderData& data, glm::vec3& localPosition) { + // Camera rig position in world coordinates. + glm::vec4 rigWorldPos = glm::vec4(data.camera.position().vec3(), 1.0); + //rigWorldPos /= data.camera.scaling().x * pow(10.0, data.camera.scaling().y); + //glm::mat4 invSgctMatrix = glm::inverse(data.camera.viewMatrix()); + + // Camera position in world coordinates. + glm::vec4 camWorldPos = rigWorldPos; + glm::vec3 objPos = data.position.vec3(); + + glm::mat4 modelTransform = glm::translate(_modelTransform, objPos); + + float divisor = 1.0; + for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { + if (abs(modelTransform[i][j] > divisor)) divisor = modelTransform[i][j]; + } + + glm::mat4 scaledModelTransform = modelTransform / divisor; + + glm::vec4 modelPos = (glm::inverse(scaledModelTransform) / divisor) * camWorldPos; + localPosition = (modelPos.xyz() + glm::vec3(0.5)); + return (localPosition.x > 0 && localPosition.y > 0 && localPosition.z > 0 && localPosition.x < 1 && localPosition.y < 1 && localPosition.z < 1); +} + std::string GalaxyRaycaster::getBoundsVsPath() const { return GlslBoundsVsPath; } @@ -135,6 +162,10 @@ void GalaxyRaycaster::setModelTransform(glm::mat4 transform) { _modelTransform = transform; } +void GalaxyRaycaster::setOpacityCoefficient(float opacityCoefficient) { + _opacityCoefficient = opacityCoefficient; +} + void GalaxyRaycaster::setTime(double time) { _time = time; } diff --git a/modules/galaxy/rendering/galaxyraycaster.h b/modules/galaxy/rendering/galaxyraycaster.h index 5d93e7d028..34720a0868 100644 --- a/modules/galaxy/rendering/galaxyraycaster.h +++ b/modules/galaxy/rendering/galaxyraycaster.h @@ -57,6 +57,8 @@ public: void renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override; void preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override; void postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override; + bool cameraIsInside(const RenderData& data, glm::vec3& localPosition) override; + std::string getBoundsVsPath() const override; std::string getBoundsFsPath() const override; @@ -67,12 +69,14 @@ public: void setModelTransform(glm::mat4 transform); void setTime(double time); void setStepSize(float stepSize); + void setOpacityCoefficient(float opacityCoefficient); private: BoxGeometry _boundingBox; float _stepSize; glm::mat4 _modelTransform; glm::vec3 _aspect; double _time; + float _opacityCoefficient; ghoul::opengl::Texture& _texture; std::unique_ptr _textureUnit; diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index d57b840fde..e1d1bbbd58 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -54,23 +55,16 @@ namespace openspace { RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) : Renderable(dictionary) - , _scalingExponent("scalingExponent", "Scaling Exponent", 1, -10, 20) , _stepSize("stepSize", "Step Size", 0.001, 0.0005, 0.05) - , _scaling("scaling", "Scaling", glm::vec3(1.0, 1.0, 1.0), glm::vec3(0.0), glm::vec3(10.0)) + , _pointStepSize("pointStepSize", "Point Step Size", 0.01, 0.01, 0.1) , _translation("translation", "Translation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0), glm::vec3(10.0)) , _rotation("rotation", "Euler rotation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0), glm::vec3(6.28)) { - float scalingExponent, stepSize; + float stepSize; glm::vec3 scaling, translation, rotation; glm::vec4 color; ghoul::Dictionary volumeDictionary, pointsDictionary; - if (dictionary.getValue("ScalingExponent", scalingExponent)) { - _scalingExponent = scalingExponent; - } - if (dictionary.getValue("Scaling", scaling)) { - _scaling = scaling; - } if (dictionary.getValue("Translation", translation)) { _translation = translation; } @@ -93,6 +87,14 @@ namespace openspace { } else { LERROR("No volume dimensions specified."); } + glm::vec3 volumeSize; + if (volumeDictionary.getValue("Size", volumeSize)) { + _volumeSize = static_cast(volumeSize); + } + else { + LERROR("No volume dimensions specified."); + } + } else { LERROR("No volume dictionary specified."); } @@ -103,6 +105,13 @@ namespace openspace { } else { LERROR("No points filename specified."); } + glm::vec3 pointsScaling; + if (pointsDictionary.getValue("Scaling", pointsScaling)) { + _pointScaling = static_cast(pointsScaling); + } + else { + LERROR("No volume dimensions specified."); + } } else { LERROR("No points dictionary specified."); } @@ -147,37 +156,51 @@ bool RenderableGalaxy::initialize() { onEnabledChange(onChange); - addProperty(_scaling); - addProperty(_scalingExponent); addProperty(_stepSize); + addProperty(_pointStepSize); addProperty(_translation); addProperty(_rotation); // initialize points. - std::ifstream pointFile(_pointsFilename, std::ios::in); + std::ifstream pointFile(_pointsFilename, std::ios::in | std::ios::binary); std::vector pointPositions; std::vector pointColors; - std::string format; - pointFile >> format >> _nPoints; + int64_t nPoints; + pointFile.seekg(0, std::ios::beg); // read heder. + pointFile.read(reinterpret_cast(&nPoints), sizeof(int64_t)); - // temporarily decrease number of points. - _nPoints = std::min(static_cast(100000), _nPoints); + _nPoints = static_cast(nPoints); + + size_t nFloats = _nPoints * 7; + + float* pointData = new float[nFloats]; + pointFile.seekg(sizeof(int64_t), std::ios::beg); // read past heder. + pointFile.read(reinterpret_cast(pointData), nFloats * sizeof(float)); + pointFile.close(); + + float maxdist = 0; + float x, y, z, r, g, b, a; for (size_t i = 0; i < _nPoints; ++i) { - pointFile >> x >> y >> z >> r >> g >> b >> a; - if (pointFile.good()) { - pointPositions.push_back(glm::vec3(x, y, z)); - pointColors.push_back(glm::vec3(r, g, b)); - } - else { - LERROR("Could not read points."); - break; - } + float x = pointData[i * 7 + 0]; + float y = pointData[i * 7 + 1]; + float z = pointData[i * 7 + 2]; + float r = pointData[i * 7 + 3]; + float g = pointData[i * 7 + 4]; + float b = pointData[i * 7 + 5]; + maxdist = std::max(maxdist, glm::length(glm::vec3(x, y, z))); + //float a = pointData[i * 7 + 6]; alpha is not used. + + pointPositions.push_back(glm::vec3(x, y, z)); + pointColors.push_back(glm::vec3(r, g, b)); } - pointFile.close(); + + std::cout << maxdist << std::endl; + + delete[] pointData; glGenVertexArrays(1, &_pointsVao); glGenBuffers(1, &_positionVbo); @@ -200,7 +223,11 @@ bool RenderableGalaxy::initialize() { RenderEngine& renderEngine = OsEng.renderEngine(); _pointsProgram = renderEngine.buildRenderProgram("Galaxy points", "${MODULE_GALAXY}/shaders/points.vs", - "${MODULE_GALAXY}/shaders/points.fs"); + "${MODULE_GALAXY}/shaders/points.fs", + ghoul::Dictionary(), + RenderEngine::RenderProgramType::Post); + + _pointsProgram->setIgnoreUniformLocationError(ghoul::opengl::ProgramObject::IgnoreError::Yes); GLint positionAttrib = _pointsProgram->attributeLocation("inPosition"); GLint colorAttrib = _pointsProgram->attributeLocation("inColor"); @@ -234,29 +261,80 @@ bool RenderableGalaxy::isReady() const { void RenderableGalaxy::update(const UpdateData& data) { if (_raycaster) { - glm::mat4 transform = glm::translate(glm::mat4(1.0), static_cast(_translation) * std::powf(10.0, static_cast(_scalingExponent))); + //glm::mat4 transform = glm::translate(, static_cast(_translation)); glm::vec3 eulerRotation = static_cast(_rotation); - transform = glm::rotate(transform, eulerRotation.x, glm::vec3(1, 0, 0)); + glm::mat4 transform = glm::rotate(glm::mat4(1.0), eulerRotation.x, glm::vec3(1, 0, 0)); transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0, 1, 0)); transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0, 0, 1)); - transform = glm::scale(transform, _aspect * static_cast(_scaling) * std::powf(10.0, static_cast(_scalingExponent))); - + + + glm::mat4 volumeTransform = glm::scale(transform, static_cast(_volumeSize)); + _pointTransform = glm::scale(transform, static_cast(_pointScaling)); + + // Todo: handle floating point overflow, to actually support translation. + volumeTransform = glm::translate(volumeTransform, static_cast(_translation)); + _pointTransform = glm::translate(_pointTransform, static_cast(_translation)); + _raycaster->setStepSize(_stepSize); _raycaster->setAspect(_aspect); - _raycaster->setModelTransform(transform); + _raycaster->setModelTransform(volumeTransform); _raycaster->setTime(data.time); } } void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) { RaycasterTask task{ _raycaster.get(), data }; - tasks.raycasterTasks.push_back(task); + + glm::vec3 position = data.camera.position().vec3(); + float length = safeLength(position); + glm::vec3 galaxySize = static_cast(_volumeSize); + + float maxDim = std::max(std::max(galaxySize.x, galaxySize.y), galaxySize.z); + + + float lowerRampStart = maxDim * 0.02; + float lowerRampEnd = maxDim * 0.5; + + float upperRampStart = maxDim * 2.0; + float upperRampEnd = maxDim * 10; + + float opacityCoefficient = 1.0; + + if (length < lowerRampStart) { + opacityCoefficient = 0; // camera really close + } else if (length < lowerRampEnd) { + opacityCoefficient = (length - lowerRampStart) / (lowerRampEnd - lowerRampStart); + } else if (length < upperRampStart) { + opacityCoefficient = 1.0; // sweet spot (max) + } else if (length < upperRampEnd) { + opacityCoefficient = 1.0 - (length - upperRampStart) / (upperRampEnd - upperRampStart); //fade out + } else { + opacityCoefficient = 0; + } + + _opacityCoefficient = opacityCoefficient; + ghoul_assert(_opacityCoefficient >= 0.0 && _opacityCoefficient <= 1.0, "Opacity coefficient was not between 0 and 1"); + if (opacityCoefficient > 0) { + _raycaster->setOpacityCoefficient(_opacityCoefficient); + tasks.raycasterTasks.push_back(task); + } +} + +float RenderableGalaxy::safeLength(const glm::vec3& vector) { + float maxComponent = std::max(std::max(std::abs(vector.x), std::abs(vector.y)), std::abs(vector.z)); + return glm::length(vector / maxComponent) * maxComponent; +} + +void RenderableGalaxy::postRender(const RenderData& data) { + + _raycaster->setStepSize(_pointStepSize); _pointsProgram->activate(); setPscUniforms(*_pointsProgram.get(), data.camera, data.position); + OsEng.ref().renderEngine().preRaycast(*_pointsProgram); - glm::mat4 modelMatrix = glm::mat4(1.0); + glm::mat4 modelMatrix = _pointTransform; glm::mat4 viewMatrix = data.camera.viewMatrix(); glm::mat4 projectionMatrix = data.camera.projectionMatrix(); @@ -264,14 +342,20 @@ void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) { _pointsProgram->setUniform("view", viewMatrix); _pointsProgram->setUniform("projection", projectionMatrix); + float emittanceFactor = _opacityCoefficient * static_cast(_volumeSize).x; + _pointsProgram->setUniform("emittanceFactor", emittanceFactor); + glBindVertexArray(_pointsVao); + glDisable(GL_DEPTH_TEST); glDepthMask(false); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glDrawArrays(GL_POINTS, 0, _nPoints); glBindVertexArray(0); glDepthMask(true); + glEnable(GL_DEPTH_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + OsEng.ref().renderEngine().postRaycast(*_pointsProgram); } } diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index 0ba5be2b07..c60ab5fa3d 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -44,12 +44,16 @@ public: bool deinitialize() override; bool isReady() const override; void render(const RenderData& data, RendererTasks& tasks) override; + void postRender(const RenderData& data) override; void update(const UpdateData& data) override; private: - properties::Vec3Property _scaling; - properties::IntProperty _scalingExponent; + float safeLength(const glm::vec3& vector); + + glm::vec3 _volumeSize; + glm::vec3 _pointScaling; properties::FloatProperty _stepSize; + properties::FloatProperty _pointStepSize; properties::Vec3Property _translation; properties::Vec3Property _rotation; @@ -60,7 +64,9 @@ private: std::unique_ptr _raycaster; std::unique_ptr>> _volume; std::unique_ptr _texture; + glm::mat4 _pointTransform; glm::vec3 _aspect; + float _opacityCoefficient; std::unique_ptr _pointsProgram; size_t _nPoints; diff --git a/modules/galaxy/shaders/galaxyraycast.glsl b/modules/galaxy/shaders/galaxyraycast.glsl index dcc1021610..23566e6f1c 100644 --- a/modules/galaxy/shaders/galaxyraycast.glsl +++ b/modules/galaxy/shaders/galaxyraycast.glsl @@ -24,6 +24,7 @@ uniform float maxStepSize#{id} = 0.1; uniform vec3 aspect#{id} = vec3(1.0); +uniform float opacityCoefficient#{id} = 1.0; uniform sampler3D galaxyTexture#{id}; @@ -34,10 +35,11 @@ void sample#{id}(vec3 samplePos, inout float maxStepSize) { vec3 aspect = aspect#{id}; - maxStepSize = maxStepSize#{id} * length(dir * 1.0/aspect); + maxStepSize = maxStepSize#{id} * length(dir * 1/aspect); + vec4 sampledColor = texture(galaxyTexture#{id}, samplePos.xyz); - float STEP_SIZE = maxStepSize#{id}; + float STEP_SIZE = maxStepSize; vec3 alphaTint = vec3(0.3, 0.54, 0.85); //alphaTint = vec3(0.0, 0.5, 1.0); @@ -54,7 +56,7 @@ void sample#{id}(vec3 samplePos, //sampledColor.a = pow(sampledColor.a, 10.0); //sampledColor.a = pow(sampledColor.a, 100000000.0); sampledColor.rgb *= 4000.0; - sampledColor.a *= 1; + sampledColor.a = sampledColor.a * 0.3; //1.0; //float emissionCoefficient = 80; @@ -75,8 +77,8 @@ void sample#{id}(vec3 samplePos, vec3 backColor = sampledColor.rgb; vec3 backAlpha = sampledColor.a * alphaTint; - backColor *= STEP_SIZE; - backAlpha *= STEP_SIZE; + backColor *= STEP_SIZE * opacityCoefficient#{id}; + backAlpha *= STEP_SIZE * opacityCoefficient#{id}; backColor = clamp(backColor, 0.0, 1.0); backAlpha = clamp(backAlpha, 0.0, 1.0); @@ -84,7 +86,10 @@ void sample#{id}(vec3 samplePos, vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha; accumulatedColor += oneMinusFrontAlpha * backColor; accumulatedAlpha += oneMinusFrontAlpha * backAlpha; - + + acc+= 1.0; + + //accumulatedColor = vec3(opacityCoefficient#{id}); } float stepSize#{id}(vec3 samplePos, vec3 dir) { diff --git a/modules/galaxy/shaders/points.fs b/modules/galaxy/shaders/points.fs index 5f87714048..db7daa29e8 100644 --- a/modules/galaxy/shaders/points.fs +++ b/modules/galaxy/shaders/points.fs @@ -22,6 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +uniform float emittanceFactor; + in vec3 vsPosition; in vec3 vsColor; @@ -30,12 +32,16 @@ in vec3 vsColor; Fragment getFragment() { vec4 color = vec4(vsColor, 1.0); - + Fragment frag; - frag.color = vec4(vsColor.rgb * 0.1, 1.0); - frag.depth = pscDepth(vec4(vsPosition, 0.0)); - frag.forceFboRendering = true; + float depth = pscDepth(vec4(vsPosition, 0.0)); + float coefficient = exp(1.27 * log(emittanceFactor) - 2*log(depth)); + + frag.color = vec4(vsColor.rgb * coefficient, 1.0); + + + frag.depth = depth; return frag; } diff --git a/modules/galaxy/shaders/points.vs b/modules/galaxy/shaders/points.vs index 90d1547718..d14f031033 100644 --- a/modules/galaxy/shaders/points.vs +++ b/modules/galaxy/shaders/points.vs @@ -41,15 +41,10 @@ void main() { vec4 p = vec4(inPosition, 0.0); vec4 tmp = p; - vec4 position = pscTransform(tmp, mat4(1.0)); + vec4 position = pscTransform(tmp, model); vsPosition = position.xyz; - position = projection * view * model * position; + position = projection * view * position; gl_Position = z_normalization(position); - - //float distThreshold = 0.0001; - - //gl_PointSize = min(1.0, position.z); - gl_PointSize = 1.0; vsColor = inColor; } diff --git a/modules/galaxy/shaders/raycasterbounds.vs b/modules/galaxy/shaders/raycasterbounds.vs index fc328f30df..37ae94349a 100644 --- a/modules/galaxy/shaders/raycasterbounds.vs +++ b/modules/galaxy/shaders/raycasterbounds.vs @@ -36,12 +36,13 @@ out vec4 worldPosition; void main() { vPosition = vertPosition.xyz; - worldPosition = modelTransform*vertPosition; - - vec4 position = pscTransform(worldPosition, mat4(1.0)); + + worldPosition = vec4(vertPosition.xyz, 0.0); + vec4 position = pscTransform(worldPosition, modelTransform); + + // project the position to view space - gl_Position = viewProjection * position; - - gl_Position.z = 1.0; + gl_Position = z_normalization(viewProjection * position); + //gl_Position.z = 1.0; } diff --git a/modules/multiresvolume/rendering/multiresvolumeraycaster.cpp b/modules/multiresvolume/rendering/multiresvolumeraycaster.cpp index 24def3475e..1d08f19e18 100644 --- a/modules/multiresvolume/rendering/multiresvolumeraycaster.cpp +++ b/modules/multiresvolume/rendering/multiresvolumeraycaster.cpp @@ -127,6 +127,33 @@ void MultiresVolumeRaycaster::preRaycast(const RaycastData& data, ghoul::opengl: program.setUniform("atlasSize_" + id, atlasSize); } +bool MultiresVolumeRaycaster::cameraIsInside(const RenderData& data, glm::vec3& localPosition) { + // Camera rig position in world coordinates. + glm::vec4 rigWorldPos = glm::vec4(data.camera.position().vec3(), 1.0); + //rigWorldPos /= data.camera.scaling().x * pow(10.0, data.camera.scaling().y); + glm::mat4 invSgctMatrix = glm::inverse(data.camera.viewMatrix()); + + // Camera position in world coordinates. + glm::vec4 camWorldPos = rigWorldPos; + glm::vec3 objPos = data.position.vec3(); + + glm::mat4 modelTransform = glm::translate(_modelTransform, objPos); + + float divisor = 1.0; + for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { + if (abs(modelTransform[i][j] > divisor)) divisor = modelTransform[i][j]; + } + + glm::mat4 scaledModelTransform = modelTransform / divisor; + + glm::vec4 modelPos = (glm::inverse(scaledModelTransform) / divisor) * camWorldPos; + + + localPosition = (modelPos.xyz() + glm::vec3(0.5)); + return (localPosition.x > 0 && localPosition.y > 0 && localPosition.z > 0 && localPosition.x < 1 && localPosition.y < 1 && localPosition.z < 1); + +} + void MultiresVolumeRaycaster::postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) { // For example: release texture units } diff --git a/modules/multiresvolume/rendering/multiresvolumeraycaster.h b/modules/multiresvolume/rendering/multiresvolumeraycaster.h index b2241fd0fe..1c48cc1828 100644 --- a/modules/multiresvolume/rendering/multiresvolumeraycaster.h +++ b/modules/multiresvolume/rendering/multiresvolumeraycaster.h @@ -66,6 +66,7 @@ public: void renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject& program) override; void preRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override; void postRaycast(const RaycastData& data, ghoul::opengl::ProgramObject& program) override; + bool cameraIsInside(const RenderData& data, glm::vec3& localPosition) override; std::string getBoundsVsPath() const override; std::string getBoundsFsPath() const override; diff --git a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp index 4a5ffacf32..b37f0fa83c 100644 --- a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp +++ b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp @@ -68,6 +68,7 @@ namespace { const std::string _loggerCat = "RenderableMultiresVolume"; const std::string KeyDataSource = "Source"; + const std::string KeyErrorHistogramsSource = "ErrorHistogramsSource"; const std::string KeyHints = "Hints"; const std::string KeyTransferFunction = "TransferFunction"; @@ -124,6 +125,13 @@ RenderableMultiresVolume::RenderableMultiresVolume (const ghoul::Dictionary& dic return; } + _errorHistogramsPath = ""; + if (dictionary.getValue(KeyErrorHistogramsSource, _errorHistogramsPath)) { + _errorHistogramsPath = absPath(_errorHistogramsPath); + } + + + float scalingExponent, stepSizeCoefficient; glm::vec3 scaling, translation, rotation; @@ -143,6 +151,7 @@ RenderableMultiresVolume::RenderableMultiresVolume (const ghoul::Dictionary& dic _stepSizeCoefficient = stepSizeCoefficient; } + std::string startTimeString, endTimeString; bool hasTimeData = true; hasTimeData &= dictionary.getValue(KeyStartTime, startTimeString); @@ -384,11 +393,16 @@ bool RenderableMultiresVolume::initializeSelector() { cacheFilename = FileSys.cacheManager()->cachedFilename( cacheName.str(), "", ghoul::filesystem::CacheManager::Persistent::Yes); std::ifstream cacheFile(cacheFilename, std::ios::in | std::ios::binary); + std::string errorHistogramsPath = _errorHistogramsPath; if (cacheFile.is_open()) { // Read histograms from cache. cacheFile.close(); - LINFO("Loading histograms from " << cacheFilename); + LINFO("Loading histograms from cache: " << cacheFilename); success &= _errorHistogramManager->loadFromFile(cacheFilename); + } else if (_errorHistogramsPath != "") { + // Read histograms from scene data. + LINFO("Loading histograms from scene data: " << _errorHistogramsPath); + success &= _errorHistogramManager->loadFromFile(_errorHistogramsPath); } else { // Build histograms from tsp file. LWARNING("Failed to open " << cacheFilename); diff --git a/modules/multiresvolume/rendering/renderablemultiresvolume.h b/modules/multiresvolume/rendering/renderablemultiresvolume.h index 408f5eea0a..1f040edfe1 100644 --- a/modules/multiresvolume/rendering/renderablemultiresvolume.h +++ b/modules/multiresvolume/rendering/renderablemultiresvolume.h @@ -81,6 +81,9 @@ public: virtual void update(const UpdateData& data) override; virtual void render(const RenderData& data, RendererTasks& tasks); + + + //virtual void preResolve(ghoul::opengl::ProgramObject* program) override; //virtual std::string getHeaderPath() override; //virtual std::string getHelperPath() override; @@ -120,6 +123,7 @@ private: std::string _volumeName; std::string _transferFunctionPath; + std::string _errorHistogramsPath; std::shared_ptr _transferFunction; diff --git a/modules/multiresvolume/shaders/boundsVs.glsl b/modules/multiresvolume/shaders/boundsVs.glsl index ab1cd161f7..3345b7a597 100644 --- a/modules/multiresvolume/shaders/boundsVs.glsl +++ b/modules/multiresvolume/shaders/boundsVs.glsl @@ -35,13 +35,11 @@ out vec4 worldPosition; #include "PowerScaling/powerScaling_vs.hglsl" void main() { - vPosition = vertPosition.xyz; - worldPosition = modelTransform*vertPosition; - - vec4 position = pscTransform(worldPosition, mat4(1.0)); - - // project the position to view space - gl_Position = viewProjection * position; + vPosition = vertPosition.xyz; - gl_Position.z = 1.0; + worldPosition = vec4(vertPosition.xyz, 0.0); + vec4 position = pscTransform(worldPosition, modelTransform); + + // project the position to view space + gl_Position = z_normalization(viewProjection * position); } diff --git a/modules/multiresvolume/shaders/raycast.glsl b/modules/multiresvolume/shaders/raycast.glsl index 50265a24de..16c8d96d4f 100644 --- a/modules/multiresvolume/shaders/raycast.glsl +++ b/modules/multiresvolume/shaders/raycast.glsl @@ -73,7 +73,13 @@ float stepSize#{id}(vec3 samplePos, vec3 dir){ } } -vec4 sample#{id}(vec3 samplePos, vec3 dir, vec4 foregroundColor, inout float maxStepSize) { +void sample#{id}(vec3 samplePos, + vec3 dir, + inout vec3 accumulatedColor, + inout vec3 accumulatedAlpha, + inout float maxStepSize) { + + //vec4 sample#{id}(vec3 samplePos, vec3 dir, vec4 foregroundColor, inout float maxStepSize) { //return vec4(1.0, 1.0, 1.0, 1.0); if (true /*opacity_#{id} >= MULTIRES_OPACITY_THRESHOLD*/) { @@ -85,23 +91,30 @@ vec4 sample#{id}(vec3 samplePos, vec3 dir, vec4 foregroundColor, inout float max //sampleCoords = vec3(1.0,0.0, 0.0); float intensity = texture(textureAtlas_#{id}, sampleCoords).x; //intensity = sampleCoords; - + maxStepSize = stepSizeCoefficient_#{id}/float(maxNumBricksPerAxis_#{id})/float(paddedBrickDim_#{id}); //return vec4(vec3(intensity), 1.0); vec4 contribution = texture(transferFunction_#{id}, intensity); - + contribution.a = 1.0 - pow(1.0 - contribution.a, maxStepSize); //contribution = vec4(sampleCoords, 1.0); //vec4 contribution = vec4(vec3(intensity), 1.0); //contribution.a *= 0.3; //contribution = vec4(1.0, 1.0, 1.0, intensity * 1000000.0); //contribution = vec4(1.0, 1.0, 1.0, 1.0); - maxStepSize = stepSizeCoefficient_#{id}/float(maxNumBricksPerAxis_#{id})/float(paddedBrickDim_#{id}); + //contribution.a *= opacity_#{id}; //maxStepSize = 0.01; - return contribution; + + vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha; + accumulatedColor += oneMinusFrontAlpha * contribution.rgb * contribution.a; + accumulatedAlpha += oneMinusFrontAlpha * vec3(contribution.a); + + + //accumulatedAlpha = vec3(1.0-); + //return contribution; } else { maxStepSize = 2.0; - return vec4(0.0); + //return vec4(0.0); } } diff --git a/shaders/PowerScaling/powerScalingMath.hglsl b/shaders/PowerScaling/powerScalingMath.hglsl index b14e15db60..035b21a958 100644 --- a/shaders/PowerScaling/powerScalingMath.hglsl +++ b/shaders/PowerScaling/powerScalingMath.hglsl @@ -76,15 +76,7 @@ vec2 psc_subtraction(vec2 v1, vec2 v2) { vec4 z_normalization(vec4 v_in) { vec4 v_out = v_in; - if(v_out.z > 0.0) { - v_out.z = 1; - } else if(v_out.z < 0.0) { - v_out.z = 1; - } else { - float tmp = max(max(abs(v_out.x), abs(v_out.y)),0); - if(tmp == 0.0) - v_out.s = FLT_MAX; - } + v_out.z = 0; return v_out; } diff --git a/shaders/PowerScaling/powerScaling_fs.hglsl b/shaders/PowerScaling/powerScaling_fs.hglsl index 855c98707a..ba2442ebcf 100644 --- a/shaders/PowerScaling/powerScaling_fs.hglsl +++ b/shaders/PowerScaling/powerScaling_fs.hglsl @@ -53,7 +53,11 @@ float pscDepth(vec4 position) { // For now: simply convert power scaled coordinates to a linear scale. // TODO: get rid of power scaled coordinates and use scale graph instead. // return (position.w + log(abs(position.z) + 1/pow(k, position.w))/log(k)) / 27.0; - return safeLength(pscToLinear(position)); + if (position.z < 0) { + return safeLength(pscToLinear(position)); + } else { + return -safeLength(pscToLinear(position)); + } } diff --git a/shaders/abuffer/abufferresources.glsl b/shaders/abuffer/abufferresources.glsl index 60abbe48f9..4241885318 100644 --- a/shaders/abuffer/abufferresources.glsl +++ b/shaders/abuffer/abufferresources.glsl @@ -29,6 +29,7 @@ #define MAX_LAYERS #{rendererData.maxLayers} ABufferFragment fragments[MAX_LAYERS]; +uint fragmentIndices[MAX_LAYERS]; layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; @@ -56,10 +57,30 @@ uint loadFragments() { while (currentIndex != NULL_POINTER && nFrags < MAX_LAYERS) { ABufferFragment frag = loadFragment(currentIndex); fragments[nFrags] = frag; + fragmentIndices[nFrags] = currentIndex; currentIndex = _next_(frag); nFrags++; } return nFrags; } +/** + * Store the current contents of the fragments array back into the abuffer. + */ +void storeFragments(uint nFrags) { + if (nFrags == 0) + return; + uint maxFragIndex = nFrags - 1; + for (int i = 0; i < maxFragIndex; i++) { + _next_(fragments[i], fragmentIndices[i+1]); + storeFragment(fragmentIndices[i], fragments[i]); + } + _next_(fragments[maxFragIndex], NULL_POINTER); + storeFragment(fragmentIndices[maxFragIndex], fragments[maxFragIndex]); + +} + + + + #endif diff --git a/shaders/abuffer/boundsabuffer.frag b/shaders/abuffer/boundsabuffer.frag index d5718c2913..3523037570 100644 --- a/shaders/abuffer/boundsabuffer.frag +++ b/shaders/abuffer/boundsabuffer.frag @@ -37,6 +37,11 @@ void main() { int sampleMask = gl_SampleMaskIn[0]; + if (frag.depth < 0) { + // discard; + } + + uint newHead = atomicCounterIncrement(atomicCounterBuffer); uint prevHead = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), newHead); diff --git a/shaders/abuffer/postrenderabuffer.frag b/shaders/abuffer/postrenderabuffer.frag new file mode 100644 index 0000000000..602a98ed67 --- /dev/null +++ b/shaders/abuffer/postrenderabuffer.frag @@ -0,0 +1,135 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 - 2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "fragment.glsl" +#include <#{fragmentPath}> +#include "abufferfragment.glsl" +#include "abufferresources.glsl" +#include "PowerScaling/powerScalingMath.hglsl" +#include "rand.glsl" +#include "resolveconstants.glsl" + +#include "resolvehelpers.glsl" + +#define RAYCASTING_ENABLED #{resolveData.raycastingEnabled} +uniform float blackoutFactor; +uniform sampler2DMS mainColorTexture; +uniform sampler2DMS mainDepthTexture; + +out vec4 _out_color_; + +void main() { + + Fragment newFrag = getFragment(); + int sampleMask = gl_SampleMaskIn[0]; + + if (newFrag.depth < 0) { + discard; + } + + float fboDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x); + vec4 fboRgba = texelFetch(mainColorTexture, ivec2(gl_FragCoord), 0); + + if (newFrag.depth > fboDepth) { + discard; + } + + //newFrag.color *= countSamples(sampleMask) / nAaSamples; +/* + vec3 accumulatedColor = vec3(0.0); + + // One alpha channel per color channel to allow for + // absorption of different wavelengths. + // Always within the interval [0, 1] + vec3 accumulatedAlpha = vec3(0.0); + + + uint nFrags = loadFragments(); + uint raycasterMask; +#if RAYCASTING_ENABLED + bool insideAnyRaycaster = initRaycasterMask(raycasterMask); +#endif + + +#if RAYCASTING_ENABLED + retrieveRaycasterData(nFrags); + + if (insideAnyRaycaster) { + //raycast to the first fragment + float startDepth = 0; + float endDepth = min(_depth_(fragments[0]), newFrag.depth); + raycast(endDepth - startDepth, raycasterMask, accumulatedColor, accumulatedAlpha); + } +#endif + + for (uint i = 0; i < nFrags; i++) { + ABufferFragment frag = fragments[i]; + + if (_depth_(frag) > newFrag.depth) { + break; + } + + int type = _type_(frag); + uint blend = _blend_(frag); + + if (type == 0) { // geometry fragment + vec4 color = _color_(frag); + if (blend == BLEND_MODE_NORMAL) { + accumulatedColor += (1 - accumulatedAlpha) * color.rgb * color.a; + accumulatedAlpha += (1 - accumulatedAlpha) * color.aaa; + } else if (blend == BLEND_MODE_ADDITIVE) { + accumulatedColor += (1 - accumulatedAlpha) * color.rgb; + } + } +#if RAYCASTING_ENABLED + else if (type > 0) { // enter volume + int raycasterId = type - 1; + // only enter volume if a valid scale was detected + if (raycasterData[raycasterId].scale > 0) { + raycasterMask |= (1 << (raycasterId)); + } + } else { // exit volume + int raycasterId = -type - 1; + raycasterMask &= INT_MAX - (1 << (raycasterId)); + } + // Ray cast to next fragment + if (i + 1 < nFrags && raycasterMask != 0) { + float startDepth = _depth_(fragments[i]); + float endDepth = min(_depth_(fragments[i + 1]), newFrag.depth); + raycast(endDepth - startDepth, raycasterMask, accumulatedColor, accumulatedAlpha); + } +#endif + } +*/ + vec4 newColor = newFrag.color; + vec3 contribution = newColor.rgb * blackoutFactor; + //vec3 contribution = newColor.rgb * blackoutFactor; + + + + _out_color_ = vec4(contribution, 1.0); + // _out_color_ = vec4(1.0); + +} + diff --git a/shaders/abuffer/raycasterdata.glsl b/shaders/abuffer/raycasterdata.glsl index 5f0b945365..d4f960d08b 100644 --- a/shaders/abuffer/raycasterdata.glsl +++ b/shaders/abuffer/raycasterdata.glsl @@ -31,6 +31,8 @@ struct RaycasterData { float scale; float previousJitterDistance; uint blend; -} +}; +RaycasterData raycasterData[N_RAYCASTERS]; + #endif diff --git a/shaders/abuffer/renderabuffer.frag b/shaders/abuffer/renderabuffer.frag index 481836a029..d3abc97ddf 100644 --- a/shaders/abuffer/renderabuffer.frag +++ b/shaders/abuffer/renderabuffer.frag @@ -33,6 +33,11 @@ void main() { Fragment frag = getFragment(); int sampleMask = gl_SampleMaskIn[0]; + if (frag.depth < 0) { +// discard; + } + + //frag.forceFboRendering = true; // todo: calculate full sample mask from nAaSamples instead of hardcoded 255. if (!frag.forceFboRendering && (frag.color.a < 1.0 || sampleMask != 255)) { uint newHead = atomicCounterIncrement(atomicCounterBuffer); @@ -54,6 +59,10 @@ void main() { discard; } else { _out_color_ = frag.color; - gl_FragDepth = normalizeFloat(frag.depth); + gl_FragDepth = normalizeFloat(frag.depth); } + + //gl_FragDepth = 1; + } + diff --git a/shaders/abuffer/resolveabuffer.frag b/shaders/abuffer/resolveabuffer.frag index dd84d05283..59526cf138 100644 --- a/shaders/abuffer/resolveabuffer.frag +++ b/shaders/abuffer/resolveabuffer.frag @@ -24,6 +24,8 @@ #version __CONTEXT__ + +#include "resolveconstants.glsl" #include "abufferfragment.glsl" #include "abufferresources.glsl" #include "fragment.glsl" @@ -34,220 +36,22 @@ layout (location = 0) out vec4 finalColor; uniform float blackoutFactor; -uniform int nAaSamples; uniform sampler2DMS mainColorTexture; uniform sampler2DMS mainDepthTexture; +uniform float gamma = 1.0; -#define RAYCASTING_ENABLED #{raycastingEnabled} -#define N_RAYCASTERS #{nRaycasters} -#define ALPHA_LIMIT 0.99 -#define RAYCAST_MAX_STEPS 10000 -#define INT_MAX 2147483647 - -///////////////////////// -#if RAYCASTING_ENABLED - -#include "raycasterdata.glsl" - -RaycasterData raycasterData[N_RAYCASTERS]; -// Include all ray caster helpers -#for id, helperPath in helperPaths -#include <#{helperPath}> -#endfor - -// Include all ray casters -#for id, raycaster in raycasters -#include <#{raycaster.raycastPath}> -#endfor - -#endif -///////////////////////// - -void sortFragments(uint nFrags) { - ABufferFragment tmp; - uint i, j; - - // Insertion sort - for(i = 1; i < nFrags; ++i) { - tmp = fragments[i]; - for(j = i; j > 0 && _depth_(tmp) < _depth_(fragments[j-1]); --j) { - fragments[j] = fragments[j-1]; - } - fragments[j] = tmp; - } -} - -uint countSamples(uint mask) { - return ((mask >> 0) & 1) - + ((mask >> 1) & 1) - + ((mask >> 2) & 1) - + ((mask >> 3) & 1) - + ((mask >> 4) & 1) - + ((mask >> 5) & 1) - + ((mask >> 6) & 1) - + ((mask >> 7) & 1); -} - -uint depthFilterFragments(uint nFrags, float depthThreshold) { - uint j = 0; - for (uint i = 0; i < nFrags; i++) { - if (_depth_(fragments[i]) < depthThreshold) { - fragments[j] = fragments[i]; - j++; - } - } - return j; -} +#include "resolvehelpers.glsl" -uint mergeFragments(uint nFrags) { - uint outputIndex = 0; - for (uint inputIndex = 0; inputIndex < nFrags; inputIndex++, outputIndex++) { - - ABufferFragment frag = fragments[inputIndex]; - uint accumulatedMask = _msaa_(fragments[inputIndex]); - uint newMask = _msaa_(fragments[inputIndex]); - int type = _type_(fragments[inputIndex]); - - // Accumulate sample mask - for (uint j = inputIndex + 1; - j < nFrags && ((newMask = _msaa_(fragments[j])) & accumulatedMask) == 0 && _type_(fragments[j]) == type; - j++) { - accumulatedMask |= newMask; - inputIndex = j; - } - uint nSamples = countSamples(accumulatedMask); - vec4 color = _color_(fragments[inputIndex]); // TODO: Possibly weigh all samples together? - - // Adjust the alpha by the ratio of accumulated samples - float alpha = float(nSamples) / float(nAaSamples); - color.a *= alpha; - - ABufferFragment outputFragment = fragments[inputIndex]; - _color_(outputFragment, color); - - fragments[outputIndex] = outputFragment; - } - - // return number of outputted fragments - return outputIndex; -} - -#if RAYCASTING_ENABLED - -/** - * Iterate through list of sorted fragments, - * and retrieve raycasting position, direction, scale - */ -void retrieveRaycasterData(uint nFrags) { - float entryDepths[N_RAYCASTERS]; - for (int i = 0; i < N_RAYCASTERS; i++) { - entryDepths[i] = -1; - } - for (int i = 0; i < nFrags; i++) { - int type = _type_(fragments[i]); // - 1; - vec3 position = _position_(fragments[i]); - float depth = _depth_(fragments[i]); - uint blend = _blend_(fragments[i]); - if (type > 0) { // enter raycaster - int raycasterId = type - 1; - if (entryDepths[raycasterId] < 0) { // first entry - raycasterData[raycasterId].position = position; - raycasterData[raycasterId].previousJitterDistance = 0; - raycasterData[raycasterId].blend = blend; - entryDepths[raycasterId] = depth; - raycasterData[raycasterId].scale = -1; - } - } else if (type < 0) { // exit raycaster - int raycasterId = -type - 1; - vec3 localDirection = position - raycasterData[raycasterId].position; - raycasterData[raycasterId].direction = safeNormalize(localDirection); - raycasterData[raycasterId].scale = safeLength(localDirection) / (depth - entryDepths[raycasterId]); - } - } -} - -/** - * Perform raycasting - */ -void raycast(float raycastDepth, uint raycasterMask, inout vec3 accumulatedColor, inout vec3 accumulatedAlpha) { - float nextStepSize = raycastDepth; - float currentStepSize = 0.0; - float jitterFactor = 0.5 + 0.5 * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0 - -#for index, raycaster in raycasters - if ((raycasterMask & #{raycaster.bitmask}) != 0) { - RaycasterData data = raycasterData[#{index}]; - float maxStepSizeLocal = stepSize#{raycaster.id}(data.position, data.direction); - float maxStepSize = maxStepSizeLocal / data.scale; - nextStepSize = min(nextStepSize, maxStepSize); - } -#endfor - - float currentDepth = 0.0; - - for (int steps = 0; - (accumulatedAlpha.x < ALPHA_LIMIT || - accumulatedAlpha.y < ALPHA_LIMIT || - accumulatedAlpha.z < ALPHA_LIMIT) && - steps < RAYCAST_MAX_STEPS; - ++steps) { - bool exceededDepth = currentDepth + nextStepSize * jitterFactor > raycastDepth; - bool shortStepSize = nextStepSize < raycastDepth / 10000000000.0; - - if (exceededDepth || shortStepSize) { - break; - } - - currentStepSize = nextStepSize; - currentDepth += currentStepSize; - nextStepSize = raycastDepth - currentDepth; - -#for index, raycaster in raycasters - - if ((raycasterMask & #{raycaster.bitmask}) != 0) { - RaycasterData data = raycasterData[#{raycaster.id}]; - float stepSizeLocal = currentStepSize * data.scale; - float jitteredStepSizeLocal = stepSizeLocal * jitterFactor; - - vec3 jitteredPosition = data.position + data.direction*jitteredStepSizeLocal; - raycasterData[#{raycaster.id}].position += data.direction * stepSizeLocal; - - float maxStepSizeLocal; - - sample#{raycaster.id}(jitteredPosition, - data.direction, - accumulatedColor, - accumulatedAlpha, - maxStepSizeLocal); - - float sampleDistance = jitteredStepSizeLocal + data.previousJitterDistance; - uint blend = raycasterData[#{raycaster.id}].blend; - - /* - if (blend == BLEND_MODE_NORMAL) { - normalBlendStep(finalColor, raycasterContribution, sampleDistance); - } else if (blend == BLEND_MODE_ADDITIVE) { - additiveBlendStep(finalColor, raycasterContribution, sampleDistance); - }*/ - //finalColor = raycasterContribution; - - raycasterData[#{raycaster.id}].previousJitterDistance = stepSizeLocal - jitteredStepSizeLocal; - float maxStepSize = maxStepSizeLocal/data.scale; - nextStepSize = min(nextStepSize, maxStepSize); - } -#endfor - } -} -#endif // RAYCASTING_ENABLED void main() { // TODO: disable multisampling for main fbo. float fboDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x); vec4 fboRgba = texelFetch(mainColorTexture, ivec2(gl_FragCoord), 0); - + // RGB color values, premultiplied with alpha channels. - vec3 accumulatedColor = vec3(0.0); + vec3 accumulatedColor = vec3(0.0); + // One alpha channel per color channel to allow for // absorption of different wavelengths. // Always within the interval [0, 1] @@ -255,7 +59,6 @@ void main() { uint nOriginalFrags = loadFragments(); uint raycasterMask = 0; - uint nFilteredFrags = nOriginalFrags; // discard all fragments in abuffer with higher depth value than the fbo @@ -264,14 +67,36 @@ void main() { // sort remaining fragments from front to back sortFragments(nFilteredFrags); - // merge fragments whose sample masks don't intersect + // merge fragments whose sample masks don't igntersect // to get the correct alpha for fragments on borders between triangles uint nFrags = mergeFragments(nFilteredFrags); + -#if RAYCASTING_ENABLED - retrieveRaycasterData(nFrags); + + +#if STORE_SORTED + //storeFragments(nFrags); #endif +#if RAYCASTING_ENABLED + + + retrieveRaycasterData(nFrags); +#if RAYCASTING_ENABLED + bool insideAnyRaycaster = initRaycasterMask(raycasterMask); +#endif + //debugColor = vec4(raycasterData[0].direction, 1.0); + + if (insideAnyRaycaster) { + //raycast to the first fragment +// discard; + float startDepth = 0; + float endDepth = _depth_(fragments[0]); + raycast(endDepth - startDepth, raycasterMask, accumulatedColor, accumulatedAlpha); + //accumulatedColor = vec3(1.0); + } +#endif + for (uint i = 0; i < nFrags; i++) { ABufferFragment frag = fragments[i]; @@ -280,9 +105,12 @@ void main() { if (type == 0) { // geometry fragment vec4 color = _color_(frag); + color.rgb = pow(color.rgb, vec3(gamma)); + if (blend == BLEND_MODE_NORMAL) { accumulatedColor += (1 - accumulatedAlpha) * color.rgb * color.a; - accumulatedAlpha += (1 - accumulatedAlpha) * color.aaa; + accumulatedAlpha += (1 - accumulatedAlpha) * color.aaa; + //normalBlend(finalColor, color); } else if (blend == BLEND_MODE_ADDITIVE) { accumulatedColor += (1 - accumulatedAlpha) * color.rgb; @@ -292,6 +120,7 @@ void main() { #if RAYCASTING_ENABLED else if (type > 0) { // enter volume int raycasterId = type - 1; + //accumulatedColor += (1 - accumulatedAlpha) * _position_(frag); // only enter volume if a valid scale was detected if (raycasterData[raycasterId].scale > 0) { raycasterMask |= (1 << (raycasterId)); @@ -299,24 +128,45 @@ void main() { } else { // exit volume int raycasterId = -type - 1; raycasterMask &= INT_MAX - (1 << (raycasterId)); + //accumulatedColor = vec3(1.0); + //accumulatedColor += (1 - accumulatedAlpha) * _position_(frag); } // Ray cast to next fragment if (i + 1 < nFrags && raycasterMask != 0) { float startDepth = _depth_(fragments[i]); float endDepth = _depth_(fragments[i + 1]); + raycast(endDepth - startDepth, raycasterMask, accumulatedColor, accumulatedAlpha); + } #endif } - - // Always blend in fbo content behind a buffer data. + + + accumulatedAlpha = clamp(accumulatedAlpha, 0.0, 1.0); + //maccumulatedAlpha = vec3(0.0); accumulatedColor += (1 - accumulatedAlpha) * fboRgba.rgb; - //accumulatedAlpha += (1 - accumulatedAlpha) * fboRgba.aaa; - - - finalColor = vec4(accumulatedColor.rgb * blackoutFactor, 1.0); + finalColor = vec4(accumulatedColor.rgb, 1.0); + // Gamma correction. - finalColor.rgb = pow(finalColor.rgb, vec3(1.0 / 2.2));// sqrt(finalColor.rgb); + finalColor.rgb = pow(finalColor.rgb, vec3(1.0 / gamma)); + // Black out factor. + + + finalColor = vec4(finalColor.rgb * blackoutFactor, 1.0); + //finalColor = vec4(0.0); + //finalColor = vec4(vec3(acc/1000.0), 1.0); + //finalColor = vec4(vec3(float(nFrags) / 10), 1.0); + //finalColor = vec4(vec3(float(_depth_(fragments[0])) / 10), 1.0); + + //finalColor = vec4(vec3(nFilteredFrags - nFrags) * 0.2, 1.0); + //finalColor = vec4(vec3(nFrags) * 0.2, 1.0); + + //finalColor = vec4(raycasterData[0].position, 1.0); + //finalColor = debugColor; + //finalColor = vec4(gamma * 0.5); + } + diff --git a/shaders/abuffer/resolveconstants.glsl b/shaders/abuffer/resolveconstants.glsl new file mode 100644 index 0000000000..65677a7cb4 --- /dev/null +++ b/shaders/abuffer/resolveconstants.glsl @@ -0,0 +1,7 @@ +#define RAYCASTING_ENABLED #{resolveData.raycastingEnabled} +#define STORE_SORTED false//#{resolveData.storeSorted} +#define N_RAYCASTERS #{resolveData.nRaycasters} +#define ALPHA_LIMIT 0.9 +#define RAYCAST_MAX_STEPS 10000 +#define INT_MAX 2147483647 +#define GAMMA 2.2 \ No newline at end of file diff --git a/shaders/abuffer/resolvehelpers.glsl b/shaders/abuffer/resolvehelpers.glsl new file mode 100644 index 0000000000..713efcc109 --- /dev/null +++ b/shaders/abuffer/resolvehelpers.glsl @@ -0,0 +1,260 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 - 2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef _RESOLVEHELPERS_GLSL_ +#define _RESOLVEHELPERS_GLSL_ + +#if RAYCASTING_ENABLED +#include "raycasterdata.glsl" + +float acc = 0; + + +// Include all ray caster helpers +#for id, helperPath in resolveData.helperPaths +#include <#{helperPath}> +#endfor + + +// Include all ray casters +#for id, raycaster in resolveData.raycasters +#include <#{raycaster.raycastPath}> +uniform bool insideRaycaster#{id}; +uniform vec3 cameraPosInRaycaster#{id} +#endfor + +#endif + + + + +uniform int nAaSamples; + +void sortFragments(uint nFrags) { + ABufferFragment tmp; + uint i, j; + + // Insertion sort + for(i = 1; i < nFrags; ++i) { + tmp = fragments[i]; + for(j = i; j > 0 && _depth_(tmp) < _depth_(fragments[j-1]); --j) { + fragments[j] = fragments[j-1]; + } + fragments[j] = tmp; + } +} + +uint countSamples(uint mask) { + return ((mask >> 0) & 1) + + ((mask >> 1) & 1) + + ((mask >> 2) & 1) + + ((mask >> 3) & 1) + + ((mask >> 4) & 1) + + ((mask >> 5) & 1) + + ((mask >> 6) & 1) + + ((mask >> 7) & 1); +} + +uint depthFilterFragments(uint nFrags, float depthThreshold) { + uint j = 0; + for (uint i = 0; i < nFrags; i++) { + if (_depth_(fragments[i]) < depthThreshold) { + fragments[j] = fragments[i]; + j++; + } + } + return j; +} + + +uint mergeFragments(uint nFrags) { + uint outputIndex = 0; + for (uint inputIndex = 0; inputIndex < nFrags; inputIndex++, outputIndex++) { + + ABufferFragment frag = fragments[inputIndex]; + uint accumulatedMask = _msaa_(fragments[inputIndex]); + uint newMask = _msaa_(fragments[inputIndex]); + int type = _type_(fragments[inputIndex]); + + // Accumulate sample mask + for (uint j = inputIndex + 1; +//abs(_depth_(fragments[j]) - _depth_(fragments[inputIndex])) < 0.000000001; //&& +j < nFrags && ((newMask = _msaa_(fragments[j])) & accumulatedMask) == 0 && _type_(fragments[j]) == type; + j++) { + accumulatedMask |= newMask; + inputIndex = j; + } + uint nSamples = countSamples(accumulatedMask); + ABufferFragment outputFragment = fragments[inputIndex]; + if (type == 0) { + vec4 color = _color_(fragments[inputIndex]); // TODO: Possibly weigh all samples together? + // Adjust the alpha by the ratio of accumulated samples + float alpha = float(nSamples) / float(nAaSamples); + color.a *= alpha; + _color_(outputFragment, color); + } + fragments[outputIndex] = outputFragment; + } + + // return number of outputted fragments + return outputIndex; +} + +#if RAYCASTING_ENABLED + +/** + * Iterate through list of sorted fragments, + * and retrieve raycasting position, direction, scale + */ +void retrieveRaycasterData(uint nFrags) { + float entryDepths[N_RAYCASTERS]; +#for i in 0..#{resolveData.nRaycasters} + { + int i = #{i}; + entryDepths[i] = -1; + raycasterData[i].scale = -1; + bool inside = insideRaycaster#{i}; + if (inside) { + entryDepths[i] = 0; + raycasterData[i].position = cameraPosInRaycaster#{i}; + raycasterData[i].previousJitterDistance = 0; + } + } +#endfor + + for (int i = 0; i < nFrags; i++) { + int type = _type_(fragments[i]); // - 1; + vec3 position = _position_(fragments[i]); + float depth = _depth_(fragments[i]); + uint blend = _blend_(fragments[i]); + if (type > 0) { // enter raycaster + int raycasterId = type - 1; + if (entryDepths[raycasterId] < 0) { // first entry + raycasterData[raycasterId].position = position; + raycasterData[raycasterId].previousJitterDistance = 0; + entryDepths[raycasterId] = depth; + raycasterData[raycasterId].scale = -1; + } + } else if (type < 0) { // exit raycaster + int raycasterId = -type - 1; + vec3 localDirection = position - raycasterData[raycasterId].position; + + raycasterData[raycasterId].direction = safeNormalize(localDirection); + raycasterData[raycasterId].scale = safeLength(localDirection) / (depth - entryDepths[raycasterId]); + raycasterData[raycasterId].blend = blend; + } + } +} + +/** + * Perform raycasting + */ +void raycast(float raycastDepth, uint raycasterMask, inout vec3 accumulatedColor, inout vec3 accumulatedAlpha) { + float nextStepSize = raycastDepth; + float currentStepSize = 0.0; + float jitterFactor = 0.5 + 0.5 * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0 + +#for index, raycaster in resolveData.raycasters + if ((raycasterMask & #{raycaster.bitmask}) != 0) { + RaycasterData data = raycasterData[#{index}]; + float maxStepSizeLocal = stepSize#{raycaster.id}(data.position, data.direction); + float maxStepSize = maxStepSizeLocal / data.scale; + nextStepSize = min(nextStepSize, maxStepSize); + } +#endfor + + float currentDepth = 0.0; + + for (int steps = 0; + (accumulatedAlpha.x < ALPHA_LIMIT || + accumulatedAlpha.y < ALPHA_LIMIT || + accumulatedAlpha.z < ALPHA_LIMIT) && + steps < RAYCAST_MAX_STEPS; + ++steps) { + bool exceededDepth = currentDepth + nextStepSize * jitterFactor > raycastDepth; + bool shortStepSize = nextStepSize < raycastDepth / 10000000000.0; + + if (exceededDepth || shortStepSize) { + break; + } + + currentStepSize = nextStepSize; + currentDepth += currentStepSize; + nextStepSize = raycastDepth - currentDepth; + +#for index, raycaster in resolveData.raycasters + if ((raycasterMask & #{raycaster.bitmask}) != 0) { + RaycasterData data = raycasterData[#{raycaster.id}]; + float stepSizeLocal = currentStepSize * data.scale; + float jitteredStepSizeLocal = stepSizeLocal * jitterFactor; + + vec3 jitteredPosition = data.position + data.direction*jitteredStepSizeLocal; + raycasterData[#{raycaster.id}].position += data.direction * stepSizeLocal; + + float maxStepSizeLocal; + + acc += 1.0; + sample#{raycaster.id}(jitteredPosition, + data.direction, + accumulatedColor, + accumulatedAlpha, + maxStepSizeLocal); + + + float sampleDistance = jitteredStepSizeLocal + data.previousJitterDistance; + uint blend = raycasterData[#{raycaster.id}].blend; + + /* + if (blend == BLEND_MODE_NORMAL) { + normalBlendStep(finalColor, raycasterContribution, sampleDistance); + } else if (blend == BLEND_MODE_ADDITIVE) { + additiveBlendStep(finalColor, raycasterContribution, sampleDistance); + }*/ + //finalColor = raycasterContribution; + + raycasterData[#{raycaster.id}].previousJitterDistance = stepSizeLocal - jitteredStepSizeLocal; + float maxStepSize = maxStepSizeLocal/data.scale; + nextStepSize = min(nextStepSize, maxStepSize); + } +#endfor + } +} + +bool initRaycasterMask(inout uint raycasterMask) { + bool insideAnyRaycaster = false; + raycasterMask = 0; +#for i in 0..#{resolveData.nRaycasters} { + if (insideRaycaster#{i} && raycasterData[#{i}].scale > 0) { + raycasterMask |= (1 << #{i}); + insideAnyRaycaster = true; + } +#endfor + return insideAnyRaycaster; +} + + + +#endif // RAYCASTING_ENABLED + +#endif // _RESOLVEHELPERS_GLSL_ diff --git a/shaders/framebuffer/postrenderframebuffer.frag b/shaders/framebuffer/postrenderframebuffer.frag new file mode 100644 index 0000000000..98905b9952 --- /dev/null +++ b/shaders/framebuffer/postrenderframebuffer.frag @@ -0,0 +1,34 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "PowerScaling/powerScalingMath.hglsl" +#include <#{fragmentPath}> + +out vec4 _out_color_; + +void main() { + Fragment f = getFragment(); + _out_color_ = f.color; + gl_FragDepth = normalizeFloat(f.depth); +} diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag index 9be8afe46d..2ef798954d 100644 --- a/shaders/framebuffer/raycastframebuffer.frag +++ b/shaders/framebuffer/raycastframebuffer.frag @@ -99,7 +99,6 @@ void main() { } - finalColor = vec4(0.0); float currentDepth = 0.0; // todo: shorten depth if geometry is intersecting! float nextStepSize = stepSize#{id}(position, direction); @@ -112,7 +111,11 @@ void main() { int sampleIndex = 0; float opacityDecay = 1.0 / nAaSamples; - for (steps = 0; finalColor.a < ALPHA_LIMIT && steps < RAYCAST_MAX_STEPS; ++steps) { + vec3 accumulatedColor = vec3(0.0); + vec3 accumulatedAlpha = vec3(0.0); + + + for (steps = 0; (accumulatedAlpha.r < ALPHA_LIMIT || accumulatedAlpha.g < ALPHA_LIMIT || accumulatedAlpha.b < ALPHA_LIMIT) && steps < RAYCAST_MAX_STEPS; ++steps) { while (sampleIndex < nAaSamples && currentDepth + nextStepSize * jitterFactor > raycastDepths[sampleIndex]) { @@ -132,11 +135,13 @@ void main() { vec3 jitteredPosition = position + direction*jitteredStepSize; position += direction * currentStepSize; - vec4 raycasterContribution = sample#{id}(jitteredPosition, direction, finalColor, nextStepSize); + + sample#{id}(jitteredPosition, direction, accumulatedColor, accumulatedAlpha, nextStepSize); float sampleDistance = aaOpacity * (jitteredStepSize + previousJitterDistance); - blendStep(finalColor, raycasterContribution, sampleDistance); + //blendStep(finalColor, raycasterContribution, sampleDistance); + //finalColor previousJitterDistance = currentStepSize - jitteredStepSize; @@ -146,6 +151,8 @@ void main() { } + finalColor = vec4(accumulatedColor, (accumulatedAlpha.r + accumulatedAlpha.g + accumulatedAlpha.b) / 3); + finalColor.rgb /= finalColor.a; gl_FragDepth = normalizeFloat(entryDepth); } diff --git a/shaders/postRender.frag b/shaders/postRender.frag new file mode 100644 index 0000000000..d290bd70c7 --- /dev/null +++ b/shaders/postRender.frag @@ -0,0 +1,2 @@ +#version __CONTEXT__ +#include <#{rendererData.postFragmentRendererPath}> \ No newline at end of file diff --git a/src/rendering/abufferrenderer.cpp b/src/rendering/abufferrenderer.cpp index 6c991102c7..402b2cc37e 100644 --- a/src/rendering/abufferrenderer.cpp +++ b/src/rendering/abufferrenderer.cpp @@ -39,6 +39,8 @@ #include #include + + #include #include @@ -46,8 +48,9 @@ namespace { const std::string _loggerCat = "ABufferRenderer"; const std::string BoundsFragmentShaderPath = "${SHADERS}/abuffer/boundsabuffer.frag"; const std::string RenderFragmentShaderPath = "${SHADERS}/abuffer/renderabuffer.frag"; + const std::string PostRenderFragmentShaderPath = "${SHADERS}/abuffer/postrenderabuffer.frag"; const int MaxRaycasters = 32; - const int MaxLayers = 16; + const int MaxLayers = 32; const int MaxAverageLayers = 8; } @@ -134,10 +137,14 @@ void ABufferRenderer::initialize() { try { + ghoul::Dictionary dict; + dict.setValue("resolveData", _resolveDictionary); + dict.setValue("rendererData", _rendererData); + _resolveProgram = ghoul::opengl::ProgramObject::Build("ABuffer Resolve", "${SHADERS}/abuffer/resolveabuffer.vert", "${SHADERS}/abuffer/resolveabuffer.frag", - _resolveDictionary); + dict); } catch (ghoul::RuntimeError e) { LERROR(e.message); } @@ -192,7 +199,10 @@ void ABufferRenderer::update() { if (_dirtyResolveDictionary) { updateResolveDictionary(); - _resolveProgram->setDictionary(_resolveDictionary); + ghoul::Dictionary dict; + dict.setValue("resolveData", _resolveDictionary); + dict.setValue("rendererData", _rendererData); + _resolveProgram->setDictionary(dict); } // If the resolve dictionary changed (or a file changed on disk) @@ -222,6 +232,16 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement if (_scene == nullptr) return; if (_camera == nullptr) return; + + + _mainColorTextureUnit = std::make_unique(); + _mainColorTextureUnit->activate(); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); + + _mainDepthTextureUnit = std::make_unique(); + _mainDepthTextureUnit->activate(); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLint defaultFbo; @@ -246,6 +266,9 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement RendererTasks tasks; _scene->render(data, tasks); + _rendererTasks = std::make_unique(tasks); + _renderData = std::make_unique(data); + _blackoutFactor = blackoutFactor; glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo); @@ -269,44 +292,65 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement // Step 3: Resolve the buffer _resolveProgram->activate(); - ghoul::opengl::TextureUnit mainColorTextureUnit; - mainColorTextureUnit.activate(); - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); - ghoul::opengl::TextureUnit mainDepthTextureUnit; - mainDepthTextureUnit.activate(); - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture); + // TEMPORARY GAMMA CORRECTION. - _resolveProgram->setUniform("mainColorTexture", mainColorTextureUnit); - _resolveProgram->setUniform("mainDepthTexture", mainDepthTextureUnit); + float gamma = 1.0; + glm::vec3 cameraPos = data.camera.position().vec3(); + float maxComponent = std::max(std::max(std::abs(cameraPos.x), std::abs(cameraPos.y)), std::abs(cameraPos.z)); + float logDistance = std::log(glm::length(cameraPos / maxComponent) * maxComponent) / std::log(10); - // 3a: Perform the pre-raycast step for all raycaster tasks. - for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) { - VolumeRaycaster* raycaster = raycasterTask.raycaster; - auto raycastData = _raycastData.find(raycaster); - if (raycastData != _raycastData.end()) { - raycaster->preRaycast(raycastData->second, *_resolveProgram.get()); + float minLogDist = 15; + float maxLogDist = 20; + + float t = (logDistance - minLogDist) / (maxLogDist - minLogDist); + t = glm::clamp(t, 0.0f, 1.0f); + gamma = 1.0 * (1 - t) + 2.2 * t; + + _resolveProgram->setUniform("gamma", gamma); + + // END TEMPORARY GAMMA CORRECTION. + + preRaycast(*_resolveProgram); + glBindVertexArray(_screenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + postRaycast(*_resolveProgram); + + _resolveProgram->deactivate(); + + _scene->postRender(data); + + _mainColorTextureUnit = nullptr; + _mainDepthTextureUnit = nullptr; +} + + +void ABufferRenderer::preRaycast(ghoul::opengl::ProgramObject& program) { + + program.setUniform("mainColorTexture", _mainColorTextureUnit->unitNumber()); + program.setUniform("mainDepthTexture", _mainDepthTextureUnit->unitNumber()); + + for (const auto& raycastData : _raycastData) { + raycastData.first->preRaycast(raycastData.second, program); + + glm::vec3 localCameraPosition; + bool cameraIsInside = raycastData.first->cameraIsInside(*_renderData, localCameraPosition); + program.setUniform("insideRaycaster" + std::to_string(raycastData.second.id), cameraIsInside); + if (cameraIsInside) { + program.setUniform("cameraPosInRaycaster" + std::to_string(raycastData.second.id), localCameraPosition); } } // 3b: Set "global" uniforms, and start the resolve pass. - _resolveProgram->setUniform("blackoutFactor", blackoutFactor); - _resolveProgram->setUniform("nAaSamples", _nAaSamples); - glBindVertexArray(_screenQuad); - glDrawArrays(GL_TRIANGLES, 0, 6); - - // 3c: Perform the post-raycast step for all raycaster tasks. - for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) { - VolumeRaycaster* raycaster = raycasterTask.raycaster; - auto raycastData = _raycastData.find(raycaster); - if (raycastData != _raycastData.end()) { - raycaster->postRaycast(raycastData->second, *_resolveProgram.get()); - } - } - - _resolveProgram->deactivate(); + program.setUniform("blackoutFactor", _blackoutFactor); + program.setUniform("nAaSamples", _nAaSamples); } +void ABufferRenderer::postRaycast(ghoul::opengl::ProgramObject& program) { + for (const auto& raycastData : _raycastData) { + raycastData.first->postRaycast(raycastData.second, program); + } +} void ABufferRenderer::setScene(Scene* scene) { _scene = scene; @@ -415,11 +459,14 @@ void ABufferRenderer::updateResolveDictionary() { } dict.setValue("helperPaths", helperPathsDict); - dict.setValue("rendererData", _rendererData); dict.setValue("raycastingEnabled", _raycastData.size() > 0); + dict.setValue("storeSorted", true); dict.setValue("nRaycasters", static_cast(_raycastData.size())); _resolveDictionary = dict; + + OsEng.renderEngine().setResolveData(dict); + _dirtyResolveDictionary = false; } @@ -496,6 +543,7 @@ void ABufferRenderer::updateRendererData() { dict.setValue("windowWidth", _resolution.x); dict.setValue("windowHeight", _resolution.y); dict.setValue("fragmentRendererPath", std::string(RenderFragmentShaderPath)); + dict.setValue("postFragmentRendererPath", std::string(PostRenderFragmentShaderPath)); dict.setValue("maxLayers", MaxLayers); dict.setValue("maxTotalFragments", MaxLayers * _resolution.x * _resolution.y); diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 096de78beb..f4dbf27dea 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -44,6 +44,7 @@ namespace { const std::string ExitFragmentShaderPath = "${SHADERS}/framebuffer/exitframebuffer.frag"; const std::string RaycastFragmentShaderPath = "${SHADERS}/framebuffer/raycastframebuffer.frag"; const std::string RenderFragmentShaderPath = "${SHADERS}/framebuffer/renderframebuffer.frag"; + const std::string PostRenderFragmentShaderPath = "${SHADERS}/framebuffer/postrenderframebuffer.frag"; } namespace openspace { @@ -400,7 +401,8 @@ void FramebufferRenderer::setResolution(glm::ivec2 res) { void FramebufferRenderer::updateRendererData() { ghoul::Dictionary dict; - dict.setValue("fragmentRendererPath", RenderFragmentShaderPath); + dict.setValue("fragmentRendererPath", std::string(RenderFragmentShaderPath)); + dict.setValue("postFragmentRendererPath", std::string(PostRenderFragmentShaderPath)); dict.setValue("windowWidth", _resolution.x); dict.setValue("windowHeight", _resolution.y); diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 11ee989c06..7122fb2f1f 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -121,6 +121,10 @@ void Renderable::render(const RenderData& data) { } +void Renderable::postRender(const RenderData& data) +{ +} + void Renderable::setPscUniforms( ghoul::opengl::ProgramObject& program, const Camera& camera, diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 0fbe969b63..52f4f8cedd 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -92,6 +92,7 @@ namespace { std::chrono::seconds ScreenLogTimeToLive(15); const std::string DefaultRenderingMethod = "ABuffer"; const std::string RenderFsPath = "${SHADERS}/render.frag"; + const std::string PostRenderFsPath = "${SHADERS}/postrender.frag"; } namespace openspace { @@ -486,7 +487,8 @@ std::unique_ptr RenderEngine::buildRenderProgram( std::string name, std::string vsPath, std::string fsPath, - const ghoul::Dictionary& data) { + const ghoul::Dictionary& data, + RenderEngine::RenderProgramType type) { ghoul::Dictionary dict = data; @@ -497,10 +499,16 @@ std::unique_ptr RenderEngine::buildRenderProgram( // instead of a void main() setting glFragColor, glFragDepth, etc. dict.setValue("fragmentPath", fsPath); + if (type == RenderEngine::RenderProgramType::Post) { + dict.setValue("resolveData", _resolveData); + } + + std::string path = (type == RenderEngine::RenderProgramType::Post) ? PostRenderFsPath : RenderFsPath; + std::unique_ptr program = ghoul::opengl::ProgramObject::Build( name, vsPath, - RenderFsPath, + path, dict); if (program) { @@ -517,20 +525,27 @@ std::unique_ptr RenderEngine::buildRenderProgram( std::string vsPath, std::string fsPath, std::string csPath, - const ghoul::Dictionary& data) { + const ghoul::Dictionary& data, + RenderEngine::RenderProgramType type) { ghoul::Dictionary dict = data; dict.setValue("rendererData", _rendererData); + if (type == RenderEngine::RenderProgramType::Post) { + dict.setValue("resolveData", _resolveData); + } + // parameterize the main fragment shader program with specific contents. // fsPath should point to a shader file defining a Fragment getFragment() function // instead of a void main() setting glFragColor, glFragDepth, etc. dict.setValue("fragmentPath", fsPath); + std::string path = (type == RenderEngine::RenderProgramType::Post) ? PostRenderFsPath : RenderFsPath; + std::unique_ptr program = ghoul::opengl::ProgramObject::Build( name, vsPath, - RenderFsPath, + path, csPath, dict); @@ -567,6 +582,37 @@ void RenderEngine::setRendererData(const ghoul::Dictionary& data) { } } + +/** +* Set resolve data +* Called from the renderer, whenever it needs to update +* the dictionary of all post rendering programs. +*/ +void RenderEngine::setResolveData(const ghoul::Dictionary& data) { + _resolveData = data; + for (auto program : _programs) { + ghoul::Dictionary dict = program->dictionary(); + dict.setValue("resolveData", _resolveData); + program->setDictionary(dict); + } +} + +/** +* Set raycasting uniforms on the program object, and setup raycasting. +*/ +void RenderEngine::preRaycast(ghoul::opengl::ProgramObject& programObject) { + _renderer->preRaycast(programObject); +} + +/** +* Tear down raycasting for the specified program object. +*/ +void RenderEngine::postRaycast(ghoul::opengl::ProgramObject& programObject) { + _renderer->postRaycast(programObject); +} + + + /** * Set renderer */ diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index 20a8b7de6e..8e17a8a7b9 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -122,6 +122,12 @@ void Scene::render(const RenderData& data, RendererTasks& tasks) { } } +void Scene::postRender(const RenderData& data) { + for (SceneGraphNode* node : _graph.nodes()) { + node->postRender(data); + } +} + void Scene::scheduleLoadSceneFile(const std::string& sceneDescriptionFilePath) { _sceneGraphToLoad = sceneDescriptionFilePath; } diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index 21d2343a24..ca0278cbfc 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -269,6 +269,18 @@ void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) { // child->render(newData); } +void SceneGraphNode::postRender(const RenderData& data) { + const psc thisPosition = worldPosition(); + RenderData newData = { data.camera, thisPosition, data.doPerformanceMeasurement }; + + _performanceRecord.renderTime = 0; + if (_renderableVisible && _renderable->isVisible() && _renderable->isReady() && _renderable->isEnabled()) { + _renderable->postRender(newData); + } +} + + + // not used anymore @AA //void SceneGraphNode::addNode(SceneGraphNode* child) From b5466e0a96c189efd0478c50f01fdc261bd3f000 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 3 Jun 2016 15:53:50 +0200 Subject: [PATCH 24/61] Project images of RenderablePlanetProjection into a separate texture layer that can be cleared faster --- ext/ghoul | 2 +- .../rendering/renderableplanetprojection.cpp | 244 ++++++------------ .../rendering/renderableplanetprojection.h | 28 +- modules/newhorizons/shaders/fboPass_fs.glsl | 39 ++- .../shaders/projectiveTexture_fs.glsl | 9 +- 5 files changed, 121 insertions(+), 201 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 8e2fe2b626..b642b91cd2 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 8e2fe2b62604e88356e5e41a8be3be3f5557343f +Subproject commit b642b91cd26410f772bbc481946ab9204d143cc5 diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index b2ee2f1207..e57fff0937 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -41,6 +41,8 @@ #include +#include + #include #include #include @@ -77,33 +79,24 @@ namespace { const std::string sequenceTypeImage = "image-sequence"; const std::string sequenceTypePlaybook = "playbook"; const std::string sequenceTypeHybrid = "hybrid"; - } namespace openspace { -//#define ORIGINAL_SEQUENCER - RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _colorTexturePath("planetTexture", "RGB Texture") , _heightMapTexturePath("heightMap", "Heightmap Texture") - , _projectionTexturePath("projectionTexture", "RGB Texture") , _rotation("rotation", "Rotation", 0, 0, 360) - //, _fadeProjection("fadeProjections", "Image Fading Factor", 0.f, 0.f, 1.f) , _performProjection("performProjection", "Perform Projections", true) , _clearAllProjections("clearAllProjections", "Clear Projections", false) , _heightExaggeration("heightExaggeration", "Height Exaggeration", 1.f, 0.f, 100.f) - , _enableNormalMapping("enableNormalMapping", "Enable Normal Mapping", true) , _programObject(nullptr) , _fboProgramObject(nullptr) - , _texture(nullptr) - , _textureOriginal(nullptr) - , _textureProj(nullptr) + , _baseTexture(nullptr) + , _projectionTexture(nullptr) , _heightMapTexture(nullptr) - , _geometry(nullptr) , _capture(false) - , _hasHeightMap(false) , _clearingImage(absPath("${OPENSPACE_DATA}/scene/common/textures/clear.png")) { std::string name; @@ -115,7 +108,10 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& keyGeometry, geometryDictionary); if (success) { geometryDictionary.setValue(SceneGraphNode::KeyName, name); - _geometry = planetgeometry::PlanetGeometry::createFromDictionary(geometryDictionary); + using planetgeometry::PlanetGeometry; + _geometry = std::unique_ptr( + PlanetGeometry::createFromDictionary(geometryDictionary) + ); } dictionary.getValue(keyFrame, _frame); @@ -134,15 +130,6 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& bool b7 = dictionary.getValue(keyInstrumentNear, _nearPlane); bool b8 = dictionary.getValue(keyInstrumentFar, _farPlane); - ghoul_assert(b1, ""); - ghoul_assert(b2, ""); - ghoul_assert(b3, ""); - ghoul_assert(b4, ""); - ghoul_assert(b5, ""); - ghoul_assert(b6, ""); - ghoul_assert(b7, ""); - ghoul_assert(b8, ""); - // @TODO copy-n-paste from renderablefov ---abock ghoul::Dictionary potentialTargets; success = dictionary.getValue(keyPotentialTargets, potentialTargets); @@ -162,36 +149,24 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& if (success){ _colorTexturePath = absPath(texturePath); } - success = dictionary.getValue("Textures.Project", texturePath); - if (success){ - _projectionTexturePath = absPath(texturePath); - } std::string heightMapPath = ""; success = dictionary.getValue("Textures.Height", heightMapPath); - if (success) { + if (success) _heightMapTexturePath = absPath(heightMapPath); - _hasHeightMap = true; - } - addPropertySubOwner(_geometry); - addProperty(_rotation); - //addProperty(_fadeProjection); + addPropertySubOwner(_geometry.get()); addProperty(_performProjection); addProperty(_clearAllProjections); addProperty(_colorTexturePath); - _colorTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this)); + _colorTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTextures, this)); addProperty(_heightMapTexturePath); - _heightMapTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this)); - - addProperty(_projectionTexturePath); - _projectionTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadProjectionTexture, this)); + _heightMapTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTextures, this)); addProperty(_heightExaggeration); - addProperty(_enableNormalMapping); SequenceParser* parser; @@ -274,13 +249,10 @@ bool RenderablePlanetProjection::initialize() { "${MODULE_NEWHORIZONS}/shaders/fboPass_vs.glsl", "${MODULE_NEWHORIZONS}/shaders/fboPass_fs.glsl" ); - - loadTexture(); - loadProjectionTexture(); - completeSuccess &= (_texture != nullptr); - completeSuccess &= (_textureOriginal != nullptr); - completeSuccess &= (_textureProj != nullptr); + loadTextures(); + completeSuccess &= (_baseTexture != nullptr); + completeSuccess &= (_projectionTexture != nullptr); completeSuccess &= _geometry->initialize(this); if (completeSuccess) @@ -291,8 +263,6 @@ bool RenderablePlanetProjection::initialize() { bool RenderablePlanetProjection::auxiliaryRendertarget() { bool completeSuccess = true; - if (!_texture) - return false; GLint defaultFBO; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); @@ -300,7 +270,7 @@ bool RenderablePlanetProjection::auxiliaryRendertarget() { // setup FBO glGenFramebuffers(1, &_fboID); glBindFramebuffer(GL_FRAMEBUFFER, _fboID); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_texture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_projectionTexture, 0); // check FBO status GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) @@ -336,10 +306,7 @@ bool RenderablePlanetProjection::auxiliaryRendertarget() { } bool RenderablePlanetProjection::deinitialize() { - _texture = nullptr; - _textureProj = nullptr; - _textureOriginal = nullptr; - delete _geometry; + _baseTexture = nullptr; _geometry = nullptr; RenderEngine& renderEngine = OsEng.renderEngine(); @@ -348,15 +315,15 @@ bool RenderablePlanetProjection::deinitialize() { _programObject = nullptr; } + _fboProgramObject = nullptr; + return true; } bool RenderablePlanetProjection::isReady() const { - return _geometry && _programObject && _texture; + return _geometry && _programObject && _baseTexture && _projectionTexture; } -void RenderablePlanetProjection::imageProjectGPU() { - glDisable(GL_DEPTH_TEST); - +void RenderablePlanetProjection::imageProjectGPU(std::unique_ptr projectionTexture) { // keep handle to the current bound FBO GLint defaultFBO; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); @@ -365,24 +332,15 @@ void RenderablePlanetProjection::imageProjectGPU() { glGetIntegerv(GL_VIEWPORT, m_viewport); //counter = 0; glBindFramebuffer(GL_FRAMEBUFFER, _fboID); - // set blend eq - glEnable(GL_BLEND); - glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ZERO); - glViewport(0, 0, static_cast(_texture->width()), static_cast(_texture->height())); + glViewport(0, 0, static_cast(_projectionTexture->width()), static_cast(_projectionTexture->height())); _fboProgramObject->activate(); ghoul::opengl::TextureUnit unitFbo; unitFbo.activate(); - _textureProj->bind(); + projectionTexture->bind(); _fboProgramObject->setUniform("projectionTexture", unitFbo); - ghoul::opengl::TextureUnit unitFbo2; - unitFbo2.activate(); - _textureOriginal->bind(); - _fboProgramObject->setUniform("baseTexture", unitFbo2); - _fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix); _fboProgramObject->setUniform("ModelTransform" , _transform); _fboProgramObject->setUniform("_scaling" , _camScaling); @@ -408,14 +366,11 @@ void RenderablePlanetProjection::imageProjectGPU() { glBindVertexArray(_quad); glDrawArrays(GL_TRIANGLES, 0, 6); _fboProgramObject->deactivate(); - //glDisable(GL_BLEND); //bind back to default glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); glViewport(m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3]); - - glEnable(GL_DEPTH_TEST); } glm::mat4 RenderablePlanetProjection::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up) { @@ -469,6 +424,7 @@ void RenderablePlanetProjection::attitudeParameters(double time) { return; } + double lightTime; glm::dvec3 p = SpiceManager::ref().targetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, lightTime); psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); @@ -480,53 +436,33 @@ void RenderablePlanetProjection::attitudeParameters(double time) { _projectorMatrix = computeProjectorMatrix(cpos, bs, _up); } -void RenderablePlanetProjection::project() { - // If high dt -> results in GPU queue overflow - // switching to using a simple queue to distribute - // images 1 image / frame -> projections appear slower - // but less viewable lagg for the sim overall. - - // Comment out if not using queue and prefer old method ------------- - // + in update() function - //if (!imageQueue.empty()){ - // Image& img = imageQueue.front(); - // RenderablePlanetProjection::attitudeParameters(img.startTime); - // // if image has new path - ie actual image, NOT placeholder - // if (_projectionTexturePath.value() != img.path){ - // // rebind and upload - // _projectionTexturePath = img.path; - // } - // imageProjectGPU(); // fbopass - // imageQueue.pop(); - //} - // ------------------------------------------------------------------ - - //---- Old method --- // - // @mm - for (const Image& img : _imageTimes) { - RenderablePlanetProjection::attitudeParameters(img.startTime); - if (_projectionTexturePath.value() != img.path){ - _projectionTexturePath = img.path; // path to current images - } - imageProjectGPU(); // fbopass - } - _capture = false; -} - void RenderablePlanetProjection::clearAllProjections() { - //float tmp = _fadeProjection; - //_fadeProjection = 1.f; - _projectionTexturePath = _clearingImage; - imageProjectGPU(); - //_fadeProjection = tmp; + // keep handle to the current bound FBO + GLint defaultFBO; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); + + GLint m_viewport[4]; + glGetIntegerv(GL_VIEWPORT, m_viewport); + //counter = 0; + glBindFramebuffer(GL_FRAMEBUFFER, _fboID); + + glViewport(0, 0, static_cast(_projectionTexture->width()), static_cast(_projectionTexture->height())); + _fboProgramObject->activate(); + + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + + //bind back to default + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + glViewport(m_viewport[0], m_viewport[1], + m_viewport[2], m_viewport[3]); + _clearAllProjections = false; } void RenderablePlanetProjection::render(const RenderData& data) { if (!_programObject) return; - if (!_textureProj) - return; if (_clearAllProjections) clearAllProjections(); @@ -534,8 +470,13 @@ void RenderablePlanetProjection::render(const RenderData& data) { _camScaling = data.camera.scaling(); _up = data.camera.lookUpVector(); - if (_capture && _performProjection) - project(); + if (_capture && _performProjection) { + for (const Image& img : _imageTimes) { + RenderablePlanetProjection::attitudeParameters(img.startTime); + imageProjectGPU(loadProjectionTexture(img.path)); + } + _capture = false; + } attitudeParameters(_time); _imageTimes.clear(); @@ -546,41 +487,40 @@ void RenderablePlanetProjection::render(const RenderData& data) { // Main renderpass _programObject->activate(); - // setup the data to the shader _programObject->setUniform("sun_pos", sun_pos.vec3()); _programObject->setUniform("ViewProjection" , data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform" , _transform); - _programObject->setUniform("_hasHeightMap", _hasHeightMap); + _programObject->setUniform("_hasHeightMap", _heightMapTexture != nullptr); _programObject->setUniform("_heightExaggeration", _heightExaggeration); setPscUniforms(*_programObject.get(), data.camera, data.position); - ghoul::opengl::TextureUnit unit[2]; + ghoul::opengl::TextureUnit unit[3]; unit[0].activate(); - _texture->bind(); + _baseTexture->bind(); _programObject->setUniform("baseTexture", unit[0]); - if (_hasHeightMap) { - unit[1].activate(); + unit[1].activate(); + _projectionTexture->bind(); + _programObject->setUniform("projectionTexture", unit[1]); + + if (_heightMapTexture) { + unit[2].activate(); _heightMapTexture->bind(); - _programObject->setUniform("heightTexture", unit[1]); + _programObject->setUniform("heightTexture", unit[2]); } - // render geometry _geometry->render(); - // disable shader _programObject->deactivate(); } void RenderablePlanetProjection::update(const UpdateData& data) { - //if (data.isTimeJump) { if (_time >= Time::ref().currentTime()) { // if jump back in time -> empty queue. imageQueue = std::queue(); } - //_time = data.time; _time = Time::ref().currentTime(); _capture = false; @@ -593,55 +533,43 @@ void RenderablePlanetProjection::update(const UpdateData& data) { _fboProgramObject->rebuildFromFile(); } - // remove these lines if not using queue ------------------------ - // @mm - //_capture = true; - //for (auto img : _imageTimes){ - // imageQueue.push(img); - //} - //_imageTimes.clear(); - // -------------------------------------------------------------- - if (_programObject->isDirty()) _programObject->rebuildFromFile(); } -void RenderablePlanetProjection::loadProjectionTexture() { - _textureProj = nullptr; - if (_projectionTexturePath.value() != "") { - _textureProj = ghoul::io::TextureReader::ref().loadTexture(absPath(_projectionTexturePath)); - if (_textureProj) { - ghoul::opengl::convertTextureFormat(ghoul::opengl::Texture::Format::RGB, *_textureProj); - _textureProj->uploadTexture(); - // TODO: AnisotropicMipMap crashes on ATI cards ---abock - //_textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); - _textureProj->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - _textureProj->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); - } +std::unique_ptr RenderablePlanetProjection::loadProjectionTexture(const std::string& texturePath) { + std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(texturePath)); + if (texture) { + ghoul::opengl::convertTextureFormat(ghoul::opengl::Texture::Format::RGB, *texture); + texture->uploadTexture(); + // TODO: AnisotropicMipMap crashes on ATI cards ---abock + //_textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); } + return texture; } -void RenderablePlanetProjection::loadTexture() { +void RenderablePlanetProjection::loadTextures() { using ghoul::opengl::Texture; - _texture = nullptr; + _baseTexture = nullptr; if (_colorTexturePath.value() != "") { - _texture = ghoul::io::TextureReader::ref().loadTexture(_colorTexturePath); - if (_texture) { - ghoul::opengl::convertTextureFormat(Texture::Format::RGB, *_texture); - _texture->uploadTexture(); - _texture->setFilter(Texture::FilterMode::Linear); + _baseTexture = ghoul::io::TextureReader::ref().loadTexture(_colorTexturePath); + if (_baseTexture) { + ghoul::opengl::convertTextureFormat(Texture::Format::RGB, *_baseTexture); + _baseTexture->uploadTexture(); + _baseTexture->setFilter(Texture::FilterMode::Linear); } } - _textureOriginal = nullptr; - if (_colorTexturePath.value() != "") { - _textureOriginal = ghoul::io::TextureReader::ref().loadTexture(_colorTexturePath); - if (_textureOriginal) { - ghoul::opengl::convertTextureFormat(Texture::Format::RGB, *_textureOriginal); - _textureOriginal->uploadTexture(); - _textureOriginal->setFilter(Texture::FilterMode::Linear); - } - } + int maxSize = OpenGLCap.max2DTextureSize() / 2; + + LINFO("Creating projection texture of size '" << maxSize << ", " << maxSize/2 << "'"); + _projectionTexture = std::make_unique( + glm::uvec3(maxSize, maxSize / 2, 1), + Texture::Format::RGBA + ); + _projectionTexture->uploadTexture(); _heightMapTexture = nullptr; if (_heightMapTexturePath.value() != "") { diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index 94762f86b2..8f2f52829a 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -70,45 +70,37 @@ public: void render(const RenderData& data) override; void update(const UpdateData& data) override; - ghoul::opengl::Texture* baseTexture() { return _texture.get(); }; + ghoul::opengl::Texture* baseTexture() { return _projectionTexture.get(); }; protected: - - void loadTexture(); - void loadProjectionTexture(); + void loadTextures(); + std::unique_ptr loadProjectionTexture(const std::string& texturePath); bool auxiliaryRendertarget(); glm::mat4 computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up); void attitudeParameters(double time); - void project(); void clearAllProjections(); private: - void imageProjectGPU(); + void imageProjectGPU(std::unique_ptr projectionTexture); - std::map _fileTranslation; - - properties::StringProperty _colorTexturePath; + properties::StringProperty _colorTexturePath; properties::StringProperty _heightMapTexturePath; - properties::StringProperty _projectionTexturePath; properties::IntProperty _rotation; - //properties::FloatProperty _fadeProjection; properties::BoolProperty _performProjection; properties::BoolProperty _clearAllProjections; std::unique_ptr _programObject; std::unique_ptr _fboProgramObject; - std::unique_ptr _texture; - std::unique_ptr _textureOriginal; - std::unique_ptr _textureProj; + std::unique_ptr _baseTexture; + std::unique_ptr _projectionTexture; std::unique_ptr _heightMapTexture; properties::FloatProperty _heightExaggeration; - properties::BoolProperty _enableNormalMapping; - planetgeometry::PlanetGeometry* _geometry; + std::unique_ptr _geometry; glm::vec2 _camScaling; glm::vec3 _up; @@ -138,9 +130,6 @@ private: glm::vec3 _boresight; double _time; - double _previousTime; - double _previousCapture; - double lightTime; std::vector _imageTimes; int _sequenceID; @@ -157,7 +146,6 @@ private: GLuint _quad; GLuint _vertexPositionBuffer; - bool _hasHeightMap; std::queue imageQueue; }; diff --git a/modules/newhorizons/shaders/fboPass_fs.glsl b/modules/newhorizons/shaders/fboPass_fs.glsl index 6f673c134a..8c4384164b 100644 --- a/modules/newhorizons/shaders/fboPass_fs.glsl +++ b/modules/newhorizons/shaders/fboPass_fs.glsl @@ -30,7 +30,6 @@ in vec4 vs_position; out vec4 color; uniform sampler2D projectionTexture; -uniform sampler2D baseTexture; uniform mat4 ProjectorMatrix; uniform mat4 ModelTransform; @@ -64,29 +63,27 @@ bool inRange(float x, float a, float b){ } void main() { - vec2 uv = (vs_position.xy + vec2(1.0)) / vec2(2.0); - - vec4 vertex = uvToModel(uv, _radius, _segments); - - vec4 raw_pos = psc_to_meter(vertex, _scaling); - vec4 projected = ProjectorMatrix * ModelTransform * raw_pos; - - projected.x /= projected.w; - projected.y /= projected.w; - - vec3 normal = normalize((ModelTransform*vec4(vertex.xyz,0)).xyz); - - vec3 v_b = normalize(boresight); - - if((inRange(projected.x, 0, 1) && + vec2 uv = (vs_position.xy + vec2(1.0)) / vec2(2.0); + + vec4 vertex = uvToModel(uv, _radius, _segments); + + vec4 raw_pos = psc_to_meter(vertex, _scaling); + vec4 projected = ProjectorMatrix * ModelTransform * raw_pos; + + projected.x /= projected.w; + projected.y /= projected.w; + + vec3 normal = normalize((ModelTransform*vec4(vertex.xyz,0)).xyz); + + vec3 v_b = normalize(boresight); + + if((inRange(projected.x, 0, 1) && inRange(projected.y, 0, 1)) && dot(v_b, normal) < 0 ) - { + { // The 1-x is in this texture call because of flipped textures // to be fixed soon ---abock color = texture(projectionTexture, vec2(projected.x, 1-projected.y)); - } else { - color = texture(baseTexture, uv); - color.a = 0.0; - } + color.a = 1.0; + } } \ No newline at end of file diff --git a/modules/newhorizons/shaders/projectiveTexture_fs.glsl b/modules/newhorizons/shaders/projectiveTexture_fs.glsl index 221c59b171..a37f9fbca3 100644 --- a/modules/newhorizons/shaders/projectiveTexture_fs.glsl +++ b/modules/newhorizons/shaders/projectiveTexture_fs.glsl @@ -31,6 +31,7 @@ in vec4 vs_normal; in vec4 ProjTexCoord; uniform sampler2D baseTexture; +uniform sampler2D projectionTexture; uniform vec4 objpos; uniform vec3 sun_pos; @@ -55,8 +56,14 @@ Fragment getFragment() { vec4 specular = vec4(0.1); vec4 ambient = vec4(0.f,0.f,0.f,1); + vec4 textureColor = texture(baseTexture, vs_st); + vec4 projectionColor = texture(projectionTexture, vs_st); + if (projectionColor.a != 0.0) { + textureColor.rgb = mix(textureColor.rgb, projectionColor.rgb, projectionColor.a); + } + Fragment frag; - frag.color = max(intensity * texture(baseTexture, vs_st), ambient); + frag.color = max(intensity * textureColor, ambient); frag.depth = depth; return frag; From 63fb61b783092b94a317d382f575f83bec7605a0 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 3 Jun 2016 15:57:48 +0200 Subject: [PATCH 25/61] Add a slider for fading the projection in and out --- .../newhorizons/rendering/renderableplanetprojection.cpp | 3 +++ .../newhorizons/rendering/renderableplanetprojection.h | 2 ++ modules/newhorizons/shaders/projectiveTexture_fs.glsl | 9 ++++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index e57fff0937..7b76281096 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -90,6 +90,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& , _rotation("rotation", "Rotation", 0, 0, 360) , _performProjection("performProjection", "Perform Projections", true) , _clearAllProjections("clearAllProjections", "Clear Projections", false) + , _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f) , _heightExaggeration("heightExaggeration", "Height Exaggeration", 1.f, 0.f, 100.f) , _programObject(nullptr) , _fboProgramObject(nullptr) @@ -166,6 +167,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& addProperty(_heightMapTexturePath); _heightMapTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTextures, this)); + addProperty(_projectionFading); addProperty(_heightExaggeration); SequenceParser* parser; @@ -493,6 +495,7 @@ void RenderablePlanetProjection::render(const RenderData& data) { _programObject->setUniform("_hasHeightMap", _heightMapTexture != nullptr); _programObject->setUniform("_heightExaggeration", _heightExaggeration); + _programObject->setUniform("_projectionFading", _projectionFading); setPscUniforms(*_programObject.get(), data.camera, data.position); diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index 8f2f52829a..97bed69da9 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -98,6 +98,8 @@ private: std::unique_ptr _projectionTexture; std::unique_ptr _heightMapTexture; + properties::FloatProperty _projectionFading; + properties::FloatProperty _heightExaggeration; std::unique_ptr _geometry; diff --git a/modules/newhorizons/shaders/projectiveTexture_fs.glsl b/modules/newhorizons/shaders/projectiveTexture_fs.glsl index a37f9fbca3..2a5600e228 100644 --- a/modules/newhorizons/shaders/projectiveTexture_fs.glsl +++ b/modules/newhorizons/shaders/projectiveTexture_fs.glsl @@ -33,6 +33,8 @@ in vec4 ProjTexCoord; uniform sampler2D baseTexture; uniform sampler2D projectionTexture; +uniform float _projectionFading; + uniform vec4 objpos; uniform vec3 sun_pos; @@ -59,9 +61,14 @@ Fragment getFragment() { vec4 textureColor = texture(baseTexture, vs_st); vec4 projectionColor = texture(projectionTexture, vs_st); if (projectionColor.a != 0.0) { - textureColor.rgb = mix(textureColor.rgb, projectionColor.rgb, projectionColor.a); + textureColor.rgb = mix( + textureColor.rgb, + projectionColor.rgb, + min(_projectionFading, projectionColor.a) + ); } + Fragment frag; frag.color = max(intensity * textureColor, ambient); frag.depth = depth; From 104cbcfd39b50424afef5e2488f70acfcbacbff7 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 3 Jun 2016 16:02:51 +0200 Subject: [PATCH 26/61] Update Pluto textures to remove superfluous textures --- data/scene/newhorizons/pluto/pluto/pluto.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/scene/newhorizons/pluto/pluto/pluto.data b/data/scene/newhorizons/pluto/pluto/pluto.data index 626f2eb2b5..fff1025604 100644 --- a/data/scene/newhorizons/pluto/pluto/pluto.data +++ b/data/scene/newhorizons/pluto/pluto/pluto.data @@ -1,7 +1,7 @@ return { FileRequest = { { Identifier = "newhorizons_plutoencounter_pluto_assets", Destination = "assets", Version = 1 }, - { Identifier = "newhorizons_plutoencounter_pluto_textures", Destination = "textures", Version = 2 }, + { Identifier = "newhorizons_plutoencounter_pluto_textures", Destination = "textures", Version = 3 }, { Identifier = "pluto_textures", Destination = "textures", Version = 2 }, { Identifier = "newhorizons_plutoencounter_pluto_images", Destination = "images", Version = 1 } }, From 239ac0ab4ef110e2dc758dfaaffea44de54a5157 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 3 Jun 2016 16:54:41 +0200 Subject: [PATCH 27/61] Project images of RenderableModelProjection into a separate texture layer that can be cleared faster --- .../rendering/renderablemodelprojection.cpp | 175 +++++++----------- .../rendering/renderablemodelprojection.h | 14 +- .../newhorizons/shaders/modelShader_fs.glsl | 51 +++-- .../newhorizons/shaders/modelShader_vs.glsl | 21 +-- .../shaders/projectionPass_fs.glsl | 10 +- .../shaders/projectiveTexture_fs.glsl | 3 +- .../shaders/projectiveTexture_vs.glsl | 3 +- 7 files changed, 105 insertions(+), 172 deletions(-) diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 1ebec0fd96..04744774b4 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -35,6 +35,8 @@ #include #include +#include + #define _USE_MATH_DEFINES #include @@ -73,17 +75,14 @@ namespace openspace { RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _colorTexturePath("colorTexture", "Color Texture") - , _projectionTexturePath("projectionTexture", "RGB Texture") , _rotationX("rotationX", "RotationX", 0, 0, 360) , _rotationY("rotationY", "RotationY", 0, 0, 360) , _rotationZ("rotationZ", "RotationZ", 0, 0, 360) , _programObject(nullptr) , _fboProgramObject(nullptr) - , _texture(nullptr) + , _baseTexture(nullptr) + , _projectionTexture(nullptr) , _geometry(nullptr) - //, _textureOriginal(nullptr) - , _textureProj(nullptr) - , _textureWhiteSquare(nullptr) , _alpha(1.f) , _performShading("performShading", "Perform Shading", true) , _performProjection("performProjection", "Perform Projections", true) @@ -108,10 +107,6 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di if (success) _colorTexturePath = absPath(texturePath); - success = dictionary.getValue(keyTextureProject, texturePath); - if (success) - _projectionTexturePath = absPath(texturePath); - success = dictionary.getValue(keyTextureDefault, texturePath); if (success) _defaultProjImage = absPath(texturePath); @@ -119,9 +114,7 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di addPropertySubOwner(_geometry); addProperty(_colorTexturePath); - addProperty(_projectionTexturePath); - _colorTexturePath.onChange(std::bind(&RenderableModelProjection::loadTexture, this)); - _projectionTexturePath.onChange(std::bind(&RenderableModelProjection::loadProjectionTexture, this)); + _colorTexturePath.onChange(std::bind(&RenderableModelProjection::loadTextures, this)); dictionary.getValue(keySource, _source); dictionary.getValue(keyDestination, _destination); @@ -184,7 +177,8 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di bool RenderableModelProjection::isReady() const { bool ready = true; ready &= (_programObject != nullptr); - ready &= (_texture != nullptr); + ready &= (_baseTexture != nullptr); + ready &= (_projectionTexture != nullptr); return ready; } @@ -213,13 +207,10 @@ bool RenderableModelProjection::initialize() { } _fboProgramObject->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*) { this->_programIsDirty = true; } ); - loadTexture(); - loadProjectionTexture(); + loadTextures(); - completeSuccess &= (_texture != nullptr); - //completeSuccess &= (_textureOriginal != nullptr); - completeSuccess &= (_textureProj != nullptr); - completeSuccess &= (_textureWhiteSquare != nullptr); + completeSuccess &= (_baseTexture != nullptr); + completeSuccess &= (_projectionTexture != nullptr); completeSuccess &= _geometry->initialize(this); completeSuccess &= !_source.empty(); @@ -244,7 +235,7 @@ bool RenderableModelProjection::auxiliaryRendertarget() { glGenFramebuffers(1, &_fboID); glBindFramebuffer(GL_FRAMEBUFFER, _fboID); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_texture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_projectionTexture, 0); // check FBO status GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) @@ -288,10 +279,8 @@ bool RenderableModelProjection::deinitialize() { } _geometry = nullptr; - _texture = nullptr; - _textureProj = nullptr; - //_textureOriginal = nullptr; - _textureWhiteSquare = nullptr; + _baseTexture = nullptr; + _projectionTexture = nullptr; glDeleteBuffers(1, &_vbo); @@ -305,39 +294,30 @@ bool RenderableModelProjection::deinitialize() { } void RenderableModelProjection::clearAllProjections() { - _texture = nullptr; - if (_colorTexturePath.value() != "") { - _texture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath))); - if (_texture) { - LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); - _texture->uploadTexture(); - _texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - } - } - GLint defaultFBO; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); + + GLint m_viewport[4]; + glGetIntegerv(GL_VIEWPORT, m_viewport); glBindFramebuffer(GL_FRAMEBUFFER, _fboID); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_texture, 0); - // check FBO status - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - // switch back to window-system-provided framebuffer + + glViewport(0, 0, static_cast(_projectionTexture->width()), static_cast(_projectionTexture->height())); + + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + glViewport(m_viewport[0], m_viewport[1], + m_viewport[2], m_viewport[3]); + - //float tmp = _fadeProjection; - //_fadeProjection = 1.f; - //_projectionTexturePath = _clearingImage; - //imageProjectGPU(); - //_fadeProjection = tmp; _clearAllProjections = false; } void RenderableModelProjection::render(const RenderData& data) { if (!_programObject) return; - if (!_textureProj) - return; if (_clearAllProjections) clearAllProjections(); @@ -367,8 +347,6 @@ void RenderableModelProjection::render(const RenderData& data) { else _alpha = 1.0f; - _programObject->setUniform("ProjectorMatrix", _projectorMatrix); - _programObject->setUniform("boresight", _boresight); _programObject->setUniform("_performShading", _performShading); _programObject->setUniform("sun_pos", _sunPosition.vec3()); _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); @@ -377,7 +355,15 @@ void RenderableModelProjection::render(const RenderData& data) { _geometry->setUniforms(*_programObject); - textureBind(); + ghoul::opengl::TextureUnit unit[2]; + unit[0].activate(); + _baseTexture->bind(); + _programObject->setUniform("baseTexture", unit[0]); + + unit[1].activate(); + _projectionTexture->bind(); + _programObject->setUniform("projectionTexture", unit[1]); + _geometry->render(); // disable shader @@ -409,9 +395,7 @@ void RenderableModelProjection::update(const UpdateData& data) { _sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); } -void RenderableModelProjection::imageProjectGPU() { - glDisable(GL_DEPTH_TEST); - +void RenderableModelProjection::imageProjectGPU(std::unique_ptr projectionTexture) { // keep handle to the current bound FBO GLint defaultFBO; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); @@ -419,25 +403,17 @@ void RenderableModelProjection::imageProjectGPU() { GLint m_viewport[4]; glGetIntegerv(GL_VIEWPORT, m_viewport); glBindFramebuffer(GL_FRAMEBUFFER, _fboID); - // set blend eq - glEnable(GL_BLEND); - glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ZERO); - glViewport(0, 0, static_cast(_texture->width()), static_cast(_texture->height())); + glViewport(0, 0, static_cast(_projectionTexture->width()), static_cast(_projectionTexture->height())); _fboProgramObject->activate(); ghoul::opengl::TextureUnit unitFboProject; unitFboProject.activate(); - _textureProj->bind(); - _fboProgramObject->setUniform("projectTexture", unitFboProject); + projectionTexture->bind(); + _fboProgramObject->setUniform("projectionTexture", unitFboProject); - ghoul::opengl::TextureUnit unitFboCurrent; - unitFboCurrent.activate(); - _texture->bind(); - _fboProgramObject->setUniform("currentTexture", unitFboCurrent); _fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix); _fboProgramObject->setUniform("ModelTransform", _transform); _fboProgramObject->setUniform("_scaling", _camScaling); @@ -452,14 +428,9 @@ void RenderableModelProjection::imageProjectGPU() { _fboProgramObject->deactivate(); - - glDisable(GL_BLEND); - //bind back to default glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); glViewport(m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3]); - - glEnable(GL_DEPTH_TEST); } void RenderableModelProjection::attitudeParameters(double time) { @@ -528,67 +499,49 @@ glm::mat4 RenderableModelProjection::computeProjectorMatrix(const glm::vec3 loc, } -void RenderableModelProjection::textureBind() { - ghoul::opengl::TextureUnit unit[2]; - unit[0].activate(); - _texture->bind(); - _programObject->setUniform("currentTexture", unit[0]); - unit[1].activate(); - _textureWhiteSquare->bind(); - _programObject->setUniform("projectedTexture", unit[1]); -} - void RenderableModelProjection::project() { for (auto img : _imageTimes) { //std::thread t1(&RenderableModelProjection::attitudeParameters, this, img.startTime); //t1.join(); attitudeParameters(img.startTime); - _projectionTexturePath = img.path; - imageProjectGPU(); //fbopass + //_projectionTexturePath = img.path; + imageProjectGPU(loadProjectionTexture(img.path)); //fbopass } _capture = false; } -void RenderableModelProjection::loadTexture() { - _texture = nullptr; +void RenderableModelProjection::loadTextures() { + _baseTexture = nullptr; if (_colorTexturePath.value() != "") { - _texture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath))); - if (_texture) { + _baseTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath))); + if (_baseTexture) { LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); - _texture->uploadTexture(); - _texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - } - } - //_textureOriginal = nullptr; - //if (_colorTexturePath.value() != "") { - // _textureOriginal = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath))); - // if (_textureOriginal) { - // LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); - // _textureOriginal->uploadTexture(); - // _textureOriginal->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - // } - //} - _textureWhiteSquare = nullptr; - if (_defaultProjImage != "") { - _textureWhiteSquare = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_defaultProjImage))); - if (_textureWhiteSquare) { - _textureWhiteSquare->uploadTexture(); - _textureWhiteSquare->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + _baseTexture->uploadTexture(); + _baseTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); } } + + int maxSize = OpenGLCap.max2DTextureSize() / 2; + + LINFO("Creating projection texture of size '" << maxSize << ", " << maxSize / 2 << "'"); + _projectionTexture = std::make_unique( + glm::uvec3(maxSize, maxSize / 2, 1), + ghoul::opengl::Texture::Format::RGBA + ); + _projectionTexture->uploadTexture(); } -void RenderableModelProjection::loadProjectionTexture() { - _textureProj = nullptr; - if (_projectionTexturePath.value() != "") { - _textureProj = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_projectionTexturePath))); - if (_textureProj) { - _textureProj->uploadTexture(); - _textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); - _textureProj->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); - } +std::unique_ptr RenderableModelProjection::loadProjectionTexture(const std::string& texturePath) { + std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(texturePath)); + + if (texture) { + texture->uploadTexture(); + // TODO: AnisotropicMipMap crashes on ATI cards ---abock + //texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); } + return texture; } } // namespace openspace diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index 73e817ff53..d4161a3535 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -59,16 +59,15 @@ namespace openspace { protected: - void loadTexture(); - void loadProjectionTexture(); + void loadTextures(); + std::unique_ptr loadProjectionTexture(const std::string& texturePath); private: bool auxiliaryRendertarget(); glm::mat4 computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up); void attitudeParameters(double time); - void imageProjectGPU(); + void imageProjectGPU(std::unique_ptr projectionTexture); - void textureBind(); void project(); void clearAllProjections(); @@ -83,10 +82,8 @@ namespace openspace { std::unique_ptr _programObject; std::unique_ptr _fboProgramObject; - std::unique_ptr _texture; - std::unique_ptr _textureOriginal; - std::unique_ptr _textureProj; - std::unique_ptr _textureWhiteSquare; + std::unique_ptr _baseTexture; + std::unique_ptr _projectionTexture; modelgeometry::ModelGeometry* _geometry; @@ -94,7 +91,6 @@ namespace openspace { glm::dmat3 _stateMatrix; glm::dmat3 _instrumentMatrix; - properties::StringProperty _projectionTexturePath; std::string _defaultProjImage; std::string _source; std::string _destination; diff --git a/modules/newhorizons/shaders/modelShader_fs.glsl b/modules/newhorizons/shaders/modelShader_fs.glsl index b0f338ffee..0e46d121a2 100644 --- a/modules/newhorizons/shaders/modelShader_fs.glsl +++ b/modules/newhorizons/shaders/modelShader_fs.glsl @@ -22,30 +22,27 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" + +in vec4 vs_position; +in vec4 vs_normal; +in vec2 vs_st; + uniform vec4 campos; uniform vec4 objpos; uniform vec3 camdir; -uniform float time; -uniform sampler2D currentTexture; -uniform sampler2D projectedTexture; +uniform sampler2D baseTexture; +uniform sampler2D projectionTexture; uniform bool _performShading; -in vec2 vs_st; -in vec4 vs_normal; -in vec4 vs_position; -in vec4 ProjTexCoord; -uniform vec3 boresight; uniform vec3 sun_pos; -#include "PowerScaling/powerScaling_fs.hglsl" -#include "fragment.glsl" - Fragment getFragment() { vec4 position = vs_position; float depth = pscDepth(position); - vec4 diffuse = texture(currentTexture, vs_st); // directional lighting vec3 origin = vec3(0.0); @@ -58,34 +55,34 @@ Fragment getFragment() { float intensity = 1; if (_performShading) { - float terminatorBright = 0.4; - intensity = min(max(5*dot(n,l_dir), terminatorBright), 1); + const float terminatorBrightness = 0.4; + intensity = min(max(5*dot(n,l_dir), terminatorBrightness), 1.0); } float shine = 0.0001; vec4 specular = vec4(0.1); - vec4 ambient = vec4(0.f,0.f,0.f,1); + vec4 ambient = vec4(vec3(0.0), 1.0); //Specular - if (intensity > 0.f) { + if (intensity > 0.0) { vec3 h = normalize(l_dir + e); float intSpec = max(dot(h,n),0.0); spec = specular * pow(intSpec, shine); } - vec4 projTexColor = textureProj(projectedTexture, ProjTexCoord); - vec4 shaded = max(intensity * diffuse, ambient); - if (ProjTexCoord[0] > 0.0 || ProjTexCoord[1] > 0.0 || - ProjTexCoord[0] < ProjTexCoord[2] || - ProjTexCoord[1] < ProjTexCoord[2]) { - diffuse = shaded; - } else if (dot(n, boresight) < 0 && projTexColor.w != 0) {// frontfacing - diffuse = projTexColor; - } else { - diffuse = shaded; + vec4 textureColor = texture(baseTexture, vs_st); + vec4 projectionColor = texture(projectionTexture, vs_st); + if (projectionColor.a != 0.0) { + textureColor.rgb = mix( + textureColor.rgb, + projectionColor.rgb, + min(1.0, projectionColor.a) + ); } + // textureColor = projectionColor; + Fragment frag; - frag.color = diffuse; + frag.color = max(intensity * textureColor, ambient); frag.depth = depth; return frag; } diff --git a/modules/newhorizons/shaders/modelShader_vs.glsl b/modules/newhorizons/shaders/modelShader_vs.glsl index 74eacac727..3e5778d8a4 100644 --- a/modules/newhorizons/shaders/modelShader_vs.glsl +++ b/modules/newhorizons/shaders/modelShader_vs.glsl @@ -24,26 +24,21 @@ #version __CONTEXT__ -uniform mat4 ViewProjection; -uniform mat4 ModelTransform; -uniform mat4 ProjectorMatrix; +#include "PowerScaling/powerScaling_vs.hglsl" layout(location = 0) in vec4 in_position; layout(location = 1) in vec2 in_st; layout(location = 2) in vec3 in_normal; -uniform vec3 boresight; +out vec4 vs_position; +out vec4 vs_normal; +out vec2 vs_st; + +uniform mat4 ViewProjection; +uniform mat4 ModelTransform; uniform float _magnification; -out vec2 vs_st; -out vec4 vs_normal; -out vec4 vs_position; -out float s; -out vec4 ProjTexCoord; - - -#include "PowerScaling/powerScaling_vs.hglsl" void main() { vec4 pos = in_position; pos.w += _magnification; @@ -56,8 +51,6 @@ void main() { vec4 position = pscTransform(tmp, ModelTransform); vs_position = tmp; - vec4 raw_pos = psc_to_meter(pos, scaling); - ProjTexCoord = ProjectorMatrix * ModelTransform * raw_pos; position = ViewProjection * position; gl_Position = z_normalization(position); } diff --git a/modules/newhorizons/shaders/projectionPass_fs.glsl b/modules/newhorizons/shaders/projectionPass_fs.glsl index 383b4ca854..a513097a51 100644 --- a/modules/newhorizons/shaders/projectionPass_fs.glsl +++ b/modules/newhorizons/shaders/projectionPass_fs.glsl @@ -24,10 +24,8 @@ #version __CONTEXT__ -uniform sampler2D projectTexture; -uniform sampler2D currentTexture; +uniform sampler2D projectionTexture; -uniform mat4 ProjectorMatrix; uniform mat4 ModelTransform; uniform vec2 _scaling; uniform vec3 boresight; @@ -60,9 +58,7 @@ void main() { // projected.y = 1 - projected.y; if((inRange(projected.x, 0, 1) && inRange(projected.y, 0, 1)) && (dot(n, boresight) < 0)) { - color = texture(projectTexture, projected.xy); - } else { - color = texture(currentTexture, uv); + color = texture(projectionTexture, projected.xy); + color.a = 1.0; } - } \ No newline at end of file diff --git a/modules/newhorizons/shaders/projectiveTexture_fs.glsl b/modules/newhorizons/shaders/projectiveTexture_fs.glsl index 2a5600e228..7b99e5c08c 100644 --- a/modules/newhorizons/shaders/projectiveTexture_fs.glsl +++ b/modules/newhorizons/shaders/projectiveTexture_fs.glsl @@ -26,9 +26,8 @@ #include "fragment.glsl" in vec4 vs_position; -in vec2 vs_st; in vec4 vs_normal; -in vec4 ProjTexCoord; +in vec2 vs_st; uniform sampler2D baseTexture; uniform sampler2D projectionTexture; diff --git a/modules/newhorizons/shaders/projectiveTexture_vs.glsl b/modules/newhorizons/shaders/projectiveTexture_vs.glsl index 9a73ade8ee..2a1802b4b8 100644 --- a/modules/newhorizons/shaders/projectiveTexture_vs.glsl +++ b/modules/newhorizons/shaders/projectiveTexture_vs.glsl @@ -31,9 +31,8 @@ layout(location = 1) in vec2 in_st; layout(location = 2) in vec3 in_normal; out vec4 vs_position; -out vec2 vs_st; out vec4 vs_normal; -out vec4 ProjTexCoord; +out vec2 vs_st; uniform mat4 ModelTransform; uniform mat4 ViewProjection; From 89d5e69da4edf20e6cb8416faf3de8f256145ed8 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 3 Jun 2016 16:57:24 +0200 Subject: [PATCH 28/61] Enable fading of projection layer --- .../newhorizons/rendering/renderablemodelprojection.cpp | 4 ++++ modules/newhorizons/rendering/renderablemodelprojection.h | 2 ++ modules/newhorizons/shaders/modelShader_fs.glsl | 7 ++----- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 04744774b4..606bd6d30a 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -82,6 +82,7 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di , _fboProgramObject(nullptr) , _baseTexture(nullptr) , _projectionTexture(nullptr) + , _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f) , _geometry(nullptr) , _alpha(1.f) , _performShading("performShading", "Perform Shading", true) @@ -113,6 +114,8 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di addPropertySubOwner(_geometry); + addProperty(_projectionFading); + addProperty(_colorTexturePath); _colorTexturePath.onChange(std::bind(&RenderableModelProjection::loadTextures, this)); @@ -351,6 +354,7 @@ void RenderableModelProjection::render(const RenderData& data) { _programObject->setUniform("sun_pos", _sunPosition.vec3()); _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _programObject->setUniform("ModelTransform", _transform); + _programObject->setUniform("_projectionFading", _projectionFading); setPscUniforms(*_programObject, data.camera, data.position); _geometry->setUniforms(*_programObject); diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index d4161a3535..564fe4303a 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -85,6 +85,8 @@ namespace openspace { std::unique_ptr _baseTexture; std::unique_ptr _projectionTexture; + properties::FloatProperty _projectionFading; + modelgeometry::ModelGeometry* _geometry; float _alpha; diff --git a/modules/newhorizons/shaders/modelShader_fs.glsl b/modules/newhorizons/shaders/modelShader_fs.glsl index 0e46d121a2..14fbe4ecd0 100644 --- a/modules/newhorizons/shaders/modelShader_fs.glsl +++ b/modules/newhorizons/shaders/modelShader_fs.glsl @@ -36,8 +36,7 @@ uniform vec3 camdir; uniform sampler2D baseTexture; uniform sampler2D projectionTexture; uniform bool _performShading; - - +uniform float _projectionFading; uniform vec3 sun_pos; Fragment getFragment() { @@ -75,12 +74,10 @@ Fragment getFragment() { textureColor.rgb = mix( textureColor.rgb, projectionColor.rgb, - min(1.0, projectionColor.a) + min(_projectionFading, projectionColor.a) ); } - // textureColor = projectionColor; - Fragment frag; frag.color = max(intensity * textureColor, ambient); frag.depth = depth; From 4ef03bb02be1102e75bf4a3551110b0758f70a5a Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 3 Jun 2016 17:35:15 +0200 Subject: [PATCH 29/61] Further cleanup of projection code --- .../rendering/renderablemodelprojection.cpp | 78 +++---- .../rendering/renderablemodelprojection.h | 203 +++++++++--------- .../rendering/renderableplanetprojection.cpp | 38 +--- .../rendering/renderableplanetprojection.h | 27 +-- .../shaders/projectionPass_fs.glsl | 22 +- .../shaders/projectionPass_vs.glsl | 16 +- .../shaders/projectiveTexture_vs.glsl | 4 +- 7 files changed, 167 insertions(+), 221 deletions(-) diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 606bd6d30a..e809244c49 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -1,47 +1,42 @@ /***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2016 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ -// open space includes #include +#include +#include + +#include +#include +#include +#include + +#include #include #include -#include - -#include -#include -#include - -#include -#include #include - -#define _USE_MATH_DEFINES -#include -#include - namespace { const std::string _loggerCat = "RenderableModelProjection"; const std::string keySource = "Rotation.Source"; @@ -67,7 +62,6 @@ namespace { const std::string keyTranslation = "DataInputTranslation"; const std::string sequenceTypeImage = "image-sequence"; - } namespace openspace { @@ -90,7 +84,6 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di , _clearAllProjections("clearAllProjections", "Clear Projections", false) , _frameCount(0) , _programIsDirty(false) - , _clearingImage(absPath("${OPENSPACE_DATA}/scene/common/textures/clear.png")) { std::string name; bool success = dictionary.getValue(SceneGraphNode::KeyName, name); @@ -100,7 +93,7 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di success = dictionary.getValue(keyGeometry, geometryDictionary); if (success) { geometryDictionary.setValue(SceneGraphNode::KeyName, name); - _geometry = modelgeometry::ModelGeometry::createFromDictionary(geometryDictionary); + _geometry = std::unique_ptr(modelgeometry::ModelGeometry::createFromDictionary(geometryDictionary)); } std::string texturePath = ""; @@ -112,7 +105,7 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di if (success) _defaultProjImage = absPath(texturePath); - addPropertySubOwner(_geometry); + addPropertySubOwner(_geometry.get()); addProperty(_projectionFading); @@ -271,15 +264,12 @@ bool RenderableModelProjection::auxiliaryRendertarget() { glBindVertexArray(0); - return completeSuccess; } bool RenderableModelProjection::deinitialize() { - if (_geometry) { + if (_geometry) _geometry->deinitialize(); - delete _geometry; - } _geometry = nullptr; _baseTexture = nullptr; diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index 564fe4303a..a526f25489 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -1,149 +1,146 @@ /***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2016 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ #ifndef __RENDERABLEMODELPROJECTION_H__ #define __RENDERABLEMODELPROJECTION_H__ #include +#include #include -#include #include #include -#include -#include #include +#include #include #include namespace openspace { - namespace modelgeometry { - class ModelGeometry; - } +namespace modelgeometry { + class ModelGeometry; +} - class RenderableModelProjection : public Renderable { - public: - RenderableModelProjection(const ghoul::Dictionary& dictionary); +class RenderableModelProjection : public Renderable { +public: + RenderableModelProjection(const ghoul::Dictionary& dictionary); - bool initialize() override; - bool deinitialize() override; + bool initialize() override; + bool deinitialize() override; - bool isReady() const override; + bool isReady() const override; - void render(const RenderData& data) override; - void update(const UpdateData& data) override; + void render(const RenderData& data) override; + void update(const UpdateData& data) override; - protected: - void loadTextures(); - std::unique_ptr loadProjectionTexture(const std::string& texturePath); +protected: + void loadTextures(); + std::unique_ptr loadProjectionTexture(const std::string& texturePath); - private: - bool auxiliaryRendertarget(); - glm::mat4 computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up); - void attitudeParameters(double time); - void imageProjectGPU(std::unique_ptr projectionTexture); +private: + bool auxiliaryRendertarget(); + glm::mat4 computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up); + void attitudeParameters(double time); + void imageProjectGPU(std::unique_ptr projectionTexture); - void project(); - void clearAllProjections(); + void project(); + void clearAllProjections(); - properties::StringProperty _colorTexturePath; - properties::BoolProperty _performProjection; - properties::BoolProperty _clearAllProjections; + properties::StringProperty _colorTexturePath; + properties::BoolProperty _performProjection; + properties::BoolProperty _clearAllProjections; - properties::IntProperty _rotationX; - properties::IntProperty _rotationY; - properties::IntProperty _rotationZ; + properties::IntProperty _rotationX; + properties::IntProperty _rotationY; + properties::IntProperty _rotationZ; - std::unique_ptr _programObject; - std::unique_ptr _fboProgramObject; + std::unique_ptr _programObject; + std::unique_ptr _fboProgramObject; - std::unique_ptr _baseTexture; - std::unique_ptr _projectionTexture; + std::unique_ptr _baseTexture; + std::unique_ptr _projectionTexture; - properties::FloatProperty _projectionFading; + properties::FloatProperty _projectionFading; - modelgeometry::ModelGeometry* _geometry; + std::unique_ptr _geometry; - float _alpha; - glm::dmat3 _stateMatrix; - glm::dmat3 _instrumentMatrix; + float _alpha; + glm::dmat3 _stateMatrix; + glm::dmat3 _instrumentMatrix; - std::string _defaultProjImage; - std::string _source; - std::string _destination; - std::string _target; + std::string _defaultProjImage; + std::string _source; + std::string _destination; + std::string _target; - // sequence loading - std::string _sequenceSource; - std::string _sequenceType; + // sequence loading + std::string _sequenceSource; + std::string _sequenceType; - // projection mod info - std::string _instrumentID; - std::string _projectorID; - std::string _projecteeID; - SpiceManager::AberrationCorrection _aberration; - std::vector _potentialTargets; - float _fovy; - float _aspectRatio; - float _nearPlane; - float _farPlane; + // projection mod info + std::string _instrumentID; + std::string _projectorID; + std::string _projecteeID; + SpiceManager::AberrationCorrection _aberration; + std::vector _potentialTargets; + float _fovy; + float _aspectRatio; + float _nearPlane; + float _farPlane; - // uniforms - glm::vec2 _camScaling; - glm::vec3 _up; - glm::mat4 _transform; - glm::mat4 _projectorMatrix; - glm::vec3 _boresight; + // uniforms + glm::vec2 _camScaling; + glm::vec3 _up; + glm::mat4 _transform; + glm::mat4 _projectorMatrix; + glm::vec3 _boresight; - // FBO stuff - GLuint _fboID; - GLuint _quad; - GLuint _vertexPositionBuffer; + // FBO stuff + GLuint _fboID; + GLuint _quad; + GLuint _vertexPositionBuffer; - GLuint _vbo; - GLuint _ibo; - GLuint _vaoID; - std::vector _geometryVertecies; - std::vector _geometryIndeces; + GLuint _vbo; + GLuint _ibo; + GLuint _vaoID; + std::vector _geometryVertecies; + std::vector _geometryIndeces; - std::vector _imageTimes; - int _frameCount; - double _time; + std::vector _imageTimes; + int _frameCount; + double _time; - bool _capture; + bool _capture; - std::string _clearingImage; + psc _sunPosition; - psc _sunPosition; - - properties::BoolProperty _performShading; - bool _programIsDirty; - }; + properties::BoolProperty _performShading; + bool _programIsDirty; +}; } // namespace openspace diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 7b76281096..1b9c922fd1 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -22,38 +22,24 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -// open space includes #include #include +#include +#include +#include +#include +#include +#include +#include -#include - +#include #include #include -//#include -#include -#include - -#include -#include - -#include - +#include #include -#include -#include -#include -#include -#include -#include - -#define _USE_MATH_DEFINES -#include - - namespace { const std::string _loggerCat = "RenderablePlanetProjection"; const std::string keyProjObserver = "Projection.Observer"; @@ -98,7 +84,6 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& , _projectionTexture(nullptr) , _heightMapTexture(nullptr) , _capture(false) - , _clearingImage(absPath("${OPENSPACE_DATA}/scene/common/textures/clear.png")) { std::string name; bool success = dictionary.getValue(SceneGraphNode::KeyName, name); @@ -519,11 +504,6 @@ void RenderablePlanetProjection::render(const RenderData& data) { } void RenderablePlanetProjection::update(const UpdateData& data) { - if (_time >= Time::ref().currentTime()) { - // if jump back in time -> empty queue. - imageQueue = std::queue(); - } - _time = Time::ref().currentTime(); _capture = false; diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index 97bed69da9..2c11eadfb6 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -25,39 +25,24 @@ #ifndef __RENDERABLEPLANETPROJECTION_H__ #define __RENDERABLEPLANETPROJECTION_H__ -#include - -// open space includes #include + #include -#include -#include -#include -#include - - #include #include -#include #include +#include -#include - -// ghoul includes #include #include -#include - -#include namespace openspace { -namespace planetgeometry{ -class PlanetGeometry; +namespace planetgeometry { + class PlanetGeometry; } - class RenderablePlanetProjection : public Renderable { public: RenderablePlanetProjection(const ghoul::Dictionary& dictionary); @@ -138,7 +123,6 @@ private: std::string _target; std::string _frame; - std::string _clearingImage; std::string _next; bool _capture; @@ -147,9 +131,6 @@ private: GLuint _fboID; GLuint _quad; GLuint _vertexPositionBuffer; - - - std::queue imageQueue; }; } // namespace openspace diff --git a/modules/newhorizons/shaders/projectionPass_fs.glsl b/modules/newhorizons/shaders/projectionPass_fs.glsl index a513097a51..9b3c4975b7 100644 --- a/modules/newhorizons/shaders/projectionPass_fs.glsl +++ b/modules/newhorizons/shaders/projectionPass_fs.glsl @@ -24,22 +24,21 @@ #version __CONTEXT__ +#include "PowerScaling/powerScaling_vs.hglsl" + +in vec4 vs_position; +in vec4 vs_normal; +in vec2 vs_uv; +in vec4 ProjTexCoord; + +out vec4 color; + uniform sampler2D projectionTexture; uniform mat4 ModelTransform; uniform vec2 _scaling; uniform vec3 boresight; - -in vec4 vs_position; -in vec4 ProjTexCoord; -in vec2 vs_uv; -in vec4 vs_normal; - -out vec4 color; - -#include "PowerScaling/powerScaling_vs.hglsl" - bool inRange(float x, float a, float b) { return (x >= a && x <= b); } @@ -55,10 +54,9 @@ void main() { projected.y /= projected.w; //invert gl coordinates projected.x = 1 - projected.x; - // projected.y = 1 - projected.y; if((inRange(projected.x, 0, 1) && inRange(projected.y, 0, 1)) && (dot(n, boresight) < 0)) { color = texture(projectionTexture, projected.xy); color.a = 1.0; } -} \ No newline at end of file +} diff --git a/modules/newhorizons/shaders/projectionPass_vs.glsl b/modules/newhorizons/shaders/projectionPass_vs.glsl index 0fed1ba6ee..583c841193 100644 --- a/modules/newhorizons/shaders/projectionPass_vs.glsl +++ b/modules/newhorizons/shaders/projectionPass_vs.glsl @@ -24,22 +24,22 @@ #version __CONTEXT__ -uniform mat4 ProjectorMatrix; -uniform mat4 ModelTransform; -uniform vec2 _scaling; +#include "PowerScaling/powerScaling_vs.hglsl" layout(location = 0) in vec4 in_position; layout(location = 1) in vec2 in_st; layout(location = 2) in vec3 in_normal; -uniform vec3 boresight; - out vec4 vs_position; -out vec4 ProjTexCoord; -out vec2 vs_uv; out vec4 vs_normal; +out vec2 vs_uv; +out vec4 ProjTexCoord; -#include "PowerScaling/powerScaling_vs.hglsl" +uniform mat4 ProjectorMatrix; +uniform mat4 ModelTransform; +uniform vec2 _scaling; + +uniform vec3 boresight; void main() { vs_position = in_position; diff --git a/modules/newhorizons/shaders/projectiveTexture_vs.glsl b/modules/newhorizons/shaders/projectiveTexture_vs.glsl index 2a1802b4b8..fb81090d2d 100644 --- a/modules/newhorizons/shaders/projectiveTexture_vs.glsl +++ b/modules/newhorizons/shaders/projectiveTexture_vs.glsl @@ -61,8 +61,8 @@ void main() { vec4 position = pscTransform(tmp, ModelTransform); vs_position = tmp; - vec4 raw_pos = psc_to_meter(tmp, scaling); - ProjTexCoord = ProjectorMatrix * ModelTransform * raw_pos; + // vec4 raw_pos = psc_to_meter(tmp, scaling); + // ProjTexCoord = ProjectorMatrix * ModelTransform * raw_pos; position = ViewProjection * position; From 491226ea7ac181eb6a6b15fe1e27b1cf06750f00 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 3 Jun 2016 18:30:16 +0200 Subject: [PATCH 30/61] Started refactoring RenderableModelProjection and RenderablePlanetProjection to place common code into ProjectionComponent --- modules/newhorizons/CMakeLists.txt | 2 + .../rendering/renderablemodelprojection.cpp | 107 +------------ .../rendering/renderablemodelprojection.h | 17 +- .../rendering/renderableplanetprojection.cpp | 147 ++++-------------- .../rendering/renderableplanetprojection.h | 17 +- .../newhorizons/util/projectioncomponent.cpp | 143 +++++++++++++++++ .../newhorizons/util/projectioncomponent.h | 69 ++++++++ 7 files changed, 255 insertions(+), 247 deletions(-) create mode 100644 modules/newhorizons/util/projectioncomponent.cpp create mode 100644 modules/newhorizons/util/projectioncomponent.h diff --git a/modules/newhorizons/CMakeLists.txt b/modules/newhorizons/CMakeLists.txt index 8f59851507..fa6b705fc9 100644 --- a/modules/newhorizons/CMakeLists.txt +++ b/modules/newhorizons/CMakeLists.txt @@ -37,6 +37,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/util/imagesequencer.h ${CMAKE_CURRENT_SOURCE_DIR}/util/instrumentdecoder.h ${CMAKE_CURRENT_SOURCE_DIR}/util/labelparser.h + ${CMAKE_CURRENT_SOURCE_DIR}/util/projectioncomponent.h ${CMAKE_CURRENT_SOURCE_DIR}/util/scannerdecoder.h ${CMAKE_CURRENT_SOURCE_DIR}/util/sequenceparser.h ${CMAKE_CURRENT_SOURCE_DIR}/util/targetdecoder.h @@ -55,6 +56,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/util/imagesequencer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/util/instrumentdecoder.cpp ${CMAKE_CURRENT_SOURCE_DIR}/util/labelparser.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/util/projectioncomponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/util/scannerdecoder.cpp ${CMAKE_CURRENT_SOURCE_DIR}/util/sequenceparser.cpp ${CMAKE_CURRENT_SOURCE_DIR}/util/targetdecoder.cpp diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index e809244c49..1413a9a747 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -75,13 +75,9 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di , _programObject(nullptr) , _fboProgramObject(nullptr) , _baseTexture(nullptr) - , _projectionTexture(nullptr) - , _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f) , _geometry(nullptr) , _alpha(1.f) , _performShading("performShading", "Perform Shading", true) - , _performProjection("performProjection", "Perform Projections", true) - , _clearAllProjections("clearAllProjections", "Clear Projections", false) , _frameCount(0) , _programIsDirty(false) { @@ -218,27 +214,6 @@ bool RenderableModelProjection::initialize() { LWARNING("Lack of vertex data from geometry for image projection"); completeSuccess &= auxiliaryRendertarget(); - - return completeSuccess; -} - -bool RenderableModelProjection::auxiliaryRendertarget() { - bool completeSuccess = true; - // set FBO to texture to project to - - GLint defaultFBO; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); - - glGenFramebuffers(1, &_fboID); - glBindFramebuffer(GL_FRAMEBUFFER, _fboID); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_projectionTexture, 0); - // check FBO status - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) - completeSuccess &= false; - // switch back to window-system-provided framebuffer - glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); - int vertexSize = sizeof(modelgeometry::ModelGeometry::Vertex); glGenVertexArrays(1, &_vaoID); @@ -253,12 +228,12 @@ bool RenderableModelProjection::auxiliaryRendertarget() { glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, vertexSize, - reinterpret_cast(offsetof(modelgeometry::ModelGeometry::Vertex, location))); + reinterpret_cast(offsetof(modelgeometry::ModelGeometry::Vertex, location))); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, vertexSize, - reinterpret_cast(offsetof(modelgeometry::ModelGeometry::Vertex, tex))); + reinterpret_cast(offsetof(modelgeometry::ModelGeometry::Vertex, tex))); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, vertexSize, - reinterpret_cast(offsetof(modelgeometry::ModelGeometry::Vertex, normal))); - + reinterpret_cast(offsetof(modelgeometry::ModelGeometry::Vertex, normal))); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, _geometryIndeces.size() * sizeof(int), &_geometryIndeces[0], GL_STATIC_DRAW); @@ -286,28 +261,6 @@ bool RenderableModelProjection::deinitialize() { return true; } -void RenderableModelProjection::clearAllProjections() { - GLint defaultFBO; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); - - GLint m_viewport[4]; - glGetIntegerv(GL_VIEWPORT, m_viewport); - glBindFramebuffer(GL_FRAMEBUFFER, _fboID); - - glViewport(0, 0, static_cast(_projectionTexture->width()), static_cast(_projectionTexture->height())); - - glClearColor(0.f, 0.f, 0.f, 0.f); - glClear(GL_COLOR_BUFFER_BIT); - - glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); - glViewport(m_viewport[0], m_viewport[1], - m_viewport[2], m_viewport[3]); - - - - _clearAllProjections = false; -} - void RenderableModelProjection::render(const RenderData& data) { if (!_programObject) return; @@ -465,34 +418,11 @@ void RenderableModelProjection::attitudeParameters(double time) { position[3] += (3 + _camScaling[1]); glm::vec3 cpos = position.vec3(); - _projectorMatrix = computeProjectorMatrix(cpos, boresight, _up); + _projectorMatrix = computeProjectorMatrix(cpos, boresight, _up, _instrumentMatrix, + _fovy, _aspectRatio, _nearPlane, _farPlane, _boresight); + } -glm::mat4 RenderableModelProjection::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up) { - //rotate boresight into correct alignment - _boresight = _instrumentMatrix*aim; - glm::vec3 uptmp(_instrumentMatrix*glm::dvec3(up)); - - // create view matrix - glm::vec3 e3 = glm::normalize(_boresight); - glm::vec3 e1 = glm::normalize(glm::cross(uptmp, e3)); - glm::vec3 e2 = glm::normalize(glm::cross(e3, e1)); - glm::mat4 projViewMatrix = glm::mat4(e1.x, e2.x, e3.x, 0.f, - e1.y, e2.y, e3.y, 0.f, - e1.z, e2.z, e3.z, 0.f, - -glm::dot(e1, loc), -glm::dot(e2, loc), -glm::dot(e3, loc), 1.f); - - // create perspective projection matrix - glm::mat4 projProjectionMatrix = glm::perspective(glm::radians(_fovy), _aspectRatio, _nearPlane, _farPlane); - // bias matrix - glm::mat4 projNormalizationMatrix = glm::mat4(0.5f, 0, 0, 0, - 0, 0.5f, 0, 0, - 0, 0, 0.5f, 0, - 0.5f, 0.5f, 0.5f, 1); - return projNormalizationMatrix*projProjectionMatrix*projViewMatrix; -} - - void RenderableModelProjection::project() { for (auto img : _imageTimes) { //std::thread t1(&RenderableModelProjection::attitudeParameters, this, img.startTime); @@ -514,28 +444,7 @@ void RenderableModelProjection::loadTextures() { _baseTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); } } - - int maxSize = OpenGLCap.max2DTextureSize() / 2; - - LINFO("Creating projection texture of size '" << maxSize << ", " << maxSize / 2 << "'"); - _projectionTexture = std::make_unique( - glm::uvec3(maxSize, maxSize / 2, 1), - ghoul::opengl::Texture::Format::RGBA - ); - _projectionTexture->uploadTexture(); -} - -std::unique_ptr RenderableModelProjection::loadProjectionTexture(const std::string& texturePath) { - std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(texturePath)); - - if (texture) { - texture->uploadTexture(); - // TODO: AnisotropicMipMap crashes on ATI cards ---abock - //texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); - texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); - } - - return texture; + generateProjectionLayerTexture(); } } // namespace openspace diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index a526f25489..620e28e170 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -26,6 +26,7 @@ #define __RENDERABLEMODELPROJECTION_H__ #include +#include #include #include @@ -44,7 +45,7 @@ namespace modelgeometry { class ModelGeometry; } -class RenderableModelProjection : public Renderable { +class RenderableModelProjection : public Renderable, private ProjectionComponent { public: RenderableModelProjection(const ghoul::Dictionary& dictionary); @@ -59,20 +60,14 @@ public: protected: void loadTextures(); - std::unique_ptr loadProjectionTexture(const std::string& texturePath); private: - bool auxiliaryRendertarget(); - glm::mat4 computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up); void attitudeParameters(double time); void imageProjectGPU(std::unique_ptr projectionTexture); void project(); - void clearAllProjections(); properties::StringProperty _colorTexturePath; - properties::BoolProperty _performProjection; - properties::BoolProperty _clearAllProjections; properties::IntProperty _rotationX; properties::IntProperty _rotationY; @@ -82,9 +77,6 @@ private: std::unique_ptr _fboProgramObject; std::unique_ptr _baseTexture; - std::unique_ptr _projectionTexture; - - properties::FloatProperty _projectionFading; std::unique_ptr _geometry; @@ -119,11 +111,6 @@ private: glm::mat4 _projectorMatrix; glm::vec3 _boresight; - // FBO stuff - GLuint _fboID; - GLuint _quad; - GLuint _vertexPositionBuffer; - GLuint _vbo; GLuint _ibo; GLuint _vaoID; diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 1b9c922fd1..e9975b1081 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -38,7 +38,6 @@ #include #include #include -#include namespace { const std::string _loggerCat = "RenderablePlanetProjection"; @@ -74,14 +73,10 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& , _colorTexturePath("planetTexture", "RGB Texture") , _heightMapTexturePath("heightMap", "Heightmap Texture") , _rotation("rotation", "Rotation", 0, 0, 360) - , _performProjection("performProjection", "Perform Projections", true) - , _clearAllProjections("clearAllProjections", "Clear Projections", false) - , _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f) , _heightExaggeration("heightExaggeration", "Height Exaggeration", 1.f, 0.f, 100.f) , _programObject(nullptr) , _fboProgramObject(nullptr) , _baseTexture(nullptr) - , _projectionTexture(nullptr) , _heightMapTexture(nullptr) , _capture(false) { @@ -213,9 +208,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& } } -RenderablePlanetProjection::~RenderablePlanetProjection() { - deinitialize(); -} +RenderablePlanetProjection::~RenderablePlanetProjection() {} bool RenderablePlanetProjection::initialize() { bool completeSuccess = true; @@ -242,52 +235,32 @@ bool RenderablePlanetProjection::initialize() { completeSuccess &= (_projectionTexture != nullptr); completeSuccess &= _geometry->initialize(this); - if (completeSuccess) + if (completeSuccess) { completeSuccess &= auxiliaryRendertarget(); + // SCREEN-QUAD + const GLfloat size = 1.f; + const GLfloat w = 1.f; + const GLfloat vertex_data[] = { + -size, -size, 0.f, w, 0.f, 0.f, + size, size, 0.f, w, 1.f, 1.f, + -size, size, 0.f, w, 0.f, 1.f, + -size, -size, 0.f, w, 0.f, 0.f, + size, -size, 0.f, w, 1.f, 0.f, + size, size, 0.f, w, 1.f, 1.f, + }; - return completeSuccess; -} + glGenVertexArrays(1, &_quad); + glBindVertexArray(_quad); + glGenBuffers(1, &_vertexPositionBuffer); + glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(0)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(sizeof(GLfloat) * 4)); -bool RenderablePlanetProjection::auxiliaryRendertarget() { - bool completeSuccess = true; - - GLint defaultFBO; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); - - // setup FBO - glGenFramebuffers(1, &_fboID); - glBindFramebuffer(GL_FRAMEBUFFER, _fboID); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_projectionTexture, 0); - // check FBO status - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) - completeSuccess &= false; - // switch back to window-system-provided framebuffer - glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); - - // SCREEN-QUAD - const GLfloat size = 1.f; - const GLfloat w = 1.f; - const GLfloat vertex_data[] = { - -size, -size, 0.f, w, 0.f, 0.f, - size, size, 0.f, w, 1.f, 1.f, - -size, size, 0.f, w, 0.f, 1.f, - -size, -size, 0.f, w, 0.f, 0.f, - size, -size, 0.f, w, 1.f, 0.f, - size, size, 0.f, w, 1.f, 1.f, - }; - - glGenVertexArrays(1, &_quad); - glBindVertexArray(_quad); - glGenBuffers(1, &_vertexPositionBuffer); - glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(0)); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast(sizeof(GLfloat) * 4)); - - glBindVertexArray(0); + glBindVertexArray(0); + } return completeSuccess; } @@ -360,29 +333,6 @@ void RenderablePlanetProjection::imageProjectGPU(std::unique_ptr(_projectionTexture->width()), static_cast(_projectionTexture->height())); - _fboProgramObject->activate(); - - glClearColor(0.f, 0.f, 0.f, 0.f); - glClear(GL_COLOR_BUFFER_BIT); - - //bind back to default - glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); - glViewport(m_viewport[0], m_viewport[1], - m_viewport[2], m_viewport[3]); - - _clearAllProjections = false; + _projectorMatrix = computeProjectorMatrix(cpos, bs, _up, _instrumentMatrix, + _fovy, _aspectRatio, _nearPlane, _farPlane, _boresight); } void RenderablePlanetProjection::render(const RenderData& data) { @@ -520,19 +447,6 @@ void RenderablePlanetProjection::update(const UpdateData& data) { _programObject->rebuildFromFile(); } -std::unique_ptr RenderablePlanetProjection::loadProjectionTexture(const std::string& texturePath) { - std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(texturePath)); - if (texture) { - ghoul::opengl::convertTextureFormat(ghoul::opengl::Texture::Format::RGB, *texture); - texture->uploadTexture(); - // TODO: AnisotropicMipMap crashes on ATI cards ---abock - //_textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); - texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); - } - return texture; -} - void RenderablePlanetProjection::loadTextures() { using ghoul::opengl::Texture; _baseTexture = nullptr; @@ -545,14 +459,7 @@ void RenderablePlanetProjection::loadTextures() { } } - int maxSize = OpenGLCap.max2DTextureSize() / 2; - - LINFO("Creating projection texture of size '" << maxSize << ", " << maxSize/2 << "'"); - _projectionTexture = std::make_unique( - glm::uvec3(maxSize, maxSize / 2, 1), - Texture::Format::RGBA - ); - _projectionTexture->uploadTexture(); + generateProjectionLayerTexture(); _heightMapTexture = nullptr; if (_heightMapTexturePath.value() != "") { diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index 2c11eadfb6..b5ab104901 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -26,6 +26,7 @@ #define __RENDERABLEPLANETPROJECTION_H__ #include +#include #include @@ -43,7 +44,7 @@ namespace planetgeometry { class PlanetGeometry; } -class RenderablePlanetProjection : public Renderable { +class RenderablePlanetProjection : public Renderable, private ProjectionComponent { public: RenderablePlanetProjection(const ghoul::Dictionary& dictionary); ~RenderablePlanetProjection(); @@ -59,12 +60,8 @@ public: protected: void loadTextures(); - std::unique_ptr loadProjectionTexture(const std::string& texturePath); - bool auxiliaryRendertarget(); - glm::mat4 computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up); void attitudeParameters(double time); - void clearAllProjections(); private: void imageProjectGPU(std::unique_ptr projectionTexture); @@ -73,18 +70,13 @@ private: properties::StringProperty _heightMapTexturePath; properties::IntProperty _rotation; - properties::BoolProperty _performProjection; - properties::BoolProperty _clearAllProjections; std::unique_ptr _programObject; std::unique_ptr _fboProgramObject; std::unique_ptr _baseTexture; - std::unique_ptr _projectionTexture; std::unique_ptr _heightMapTexture; - properties::FloatProperty _projectionFading; - properties::FloatProperty _heightExaggeration; std::unique_ptr _geometry; @@ -127,11 +119,10 @@ private: bool _capture; - // FBO stuff - GLuint _fboID; GLuint _quad; GLuint _vertexPositionBuffer; + }; } // namespace openspace -#endif // __RENDERABLEPLANETPROJECTION_H__ \ No newline at end of file +#endif // __RENDERABLEPLANETPROJECTION_H__ diff --git a/modules/newhorizons/util/projectioncomponent.cpp b/modules/newhorizons/util/projectioncomponent.cpp new file mode 100644 index 0000000000..f11f350604 --- /dev/null +++ b/modules/newhorizons/util/projectioncomponent.cpp @@ -0,0 +1,143 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include +#include + +namespace openspace { + +ProjectionComponent::ProjectionComponent() + : _performProjection("performProjection", "Perform Projections", true) + , _clearAllProjections("clearAllProjections", "Clear Projections", false) + , _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f) + , _projectionTexture(nullptr) +{ + +} + +bool ProjectionComponent::auxiliaryRendertarget() { + bool completeSuccess = true; + + GLint defaultFBO; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); + + // setup FBO + glGenFramebuffers(1, &_fboID); + glBindFramebuffer(GL_FRAMEBUFFER, _fboID); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_projectionTexture, 0); + // check FBO status + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + completeSuccess &= false; + // switch back to window-system-provided framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + + return completeSuccess; +} + +glm::mat4 ProjectionComponent::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up, + const glm::dmat3& instrumentMatrix, + float fieldOfViewY, + float aspectRatio, + float nearPlane, + float farPlane, + glm::vec3& boreSight) +{ + //rotate boresight into correct alignment + boreSight = instrumentMatrix*aim; + glm::vec3 uptmp(instrumentMatrix*glm::dvec3(up)); + + // create view matrix + glm::vec3 e3 = glm::normalize(boreSight); + glm::vec3 e1 = glm::normalize(glm::cross(uptmp, e3)); + glm::vec3 e2 = glm::normalize(glm::cross(e3, e1)); + glm::mat4 projViewMatrix = glm::mat4(e1.x, e2.x, e3.x, 0.f, + e1.y, e2.y, e3.y, 0.f, + e1.z, e2.z, e3.z, 0.f, + -glm::dot(e1, loc), -glm::dot(e2, loc), -glm::dot(e3, loc), 1.f); + // create perspective projection matrix + glm::mat4 projProjectionMatrix = glm::perspective(glm::radians(fieldOfViewY), aspectRatio, nearPlane, farPlane); + // bias matrix + glm::mat4 projNormalizationMatrix = glm::mat4(0.5f, 0, 0, 0, + 0, 0.5f, 0, 0, + 0, 0, 0.5f, 0, + 0.5f, 0.5f, 0.5f, 1); + return projNormalizationMatrix*projProjectionMatrix*projViewMatrix; +} + +void ProjectionComponent::clearAllProjections() { + // keep handle to the current bound FBO + GLint defaultFBO; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); + + GLint m_viewport[4]; + glGetIntegerv(GL_VIEWPORT, m_viewport); + //counter = 0; + glBindFramebuffer(GL_FRAMEBUFFER, _fboID); + + glViewport(0, 0, static_cast(_projectionTexture->width()), static_cast(_projectionTexture->height())); + + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + + //bind back to default + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + glViewport(m_viewport[0], m_viewport[1], + m_viewport[2], m_viewport[3]); + + _clearAllProjections = false; +} + +std::unique_ptr ProjectionComponent::loadProjectionTexture(const std::string& texturePath) { + std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(texturePath)); + if (texture) { + ghoul::opengl::convertTextureFormat(ghoul::opengl::Texture::Format::RGB, *texture); + texture->uploadTexture(); + // TODO: AnisotropicMipMap crashes on ATI cards ---abock + //_textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); + } + return texture; +} + +void ProjectionComponent::generateProjectionLayerTexture() { + int maxSize = OpenGLCap.max2DTextureSize() / 2; + + LINFOC( + "ProjectionComponent", + "Creating projection texture of size '" << maxSize << ", " << maxSize / 2 << "'" + ); + _projectionTexture = std::make_unique ( + glm::uvec3(maxSize, maxSize / 2, 1), + ghoul::opengl::Texture::Format::RGBA + ); + _projectionTexture->uploadTexture(); +} + +} // namespace openspace diff --git a/modules/newhorizons/util/projectioncomponent.h b/modules/newhorizons/util/projectioncomponent.h new file mode 100644 index 0000000000..9ac9a5d9a2 --- /dev/null +++ b/modules/newhorizons/util/projectioncomponent.h @@ -0,0 +1,69 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __PROJECTIONCOMPONENT_H__ +#define __PROJECTIONCOMPONENT_H__ + +#include + +#include + +namespace openspace { + +class ProjectionComponent { +public: + ProjectionComponent(); + +protected: + void generateProjectionLayerTexture(); + bool auxiliaryRendertarget(); + + std::unique_ptr loadProjectionTexture(const std::string& texturePath); + glm::mat4 computeProjectorMatrix( + const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up, + const glm::dmat3& instrumentMatrix, + float fieldOfViewY, + float aspectRatio, + float nearPlane, + float farPlane, + glm::vec3& boreSight + ); + + void clearAllProjections(); + + + properties::BoolProperty _performProjection; + properties::BoolProperty _clearAllProjections; + + properties::FloatProperty _projectionFading; + + std::unique_ptr _projectionTexture; + + GLuint _fboID; + +}; + +} // namespace openspace + +#endif // __PROJECTIONCOMPONENT_H__ From 4dda541d1ffe45cc3b45486ab2e209c8e902fbbf Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 4 Jun 2016 12:04:19 +0200 Subject: [PATCH 31/61] More work on refactoring RenderablePlanetProjection and RenderableModelProjection --- .../rendering/renderablemodelprojection.cpp | 253 +++++------------- .../rendering/renderablemodelprojection.h | 35 +-- .../rendering/renderableplanetprojection.cpp | 202 +++++--------- .../rendering/renderableplanetprojection.h | 34 +-- .../newhorizons/util/projectioncomponent.cpp | 188 ++++++++++++- .../newhorizons/util/projectioncomponent.h | 27 +- 6 files changed, 338 insertions(+), 401 deletions(-) diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 1413a9a747..2b8e8129b2 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -24,9 +24,6 @@ #include -#include -#include - #include #include #include @@ -35,7 +32,6 @@ #include #include #include -#include namespace { const std::string _loggerCat = "RenderableModelProjection"; @@ -47,21 +43,6 @@ namespace { const std::string keyTextureColor = "Textures.Color"; const std::string keyTextureProject = "Textures.Project"; const std::string keyTextureDefault = "Textures.Default"; - - const std::string keySequenceDir = "Projection.Sequence"; - const std::string keySequenceType = "Projection.SequenceType"; - const std::string keyProjObserver = "Projection.Observer"; - const std::string keyProjTarget = "Projection.Target"; - const std::string keyProjAberration = "Projection.Aberration"; - - const std::string keyInstrument = "Instrument.Name"; - const std::string keyInstrumentFovy = "Instrument.Fovy"; - const std::string keyInstrumentAspect = "Instrument.Aspect"; - const std::string keyInstrumentNear = "Instrument.Near"; - const std::string keyInstrumentFar = "Instrument.Far"; - - const std::string keyTranslation = "DataInputTranslation"; - const std::string sequenceTypeImage = "image-sequence"; } namespace openspace { @@ -69,17 +50,12 @@ namespace openspace { RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _colorTexturePath("colorTexture", "Color Texture") - , _rotationX("rotationX", "RotationX", 0, 0, 360) - , _rotationY("rotationY", "RotationY", 0, 0, 360) - , _rotationZ("rotationZ", "RotationZ", 0, 0, 360) + , _rotation("rotation", "Rotation", glm::vec3(0.f), glm::vec3(0.f), glm::vec3(360.f)) , _programObject(nullptr) , _fboProgramObject(nullptr) , _baseTexture(nullptr) , _geometry(nullptr) - , _alpha(1.f) , _performShading("performShading", "Perform Shading", true) - , _frameCount(0) - , _programIsDirty(false) { std::string name; bool success = dictionary.getValue(SceneGraphNode::KeyName, name); @@ -88,8 +64,11 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di ghoul::Dictionary geometryDictionary; success = dictionary.getValue(keyGeometry, geometryDictionary); if (success) { + using modelgeometry::ModelGeometry; geometryDictionary.setValue(SceneGraphNode::KeyName, name); - _geometry = std::unique_ptr(modelgeometry::ModelGeometry::createFromDictionary(geometryDictionary)); + _geometry = std::unique_ptr( + ModelGeometry::createFromDictionary(geometryDictionary) + ); } std::string texturePath = ""; @@ -115,20 +94,7 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di setBody(_target); bool completeSuccess = true; - completeSuccess &= dictionary.getValue(keyInstrument, _instrumentID); - completeSuccess &= dictionary.getValue(keyProjObserver, _projectorID); - completeSuccess &= dictionary.getValue(keyProjTarget, _projecteeID); - completeSuccess &= dictionary.getValue(keyInstrumentFovy, _fovy); - completeSuccess &= dictionary.getValue(keyInstrumentAspect, _aspectRatio); - completeSuccess &= dictionary.getValue(keyInstrumentNear, _nearPlane); - completeSuccess &= dictionary.getValue(keyInstrumentFar, _farPlane); - ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile"); - - std::string a = "NONE"; - bool s = dictionary.getValue(keyProjAberration, a); - _aberration = SpiceManager::AberrationCorrection(a); - completeSuccess &= s; - ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile"); + completeSuccess &= initializeProjectionSettings(dictionary); openspace::SpiceManager::ref().addFrame(_target, _source); setBoundingSphere(pss(1.f, 9.f)); @@ -136,34 +102,10 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di addProperty(_performShading); addProperty(_performProjection); addProperty(_clearAllProjections); - addProperty(_rotationX); - addProperty(_rotationY); - addProperty(_rotationZ); - - SequenceParser* parser; - - bool foundSequence = dictionary.getValue(keySequenceDir, _sequenceSource); - if (foundSequence) { - _sequenceSource = absPath(_sequenceSource); - - foundSequence = dictionary.getValue(keySequenceType, _sequenceType); - ghoul_assert(foundSequence, "Did not find sequence"); - //Important: client must define translation-list in mod file IFF playbook - if (dictionary.hasKey(keyTranslation)) { - ghoul::Dictionary translationDictionary; - //get translation dictionary - dictionary.getValue(keyTranslation, translationDictionary); - if (_sequenceType == sequenceTypeImage) { - parser = new LabelParser(name, _sequenceSource, translationDictionary); - openspace::ImageSequencer::ref().runSequenceParser(parser); - - } - } - else { - LWARNING("No translation provided, please make sure all spice calls match playbook!"); - } - } + addProperty(_rotation); + success = initializeParser(dictionary); + ghoul_assert(success, ""); } bool RenderableModelProjection::isReady() const { @@ -177,67 +119,26 @@ bool RenderableModelProjection::isReady() const { bool RenderableModelProjection::initialize() { bool completeSuccess = true; - if (_programObject == nullptr) { - RenderEngine& renderEngine = OsEng.renderEngine(); - _programObject = renderEngine.buildRenderProgram("ModelShader", - "${MODULE_NEWHORIZONS}/shaders/modelShader_vs.glsl", - "${MODULE_NEWHORIZONS}/shaders/modelShader_fs.glsl"); + RenderEngine& renderEngine = OsEng.renderEngine(); + _programObject = renderEngine.buildRenderProgram("ModelShader", + "${MODULE_NEWHORIZONS}/shaders/modelShader_vs.glsl", + "${MODULE_NEWHORIZONS}/shaders/modelShader_fs.glsl"); - if (!_programObject) - return false; - } - _programObject->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*) { this->_programIsDirty = true; } ); + _fboProgramObject = ghoul::opengl::ProgramObject::Build("ProjectionPass", + "${MODULE_NEWHORIZONS}/shaders/projectionPass_vs.glsl", + "${MODULE_NEWHORIZONS}/shaders/projectionPass_fs.glsl"); + _fboProgramObject->setIgnoreUniformLocationError( + ghoul::opengl::ProgramObject::IgnoreError::Yes + ); - if (_fboProgramObject == nullptr) { - _fboProgramObject = ghoul::opengl::ProgramObject::Build("ProjectionPass", - "${MODULE_NEWHORIZONS}/shaders/projectionPass_vs.glsl", - "${MODULE_NEWHORIZONS}/shaders/projectionPass_fs.glsl"); - _fboProgramObject->setIgnoreUniformLocationError(ghoul::opengl::ProgramObject::IgnoreError::Yes); - if (!_fboProgramObject) - return false; - } - _fboProgramObject->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*) { this->_programIsDirty = true; } ); + completeSuccess &= loadTextures(); - loadTextures(); - - completeSuccess &= (_baseTexture != nullptr); - completeSuccess &= (_projectionTexture != nullptr); + completeSuccess &= ProjectionComponent::initialize(); completeSuccess &= _geometry->initialize(this); completeSuccess &= !_source.empty(); completeSuccess &= !_destination.empty(); - - - bool gotverts = _geometry->getVertices(&_geometryVertecies) && _geometry->getIndices(&_geometryIndeces); - if (!gotverts) - LWARNING("Lack of vertex data from geometry for image projection"); - - completeSuccess &= auxiliaryRendertarget(); - int vertexSize = sizeof(modelgeometry::ModelGeometry::Vertex); - - glGenVertexArrays(1, &_vaoID); - glGenBuffers(1, &_vbo); - glGenBuffers(1, &_ibo); - - glBindVertexArray(_vaoID); - glBindBuffer(GL_ARRAY_BUFFER, _vbo); - glBufferData(GL_ARRAY_BUFFER, _geometryVertecies.size() * vertexSize, &_geometryVertecies[0], GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, vertexSize, - reinterpret_cast(offsetof(modelgeometry::ModelGeometry::Vertex, location))); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, vertexSize, - reinterpret_cast(offsetof(modelgeometry::ModelGeometry::Vertex, tex))); - glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, vertexSize, - reinterpret_cast(offsetof(modelgeometry::ModelGeometry::Vertex, normal))); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, _geometryIndeces.size() * sizeof(int), &_geometryIndeces[0], GL_STATIC_DRAW); - - glBindVertexArray(0); return completeSuccess; } @@ -248,28 +149,19 @@ bool RenderableModelProjection::deinitialize() { _geometry = nullptr; _baseTexture = nullptr; - _projectionTexture = nullptr; - glDeleteBuffers(1, &_vbo); + ProjectionComponent::deinitialize(); - RenderEngine& renderEngine = OsEng.renderEngine(); - if (_programObject) { - renderEngine.removeRenderProgram(_programObject); - _programObject = nullptr; - } + OsEng.renderEngine().removeRenderProgram(_programObject); + _programObject = nullptr; return true; } void RenderableModelProjection::render(const RenderData& data) { - if (!_programObject) - return; - if (_clearAllProjections) clearAllProjections(); - _frameCount++; - _camScaling = data.camera.scaling(); _up = data.camera.lookUpVector(); @@ -278,21 +170,9 @@ void RenderableModelProjection::render(const RenderData& data) { _programObject->activate(); - attitudeParameters(_time); _imageTimes.clear(); - double time = openspace::Time::ref().currentTime(); - bool targetPositionCoverage = openspace::SpiceManager::ref().hasSpkCoverage(_target, time); - if (!targetPositionCoverage) { - int frame = _frameCount % 180; - - float fadingFactor = static_cast(sin((frame * M_PI) / 180)); - _alpha = 0.5f + fadingFactor * 0.5f; - } - else - _alpha = 1.0f; - _programObject->setUniform("_performShading", _performShading); _programObject->setUniform("sun_pos", _sunPosition.vec3()); _programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); @@ -313,53 +193,49 @@ void RenderableModelProjection::render(const RenderData& data) { _geometry->render(); - // disable shader _programObject->deactivate(); } void RenderableModelProjection::update(const UpdateData& data) { - if (_programIsDirty) { + if (_programObject->isDirty()) _programObject->rebuildFromFile(); + + if (_fboProgramObject->isDirty()) _fboProgramObject->rebuildFromFile(); - _programIsDirty = false; - } _time = data.time; if (openspace::ImageSequencer::ref().isReady() && _performProjection) { openspace::ImageSequencer::ref().updateSequencer(_time); - _capture = openspace::ImageSequencer::ref().getImagePaths(_imageTimes, _projecteeID, _instrumentID); + _capture = openspace::ImageSequencer::ref().getImagePaths( + _imageTimes, _projecteeID, _instrumentID + ); } // set spice-orientation in accordance to timestamp if (!_source.empty()) { - _stateMatrix = SpiceManager::ref().positionTransformMatrix(_source, _destination, _time); + _stateMatrix = SpiceManager::ref().positionTransformMatrix( + _source, _destination, _time + ); } - double lt; + double lt; glm::dvec3 p = - openspace::SpiceManager::ref().targetPosition("SUN", _target, "GALACTIC", {}, _time, lt); + openspace::SpiceManager::ref().targetPosition( + "SUN", _target, "GALACTIC", {}, _time, lt + ); _sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); } void RenderableModelProjection::imageProjectGPU(std::unique_ptr projectionTexture) { - // keep handle to the current bound FBO - GLint defaultFBO; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); - - GLint m_viewport[4]; - glGetIntegerv(GL_VIEWPORT, m_viewport); - glBindFramebuffer(GL_FRAMEBUFFER, _fboID); - - glViewport(0, 0, static_cast(_projectionTexture->width()), static_cast(_projectionTexture->height())); - + ProjectionComponent::imageProjectBegin(); _fboProgramObject->activate(); - ghoul::opengl::TextureUnit unitFboProject; - unitFboProject.activate(); + ghoul::opengl::TextureUnit unitFbo; + unitFbo.activate(); projectionTexture->bind(); - _fboProgramObject->setUniform("projectionTexture", unitFboProject); + _fboProgramObject->setUniform("projectionTexture", unitFbo); _fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix); _fboProgramObject->setUniform("ModelTransform", _transform); @@ -367,17 +243,11 @@ void RenderableModelProjection::imageProjectGPU(std::unique_ptrsetUniform("boresight", _boresight); _geometry->setUniforms(*_fboProgramObject); + _geometry->render(); - glBindVertexArray(_vaoID); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo); - glDrawElements(GL_TRIANGLES, static_cast(_geometryIndeces.size()), GL_UNSIGNED_INT, 0); - glBindVertexArray(0); - _fboProgramObject->deactivate(); - glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); - glViewport(m_viewport[0], m_viewport[1], - m_viewport[2], m_viewport[3]); + ProjectionComponent::imageProjectEnd(); } void RenderableModelProjection::attitudeParameters(double time) { @@ -390,10 +260,21 @@ void RenderableModelProjection::attitudeParameters(double time) { } _transform = glm::mat4(1); - - glm::mat4 rotPropX = glm::rotate(_transform, glm::radians(static_cast(_rotationX)), glm::vec3(1, 0, 0)); - glm::mat4 rotPropY = glm::rotate(_transform, glm::radians(static_cast(_rotationY)), glm::vec3(0, 1, 0)); - glm::mat4 rotPropZ = glm::rotate(_transform, glm::radians(static_cast(_rotationZ)), glm::vec3(0, 0, 1)); + glm::mat4 rotPropX = glm::rotate( + _transform, + glm::radians(static_cast(_rotation.value().x)), + glm::vec3(1, 0, 0) + ); + glm::mat4 rotPropY = glm::rotate( + _transform, + glm::radians(static_cast(_rotation.value().y)), + glm::vec3(0, 1, 0) + ); + glm::mat4 rotPropZ = glm::rotate( + _transform, + glm::radians(static_cast(_rotation.value().z)), + glm::vec3(0, 0, 1) + ); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { @@ -419,32 +300,32 @@ void RenderableModelProjection::attitudeParameters(double time) { glm::vec3 cpos = position.vec3(); _projectorMatrix = computeProjectorMatrix(cpos, boresight, _up, _instrumentMatrix, - _fovy, _aspectRatio, _nearPlane, _farPlane, _boresight); - + _fovy, _aspectRatio, _nearPlane, _farPlane, _boresight + ); } void RenderableModelProjection::project() { for (auto img : _imageTimes) { - //std::thread t1(&RenderableModelProjection::attitudeParameters, this, img.startTime); - //t1.join(); attitudeParameters(img.startTime); - //_projectionTexturePath = img.path; - imageProjectGPU(loadProjectionTexture(img.path)); //fbopass + imageProjectGPU(loadProjectionTexture(img.path)); } _capture = false; } -void RenderableModelProjection::loadTextures() { +bool RenderableModelProjection::loadTextures() { _baseTexture = nullptr; if (_colorTexturePath.value() != "") { - _baseTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath))); + _baseTexture = std::move( + ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath)) + ); if (_baseTexture) { LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); _baseTexture->uploadTexture(); _baseTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); } } - generateProjectionLayerTexture(); + + return _baseTexture != nullptr; } } // namespace openspace diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index 620e28e170..d1f1742dd1 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include @@ -57,11 +57,8 @@ public: void render(const RenderData& data) override; void update(const UpdateData& data) override; - -protected: - void loadTextures(); - private: + bool loadTextures(); void attitudeParameters(double time); void imageProjectGPU(std::unique_ptr projectionTexture); @@ -69,9 +66,7 @@ private: properties::StringProperty _colorTexturePath; - properties::IntProperty _rotationX; - properties::IntProperty _rotationY; - properties::IntProperty _rotationZ; + properties::Vec3Property _rotation; std::unique_ptr _programObject; std::unique_ptr _fboProgramObject; @@ -80,7 +75,6 @@ private: std::unique_ptr _geometry; - float _alpha; glm::dmat3 _stateMatrix; glm::dmat3 _instrumentMatrix; @@ -89,21 +83,6 @@ private: std::string _destination; std::string _target; - // sequence loading - std::string _sequenceSource; - std::string _sequenceType; - - // projection mod info - std::string _instrumentID; - std::string _projectorID; - std::string _projecteeID; - SpiceManager::AberrationCorrection _aberration; - std::vector _potentialTargets; - float _fovy; - float _aspectRatio; - float _nearPlane; - float _farPlane; - // uniforms glm::vec2 _camScaling; glm::vec3 _up; @@ -111,14 +90,7 @@ private: glm::mat4 _projectorMatrix; glm::vec3 _boresight; - GLuint _vbo; - GLuint _ibo; - GLuint _vaoID; - std::vector _geometryVertecies; - std::vector _geometryIndeces; - std::vector _imageTimes; - int _frameCount; double _time; bool _capture; @@ -126,7 +98,6 @@ private: psc _sunPosition; properties::BoolProperty _performShading; - bool _programIsDirty; }; } // namespace openspace diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index e9975b1081..9110a85376 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -25,9 +25,6 @@ #include #include -#include -#include -#include #include #include @@ -41,29 +38,13 @@ namespace { const std::string _loggerCat = "RenderablePlanetProjection"; - const std::string keyProjObserver = "Projection.Observer"; - const std::string keyProjTarget = "Projection.Target"; - const std::string keyProjAberration = "Projection.Aberration"; - const std::string keyInstrument = "Instrument.Name"; - const std::string keyInstrumentFovy = "Instrument.Fovy"; - const std::string keyInstrumentAspect = "Instrument.Aspect"; - const std::string keyInstrumentNear = "Instrument.Near"; - const std::string keyInstrumentFar = "Instrument.Far"; - const std::string keySequenceDir = "Projection.Sequence"; - const std::string keySequenceType = "Projection.SequenceType"; const std::string keyPotentialTargets = "PotentialTargets"; - const std::string keyTranslation = "DataInputTranslation"; - - const std::string keyFrame = "Frame"; const std::string keyGeometry = "Geometry"; const std::string keyShading = "PerformShading"; const std::string keyBody = "Body"; const std::string _mainFrame = "GALACTIC"; - const std::string sequenceTypeImage = "image-sequence"; - const std::string sequenceTypePlaybook = "playbook"; - const std::string sequenceTypeHybrid = "hybrid"; } namespace openspace { @@ -100,16 +81,8 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& if (_target != "") setBody(_target); - bool b1 = dictionary.getValue(keyInstrument, _instrumentID); - bool b2 = dictionary.getValue(keyProjObserver, _projectorID); - bool b3 = dictionary.getValue(keyProjTarget, _projecteeID); - std::string a = "NONE"; - bool b4 = dictionary.getValue(keyProjAberration, a); - _aberration = SpiceManager::AberrationCorrection(a); - bool b5 = dictionary.getValue(keyInstrumentFovy, _fovy); - bool b6 = dictionary.getValue(keyInstrumentAspect, _aspectRatio); - bool b7 = dictionary.getValue(keyInstrumentNear, _nearPlane); - bool b8 = dictionary.getValue(keyInstrumentFar, _farPlane); + success = initializeProjectionSettings(dictionary); + ghoul_assert(success, ""); // @TODO copy-n-paste from renderablefov ---abock ghoul::Dictionary potentialTargets; @@ -150,93 +123,32 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& addProperty(_projectionFading); addProperty(_heightExaggeration); - SequenceParser* parser; - - // std::string sequenceSource; - bool _foundSequence = dictionary.getValue(keySequenceDir, _sequenceSource); - if (_foundSequence) { - _sequenceSource = absPath(_sequenceSource); - - _foundSequence = dictionary.getValue(keySequenceType, _sequenceType); - //Important: client must define translation-list in mod file IFF playbook - if (dictionary.hasKey(keyTranslation)){ - ghoul::Dictionary translationDictionary; - //get translation dictionary - dictionary.getValue(keyTranslation, translationDictionary); - - if (_sequenceType == sequenceTypePlaybook) { - parser = new HongKangParser(name, - _sequenceSource, - _projectorID, - translationDictionary, - _potentialTargets); - openspace::ImageSequencer::ref().runSequenceParser(parser); - } - else if (_sequenceType == sequenceTypeImage) { - parser = new LabelParser(name, - _sequenceSource, - translationDictionary); - openspace::ImageSequencer::ref().runSequenceParser(parser); - } - else if (_sequenceType == sequenceTypeHybrid) { - //first read labels - parser = new LabelParser(name, - _sequenceSource, - translationDictionary); - openspace::ImageSequencer::ref().runSequenceParser(parser); - - std::string _eventFile; - bool foundEventFile = dictionary.getValue("Projection.EventFile", _eventFile); - if (foundEventFile){ - //then read playbook - _eventFile = absPath(_eventFile); - parser = new HongKangParser(name, - _eventFile, - _projectorID, - translationDictionary, - _potentialTargets); - openspace::ImageSequencer::ref().runSequenceParser(parser); - } - else{ - LWARNING("No eventfile has been provided, please check modfiles"); - } - } - } - else{ - LWARNING("No playbook translation provided, please make sure all spice calls match playbook!"); - } - } + success = initializeParser(dictionary); + ghoul_assert(success, ""); } RenderablePlanetProjection::~RenderablePlanetProjection() {} bool RenderablePlanetProjection::initialize() { bool completeSuccess = true; - if (_programObject == nullptr) { - // projection program - RenderEngine& renderEngine = OsEng.renderEngine(); - _programObject = renderEngine.buildRenderProgram("projectiveProgram", - "${MODULE_NEWHORIZONS}/shaders/projectiveTexture_vs.glsl", - "${MODULE_NEWHORIZONS}/shaders/projectiveTexture_fs.glsl" - ); - - if (!_programObject) - return false; - } + _programObject = OsEng.renderEngine().buildRenderProgram("projectiveProgram", + "${MODULE_NEWHORIZONS}/shaders/projectiveTexture_vs.glsl", + "${MODULE_NEWHORIZONS}/shaders/projectiveTexture_fs.glsl" + ); _fboProgramObject = ghoul::opengl::ProgramObject::Build("fboPassProgram", "${MODULE_NEWHORIZONS}/shaders/fboPass_vs.glsl", "${MODULE_NEWHORIZONS}/shaders/fboPass_fs.glsl" ); - loadTextures(); - completeSuccess &= (_baseTexture != nullptr); - completeSuccess &= (_projectionTexture != nullptr); + completeSuccess &= loadTextures(); + completeSuccess &= ProjectionComponent::initialize(); + completeSuccess &= _geometry->initialize(this); if (completeSuccess) { - completeSuccess &= auxiliaryRendertarget(); + //completeSuccess &= auxiliaryRendertarget(); // SCREEN-QUAD const GLfloat size = 1.f; const GLfloat w = 1.f; @@ -266,14 +178,15 @@ bool RenderablePlanetProjection::initialize() { } bool RenderablePlanetProjection::deinitialize() { + ProjectionComponent::deinitialize(); _baseTexture = nullptr; _geometry = nullptr; - RenderEngine& renderEngine = OsEng.renderEngine(); - if (_programObject) { - renderEngine.removeRenderProgram(_programObject); - _programObject = nullptr; - } + glDeleteVertexArrays(1, &_quad); + glDeleteBuffers(1, &_vertexPositionBuffer); + + OsEng.renderEngine().removeRenderProgram(_programObject); + _programObject = nullptr; _fboProgramObject = nullptr; @@ -283,17 +196,11 @@ bool RenderablePlanetProjection::isReady() const { return _geometry && _programObject && _baseTexture && _projectionTexture; } -void RenderablePlanetProjection::imageProjectGPU(std::unique_ptr projectionTexture) { - // keep handle to the current bound FBO - GLint defaultFBO; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); +void RenderablePlanetProjection::imageProjectGPU( + std::unique_ptr projectionTexture) +{ + imageProjectBegin(); - GLint m_viewport[4]; - glGetIntegerv(GL_VIEWPORT, m_viewport); - //counter = 0; - glBindFramebuffer(GL_FRAMEBUFFER, _fboID); - - glViewport(0, 0, static_cast(_projectionTexture->width()), static_cast(_projectionTexture->height())); _fboProgramObject->activate(); ghoul::opengl::TextureUnit unitFbo; @@ -327,22 +234,33 @@ void RenderablePlanetProjection::imageProjectGPU(std::unique_ptrdeactivate(); - //bind back to default - glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); - glViewport(m_viewport[0], m_viewport[1], - m_viewport[2], m_viewport[3]); + imageProjectEnd(); } void RenderablePlanetProjection::attitudeParameters(double time) { // precomputations for shader _stateMatrix = SpiceManager::ref().positionTransformMatrix(_frame, _mainFrame, time); - _instrumentMatrix = SpiceManager::ref().positionTransformMatrix(_instrumentID, _mainFrame, time); + _instrumentMatrix = SpiceManager::ref().positionTransformMatrix( + _instrumentID, _mainFrame, time + ); _transform = glm::mat4(1); //90 deg rotation w.r.t spice req. - glm::mat4 rot = glm::rotate(_transform, static_cast(M_PI_2), glm::vec3(1, 0, 0)); - glm::mat4 roty = glm::rotate(_transform, static_cast(M_PI_2), glm::vec3(0, -1, 0)); - glm::mat4 rotProp = glm::rotate(_transform, static_cast(glm::radians(static_cast(_rotation))), glm::vec3(0, 1, 0)); + glm::mat4 rot = glm::rotate( + _transform, + static_cast(M_PI_2), + glm::vec3(1, 0, 0) + ); + glm::mat4 roty = glm::rotate( + _transform, + static_cast(M_PI_2), + glm::vec3(0, -1, 0) + ); + glm::mat4 rotProp = glm::rotate( + _transform, + static_cast(glm::radians(static_cast(_rotation))), + glm::vec3(0, 1, 0) + ); for (int i = 0; i < 3; i++){ for (int j = 0; j < 3; j++){ @@ -362,7 +280,9 @@ void RenderablePlanetProjection::attitudeParameters(double time) { } double lightTime; - glm::dvec3 p = SpiceManager::ref().targetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, lightTime); + glm::dvec3 p = SpiceManager::ref().targetPosition( + _projectorID, _projecteeID, _mainFrame, _aberration, time, lightTime + ); psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); //change to KM and add psc camera scaling. @@ -371,13 +291,11 @@ void RenderablePlanetProjection::attitudeParameters(double time) { glm::vec3 cpos = position.vec3(); _projectorMatrix = computeProjectorMatrix(cpos, bs, _up, _instrumentMatrix, - _fovy, _aspectRatio, _nearPlane, _farPlane, _boresight); + _fovy, _aspectRatio, _nearPlane, _farPlane, _boresight + ); } void RenderablePlanetProjection::render(const RenderData& data) { - if (!_programObject) - return; - if (_clearAllProjections) clearAllProjections(); @@ -431,23 +349,26 @@ void RenderablePlanetProjection::render(const RenderData& data) { } void RenderablePlanetProjection::update(const UpdateData& data) { - _time = Time::ref().currentTime(); - _capture = false; - - if (openspace::ImageSequencer::ref().isReady() && _performProjection){ - openspace::ImageSequencer::ref().updateSequencer(_time); - _capture = openspace::ImageSequencer::ref().getImagePaths(_imageTimes, _projecteeID, _instrumentID); - } - - if (_fboProgramObject && _fboProgramObject->isDirty()) { + if (_fboProgramObject->isDirty()) { _fboProgramObject->rebuildFromFile(); } if (_programObject->isDirty()) _programObject->rebuildFromFile(); + + _time = Time::ref().currentTime(); + _capture = false; + + if (openspace::ImageSequencer::ref().isReady() && _performProjection){ + openspace::ImageSequencer::ref().updateSequencer(_time); + _capture = openspace::ImageSequencer::ref().getImagePaths( + _imageTimes, _projecteeID, _instrumentID + ); + } + } -void RenderablePlanetProjection::loadTextures() { +bool RenderablePlanetProjection::loadTextures() { using ghoul::opengl::Texture; _baseTexture = nullptr; if (_colorTexturePath.value() != "") { @@ -459,8 +380,6 @@ void RenderablePlanetProjection::loadTextures() { } } - generateProjectionLayerTexture(); - _heightMapTexture = nullptr; if (_heightMapTexturePath.value() != "") { _heightMapTexture = ghoul::io::TextureReader::ref().loadTexture(_heightMapTexturePath); @@ -470,6 +389,9 @@ void RenderablePlanetProjection::loadTextures() { _heightMapTexture->setFilter(Texture::FilterMode::Linear); } } + + return _baseTexture != nullptr; + } } // namespace openspace diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index b5ab104901..13d07b760c 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -32,7 +32,6 @@ #include #include -#include #include #include @@ -53,13 +52,12 @@ public: bool deinitialize() override; bool isReady() const override; - void render(const RenderData& data) override; void update(const UpdateData& data) override; ghoul::opengl::Texture* baseTexture() { return _projectionTexture.get(); }; protected: - void loadTextures(); + bool loadTextures(); void attitudeParameters(double time); @@ -81,41 +79,21 @@ private: std::unique_ptr _geometry; - glm::vec2 _camScaling; - glm::vec3 _up; - glm::mat4 _transform; - glm::mat4 _projectorMatrix; - - //sequenceloading - std::string _sequenceSource; - std::string _sequenceType; - bool _foundSequence; - - // spice - std::string _instrumentID; - std::string _projectorID; - std::string _projecteeID; - SpiceManager::AberrationCorrection _aberration; - std::vector _potentialTargets; // @TODO copy-n-paste from renderablefov - - - float _fovy; - float _aspectRatio; - float _nearPlane; - float _farPlane; + glm::vec2 _camScaling; + glm::vec3 _up; + glm::mat4 _transform; + glm::mat4 _projectorMatrix; glm::dmat3 _stateMatrix; glm::dmat3 _instrumentMatrix; - glm::vec3 _boresight; + glm::vec3 _boresight; double _time; std::vector _imageTimes; - int _sequenceID; std::string _target; std::string _frame; - std::string _next; bool _capture; diff --git a/modules/newhorizons/util/projectioncomponent.cpp b/modules/newhorizons/util/projectioncomponent.cpp index f11f350604..769bbf1616 100644 --- a/modules/newhorizons/util/projectioncomponent.cpp +++ b/modules/newhorizons/util/projectioncomponent.cpp @@ -24,20 +24,168 @@ #include +#include +#include +#include + +#include + #include #include #include #include +namespace { + const std::string keyInstrument = "Instrument.Name"; + const std::string keyInstrumentFovy = "Instrument.Fovy"; + const std::string keyInstrumentAspect = "Instrument.Aspect"; + const std::string keyInstrumentNear = "Instrument.Near"; + const std::string keyInstrumentFar = "Instrument.Far"; + + const std::string keyProjObserver = "Projection.Observer"; + const std::string keyProjTarget = "Projection.Target"; + const std::string keyProjAberration = "Projection.Aberration"; + + const std::string keySequenceDir = "Projection.Sequence"; + const std::string keySequenceType = "Projection.SequenceType"; + const std::string keyTranslation = "DataInputTranslation"; + + const std::string sequenceTypeImage = "image-sequence"; + const std::string sequenceTypePlaybook = "playbook"; + const std::string sequenceTypeHybrid = "hybrid"; + + const std::string _loggerCat = "ProjectionComponent"; +} + namespace openspace { +using ghoul::Dictionary; + ProjectionComponent::ProjectionComponent() : _performProjection("performProjection", "Perform Projections", true) , _clearAllProjections("clearAllProjections", "Clear Projections", false) , _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f) , _projectionTexture(nullptr) -{ +{} +bool ProjectionComponent::initialize() { + bool a = generateProjectionLayerTexture(); + bool b = auxiliaryRendertarget(); + return a && b; +} + +bool ProjectionComponent::deinitialize() { + _projectionTexture = nullptr; + + glDeleteFramebuffers(1, &_fboID); + + return true; +} + +bool ProjectionComponent::initializeProjectionSettings(const Dictionary& dictionary) { + bool completeSuccess = true; + completeSuccess &= dictionary.getValue(keyInstrument, _instrumentID); + completeSuccess &= dictionary.getValue(keyProjObserver, _projectorID); + completeSuccess &= dictionary.getValue(keyProjTarget, _projecteeID); + completeSuccess &= dictionary.getValue(keyInstrumentFovy, _fovy); + completeSuccess &= dictionary.getValue(keyInstrumentAspect, _aspectRatio); + completeSuccess &= dictionary.getValue(keyInstrumentNear, _nearPlane); + completeSuccess &= dictionary.getValue(keyInstrumentFar, _farPlane); + ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile"); + + std::string a = "NONE"; + bool s = dictionary.getValue(keyProjAberration, a); + _aberration = SpiceManager::AberrationCorrection(a); + completeSuccess &= s; + ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile"); + + return completeSuccess; +} + +bool ProjectionComponent::initializeParser(const ghoul::Dictionary& dictionary) { + bool completeSuccess = true; + + std::string name; + dictionary.getValue(SceneGraphNode::KeyName, name); + + SequenceParser* parser; + + std::string sequenceSource; + std::string sequenceType; + bool foundSequence = dictionary.getValue(keySequenceDir, sequenceSource); + if (foundSequence) { + sequenceSource = absPath(sequenceSource); + + foundSequence = dictionary.getValue(keySequenceType, sequenceType); + //Important: client must define translation-list in mod file IFF playbook + if (dictionary.hasKey(keyTranslation)) { + ghoul::Dictionary translationDictionary; + //get translation dictionary + dictionary.getValue(keyTranslation, translationDictionary); + + if (sequenceType == sequenceTypePlaybook) { + parser = new HongKangParser(name, + sequenceSource, + _projectorID, + translationDictionary, + _potentialTargets); + openspace::ImageSequencer::ref().runSequenceParser(parser); + } + else if (sequenceType == sequenceTypeImage) { + parser = new LabelParser(name, + sequenceSource, + translationDictionary); + openspace::ImageSequencer::ref().runSequenceParser(parser); + } + else if (sequenceType == sequenceTypeHybrid) { + //first read labels + parser = new LabelParser(name, + sequenceSource, + translationDictionary); + openspace::ImageSequencer::ref().runSequenceParser(parser); + + std::string _eventFile; + bool foundEventFile = dictionary.getValue("Projection.EventFile", _eventFile); + if (foundEventFile) { + //then read playbook + _eventFile = absPath(_eventFile); + parser = new HongKangParser(name, + _eventFile, + _projectorID, + translationDictionary, + _potentialTargets); + openspace::ImageSequencer::ref().runSequenceParser(parser); + } + else { + LWARNING("No eventfile has been provided, please check modfiles"); + } + } + } + else { + LWARNING("No playbook translation provided, please make sure all spice calls match playbook!"); + } + } + + return completeSuccess; +} + +void ProjectionComponent::imageProjectBegin() { + // keep handle to the current bound FBO + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); + + glGetIntegerv(GL_VIEWPORT, _viewport); + glBindFramebuffer(GL_FRAMEBUFFER, _fboID); + + glViewport( + 0, 0, + static_cast(_projectionTexture->width()), + static_cast(_projectionTexture->height()) + ); +} + +void ProjectionComponent::imageProjectEnd() { + glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); + glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]); } bool ProjectionComponent::auxiliaryRendertarget() { @@ -49,7 +197,13 @@ bool ProjectionComponent::auxiliaryRendertarget() { // setup FBO glGenFramebuffers(1, &_fboID); glBindFramebuffer(GL_FRAMEBUFFER, _fboID); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *_projectionTexture, 0); + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + *_projectionTexture, + 0 + ); // check FBO status GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) @@ -60,12 +214,12 @@ bool ProjectionComponent::auxiliaryRendertarget() { return completeSuccess; } -glm::mat4 ProjectionComponent::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up, +glm::mat4 ProjectionComponent::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, + const glm::vec3 up, const glm::dmat3& instrumentMatrix, float fieldOfViewY, float aspectRatio, - float nearPlane, - float farPlane, + float nearPlane, float farPlane, glm::vec3& boreSight) { //rotate boresight into correct alignment @@ -113,31 +267,39 @@ void ProjectionComponent::clearAllProjections() { _clearAllProjections = false; } -std::unique_ptr ProjectionComponent::loadProjectionTexture(const std::string& texturePath) { - std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(texturePath)); +std::unique_ptr ProjectionComponent::loadProjectionTexture( + const std::string& texturePath) +{ + using std::unique_ptr; + using ghoul::opengl::Texture; + using ghoul::io::TextureReader; + unique_ptr texture = TextureReader::ref().loadTexture(absPath(texturePath)); if (texture) { ghoul::opengl::convertTextureFormat(ghoul::opengl::Texture::Format::RGB, *texture); texture->uploadTexture(); // TODO: AnisotropicMipMap crashes on ATI cards ---abock //_textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); - texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); + texture->setFilter(Texture::FilterMode::Linear); + texture->setWrapping(Texture::WrappingMode::ClampToBorder); } return texture; } -void ProjectionComponent::generateProjectionLayerTexture() { +bool ProjectionComponent::generateProjectionLayerTexture() { int maxSize = OpenGLCap.max2DTextureSize() / 2; - LINFOC( - "ProjectionComponent", + LINFO( "Creating projection texture of size '" << maxSize << ", " << maxSize / 2 << "'" ); _projectionTexture = std::make_unique ( glm::uvec3(maxSize, maxSize / 2, 1), ghoul::opengl::Texture::Format::RGBA ); - _projectionTexture->uploadTexture(); + if (_projectionTexture) + _projectionTexture->uploadTexture(); + + return _projectionTexture != nullptr; + } } // namespace openspace diff --git a/modules/newhorizons/util/projectioncomponent.h b/modules/newhorizons/util/projectioncomponent.h index 9ac9a5d9a2..9ff0638a14 100644 --- a/modules/newhorizons/util/projectioncomponent.h +++ b/modules/newhorizons/util/projectioncomponent.h @@ -26,7 +26,9 @@ #define __PROJECTIONCOMPONENT_H__ #include +#include +#include #include namespace openspace { @@ -36,7 +38,16 @@ public: ProjectionComponent(); protected: - void generateProjectionLayerTexture(); + bool initialize(); + bool deinitialize(); + + bool initializeProjectionSettings(const ghoul::Dictionary& dictionary); + bool initializeParser(const ghoul::Dictionary& dictionary); + + void imageProjectBegin(); + void imageProjectEnd(); + + bool generateProjectionLayerTexture(); bool auxiliaryRendertarget(); std::unique_ptr loadProjectionTexture(const std::string& texturePath); @@ -55,13 +66,25 @@ protected: properties::BoolProperty _performProjection; properties::BoolProperty _clearAllProjections; - properties::FloatProperty _projectionFading; std::unique_ptr _projectionTexture; + std::string _instrumentID; + std::string _projectorID; + std::string _projecteeID; + SpiceManager::AberrationCorrection _aberration; + std::vector _potentialTargets; + float _fovy; + float _aspectRatio; + float _nearPlane; + float _farPlane; + + GLuint _fboID; + GLint _defaultFBO; + GLint _viewport[4]; }; } // namespace openspace From afe2ecc1e8b91e1275fabf3f4d579efe53eaee69 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 4 Jun 2016 13:39:11 +0200 Subject: [PATCH 32/61] Allow RenderEngine's removeRenderProgram method to reject passed nullptrs --- src/rendering/renderengine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index aecc8bf4e5..c491cde6ac 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -557,6 +557,9 @@ std::unique_ptr RenderEngine::buildRenderProgram( } void RenderEngine::removeRenderProgram(const std::unique_ptr& program) { + if (!program) + return; + ghoul::opengl::ProgramObject* ptr = program.get(); auto it = std::find( _programs.begin(), From 2700ef6ea8bc1bc6cad7388403c876fff3401cb2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 4 Jun 2016 13:45:55 +0200 Subject: [PATCH 33/61] Moving potential targets into ProjectionComponent --- .../rendering/renderableplanetprojection.cpp | 14 -------------- modules/newhorizons/util/projectioncomponent.cpp | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 9110a85376..e4954dcc6e 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -38,7 +38,6 @@ namespace { const std::string _loggerCat = "RenderablePlanetProjection"; - const std::string keyPotentialTargets = "PotentialTargets"; const std::string keyFrame = "Frame"; const std::string keyGeometry = "Geometry"; @@ -84,18 +83,6 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& success = initializeProjectionSettings(dictionary); ghoul_assert(success, ""); - // @TODO copy-n-paste from renderablefov ---abock - ghoul::Dictionary potentialTargets; - success = dictionary.getValue(keyPotentialTargets, potentialTargets); - ghoul_assert(success, ""); - - _potentialTargets.resize(potentialTargets.size()); - for (int i = 0; i < potentialTargets.size(); ++i) { - std::string target; - potentialTargets.getValue(std::to_string(i + 1), target); - _potentialTargets[i] = target; - } - // TODO: textures need to be replaced by a good system similar to the geometry as soon // as the requirements are fixed (ab) std::string texturePath = ""; @@ -113,7 +100,6 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& addProperty(_performProjection); addProperty(_clearAllProjections); - addProperty(_colorTexturePath); _colorTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTextures, this)); diff --git a/modules/newhorizons/util/projectioncomponent.cpp b/modules/newhorizons/util/projectioncomponent.cpp index 769bbf1616..5b212223b4 100644 --- a/modules/newhorizons/util/projectioncomponent.cpp +++ b/modules/newhorizons/util/projectioncomponent.cpp @@ -36,6 +36,8 @@ #include namespace { + const std::string keyPotentialTargets = "PotentialTargets"; + const std::string keyInstrument = "Instrument.Name"; const std::string keyInstrumentFovy = "Instrument.Fovy"; const std::string keyInstrumentAspect = "Instrument.Aspect"; @@ -99,6 +101,19 @@ bool ProjectionComponent::initializeProjectionSettings(const Dictionary& diction completeSuccess &= s; ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile"); + + if (dictionary.hasKeyAndValue(keyPotentialTargets)) { + ghoul::Dictionary potentialTargets = dictionary.value( + keyPotentialTargets + ); + + _potentialTargets.resize(potentialTargets.size()); + for (int i = 0; i < potentialTargets.size(); ++i) { + std::string target; + potentialTargets.getValue(std::to_string(i + 1), target); + _potentialTargets[i] = target; + } + } return completeSuccess; } From 30264fb00e3a33221fd8370e7c1132096e1fd0e0 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 4 Jun 2016 19:38:56 +0200 Subject: [PATCH 34/61] Add Lua function to check whether a specific module is loaded (closing #36) --- include/openspace/engine/moduleengine.h | 7 +++ src/CMakeLists.txt | 1 + src/engine/moduleengine.cpp | 17 +++++++ src/engine/moduleengine_lua.inl | 65 +++++++++++++++++++++++++ src/engine/openspaceengine.cpp | 1 + src/rendering/renderengine_lua.inl | 14 +----- 6 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 src/engine/moduleengine_lua.inl diff --git a/include/openspace/engine/moduleengine.h b/include/openspace/engine/moduleengine.h index bb7c86aa15..a15515c4d0 100644 --- a/include/openspace/engine/moduleengine.h +++ b/include/openspace/engine/moduleengine.h @@ -26,6 +26,7 @@ #define __MODULEENGINE_H__ #include +#include #include #include @@ -74,6 +75,12 @@ public: */ std::vector modules() const; + /** + * Returns the Lua library that contains all Lua functions available to affect the + * modules. + */ + static scripting::ScriptEngine::LuaLibrary luaLibrary(); + private: /// The list of all registered OpenSpaceModule%s std::vector> _modules; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8a9992e1af..0f6ad12718 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,6 +28,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/engine/downloadmanager.cpp ${OPENSPACE_BASE_DIR}/src/engine/logfactory.cpp ${OPENSPACE_BASE_DIR}/src/engine/moduleengine.cpp + ${OPENSPACE_BASE_DIR}/src/engine/moduleengine_lua.inl ${OPENSPACE_BASE_DIR}/src/engine/openspaceengine.cpp ${OPENSPACE_BASE_DIR}/src/engine/wrapper/sgctwindowwrapper.cpp ${OPENSPACE_BASE_DIR}/src/engine/wrapper/windowwrapper.cpp diff --git a/src/engine/moduleengine.cpp b/src/engine/moduleengine.cpp index f78cdf6314..ed14d9a74e 100644 --- a/src/engine/moduleengine.cpp +++ b/src/engine/moduleengine.cpp @@ -31,6 +31,8 @@ #include +#include "moduleengine_lua.inl" + namespace { const std::string _loggerCat = "ModuleEngine"; } @@ -80,4 +82,19 @@ std::vector ModuleEngine::modules() const { return result; } +scripting::ScriptEngine::LuaLibrary ModuleEngine::luaLibrary() { + return { + "modules", + { + { + "isLoaded", + &luascriptfunctions::isLoaded, + "string", + "Checks whether a specific module is loaded" + } + } + + }; +} + } // namespace openspace diff --git a/src/engine/moduleengine_lua.inl b/src/engine/moduleengine_lua.inl new file mode 100644 index 0000000000..a0524891e0 --- /dev/null +++ b/src/engine/moduleengine_lua.inl @@ -0,0 +1,65 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include + +namespace openspace { +namespace luascriptfunctions { + +/** + * \ingroup LuaScripts + * isLoaded(string): + * Checks whether the passed OpenSpaceModule is loaded or not + */ +int isLoaded(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + + const int type = lua_type(L, -1); + if (type != LUA_TSTRING) + return luaL_error(L, "Expected argument of type 'string'"); + std::string moduleName = lua_tostring(L, -1); + + std::vector modules = OsEng.moduleEngine().modules(); + + auto it = std::find_if( + modules.begin(), + modules.end(), + [moduleName](OpenSpaceModule* module) { + return module->name() == moduleName; + } + ); + + if (it != modules.end()) + lua_pushboolean(L, 1); + else + lua_pushboolean(L, 0); + + return 1; +} + +} // namespace luascriptfunctions +} // namespace openspace diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 29b1a9071c..28b5fb4777 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -370,6 +370,7 @@ bool OpenSpaceEngine::initialize() { _scriptEngine->addLibrary(LuaConsole::luaLibrary()); _scriptEngine->addLibrary(gui::GUI::luaLibrary()); _scriptEngine->addLibrary(network::ParallelConnection::luaLibrary()); + _scriptEngine->addLibrary(ModuleEngine::luaLibrary()); #ifdef OPENSPACE_MODULE_ISWA_ENABLED _scriptEngine->addLibrary(IswaManager::luaLibrary()); diff --git a/src/rendering/renderengine_lua.inl b/src/rendering/renderengine_lua.inl index 087df65e83..18fc6235d0 100644 --- a/src/rendering/renderengine_lua.inl +++ b/src/rendering/renderengine_lua.inl @@ -26,18 +26,6 @@ namespace openspace { namespace luascriptfunctions { -/** -int changeCoordinateSystem(lua_State* L) { - int nArguments = lua_gettop(L); - if (nArguments != 1) - return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); - - std::string newCenter = std::string(lua_tostring(L, -1)); - OsEng.renderEngine()->changeViewPoint(newCenter); - return 1; -} -*/ - /** * \ingroup LuaScripts * takeScreenshot(): @@ -63,7 +51,7 @@ int setRenderer(lua_State* L) { const int type = lua_type(L, -1); if (type != LUA_TSTRING) - return luaL_error(L, "Expected argument of type 'bool'"); + return luaL_error(L, "Expected argument of type 'string'"); std::string r = lua_tostring(L, -1); OsEng.renderEngine().setRendererFromString(r); return 0; From 36f5f7bb049d5709dcb5398f44a977d62f8eed29 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 4 Jun 2016 19:39:22 +0200 Subject: [PATCH 35/61] Only load cdf list if ISWA module is loaded --- data/scene/default.scene | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/scene/default.scene b/data/scene/default.scene index 994cc7e3b4..1c30a2a34d 100644 --- a/data/scene/default.scene +++ b/data/scene/default.scene @@ -27,7 +27,9 @@ function postInitialization() openspace.printInfo("Done setting default values") - openspace.iswa.addCdfFiles("${OPENSPACE_DATA}/cdflist.json"); + if openspace.modules.isLoaded("ISWA") then + openspace.iswa.addCdfFiles("${OPENSPACE_DATA}/cdflist.json"); + end end From fe9a97fc80158aa0b9caae191581ca3a9e8f5180 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 4 Jun 2016 19:56:29 +0200 Subject: [PATCH 36/61] Fix GLSL compile error --- modules/galaxy/shaders/galaxyraycast.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/galaxy/shaders/galaxyraycast.glsl b/modules/galaxy/shaders/galaxyraycast.glsl index 23566e6f1c..1d4db0dbcb 100644 --- a/modules/galaxy/shaders/galaxyraycast.glsl +++ b/modules/galaxy/shaders/galaxyraycast.glsl @@ -87,7 +87,7 @@ void sample#{id}(vec3 samplePos, accumulatedColor += oneMinusFrontAlpha * backColor; accumulatedAlpha += oneMinusFrontAlpha * backAlpha; - acc+= 1.0; + // acc+= 1.0; //accumulatedColor = vec3(opacityCoefficient#{id}); } From 50e0c1a43be7816324222482ac604c5dd6ec7dfe Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 4 Jun 2016 20:03:16 +0200 Subject: [PATCH 37/61] Reset Earth as camera focus --- data/scene/default.scene | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/scene/default.scene b/data/scene/default.scene index e514e7a11a..4a4a3e49dc 100644 --- a/data/scene/default.scene +++ b/data/scene/default.scene @@ -37,7 +37,7 @@ return { ScenePath = ".", CommonFolder = "common", Camera = { - Focus = "Root", + Focus = "Earth", Position = {1, 0, 0, 2}, }, Modules = { From 636231839946821def45a2b0c1901c7c3216d7ce Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 4 Jun 2016 20:17:28 +0200 Subject: [PATCH 38/61] Make textured milkyway show again --- data/scene/milkyway/milkyway.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/scene/milkyway/milkyway.mod b/data/scene/milkyway/milkyway.mod index b616119cf9..824529977c 100644 --- a/data/scene/milkyway/milkyway.mod +++ b/data/scene/milkyway/milkyway.mod @@ -7,7 +7,7 @@ return { }, Renderable = { Type = "RenderableSphere", - Size = {10, 30}, + Size = {10, 25}, Segments = 40, Texture = "textures/DarkUniverse_mellinger_8k.jpg", Orientation = "Inside/Outside" From 3d82173ff03a65a80b26d6b890459c625dc1e130 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 4 Jun 2016 20:33:17 +0200 Subject: [PATCH 39/61] Don't set alpha value to 1.0 for all projection images --- data/scene/rosetta/67P/67P.mod | 2 +- modules/newhorizons/shaders/fboPass_fs.glsl | 1 - modules/newhorizons/util/projectioncomponent.cpp | 3 ++- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/scene/rosetta/67P/67P.mod b/data/scene/rosetta/67P/67P.mod index e5c1e2962b..a6ec406f4c 100644 --- a/data/scene/rosetta/67P/67P.mod +++ b/data/scene/rosetta/67P/67P.mod @@ -23,7 +23,7 @@ return { Destination = "GALACTIC" }, Projection = { - Sequence = "rosettaimages2", + Sequence = "rosettaimages", SequenceType = "image-sequence", Observer = "ROSETTA", Target = "CHURYUMOV-GERASIMENKO", diff --git a/modules/newhorizons/shaders/fboPass_fs.glsl b/modules/newhorizons/shaders/fboPass_fs.glsl index 8c4384164b..c9772d724a 100644 --- a/modules/newhorizons/shaders/fboPass_fs.glsl +++ b/modules/newhorizons/shaders/fboPass_fs.glsl @@ -84,6 +84,5 @@ void main() { // The 1-x is in this texture call because of flipped textures // to be fixed soon ---abock color = texture(projectionTexture, vec2(projected.x, 1-projected.y)); - color.a = 1.0; } } \ No newline at end of file diff --git a/modules/newhorizons/util/projectioncomponent.cpp b/modules/newhorizons/util/projectioncomponent.cpp index 5b212223b4..780af31965 100644 --- a/modules/newhorizons/util/projectioncomponent.cpp +++ b/modules/newhorizons/util/projectioncomponent.cpp @@ -290,7 +290,8 @@ std::unique_ptr ProjectionComponent::loadProjectionTextu using ghoul::io::TextureReader; unique_ptr texture = TextureReader::ref().loadTexture(absPath(texturePath)); if (texture) { - ghoul::opengl::convertTextureFormat(ghoul::opengl::Texture::Format::RGB, *texture); + if (texture->format() == Texture::Format::Red) + ghoul::opengl::convertTextureFormat(ghoul::opengl::Texture::Format::RGB, *texture); texture->uploadTexture(); // TODO: AnisotropicMipMap crashes on ATI cards ---abock //_textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); From ef750664787ea1a1a34347fa8e3c32faf00ca50f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 4 Jun 2016 20:42:10 +0200 Subject: [PATCH 40/61] Rename projection shaders to more sensible names --- modules/newhorizons/CMakeLists.txt | 16 ++++++++-------- .../rendering/renderablemodelprojection.cpp | 8 ++++---- .../rendering/renderableplanetprojection.cpp | 8 ++++---- ...fs.glsl => renderableModelProjection_fs.glsl} | 0 ...vs.glsl => renderableModelProjection_vs.glsl} | 0 ...delShader_fs.glsl => renderableModel_fs.glsl} | 0 ...delShader_vs.glsl => renderableModel_vs.glsl} | 0 ...s.glsl => renderablePlanetProjection_fs.glsl} | 0 ...s.glsl => renderablePlanetProjection_vs.glsl} | 0 ...eTexture_fs.glsl => renderablePlanet_fs.glsl} | 0 ...eTexture_vs.glsl => renderablePlanet_vs.glsl} | 0 modules/newhorizons/util/projectioncomponent.cpp | 2 +- 12 files changed, 17 insertions(+), 17 deletions(-) rename modules/newhorizons/shaders/{projectionPass_fs.glsl => renderableModelProjection_fs.glsl} (100%) rename modules/newhorizons/shaders/{projectionPass_vs.glsl => renderableModelProjection_vs.glsl} (100%) rename modules/newhorizons/shaders/{modelShader_fs.glsl => renderableModel_fs.glsl} (100%) rename modules/newhorizons/shaders/{modelShader_vs.glsl => renderableModel_vs.glsl} (100%) rename modules/newhorizons/shaders/{fboPass_fs.glsl => renderablePlanetProjection_fs.glsl} (100%) rename modules/newhorizons/shaders/{fboPass_vs.glsl => renderablePlanetProjection_vs.glsl} (100%) rename modules/newhorizons/shaders/{projectiveTexture_fs.glsl => renderablePlanet_fs.glsl} (100%) rename modules/newhorizons/shaders/{projectiveTexture_vs.glsl => renderablePlanet_vs.glsl} (100%) diff --git a/modules/newhorizons/CMakeLists.txt b/modules/newhorizons/CMakeLists.txt index fa6b705fc9..6ed7a3e3e0 100644 --- a/modules/newhorizons/CMakeLists.txt +++ b/modules/newhorizons/CMakeLists.txt @@ -66,16 +66,16 @@ source_group("Source Files" FILES ${SOURCE_FILES}) set(SHADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/shaders/crawlingline_fs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/crawlingline_vs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/fboPass_fs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/fboPass_vs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/fov_fs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/fov_vs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/projectiveTexture_fs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/projectiveTexture_vs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/projectionPass_fs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/projectionPass_vs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/modelShader_fs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/modelShader_vs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderableModel_fs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderableModel_vs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderableModelProjection_fs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderableModelProjection_vs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderablePlanet_fs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderablePlanet_vs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderablePlanetProjection_fs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderablePlanetProjection_vs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/terminatorshadow_fs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/terminatorshadow_vs.glsl ) diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 2b8e8129b2..bb929b53a0 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -121,13 +121,13 @@ bool RenderableModelProjection::initialize() { RenderEngine& renderEngine = OsEng.renderEngine(); _programObject = renderEngine.buildRenderProgram("ModelShader", - "${MODULE_NEWHORIZONS}/shaders/modelShader_vs.glsl", - "${MODULE_NEWHORIZONS}/shaders/modelShader_fs.glsl"); + "${MODULE_NEWHORIZONS}/shaders/renderableModel_vs.glsl", + "${MODULE_NEWHORIZONS}/shaders/renderableModel_fs.glsl"); _fboProgramObject = ghoul::opengl::ProgramObject::Build("ProjectionPass", - "${MODULE_NEWHORIZONS}/shaders/projectionPass_vs.glsl", - "${MODULE_NEWHORIZONS}/shaders/projectionPass_fs.glsl"); + "${MODULE_NEWHORIZONS}/shaders/renderableModelProjection_vs.glsl", + "${MODULE_NEWHORIZONS}/shaders/renderableModelProjection_fs.glsl"); _fboProgramObject->setIgnoreUniformLocationError( ghoul::opengl::ProgramObject::IgnoreError::Yes ); diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index e4954dcc6e..45e091814c 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -119,13 +119,13 @@ bool RenderablePlanetProjection::initialize() { bool completeSuccess = true; _programObject = OsEng.renderEngine().buildRenderProgram("projectiveProgram", - "${MODULE_NEWHORIZONS}/shaders/projectiveTexture_vs.glsl", - "${MODULE_NEWHORIZONS}/shaders/projectiveTexture_fs.glsl" + "${MODULE_NEWHORIZONS}/shaders/renderablePlanet_vs.glsl", + "${MODULE_NEWHORIZONS}/shaders/renderablePlanet_fs.glsl" ); _fboProgramObject = ghoul::opengl::ProgramObject::Build("fboPassProgram", - "${MODULE_NEWHORIZONS}/shaders/fboPass_vs.glsl", - "${MODULE_NEWHORIZONS}/shaders/fboPass_fs.glsl" + "${MODULE_NEWHORIZONS}/shaders/renderablePlanetProjection_vs.glsl", + "${MODULE_NEWHORIZONS}/shaders/renderablePlanetProjection_fs.glsl" ); completeSuccess &= loadTextures(); diff --git a/modules/newhorizons/shaders/projectionPass_fs.glsl b/modules/newhorizons/shaders/renderableModelProjection_fs.glsl similarity index 100% rename from modules/newhorizons/shaders/projectionPass_fs.glsl rename to modules/newhorizons/shaders/renderableModelProjection_fs.glsl diff --git a/modules/newhorizons/shaders/projectionPass_vs.glsl b/modules/newhorizons/shaders/renderableModelProjection_vs.glsl similarity index 100% rename from modules/newhorizons/shaders/projectionPass_vs.glsl rename to modules/newhorizons/shaders/renderableModelProjection_vs.glsl diff --git a/modules/newhorizons/shaders/modelShader_fs.glsl b/modules/newhorizons/shaders/renderableModel_fs.glsl similarity index 100% rename from modules/newhorizons/shaders/modelShader_fs.glsl rename to modules/newhorizons/shaders/renderableModel_fs.glsl diff --git a/modules/newhorizons/shaders/modelShader_vs.glsl b/modules/newhorizons/shaders/renderableModel_vs.glsl similarity index 100% rename from modules/newhorizons/shaders/modelShader_vs.glsl rename to modules/newhorizons/shaders/renderableModel_vs.glsl diff --git a/modules/newhorizons/shaders/fboPass_fs.glsl b/modules/newhorizons/shaders/renderablePlanetProjection_fs.glsl similarity index 100% rename from modules/newhorizons/shaders/fboPass_fs.glsl rename to modules/newhorizons/shaders/renderablePlanetProjection_fs.glsl diff --git a/modules/newhorizons/shaders/fboPass_vs.glsl b/modules/newhorizons/shaders/renderablePlanetProjection_vs.glsl similarity index 100% rename from modules/newhorizons/shaders/fboPass_vs.glsl rename to modules/newhorizons/shaders/renderablePlanetProjection_vs.glsl diff --git a/modules/newhorizons/shaders/projectiveTexture_fs.glsl b/modules/newhorizons/shaders/renderablePlanet_fs.glsl similarity index 100% rename from modules/newhorizons/shaders/projectiveTexture_fs.glsl rename to modules/newhorizons/shaders/renderablePlanet_fs.glsl diff --git a/modules/newhorizons/shaders/projectiveTexture_vs.glsl b/modules/newhorizons/shaders/renderablePlanet_vs.glsl similarity index 100% rename from modules/newhorizons/shaders/projectiveTexture_vs.glsl rename to modules/newhorizons/shaders/renderablePlanet_vs.glsl diff --git a/modules/newhorizons/util/projectioncomponent.cpp b/modules/newhorizons/util/projectioncomponent.cpp index 780af31965..f47184285c 100644 --- a/modules/newhorizons/util/projectioncomponent.cpp +++ b/modules/newhorizons/util/projectioncomponent.cpp @@ -310,7 +310,7 @@ bool ProjectionComponent::generateProjectionLayerTexture() { _projectionTexture = std::make_unique ( glm::uvec3(maxSize, maxSize / 2, 1), ghoul::opengl::Texture::Format::RGBA - ); + ); if (_projectionTexture) _projectionTexture->uploadTexture(); From 9a3818f00739dc2a0d0ce1881dfa5c5abe42ed0d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 4 Jun 2016 20:58:58 +0200 Subject: [PATCH 41/61] ProjectionComponent always loads the placeholder textures and reuses it --- .../rendering/renderablemodelprojection.cpp | 4 ++- .../rendering/renderablemodelprojection.h | 2 +- .../rendering/renderableplanetprojection.cpp | 2 +- .../rendering/renderableplanetprojection.h | 2 +- .../newhorizons/util/projectioncomponent.cpp | 27 +++++++++++++++++-- .../newhorizons/util/projectioncomponent.h | 4 ++- 6 files changed, 34 insertions(+), 7 deletions(-) diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index bb929b53a0..df13bbcec7 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -227,7 +227,9 @@ void RenderableModelProjection::update(const UpdateData& data) { _sunPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); } -void RenderableModelProjection::imageProjectGPU(std::unique_ptr projectionTexture) { +void RenderableModelProjection::imageProjectGPU( + std::shared_ptr projectionTexture) +{ ProjectionComponent::imageProjectBegin(); _fboProgramObject->activate(); diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index d1f1742dd1..de9508f445 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -60,7 +60,7 @@ public: private: bool loadTextures(); void attitudeParameters(double time); - void imageProjectGPU(std::unique_ptr projectionTexture); + void imageProjectGPU(std::shared_ptr projectionTexture); void project(); diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 45e091814c..8d5379e210 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -183,7 +183,7 @@ bool RenderablePlanetProjection::isReady() const { } void RenderablePlanetProjection::imageProjectGPU( - std::unique_ptr projectionTexture) + std::shared_ptr projectionTexture) { imageProjectBegin(); diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index 13d07b760c..c3927896f4 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -62,7 +62,7 @@ protected: private: - void imageProjectGPU(std::unique_ptr projectionTexture); + void imageProjectGPU(std::shared_ptr projectionTexture); properties::StringProperty _colorTexturePath; properties::StringProperty _heightMapTexturePath; diff --git a/modules/newhorizons/util/projectioncomponent.cpp b/modules/newhorizons/util/projectioncomponent.cpp index f47184285c..74c2ec9eb1 100644 --- a/modules/newhorizons/util/projectioncomponent.cpp +++ b/modules/newhorizons/util/projectioncomponent.cpp @@ -56,6 +56,9 @@ namespace { const std::string sequenceTypePlaybook = "playbook"; const std::string sequenceTypeHybrid = "hybrid"; + const std::string placeholderFile = + "${OPENSPACE_DATA}/scene/common/textures/placeholder.png"; + const std::string _loggerCat = "ProjectionComponent"; } @@ -73,6 +76,21 @@ ProjectionComponent::ProjectionComponent() bool ProjectionComponent::initialize() { bool a = generateProjectionLayerTexture(); bool b = auxiliaryRendertarget(); + + using std::unique_ptr; + using ghoul::opengl::Texture; + using ghoul::io::TextureReader; + + unique_ptr texture = TextureReader::ref().loadTexture(absPath(placeholderFile)); + if (texture) { + texture->uploadTexture(); + // TODO: AnisotropicMipMap crashes on ATI cards ---abock + //_textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + texture->setFilter(Texture::FilterMode::Linear); + texture->setWrapping(Texture::WrappingMode::ClampToBorder); + } + _placeholderTexture = std::move(texture); + return a && b; } @@ -282,12 +300,17 @@ void ProjectionComponent::clearAllProjections() { _clearAllProjections = false; } -std::unique_ptr ProjectionComponent::loadProjectionTexture( +std::shared_ptr ProjectionComponent::loadProjectionTexture( const std::string& texturePath) { using std::unique_ptr; using ghoul::opengl::Texture; using ghoul::io::TextureReader; + + if (absPath(texturePath) == absPath(placeholderFile)) + return _placeholderTexture; + + unique_ptr texture = TextureReader::ref().loadTexture(absPath(texturePath)); if (texture) { if (texture->format() == Texture::Format::Red) @@ -298,7 +321,7 @@ std::unique_ptr ProjectionComponent::loadProjectionTextu texture->setFilter(Texture::FilterMode::Linear); texture->setWrapping(Texture::WrappingMode::ClampToBorder); } - return texture; + return std::move(texture); } bool ProjectionComponent::generateProjectionLayerTexture() { diff --git a/modules/newhorizons/util/projectioncomponent.h b/modules/newhorizons/util/projectioncomponent.h index 9ff0638a14..b5d30f199b 100644 --- a/modules/newhorizons/util/projectioncomponent.h +++ b/modules/newhorizons/util/projectioncomponent.h @@ -50,7 +50,7 @@ protected: bool generateProjectionLayerTexture(); bool auxiliaryRendertarget(); - std::unique_ptr loadProjectionTexture(const std::string& texturePath); + std::shared_ptr loadProjectionTexture(const std::string& texturePath); glm::mat4 computeProjectorMatrix( const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up, const glm::dmat3& instrumentMatrix, @@ -70,6 +70,8 @@ protected: std::unique_ptr _projectionTexture; + std::shared_ptr _placeholderTexture; + std::string _instrumentID; std::string _projectorID; std::string _projecteeID; From 25b49e882d83cbe02f0330ab0a959e5c5221b2e6 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 5 Jun 2016 16:11:06 +0200 Subject: [PATCH 42/61] Automatically remove placeholder.png for the projection cases where a real image is available --- ext/ghoul | 2 +- modules/newhorizons/util/hongkangparser.cpp | 1 + modules/newhorizons/util/imagesequencer.cpp | 37 ++++++++++++++++--- .../newhorizons/util/projectioncomponent.cpp | 6 ++- .../newhorizons/util/projectioncomponent.h | 6 ++- modules/newhorizons/util/sequenceparser.h | 7 ++-- 6 files changed, 47 insertions(+), 12 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index b642b91cd2..735ed53cd2 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit b642b91cd26410f772bbc481946ab9204d143cc5 +Subproject commit 735ed53cd236a7a7cca36d6289ce95909e6a0c92 diff --git a/modules/newhorizons/util/hongkangparser.cpp b/modules/newhorizons/util/hongkangparser.cpp index ca32d28388..e41446d449 100644 --- a/modules/newhorizons/util/hongkangparser.cpp +++ b/modules/newhorizons/util/hongkangparser.cpp @@ -313,6 +313,7 @@ void HongKangParser::createImage(Image& image, double startTime, double stopTime } image.target = targ; image.projected = false; + image.isPlaceholder = true; } double HongKangParser::getETfromMet(std::string line){ diff --git a/modules/newhorizons/util/imagesequencer.cpp b/modules/newhorizons/util/imagesequencer.cpp index 57ba88d127..ea7038973b 100644 --- a/modules/newhorizons/util/imagesequencer.cpp +++ b/modules/newhorizons/util/imagesequencer.cpp @@ -22,7 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -// open space includes #include #include #include @@ -164,8 +163,7 @@ const Image ImageSequencer::getLatestImageForInstrument(const std::string _instr if (it != _latestImages.end()) return _latestImages[_instrumentID]; else { - Image dummyImage = { 0, 0, "", std::vector(), "", false }; - return dummyImage; + return Image(); } } @@ -262,7 +260,8 @@ bool ImageSequencer::getImagePaths(std::vector& captures, if (curr->startTime >= prev->startTime){ std::copy_if(prev, curr, back_inserter(captureTimes), [instrumentRequest](const Image& i) { - return i.activeInstruments[0] == instrumentRequest; + bool correctInstrument = i.activeInstruments[0] == instrumentRequest; + return correctInstrument; }); //std::reverse(captureTimes.begin(), captureTimes.end()); @@ -270,13 +269,41 @@ bool ImageSequencer::getImagePaths(std::vector& captures, if (!captures.empty()) _latestImages[captures.back().activeInstruments.front()] = captures.back(); + std::vector toDelete; + for (auto it = captures.begin(); it != captures.end(); ++it) { + if (it->isPlaceholder) { + double beforeDist = std::numeric_limits::max(); + if (it != captures.begin()) { + auto before = std::prev(it); + beforeDist = abs(before->startTime - it->startTime); + } + + double nextDist = std::numeric_limits::max(); + if (it != captures.end() - 1) { + auto next = std::next(it); + nextDist = abs(next->startTime - it->startTime); + } + + if (beforeDist < 1.0 || nextDist < 1.0) { + toDelete.push_back(std::distance(captures.begin(), it)); + } + } + } + + for (size_t i = 0; i < toDelete.size(); ++i) { + // We have to subtract i here as we already have deleted i value + // before this and we need to adjust the location + int v = toDelete[i] - i; + captures.erase(captures.begin() + v); + } + return true; } } } return false; } -void ImageSequencer::sortData(){ +void ImageSequencer::sortData() { auto targetComparer = [](const std::pair &a, const std::pair &b)->bool{ return a.first < b.first; diff --git a/modules/newhorizons/util/projectioncomponent.cpp b/modules/newhorizons/util/projectioncomponent.cpp index 74c2ec9eb1..6f9004afa3 100644 --- a/modules/newhorizons/util/projectioncomponent.cpp +++ b/modules/newhorizons/util/projectioncomponent.cpp @@ -301,13 +301,15 @@ void ProjectionComponent::clearAllProjections() { } std::shared_ptr ProjectionComponent::loadProjectionTexture( - const std::string& texturePath) + const std::string& texturePath, + bool isPlaceholder) { using std::unique_ptr; using ghoul::opengl::Texture; using ghoul::io::TextureReader; - if (absPath(texturePath) == absPath(placeholderFile)) + + if (isPlaceholder) return _placeholderTexture; diff --git a/modules/newhorizons/util/projectioncomponent.h b/modules/newhorizons/util/projectioncomponent.h index b5d30f199b..88ec3c5ce6 100644 --- a/modules/newhorizons/util/projectioncomponent.h +++ b/modules/newhorizons/util/projectioncomponent.h @@ -50,7 +50,11 @@ protected: bool generateProjectionLayerTexture(); bool auxiliaryRendertarget(); - std::shared_ptr loadProjectionTexture(const std::string& texturePath); + std::shared_ptr loadProjectionTexture( + const std::string& texturePath, + bool isPlaceholder = false + ); + glm::mat4 computeProjectorMatrix( const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up, const glm::dmat3& instrumentMatrix, diff --git a/modules/newhorizons/util/sequenceparser.h b/modules/newhorizons/util/sequenceparser.h index 9bb1606393..3b385d337b 100644 --- a/modules/newhorizons/util/sequenceparser.h +++ b/modules/newhorizons/util/sequenceparser.h @@ -36,12 +36,13 @@ namespace openspace { class Decoder; struct Image { - double startTime; - double stopTime; + double startTime = 0.0; + double stopTime = 0.0; std::string path; std::vector activeInstruments; std::string target; - bool projected; + bool isPlaceholder = false; + bool projected = false; }; struct TimeRange { From 6a4362d6edf20cf66b7c97477e31c380509be6d7 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 5 Jun 2016 18:52:00 +0200 Subject: [PATCH 43/61] Make OpenSpace not crash on a fault rebuild of shaders --- .../newhorizons/rendering/renderableplanetprojection.cpp | 4 ++++ .../newhorizons/rendering/renderableplanetprojection.h | 1 + modules/newhorizons/shaders/renderablePlanet_vs.glsl | 4 ---- src/rendering/renderengine.cpp | 9 +++++++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 8d5379e210..79db055207 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -54,6 +54,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& , _heightMapTexturePath("heightMap", "Heightmap Texture") , _rotation("rotation", "Rotation", 0, 0, 360) , _heightExaggeration("heightExaggeration", "Height Exaggeration", 1.f, 0.f, 100.f) + , _debugProjectionTextureRotation("debug.projectionTextureRotation", "Projection Texture Rotation", 0.f, 0.f, 360.f) , _programObject(nullptr) , _fboProgramObject(nullptr) , _baseTexture(nullptr) @@ -108,6 +109,7 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& addProperty(_projectionFading); addProperty(_heightExaggeration); + addProperty(_debugProjectionTextureRotation); success = initializeParser(dictionary); ghoul_assert(success, ""); @@ -313,6 +315,8 @@ void RenderablePlanetProjection::render(const RenderData& data) { _programObject->setUniform("_heightExaggeration", _heightExaggeration); _programObject->setUniform("_projectionFading", _projectionFading); + _programObject->setUniform("debug_projectionTextureRotation", glm::radians(_debugProjectionTextureRotation.value())); + setPscUniforms(*_programObject.get(), data.camera, data.position); ghoul::opengl::TextureUnit unit[3]; diff --git a/modules/newhorizons/rendering/renderableplanetprojection.h b/modules/newhorizons/rendering/renderableplanetprojection.h index c3927896f4..404b0a452e 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.h +++ b/modules/newhorizons/rendering/renderableplanetprojection.h @@ -76,6 +76,7 @@ private: std::unique_ptr _heightMapTexture; properties::FloatProperty _heightExaggeration; + properties::FloatProperty _debugProjectionTextureRotation; std::unique_ptr _geometry; diff --git a/modules/newhorizons/shaders/renderablePlanet_vs.glsl b/modules/newhorizons/shaders/renderablePlanet_vs.glsl index fb81090d2d..6e2812d655 100644 --- a/modules/newhorizons/shaders/renderablePlanet_vs.glsl +++ b/modules/newhorizons/shaders/renderablePlanet_vs.glsl @@ -61,10 +61,6 @@ void main() { vec4 position = pscTransform(tmp, ModelTransform); vs_position = tmp; - // vec4 raw_pos = psc_to_meter(tmp, scaling); - // ProjTexCoord = ProjectorMatrix * ModelTransform * raw_pos; - - position = ViewProjection * position; gl_Position = z_normalization(position); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 9430707348..5dc84a7710 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -372,8 +372,13 @@ void RenderEngine::postSynchronizationPreDraw() { _renderer->update(); for (auto program : _programs) { - if (program->isDirty()) { - program->rebuildFromFile(); + try { + if (program->isDirty()) { + program->rebuildFromFile(); + } + } + catch (const ghoul::opengl::ShaderObject::ShaderCompileError& e) { + LERRORC(e.component, e.what()); } } From 6a2624dbb244fd44916e045806437bbb2e1765c0 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 5 Jun 2016 23:27:24 +0200 Subject: [PATCH 44/61] Enable the sorting of performance measurement values --- .../rendering/renderableplanetprojection.cpp | 2 +- .../rendering/renderableshadowcylinder.cpp | 49 ++++----- .../include/guiperformancecomponent.h | 1 + .../src/guiperformancecomponent.cpp | 99 +++++++++++++++++-- 4 files changed, 120 insertions(+), 31 deletions(-) diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 79db055207..7a49f76a7e 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -315,7 +315,7 @@ void RenderablePlanetProjection::render(const RenderData& data) { _programObject->setUniform("_heightExaggeration", _heightExaggeration); _programObject->setUniform("_projectionFading", _projectionFading); - _programObject->setUniform("debug_projectionTextureRotation", glm::radians(_debugProjectionTextureRotation.value())); + //_programObject->setUniform("debug_projectionTextureRotation", glm::radians(_debugProjectionTextureRotation.value())); setPscUniforms(*_programObject.get(), data.camera, data.position); diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.cpp b/modules/newhorizons/rendering/renderableshadowcylinder.cpp index 21c85c2523..79ed65e57d 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.cpp +++ b/modules/newhorizons/rendering/renderableshadowcylinder.cpp @@ -1,26 +1,26 @@ /***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2016 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ #include #include @@ -80,8 +80,7 @@ namespace openspace { ghoul_assert(success, ""); } -RenderableShadowCylinder::~RenderableShadowCylinder() { -} +RenderableShadowCylinder::~RenderableShadowCylinder() {} bool RenderableShadowCylinder::isReady() const { bool ready = true; @@ -103,6 +102,8 @@ bool RenderableShadowCylinder::initialize() { if (!_shader) return false; + + return completeSuccess; } diff --git a/modules/onscreengui/include/guiperformancecomponent.h b/modules/onscreengui/include/guiperformancecomponent.h index e2f31f9f45..f7fde598ac 100644 --- a/modules/onscreengui/include/guiperformancecomponent.h +++ b/modules/onscreengui/include/guiperformancecomponent.h @@ -44,6 +44,7 @@ public: protected: ghoul::SharedMemory* _performanceMemory = nullptr; float _minMaxValues[2]; + int _sortingSelection; }; } // namespace gui diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index e12c639288..8ad8df84fc 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -27,8 +27,12 @@ #include #include #include + #include +#include + #include +#include namespace { const std::string _loggerCat = "GuiPerformanceComponent"; @@ -40,6 +44,7 @@ namespace gui { void GuiPerformanceComponent::initialize() { _minMaxValues[0] = 100.f; _minMaxValues[1] = 250.f; + _sortingSelection = -1; } void GuiPerformanceComponent::deinitialize() { @@ -82,26 +87,108 @@ void GuiPerformanceComponent::render() { ImGui::SliderFloat2("Min values, max Value", _minMaxValues, 0.f, 10000.f); _minMaxValues[1] = fmaxf(_minMaxValues[0], _minMaxValues[1]); + // The indices correspond to the index into the average array further below + ImGui::Text("Sorting"); + ImGui::RadioButton("No Sorting", &_sortingSelection, -1); + ImGui::RadioButton("UpdateEphemeris", &_sortingSelection, 0); + ImGui::RadioButton("UpdateRender", &_sortingSelection, 1); + ImGui::RadioButton("RenderTime", &_sortingSelection, 2); if (!_performanceMemory) _performanceMemory = new ghoul::SharedMemory(RenderEngine::PerformanceMeasurementSharedData); void* ptr = _performanceMemory->memory(); - PerformanceLayout* layout = reinterpret_cast(ptr); - for (int i = 0; i < layout->nEntries; ++i) { - const PerformanceLayout::PerformanceLayoutEntry& entry = layout->entries[i]; + PerformanceLayout layout = *reinterpret_cast(ptr); + + std::vector indices(layout.nEntries); + std::iota(indices.begin(), indices.end(), 0); + + // Ordering: + // updateEphemeris + // UpdateRender + // RenderTime + std::vector> averages(layout.nEntries, { 0.f, 0.f, 0.f }); + + for (int i = 0; i < layout.nEntries; ++i) { + const PerformanceLayout::PerformanceLayoutEntry& entry = layout.entries[i]; + + int v[3] = { 0, 0, 0 }; + + for (int j = 0; j < nValues; ++j) { + averages[i][0] += entry.updateEphemeris[j]; + if (entry.updateEphemeris[j] != 0.f) + ++v[0]; + averages[i][1] += entry.updateRenderable[j]; + if (entry.updateRenderable[j] != 0.f) + ++v[1]; + averages[i][2] += entry.renderTime[j]; + if (entry.renderTime[j] != 0.f) + ++v[2]; + } + + if (v[0] != 0) + averages[i][0] /= static_cast(v[0]); + if (v[1] != 0) + averages[i][1] /= static_cast(v[1]); + if (v[2] != 0) + averages[i][2] /= static_cast(v[2]); + } + + if (_sortingSelection != -1) { + int sortIndex = _sortingSelection; + + std::sort( + indices.begin(), + indices.end(), + [sortIndex, &averages](int a, int b) { + return averages[a][sortIndex] > averages[b][sortIndex]; + } + ); + + } + + for (int i = 0; i < layout.nEntries; ++i) { + const PerformanceLayout::PerformanceLayoutEntry& entry = layout.entries[indices[i]]; if (ImGui::CollapsingHeader(entry.name)) { std::string updateEphemerisTime = std::to_string(entry.updateEphemeris[entry.currentUpdateEphemeris - 1]) + "us"; - ImGui::PlotLines("UpdateEphemeris", &entry.updateEphemeris[0], layout->nValuesPerEntry, 0, updateEphemerisTime.c_str(), _minMaxValues[0], _minMaxValues[1], ImVec2(0, 40)); + ; + ImGui::PlotLines( + fmt::format("UpdateEphemeris\nAverage: {}us", averages[i][0]).c_str(), + &entry.updateEphemeris[0], + layout.nValuesPerEntry, + 0, + updateEphemerisTime.c_str(), + _minMaxValues[0], + _minMaxValues[1], + ImVec2(0, 40) + ); std::string updateRenderableTime = std::to_string(entry.updateRenderable[entry.currentUpdateRenderable - 1]) + "us"; - ImGui::PlotLines("UpdateRender", &entry.updateRenderable[0], layout->nValuesPerEntry, 0, updateRenderableTime.c_str(), _minMaxValues[0], _minMaxValues[1], ImVec2(0, 40)); + ImGui::PlotLines( + fmt::format("UpdateRender\nAverage: {}us", averages[i][1]).c_str(), + &entry.updateRenderable[0], + layout.nValuesPerEntry, + 0, + updateRenderableTime.c_str(), + _minMaxValues[0], + _minMaxValues[1], + ImVec2(0, 40) + ); std::string renderTime = std::to_string(entry.renderTime[entry.currentRenderTime - 1]) + "us"; - ImGui::PlotLines("RenderTime", &entry.renderTime[0], layout->nValuesPerEntry, 0, renderTime.c_str(), _minMaxValues[0], _minMaxValues[1], ImVec2(0, 40)); + ImGui::PlotLines( + fmt::format("RenderTime\nAverage: {}us", averages[i][2]).c_str(), + &entry.renderTime[0], + layout.nValuesPerEntry, + 0, + renderTime.c_str(), + _minMaxValues[0], + _minMaxValues[1], + ImVec2(0, 40) + ); } } } From e85144b4eb545031f0a33327f88b9751c1bf02df Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 00:45:40 +0200 Subject: [PATCH 45/61] Performance optimization of ImageSequencer::instrumentActive --- modules/newhorizons/util/imagesequencer.cpp | 21 +++++++++++++------ modules/newhorizons/util/sequenceparser.h | 2 +- .../src/guiperformancecomponent.cpp | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/modules/newhorizons/util/imagesequencer.cpp b/modules/newhorizons/util/imagesequencer.cpp index ea7038973b..95843925e5 100644 --- a/modules/newhorizons/util/imagesequencer.cpp +++ b/modules/newhorizons/util/imagesequencer.cpp @@ -191,15 +191,16 @@ std::map ImageSequencer::getActiveInstruments(){ // return entire map, seen in GUI. return _switchingMap; } -bool ImageSequencer::instrumentActive(std::string instrumentID){ - for (auto i : _instrumentTimes){ + +bool ImageSequencer::instrumentActive(std::string instrumentID) { + for (const auto& i : _instrumentTimes) { //check if this instrument is in range - if (i.second.inRange(_currentTime)){ + if (i.second.inRange(_currentTime)) { //if so, then get the corresponding spiceID std::vector spiceIDs = _fileTranslation[i.first]->getTranslation(); //check which specific subinstrument is firing - for (auto s : spiceIDs){ - if (s == instrumentID){ + for (auto s : spiceIDs) { + if (s == instrumentID) { return true; } } @@ -209,7 +210,7 @@ bool ImageSequencer::instrumentActive(std::string instrumentID){ } float ImageSequencer::instrumentActiveTime(const std::string& instrumentID) const { - for (auto i : _instrumentTimes){ + for (const auto& i : _instrumentTimes){ //check if this instrument is in range if (i.second.inRange(_currentTime)){ //if so, then get the corresponding spiceID @@ -319,6 +320,14 @@ void ImageSequencer::sortData() { std::sort(_subsetMap[sub.first]._subset.begin(), _subsetMap[sub.first]._subset.end(), imageComparer); } + + std::sort( + _instrumentTimes.begin(), + _instrumentTimes.end(), + [](const std::pair& a, const std::pair& b) { + return a.second._min < b.second._min; + } + ); } void ImageSequencer::runSequenceParser(SequenceParser* parser){ diff --git a/modules/newhorizons/util/sequenceparser.h b/modules/newhorizons/util/sequenceparser.h index 3b385d337b..7bf232608e 100644 --- a/modules/newhorizons/util/sequenceparser.h +++ b/modules/newhorizons/util/sequenceparser.h @@ -54,7 +54,7 @@ struct TimeRange { bool inRange(double min, double max){ return (min >= _min && max <= _max); } - bool inRange(double val){ + bool inRange(double val) const { return (val >= _min && val <= _max); } double _min; diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index 8ad8df84fc..57bc4ab20b 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -142,7 +142,7 @@ void GuiPerformanceComponent::render() { std::sort( indices.begin(), indices.end(), - [sortIndex, &averages](int a, int b) { + [sortIndex, &averages](size_t a, size_t b) { return averages[a][sortIndex] > averages[b][sortIndex]; } ); From a0e5fe34fea684e085f549e6331d04c8db6e1ffc Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 00:49:09 +0200 Subject: [PATCH 46/61] Use more fine-grained texture specification for Pluto and Charon --- data/scene/newhorizons.scene | 4 +++- data/scene/newhorizons/pluto/charon/charon.mod | 11 ++++++----- data/scene/newhorizons/pluto/pluto/pluto.mod | 13 +++++++------ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/data/scene/newhorizons.scene b/data/scene/newhorizons.scene index bc0d07db16..6512ec8948 100644 --- a/data/scene/newhorizons.scene +++ b/data/scene/newhorizons.scene @@ -1,5 +1,7 @@ UseAccurateNewHorizonsKernels = false -UseHighResolutionTextures = false +-- TextureResolution = "low" +TextureResolution = "med" +-- TextureResolution = "high" function preInitialization() --[[ diff --git a/data/scene/newhorizons/pluto/charon/charon.mod b/data/scene/newhorizons/pluto/charon/charon.mod index 212760d979..674cb55892 100644 --- a/data/scene/newhorizons/pluto/charon/charon.mod +++ b/data/scene/newhorizons/pluto/charon/charon.mod @@ -8,11 +8,12 @@ else } end -if UseHighResolutionTextures then - ColorTexture = "textures/cpmap_cyl_HR_0e.jpg" -else - ColorTexture = "textures/charon_highres.jpg" -end +Files = { + low = "textures/charon_highres.jpg", + med = "textures/charon_highres.jpg", + high = "textures/cpmap_cyl_HR_0e.jpg" +} +ColorTexture = Files[TextureResolution] return { -- CharonProjection module diff --git a/data/scene/newhorizons/pluto/pluto/pluto.mod b/data/scene/newhorizons/pluto/pluto/pluto.mod index aed21e333f..4f71b1c04c 100644 --- a/data/scene/newhorizons/pluto/pluto/pluto.mod +++ b/data/scene/newhorizons/pluto/pluto/pluto.mod @@ -9,11 +9,12 @@ else } end -if UseHighResolutionTextures then - ColorTexture = "textures/pmap_cyl_HR_LOR_lowres.jpg" -else - ColorTexture = "textures/Shenk_180.jpg" -end +Files = { + low = "textures/pluto_large.jpg", + med = "textures/Shenk_180.jpg", + high = "textures/pmap_cyl_HR_LOR_lowres.jpg" +} +ColorTexture = Files[TextureResolution] return { -- Pluto barycenter module @@ -49,7 +50,7 @@ return { Sequencing = "true" }, Projection = { - Sequence = "${OPENSPACE_DATA}/scene/newhorizons/pluto/pluto/images", + Sequence = "${OPENSPACE_DATA}/scene/newhorizons/pluto/pluto/full_images", EventFile = "${OPENSPACE_DATA}/scene/newhorizons/pluto/pluto/assets/core_v9h_obs_getmets_v8_time_fix_nofrcd_mld.txt", SequenceType = "hybrid", Observer = "NEW HORIZONS", From 2c8e3fd7b9ef8861c2478ddfb93c3740c11f5c83 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 01:54:41 +0200 Subject: [PATCH 47/61] Refactor PerformanceLayout into new file and reuse between RenderEngine and GuiPerformanceComponent --- .../openspace/util/performancemeasurement.h | 62 +++++++++++++++++++ include/openspace/util/screenlog.h | 7 ++- .../src/guiperformancecomponent.cpp | 39 +++--------- src/CMakeLists.txt | 2 + src/rendering/renderengine.cpp | 51 ++++----------- src/util/performancemeasurement.cpp | 37 +++++++++++ 6 files changed, 128 insertions(+), 70 deletions(-) create mode 100644 include/openspace/util/performancemeasurement.h create mode 100644 src/util/performancemeasurement.cpp diff --git a/include/openspace/util/performancemeasurement.h b/include/openspace/util/performancemeasurement.h new file mode 100644 index 0000000000..6682e71a4a --- /dev/null +++ b/include/openspace/util/performancemeasurement.h @@ -0,0 +1,62 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __PERFORMANCEMEASUREMENT_H__ +#define __PERFORMANCEMEASUREMENT_H__ + +#include + +namespace openspace { +namespace performance { + + + +struct PerformanceLayout { + static const int8_t Version = 0; + static const int LengthName = 256; + static const int NumberValues = 256; + static const int MaxValues = 256; + + PerformanceLayout(int32_t nEntries); + + int32_t nEntries; + + struct PerformanceLayoutEntry { + char name[LengthName]; + float renderTime[NumberValues]; + float updateRenderable[NumberValues]; + float updateEphemeris[NumberValues]; + + int32_t currentRenderTime; + int32_t currentUpdateRenderable; + int32_t currentUpdateEphemeris; + }; + + PerformanceLayoutEntry entries[MaxValues]; +}; + +} // namespace performance +} // namespace openspace + +#endif // __PERFORMANCEMEASUREMENT_H__ diff --git a/include/openspace/util/screenlog.h b/include/openspace/util/screenlog.h index 01c9e9283e..afeaf2ecc2 100644 --- a/include/openspace/util/screenlog.h +++ b/include/openspace/util/screenlog.h @@ -22,6 +22,9 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#ifndef __SCREENLOG_H__ +#define __SCREENLOG_H__ + #include #include @@ -110,4 +113,6 @@ private: LogLevel _logLevel; }; -} // namespace openspace \ No newline at end of file +} // namespace openspace + +#endif // __SCREENLOG_H__ diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index 57bc4ab20b..c749cba218 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -26,6 +26,8 @@ #include #include +#include + #include #include @@ -53,32 +55,7 @@ void GuiPerformanceComponent::deinitialize() { } void GuiPerformanceComponent::render() { - // Copy and paste from renderengine.cpp::storePerformanceMeasurements method -// const int8_t Version = 0; - const int nValues = 250; - const int lengthName = 256; - const int maxValues = 256; - - struct PerformanceLayout { - int8_t version; - int32_t nValuesPerEntry; - int32_t nEntries; - int32_t maxNameLength; - int32_t maxEntries; - - struct PerformanceLayoutEntry { - char name[lengthName]; - float renderTime[nValues]; - float updateRenderable[nValues]; - float updateEphemeris[nValues]; - - int32_t currentRenderTime; - int32_t currentUpdateRenderable; - int32_t currentUpdateEphemeris; - }; - - PerformanceLayoutEntry entries[maxValues]; - }; + using namespace performance; ImGui::Begin("Performance", &_isEnabled); if (OsEng.renderEngine().doesPerformanceMeasurements() && @@ -116,7 +93,7 @@ void GuiPerformanceComponent::render() { int v[3] = { 0, 0, 0 }; - for (int j = 0; j < nValues; ++j) { + for (int j = 0; j < PerformanceLayout::NumberValues; ++j) { averages[i][0] += entry.updateEphemeris[j]; if (entry.updateEphemeris[j] != 0.f) ++v[0]; @@ -158,7 +135,8 @@ void GuiPerformanceComponent::render() { ImGui::PlotLines( fmt::format("UpdateEphemeris\nAverage: {}us", averages[i][0]).c_str(), &entry.updateEphemeris[0], - layout.nValuesPerEntry, + PerformanceLayout::NumberValues, + //layout.nValuesPerEntry, 0, updateEphemerisTime.c_str(), _minMaxValues[0], @@ -170,7 +148,7 @@ void GuiPerformanceComponent::render() { ImGui::PlotLines( fmt::format("UpdateRender\nAverage: {}us", averages[i][1]).c_str(), &entry.updateRenderable[0], - layout.nValuesPerEntry, + PerformanceLayout::NumberValues, 0, updateRenderableTime.c_str(), _minMaxValues[0], @@ -182,7 +160,7 @@ void GuiPerformanceComponent::render() { ImGui::PlotLines( fmt::format("RenderTime\nAverage: {}us", averages[i][2]).c_str(), &entry.renderTime[0], - layout.nValuesPerEntry, + PerformanceLayout::NumberValues, 0, renderTime.c_str(), _minMaxValues[0], @@ -200,6 +178,5 @@ void GuiPerformanceComponent::render() { ImGui::End(); } - } // namespace gui } // namespace openspace diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f6ad12718..8adbf333ce 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -81,6 +81,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/util/factorymanager.cpp ${OPENSPACE_BASE_DIR}/src/util/keys.cpp ${OPENSPACE_BASE_DIR}/src/util/openspacemodule.cpp + ${OPENSPACE_BASE_DIR}/src/util/performancemeasurement.cpp ${OPENSPACE_BASE_DIR}/src/util/powerscaledcoordinate.cpp ${OPENSPACE_BASE_DIR}/src/util/powerscaledscalar.cpp ${OPENSPACE_BASE_DIR}/src/util/powerscaledsphere.cpp @@ -160,6 +161,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/util/keys.h ${OPENSPACE_BASE_DIR}/include/openspace/util/mouse.h ${OPENSPACE_BASE_DIR}/include/openspace/util/openspacemodule.h + ${OPENSPACE_BASE_DIR}/include/openspace/util/performancemeasurement.h ${OPENSPACE_BASE_DIR}/include/openspace/util/powerscaledcoordinate.h ${OPENSPACE_BASE_DIR}/include/openspace/util/powerscaledscalar.h ${OPENSPACE_BASE_DIR}/include/openspace/util/powerscaledsphere.h diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 5dc84a7710..70788f9787 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -58,6 +58,8 @@ #include #include +#include + #include #include @@ -722,38 +724,15 @@ bool RenderEngine::doesPerformanceMeasurements() const { } void RenderEngine::storePerformanceMeasurements() { - const int8_t Version = 0; - const int nValues = 250; - const int lengthName = 256; - const int maxValues = 256; + using namespace performance; - struct PerformanceLayout { - int8_t version; - int32_t nValuesPerEntry; - int32_t nEntries; - int32_t maxNameLength; - int32_t maxEntries; - - struct PerformanceLayoutEntry { - char name[lengthName]; - float renderTime[nValues]; - float updateRenderable[nValues]; - float updateEphemeris[nValues]; - - int32_t currentRenderTime; - int32_t currentUpdateRenderable; - int32_t currentUpdateEphemeris; - }; - - PerformanceLayoutEntry entries[maxValues]; - }; const int nNodes = static_cast(scene()->allSceneGraphNodes().size()); if (!_performanceMemory) { // Compute the total size const int totalSize = sizeof(int8_t) + 4 * sizeof(int32_t) + - maxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry); + PerformanceLayout::MaxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry); LINFO("Create shared memory of " << totalSize << " bytes"); try { @@ -762,24 +741,20 @@ void RenderEngine::storePerformanceMeasurements() { catch (const ghoul::SharedMemory::SharedMemoryError& e) { LINFOC(e.component, e.what()); } - + ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize); _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); - void* ptr = _performanceMemory->memory(); - PerformanceLayout* layout = reinterpret_cast(ptr); - layout->version = Version; - layout->nValuesPerEntry = nValues; - layout->nEntries = nNodes; - layout->maxNameLength = lengthName; - layout->maxEntries = maxValues; - memset(layout->entries, 0, maxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry)); + PerformanceLayout* layout = new (ptr) PerformanceLayout(nNodes); + + + memset(layout->entries, 0, PerformanceLayout::MaxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry)); for (int i = 0; i < nNodes; ++i) { SceneGraphNode* node = scene()->allSceneGraphNodes()[i]; - memset(layout->entries[i].name, 0, lengthName); + memset(layout->entries[i].name, 0, PerformanceLayout::LengthName); #ifdef _MSC_VER strcpy_s(layout->entries[i].name, node->name().length() + 1, node->name().c_str()); #else @@ -804,9 +779,9 @@ void RenderEngine::storePerformanceMeasurements() { entry.updateEphemeris[entry.currentUpdateEphemeris] = r.updateTimeEphemeris / 1000.f; entry.updateRenderable[entry.currentUpdateRenderable] = r.updateTimeRenderable / 1000.f; - entry.currentRenderTime = (entry.currentRenderTime + 1) % nValues; - entry.currentUpdateEphemeris = (entry.currentUpdateEphemeris + 1) % nValues; - entry.currentUpdateRenderable = (entry.currentUpdateRenderable + 1) % nValues; + entry.currentRenderTime = (entry.currentRenderTime + 1) % PerformanceLayout::NumberValues; + entry.currentUpdateEphemeris = (entry.currentUpdateEphemeris + 1) % PerformanceLayout::NumberValues; + entry.currentUpdateRenderable = (entry.currentUpdateRenderable + 1) % PerformanceLayout::NumberValues; } _performanceMemory->releaseLock(); } diff --git a/src/util/performancemeasurement.cpp b/src/util/performancemeasurement.cpp new file mode 100644 index 0000000000..5210126428 --- /dev/null +++ b/src/util/performancemeasurement.cpp @@ -0,0 +1,37 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +namespace openspace { +namespace performance { + +PerformanceLayout::PerformanceLayout(int32_t nEntries) + : nEntries(nEntries) +{ + +} + +} // namespace performance +} // namespace openspace From f8f89e6fd1fbf7735c0de00e9c98c23d1c73182d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 02:12:46 +0200 Subject: [PATCH 48/61] Moving more code into performance files --- include/openspace/rendering/renderengine.h | 3 +++ .../openspace/util/performancemeasurement.h | 19 +++++++++++++++---- src/rendering/renderengine.cpp | 11 +++-------- src/util/performancemeasurement.cpp | 12 ++++++++++++ 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 913ccd9c82..d56e5c09a1 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -97,9 +97,12 @@ public: void takeScreenshot(); void toggleInfoText(bool b); + // Performance measurements void setPerformanceMeasurements(bool performanceMeasurements); bool doesPerformanceMeasurements() const; + + void serialize(SyncBuffer* syncBuffer); void deserialize(SyncBuffer* syncBuffer); diff --git a/include/openspace/util/performancemeasurement.h b/include/openspace/util/performancemeasurement.h index 6682e71a4a..83cc649a72 100644 --- a/include/openspace/util/performancemeasurement.h +++ b/include/openspace/util/performancemeasurement.h @@ -30,8 +30,6 @@ namespace openspace { namespace performance { - - struct PerformanceLayout { static const int8_t Version = 0; static const int LengthName = 256; @@ -42,7 +40,7 @@ struct PerformanceLayout { int32_t nEntries; - struct PerformanceLayoutEntry { + struct SceneGraphPerformanceLayout { char name[LengthName]; float renderTime[NumberValues]; float updateRenderable[NumberValues]; @@ -52,8 +50,21 @@ struct PerformanceLayout { int32_t currentUpdateRenderable; int32_t currentUpdateEphemeris; }; + SceneGraphPerformanceLayout sceneGraphEntries[MaxValues]; + + struct FunctionPerformanceLayout { + char name[LengthName]; + float time[NumberValues]; + int32_t currentTime; + }; + FunctionPerformanceLayout functionEntries[MaxValues]; +}; + +struct FunctionPerformanceHelper { + FunctionPerformanceHelper(); + ~FunctionPerformanceHelper(); + - PerformanceLayoutEntry entries[MaxValues]; }; } // namespace performance diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 70788f9787..11e914f142 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -726,13 +726,10 @@ bool RenderEngine::doesPerformanceMeasurements() const { void RenderEngine::storePerformanceMeasurements() { using namespace performance; - - const int nNodes = static_cast(scene()->allSceneGraphNodes().size()); + int nNodes = static_cast(scene()->allSceneGraphNodes().size()); if (!_performanceMemory) { - // Compute the total size - const int totalSize = sizeof(int8_t) + 4 * sizeof(int32_t) + - PerformanceLayout::MaxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry); + const int totalSize = sizeof(PerformanceLayout); LINFO("Create shared memory of " << totalSize << " bytes"); try { @@ -746,11 +743,9 @@ void RenderEngine::storePerformanceMeasurements() { _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); void* ptr = _performanceMemory->memory(); + // Using the placement-new to create a PerformanceLayout in the shared memory PerformanceLayout* layout = new (ptr) PerformanceLayout(nNodes); - - memset(layout->entries, 0, PerformanceLayout::MaxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry)); - for (int i = 0; i < nNodes; ++i) { SceneGraphNode* node = scene()->allSceneGraphNodes()[i]; diff --git a/src/util/performancemeasurement.cpp b/src/util/performancemeasurement.cpp index 5210126428..6239714b42 100644 --- a/src/util/performancemeasurement.cpp +++ b/src/util/performancemeasurement.cpp @@ -24,13 +24,25 @@ #include +#include + namespace openspace { namespace performance { PerformanceLayout::PerformanceLayout(int32_t nEntries) : nEntries(nEntries) { + std::memset( + sceneGraphEntries, + 0, + MaxValues * sizeof(SceneGraphPerformanceLayout) + ); + std::memset( + functionEntries, + 0, + MaxValues * sizeof(FunctionPerformanceLayout) + ); } } // namespace performance From 55d484205a9bec72abf57f42ab56a73419315a4b Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 02:14:42 +0200 Subject: [PATCH 49/61] Rename performance file --- .../performancelayout.h} | 0 src/CMakeLists.txt | 4 ++-- .../performancelayout.cpp} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename include/openspace/{util/performancemeasurement.h => performance/performancelayout.h} (100%) rename src/{util/performancemeasurement.cpp => performance/performancelayout.cpp} (100%) diff --git a/include/openspace/util/performancemeasurement.h b/include/openspace/performance/performancelayout.h similarity index 100% rename from include/openspace/util/performancemeasurement.h rename to include/openspace/performance/performancelayout.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8adbf333ce..7ec574b652 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -50,6 +50,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/network/networkengine.cpp ${OPENSPACE_BASE_DIR}/src/network/parallelconnection.cpp ${OPENSPACE_BASE_DIR}/src/network/parallelconnection_lua.inl + ${OPENSPACE_BASE_DIR}/src/performance/performancelayout.cpp ${OPENSPACE_BASE_DIR}/src/properties/matrixproperty.cpp ${OPENSPACE_BASE_DIR}/src/properties/optionproperty.cpp ${OPENSPACE_BASE_DIR}/src/properties/property.cpp @@ -81,7 +82,6 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/util/factorymanager.cpp ${OPENSPACE_BASE_DIR}/src/util/keys.cpp ${OPENSPACE_BASE_DIR}/src/util/openspacemodule.cpp - ${OPENSPACE_BASE_DIR}/src/util/performancemeasurement.cpp ${OPENSPACE_BASE_DIR}/src/util/powerscaledcoordinate.cpp ${OPENSPACE_BASE_DIR}/src/util/powerscaledscalar.cpp ${OPENSPACE_BASE_DIR}/src/util/powerscaledsphere.cpp @@ -120,6 +120,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/network/networkengine.h ${OPENSPACE_BASE_DIR}/include/openspace/network/parallelconnection.h ${OPENSPACE_BASE_DIR}/include/openspace/network/messagestructures.h + ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancelayout.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/matrixproperty.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/numericalproperty.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/numericalproperty.inl @@ -161,7 +162,6 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/util/keys.h ${OPENSPACE_BASE_DIR}/include/openspace/util/mouse.h ${OPENSPACE_BASE_DIR}/include/openspace/util/openspacemodule.h - ${OPENSPACE_BASE_DIR}/include/openspace/util/performancemeasurement.h ${OPENSPACE_BASE_DIR}/include/openspace/util/powerscaledcoordinate.h ${OPENSPACE_BASE_DIR}/include/openspace/util/powerscaledscalar.h ${OPENSPACE_BASE_DIR}/include/openspace/util/powerscaledsphere.h diff --git a/src/util/performancemeasurement.cpp b/src/performance/performancelayout.cpp similarity index 100% rename from src/util/performancemeasurement.cpp rename to src/performance/performancelayout.cpp From 53c35c7531d8d964135e37d2da851b5ef2611e76 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 03:19:44 +0200 Subject: [PATCH 50/61] Moving performance-related collection code from RenderEngine into new PerformanceManager code --- .../openspace/performance/performancelayout.h | 13 +- .../performance/performancemanager.h | 58 +++++++++ include/openspace/rendering/renderengine.h | 13 +- .../src/guiperformancecomponent.cpp | 23 ++-- src/CMakeLists.txt | 2 + src/performance/performancelayout.cpp | 2 +- src/performance/performancemanager.cpp | 118 ++++++++++++++++++ src/rendering/renderengine.cpp | 89 +++---------- 8 files changed, 211 insertions(+), 107 deletions(-) create mode 100644 include/openspace/performance/performancemanager.h create mode 100644 src/performance/performancemanager.cpp diff --git a/include/openspace/performance/performancelayout.h b/include/openspace/performance/performancelayout.h index 83cc649a72..06104144db 100644 --- a/include/openspace/performance/performancelayout.h +++ b/include/openspace/performance/performancelayout.h @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __PERFORMANCEMEASUREMENT_H__ -#define __PERFORMANCEMEASUREMENT_H__ +#ifndef __PERFORMANCELAYOUT_H__ +#define __PERFORMANCELAYOUT_H__ #include @@ -60,14 +60,7 @@ struct PerformanceLayout { FunctionPerformanceLayout functionEntries[MaxValues]; }; -struct FunctionPerformanceHelper { - FunctionPerformanceHelper(); - ~FunctionPerformanceHelper(); - - -}; - } // namespace performance } // namespace openspace -#endif // __PERFORMANCEMEASUREMENT_H__ +#endif // __PERFORMANCELAYOUT_H__ diff --git a/include/openspace/performance/performancemanager.h b/include/openspace/performance/performancemanager.h new file mode 100644 index 0000000000..cce46761c6 --- /dev/null +++ b/include/openspace/performance/performancemanager.h @@ -0,0 +1,58 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __PERFORMANCEMANAGER_H__ +#define __PERFORMANCEMANAGER_H__ + +#include + +namespace ghoul { + class SharedMemory; +} + +namespace openspace { + +class SceneGraphNode; + +namespace performance { + +class PerformanceManager { +public: + static const std::string PerformanceMeasurementSharedData; + + PerformanceManager(); + ~PerformanceManager(); + + bool isMeasuringPerformance() const; + void storeScenePerformanceMeasurements(const std::vector& sceneNodes); + +private: + bool _doPerformanceMeasurements; + ghoul::SharedMemory* _performanceMemory; +}; + +} // namespace performance +} // namespace openspace + +#endif // __PERFORMANCEMANAGER_H__ diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index d56e5c09a1..5ff6bfadd6 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -31,6 +31,7 @@ #include #include +#include namespace ghoul { namespace fontrendering { @@ -67,9 +68,6 @@ public: Post }; - - static const std::string PerformanceMeasurementSharedData; - static const std::string KeyFontMono; static const std::string KeyFontLight; @@ -101,8 +99,6 @@ public: void setPerformanceMeasurements(bool performanceMeasurements); bool doesPerformanceMeasurements() const; - - void serialize(SyncBuffer* syncBuffer); void deserialize(SyncBuffer* syncBuffer); @@ -181,7 +177,7 @@ public: private: void setRenderer(std::unique_ptr renderer); RendererImplementation rendererFromString(const std::string& method); - void storePerformanceMeasurements(); + void renderInformation(); void renderScreenLog(); @@ -189,6 +185,8 @@ private: Scene* _sceneGraph; RaycasterManager* _raycasterManager; + std::unique_ptr _performanceManager; + std::unique_ptr _renderer; RendererImplementation _rendererImplementation; ghoul::Dictionary _rendererData; @@ -199,9 +197,6 @@ private: bool _showLog; bool _takeScreenshot; - bool _doPerformanceMeasurements; - ghoul::SharedMemory* _performanceMemory; - float _globalBlackOutFactor; float _fadeDuration; float _currentFadeTime; diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index c749cba218..d1be505f64 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -25,8 +25,9 @@ #include #include +#include +#include #include -#include #include @@ -59,7 +60,7 @@ void GuiPerformanceComponent::render() { ImGui::Begin("Performance", &_isEnabled); if (OsEng.renderEngine().doesPerformanceMeasurements() && - ghoul::SharedMemory::exists(RenderEngine::PerformanceMeasurementSharedData)) + ghoul::SharedMemory::exists(PerformanceManager::PerformanceMeasurementSharedData)) { ImGui::SliderFloat2("Min values, max Value", _minMaxValues, 0.f, 10000.f); _minMaxValues[1] = fmaxf(_minMaxValues[0], _minMaxValues[1]); @@ -72,24 +73,23 @@ void GuiPerformanceComponent::render() { ImGui::RadioButton("RenderTime", &_sortingSelection, 2); if (!_performanceMemory) - _performanceMemory = new ghoul::SharedMemory(RenderEngine::PerformanceMeasurementSharedData); - + _performanceMemory = new ghoul::SharedMemory(PerformanceManager::PerformanceMeasurementSharedData); void* ptr = _performanceMemory->memory(); - PerformanceLayout layout = *reinterpret_cast(ptr); + PerformanceLayout* layout = reinterpret_cast(ptr); - std::vector indices(layout.nEntries); + std::vector indices(layout->nEntries); std::iota(indices.begin(), indices.end(), 0); // Ordering: // updateEphemeris // UpdateRender // RenderTime - std::vector> averages(layout.nEntries, { 0.f, 0.f, 0.f }); + std::vector> averages(layout->nEntries, { 0.f, 0.f, 0.f }); - for (int i = 0; i < layout.nEntries; ++i) { - const PerformanceLayout::PerformanceLayoutEntry& entry = layout.entries[i]; + for (int i = 0; i < layout->nEntries; ++i) { + const PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[i]; int v[3] = { 0, 0, 0 }; @@ -126,8 +126,8 @@ void GuiPerformanceComponent::render() { } - for (int i = 0; i < layout.nEntries; ++i) { - const PerformanceLayout::PerformanceLayoutEntry& entry = layout.entries[indices[i]]; + for (int i = 0; i < layout->nEntries; ++i) { + const PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[indices[i]]; if (ImGui::CollapsingHeader(entry.name)) { std::string updateEphemerisTime = std::to_string(entry.updateEphemeris[entry.currentUpdateEphemeris - 1]) + "us"; @@ -136,7 +136,6 @@ void GuiPerformanceComponent::render() { fmt::format("UpdateEphemeris\nAverage: {}us", averages[i][0]).c_str(), &entry.updateEphemeris[0], PerformanceLayout::NumberValues, - //layout.nValuesPerEntry, 0, updateEphemerisTime.c_str(), _minMaxValues[0], diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7ec574b652..b0169dc3c7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,6 +51,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/network/parallelconnection.cpp ${OPENSPACE_BASE_DIR}/src/network/parallelconnection_lua.inl ${OPENSPACE_BASE_DIR}/src/performance/performancelayout.cpp + ${OPENSPACE_BASE_DIR}/src/performance/performancemanager.cpp ${OPENSPACE_BASE_DIR}/src/properties/matrixproperty.cpp ${OPENSPACE_BASE_DIR}/src/properties/optionproperty.cpp ${OPENSPACE_BASE_DIR}/src/properties/property.cpp @@ -121,6 +122,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/network/parallelconnection.h ${OPENSPACE_BASE_DIR}/include/openspace/network/messagestructures.h ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancelayout.h + ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancemanager.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/matrixproperty.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/numericalproperty.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/numericalproperty.inl diff --git a/src/performance/performancelayout.cpp b/src/performance/performancelayout.cpp index 6239714b42..803a577443 100644 --- a/src/performance/performancelayout.cpp +++ b/src/performance/performancelayout.cpp @@ -22,7 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #include diff --git a/src/performance/performancemanager.cpp b/src/performance/performancemanager.cpp new file mode 100644 index 0000000000..46f89ebec8 --- /dev/null +++ b/src/performance/performancemanager.cpp @@ -0,0 +1,118 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include + +#include +#include + +namespace { + const std::string _loggerCat = "PerformanceManager"; +} + +namespace openspace { +namespace performance { + +const std::string PerformanceManager::PerformanceMeasurementSharedData = + "OpenSpacePerformanceMeasurementSharedData"; + +PerformanceManager::PerformanceManager() + : _performanceMemory(nullptr) +{ +} + +PerformanceManager::~PerformanceManager() { + if (ghoul::SharedMemory::exists(PerformanceMeasurementSharedData)) + ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); +} + +bool PerformanceManager::isMeasuringPerformance() const { + return _doPerformanceMeasurements; +} + +void PerformanceManager::storeScenePerformanceMeasurements( + const std::vector& sceneNodes) +{ + using namespace performance; + + int nNodes = static_cast(sceneNodes.size()); + if (!_performanceMemory) { + // Compute the total size + const int totalSize = sizeof(PerformanceLayout); + LINFO("Create shared memory of " << totalSize << " bytes"); + + try { + ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); + } + catch (const ghoul::SharedMemory::SharedMemoryError& e) { + LINFOC(e.component, e.what()); + } + + ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize); + _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); + void* ptr = _performanceMemory->memory(); + + // Using the placement-new to create a PerformanceLayout in the shared memory + PerformanceLayout* layout = new (ptr) PerformanceLayout(nNodes); + + for (int i = 0; i < nNodes; ++i) { + SceneGraphNode* node = sceneNodes[i]; + + memset(layout->sceneGraphEntries[i].name, 0, PerformanceLayout::LengthName); +#ifdef _MSC_VER + strcpy_s(layout->sceneGraphEntries[i].name, node->name().length() + 1, node->name().c_str()); +#else + strcpy(layout->entries[i].name, node->name().c_str()); +#endif + + layout->sceneGraphEntries[i].currentRenderTime = 0; + layout->sceneGraphEntries[i].currentUpdateRenderable = 0; + layout->sceneGraphEntries[i].currentUpdateEphemeris = 0; + } + } + + void* ptr = _performanceMemory->memory(); + PerformanceLayout* layout = reinterpret_cast(ptr); + _performanceMemory->acquireLock(); + for (int i = 0; i < nNodes; ++i) { + SceneGraphNode* node = sceneNodes[i]; + SceneGraphNode::PerformanceRecord r = node->performanceRecord(); + PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[i]; + + entry.renderTime[entry.currentRenderTime] = r.renderTime / 1000.f; + entry.updateEphemeris[entry.currentUpdateEphemeris] = r.updateTimeEphemeris / 1000.f; + entry.updateRenderable[entry.currentUpdateRenderable] = r.updateTimeRenderable / 1000.f; + + entry.currentRenderTime = (entry.currentRenderTime + 1) % PerformanceLayout::NumberValues; + entry.currentUpdateEphemeris = (entry.currentUpdateEphemeris + 1) % PerformanceLayout::NumberValues; + entry.currentUpdateRenderable = (entry.currentUpdateRenderable + 1) % PerformanceLayout::NumberValues; + } + _performanceMemory->releaseLock(); +} + +} // namespace performance +} // namespace openspace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 11e914f142..fad8d2131e 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -36,6 +36,8 @@ #include #include +#include + #include #include #include @@ -58,9 +60,6 @@ #include #include -#include - - #include #include #ifdef GHOUL_USE_DEVIL @@ -104,9 +103,6 @@ namespace { namespace openspace { -const std::string RenderEngine::PerformanceMeasurementSharedData = - "OpenSpacePerformanceMeasurementSharedData"; - const std::string RenderEngine::KeyFontMono = "Mono"; const std::string RenderEngine::KeyFontLight = "Light"; @@ -115,12 +111,11 @@ RenderEngine::RenderEngine() , _sceneGraph(nullptr) , _renderer(nullptr) , _rendererImplementation(RendererImplementation::Invalid) + , _performanceManager(nullptr) , _log(nullptr) , _showInfo(true) , _showLog(true) , _takeScreenshot(false) - , _doPerformanceMeasurements(false) - , _performanceMemory(nullptr) , _globalBlackOutFactor(1.f) , _fadeDuration(2.f) , _currentFadeTime(0.f) @@ -139,11 +134,8 @@ RenderEngine::~RenderEngine() { _sceneGraph = nullptr; delete _mainCamera; - delete _performanceMemory; delete _raycasterManager; - if (ghoul::SharedMemory::exists(PerformanceMeasurementSharedData)) - ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); } bool RenderEngine::deinitialize() { @@ -367,7 +359,7 @@ void RenderEngine::postSynchronizationPreDraw() { Time::ref().currentTime(), Time::ref().timeJumped(), Time::ref().deltaTime(), - _doPerformanceMeasurements + _performanceManager != nullptr }); _sceneGraph->evaluate(_mainCamera); @@ -401,7 +393,7 @@ void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &vi if (!(OsEng.isMaster() && _disableMasterRendering)) { - _renderer->render(_globalBlackOutFactor, _doPerformanceMeasurements); + _renderer->render(_globalBlackOutFactor, _performanceManager != nullptr); } // Print some useful information on the master viewport @@ -428,8 +420,8 @@ void RenderEngine::postDraw() { _takeScreenshot = false; } - if (_doPerformanceMeasurements) - storePerformanceMeasurements(); + if (_performanceManager) + _performanceManager->storeScenePerformanceMeasurements(scene()->allSceneGraphNodes()); } void RenderEngine::takeScreenshot() { @@ -716,69 +708,16 @@ scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { } void RenderEngine::setPerformanceMeasurements(bool performanceMeasurements) { - _doPerformanceMeasurements = performanceMeasurements; + if (performanceMeasurements) { + if (!_performanceManager) + _performanceManager = std::make_unique(); + } + else + _performanceManager = nullptr; } bool RenderEngine::doesPerformanceMeasurements() const { - return _doPerformanceMeasurements; -} - -void RenderEngine::storePerformanceMeasurements() { - using namespace performance; - - int nNodes = static_cast(scene()->allSceneGraphNodes().size()); - if (!_performanceMemory) { - // Compute the total size - const int totalSize = sizeof(PerformanceLayout); - LINFO("Create shared memory of " << totalSize << " bytes"); - - try { - ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); - } - catch (const ghoul::SharedMemory::SharedMemoryError& e) { - LINFOC(e.component, e.what()); - } - - ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize); - _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); - void* ptr = _performanceMemory->memory(); - - // Using the placement-new to create a PerformanceLayout in the shared memory - PerformanceLayout* layout = new (ptr) PerformanceLayout(nNodes); - - for (int i = 0; i < nNodes; ++i) { - SceneGraphNode* node = scene()->allSceneGraphNodes()[i]; - - memset(layout->entries[i].name, 0, PerformanceLayout::LengthName); -#ifdef _MSC_VER - strcpy_s(layout->entries[i].name, node->name().length() + 1, node->name().c_str()); -#else - strcpy(layout->entries[i].name, node->name().c_str()); -#endif - - layout->entries[i].currentRenderTime = 0; - layout->entries[i].currentUpdateRenderable = 0; - layout->entries[i].currentUpdateEphemeris = 0; - } - } - - void* ptr = _performanceMemory->memory(); - PerformanceLayout* layout = reinterpret_cast(ptr); - _performanceMemory->acquireLock(); - for (int i = 0; i < nNodes; ++i) { - SceneGraphNode* node = scene()->allSceneGraphNodes()[i]; - SceneGraphNode::PerformanceRecord r = node->performanceRecord(); - PerformanceLayout::PerformanceLayoutEntry& entry = layout->entries[i]; - - entry.renderTime[entry.currentRenderTime] = r.renderTime / 1000.f; - entry.updateEphemeris[entry.currentUpdateEphemeris] = r.updateTimeEphemeris / 1000.f; - entry.updateRenderable[entry.currentUpdateRenderable] = r.updateTimeRenderable / 1000.f; - - entry.currentRenderTime = (entry.currentRenderTime + 1) % PerformanceLayout::NumberValues; - entry.currentUpdateEphemeris = (entry.currentUpdateEphemeris + 1) % PerformanceLayout::NumberValues; - entry.currentUpdateRenderable = (entry.currentUpdateRenderable + 1) % PerformanceLayout::NumberValues; - } - _performanceMemory->releaseLock(); + return _performanceManager != nullptr; } // This method is temporary and will be removed once the scalegraph is in effect ---abock From 14ee3af94d4a68c810ac2c705bbd47fd3bd4942e Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 03:30:10 +0200 Subject: [PATCH 51/61] Make PerformanceManager available Add empty PerformanceHelper file --- .../openspace/performance/performancehelper.h | 32 +++++++++++++++++++ include/openspace/rendering/renderengine.h | 1 + src/CMakeLists.txt | 2 ++ src/performance/performancehelper.cpp | 32 +++++++++++++++++++ src/rendering/renderengine.cpp | 4 +++ 5 files changed, 71 insertions(+) create mode 100644 include/openspace/performance/performancehelper.h create mode 100644 src/performance/performancehelper.cpp diff --git a/include/openspace/performance/performancehelper.h b/include/openspace/performance/performancehelper.h new file mode 100644 index 0000000000..a97f35b049 --- /dev/null +++ b/include/openspace/performance/performancehelper.h @@ -0,0 +1,32 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __PERFORMANCEHELPER_H__ +#define __PERFORMANCEHELPER_H__ + + +} // namespace performance +} // namespace openspace + +#endif // __PERFORMANCEHELPER_H__ diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 5ff6bfadd6..14c666eda7 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -98,6 +98,7 @@ public: // Performance measurements void setPerformanceMeasurements(bool performanceMeasurements); bool doesPerformanceMeasurements() const; + performance::PerformanceManager* performanceManager(); void serialize(SyncBuffer* syncBuffer); void deserialize(SyncBuffer* syncBuffer); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b0169dc3c7..a9d1bf1732 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -50,6 +50,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/network/networkengine.cpp ${OPENSPACE_BASE_DIR}/src/network/parallelconnection.cpp ${OPENSPACE_BASE_DIR}/src/network/parallelconnection_lua.inl + ${OPENSPACE_BASE_DIR}/src/performance/performancehelper.cpp ${OPENSPACE_BASE_DIR}/src/performance/performancelayout.cpp ${OPENSPACE_BASE_DIR}/src/performance/performancemanager.cpp ${OPENSPACE_BASE_DIR}/src/properties/matrixproperty.cpp @@ -121,6 +122,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/network/networkengine.h ${OPENSPACE_BASE_DIR}/include/openspace/network/parallelconnection.h ${OPENSPACE_BASE_DIR}/include/openspace/network/messagestructures.h + ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancehelper.h ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancelayout.h ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancemanager.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/matrixproperty.h diff --git a/src/performance/performancehelper.cpp b/src/performance/performancehelper.cpp new file mode 100644 index 0000000000..dad5936285 --- /dev/null +++ b/src/performance/performancehelper.cpp @@ -0,0 +1,32 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +namespace openspace { +namespace performance { + + +} // namespace performance +} // namespace openspace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index fad8d2131e..6fe69e311e 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -720,6 +720,10 @@ bool RenderEngine::doesPerformanceMeasurements() const { return _performanceManager != nullptr; } +performance::PerformanceManager* RenderEngine::performanceManager() { + return _performanceManager.get(); +} + // This method is temporary and will be removed once the scalegraph is in effect ---abock void RenderEngine::changeViewPoint(std::string origin) { SceneGraphNode* solarSystemBarycenterNode = scene()->sceneGraphNode("SolarSystemBarycenter"); From 1430f6b9c2db97f4b1bc09eb01205bb9478642a3 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 03:34:56 +0200 Subject: [PATCH 52/61] Clang compile fix --- include/openspace/performance/performancehelper.h | 2 ++ src/performance/performancemanager.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/openspace/performance/performancehelper.h b/include/openspace/performance/performancehelper.h index a97f35b049..f7c9429fe2 100644 --- a/include/openspace/performance/performancehelper.h +++ b/include/openspace/performance/performancehelper.h @@ -25,6 +25,8 @@ #ifndef __PERFORMANCEHELPER_H__ #define __PERFORMANCEHELPER_H__ +namespace openspace { +namespace performance { } // namespace performance } // namespace openspace diff --git a/src/performance/performancemanager.cpp b/src/performance/performancemanager.cpp index 46f89ebec8..0caf8d2f0a 100644 --- a/src/performance/performancemanager.cpp +++ b/src/performance/performancemanager.cpp @@ -86,7 +86,7 @@ void PerformanceManager::storeScenePerformanceMeasurements( #ifdef _MSC_VER strcpy_s(layout->sceneGraphEntries[i].name, node->name().length() + 1, node->name().c_str()); #else - strcpy(layout->entries[i].name, node->name().c_str()); + strcpy(layout->sceneGraphEntries[i].name, node->name().c_str()); #endif layout->sceneGraphEntries[i].currentRenderTime = 0; From ff0b916b90f6513d64f364e2a30cbd93cf05b9f2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 03:53:42 +0200 Subject: [PATCH 53/61] Started implementing PerformanceHelper class --- .../openspace/performance/performancehelper.h | 17 ++++++++++++++ .../performance/performancemanager.h | 3 +++ src/performance/performancehelper.cpp | 22 +++++++++++++++++++ src/performance/performancemanager.cpp | 4 ++++ 4 files changed, 46 insertions(+) diff --git a/include/openspace/performance/performancehelper.h b/include/openspace/performance/performancehelper.h index f7c9429fe2..758be2d19a 100644 --- a/include/openspace/performance/performancehelper.h +++ b/include/openspace/performance/performancehelper.h @@ -25,9 +25,26 @@ #ifndef __PERFORMANCEHELPER_H__ #define __PERFORMANCEHELPER_H__ +#include +#include + namespace openspace { namespace performance { +class PerformanceManager; + +class PerformanceHelper { +public: + PerformanceHelper(std::string identifier, performance::PerformanceManager* manager); + ~PerformanceHelper(); + +private: + std::string _identifier; + performance::PerformanceManager* _manager; + + std::chrono::high_resolution_clock::time_point _startTime; +}; + } // namespace performance } // namespace openspace diff --git a/include/openspace/performance/performancemanager.h b/include/openspace/performance/performancemanager.h index cce46761c6..d8e17aa4c6 100644 --- a/include/openspace/performance/performancemanager.h +++ b/include/openspace/performance/performancemanager.h @@ -25,6 +25,7 @@ #ifndef __PERFORMANCEMANAGER_H__ #define __PERFORMANCEMANAGER_H__ +#include #include namespace ghoul { @@ -45,6 +46,8 @@ public: ~PerformanceManager(); bool isMeasuringPerformance() const; + + void storeIndividualPerformanceMeasurement(std::string identifier, long long us); void storeScenePerformanceMeasurements(const std::vector& sceneNodes); private: diff --git a/src/performance/performancehelper.cpp b/src/performance/performancehelper.cpp index dad5936285..2858b3a91c 100644 --- a/src/performance/performancehelper.cpp +++ b/src/performance/performancehelper.cpp @@ -24,9 +24,31 @@ #include +#include + +#include + namespace openspace { namespace performance { +PerformanceHelper::PerformanceHelper(std::string identifier, + performance::PerformanceManager* manager) + : _identifier(std::move(identifier)) + , _manager(manager) +{ + glFinish(); + + _startTime = std::chrono::high_resolution_clock::now(); +} + +PerformanceHelper::~PerformanceHelper() { + auto endTime = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast( + endTime - _startTime).count(); + + _manager->storeIndividualPerformanceMeasurement(std::move(_identifier), duration); +} + } // namespace performance } // namespace openspace diff --git a/src/performance/performancemanager.cpp b/src/performance/performancemanager.cpp index 0caf8d2f0a..bb27fdc626 100644 --- a/src/performance/performancemanager.cpp +++ b/src/performance/performancemanager.cpp @@ -54,6 +54,10 @@ bool PerformanceManager::isMeasuringPerformance() const { return _doPerformanceMeasurements; } +void PerformanceManager::storeIndividualPerformanceMeasurement(std::string identifier, long long us) { + +} + void PerformanceManager::storeScenePerformanceMeasurements( const std::vector& sceneNodes) { From 55bd1341e64a5b5b7ef4c111581f31422f9ea970 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 07:00:36 +0200 Subject: [PATCH 54/61] More work on PerformanceHelper Getting first version to run and produce output --- .../openspace/performance/performancelayout.h | 6 +- .../performance/performancemanager.h | 8 +- .../src/guiperformancecomponent.cpp | 197 +++++++++++------- src/performance/performancehelper.cpp | 10 +- src/performance/performancelayout.cpp | 5 +- src/performance/performancemanager.cpp | 101 +++++---- 6 files changed, 203 insertions(+), 124 deletions(-) diff --git a/include/openspace/performance/performancelayout.h b/include/openspace/performance/performancelayout.h index 06104144db..2348d765b8 100644 --- a/include/openspace/performance/performancelayout.h +++ b/include/openspace/performance/performancelayout.h @@ -36,9 +36,7 @@ struct PerformanceLayout { static const int NumberValues = 256; static const int MaxValues = 256; - PerformanceLayout(int32_t nEntries); - - int32_t nEntries; + PerformanceLayout(); struct SceneGraphPerformanceLayout { char name[LengthName]; @@ -51,6 +49,7 @@ struct PerformanceLayout { int32_t currentUpdateEphemeris; }; SceneGraphPerformanceLayout sceneGraphEntries[MaxValues]; + int16_t nScaleGraphEntries; struct FunctionPerformanceLayout { char name[LengthName]; @@ -58,6 +57,7 @@ struct PerformanceLayout { int32_t currentTime; }; FunctionPerformanceLayout functionEntries[MaxValues]; + int16_t nFunctionEntries; }; } // namespace performance diff --git a/include/openspace/performance/performancemanager.h b/include/openspace/performance/performancemanager.h index d8e17aa4c6..c99538358b 100644 --- a/include/openspace/performance/performancemanager.h +++ b/include/openspace/performance/performancemanager.h @@ -26,6 +26,7 @@ #define __PERFORMANCEMANAGER_H__ #include +#include #include namespace ghoul { @@ -45,13 +46,18 @@ public: PerformanceManager(); ~PerformanceManager(); + void resetPerformanceMeasurements(); + bool isMeasuringPerformance() const; - void storeIndividualPerformanceMeasurement(std::string identifier, long long us); + void storeIndividualPerformanceMeasurement(std::string identifier, long long nanoseconds); void storeScenePerformanceMeasurements(const std::vector& sceneNodes); private: bool _doPerformanceMeasurements; + + std::map individualPerformanceLocations; + ghoul::SharedMemory* _performanceMemory; }; diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index d1be505f64..8193ec9657 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -65,100 +65,140 @@ void GuiPerformanceComponent::render() { ImGui::SliderFloat2("Min values, max Value", _minMaxValues, 0.f, 10000.f); _minMaxValues[1] = fmaxf(_minMaxValues[0], _minMaxValues[1]); - // The indices correspond to the index into the average array further below - ImGui::Text("Sorting"); - ImGui::RadioButton("No Sorting", &_sortingSelection, -1); - ImGui::RadioButton("UpdateEphemeris", &_sortingSelection, 0); - ImGui::RadioButton("UpdateRender", &_sortingSelection, 1); - ImGui::RadioButton("RenderTime", &_sortingSelection, 2); + if (ImGui::CollapsingHeader("SceneGraph")) { + // The indices correspond to the index into the average array further below + ImGui::Text("Sorting"); + ImGui::RadioButton("No Sorting", &_sortingSelection, -1); + ImGui::RadioButton("UpdateEphemeris", &_sortingSelection, 0); + ImGui::RadioButton("UpdateRender", &_sortingSelection, 1); + ImGui::RadioButton("RenderTime", &_sortingSelection, 2); - if (!_performanceMemory) - _performanceMemory = new ghoul::SharedMemory(PerformanceManager::PerformanceMeasurementSharedData); + if (!_performanceMemory) + _performanceMemory = new ghoul::SharedMemory(PerformanceManager::PerformanceMeasurementSharedData); - void* ptr = _performanceMemory->memory(); + void* ptr = _performanceMemory->memory(); - PerformanceLayout* layout = reinterpret_cast(ptr); + PerformanceLayout* layout = reinterpret_cast(ptr); - std::vector indices(layout->nEntries); - std::iota(indices.begin(), indices.end(), 0); + std::vector indices(layout->nScaleGraphEntries); + std::iota(indices.begin(), indices.end(), 0); - // Ordering: - // updateEphemeris - // UpdateRender - // RenderTime - std::vector> averages(layout->nEntries, { 0.f, 0.f, 0.f }); + // Ordering: + // updateEphemeris + // UpdateRender + // RenderTime + std::vector> averages(layout->nScaleGraphEntries, { 0.f, 0.f, 0.f }); - for (int i = 0; i < layout->nEntries; ++i) { - const PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[i]; + for (int i = 0; i < layout->nScaleGraphEntries; ++i) { + const PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[i]; - int v[3] = { 0, 0, 0 }; + int v[3] = { 0, 0, 0 }; - for (int j = 0; j < PerformanceLayout::NumberValues; ++j) { - averages[i][0] += entry.updateEphemeris[j]; - if (entry.updateEphemeris[j] != 0.f) - ++v[0]; - averages[i][1] += entry.updateRenderable[j]; - if (entry.updateRenderable[j] != 0.f) - ++v[1]; - averages[i][2] += entry.renderTime[j]; - if (entry.renderTime[j] != 0.f) - ++v[2]; + for (int j = 0; j < PerformanceLayout::NumberValues; ++j) { + averages[i][0] += entry.updateEphemeris[j]; + if (entry.updateEphemeris[j] != 0.f) + ++v[0]; + averages[i][1] += entry.updateRenderable[j]; + if (entry.updateRenderable[j] != 0.f) + ++v[1]; + averages[i][2] += entry.renderTime[j]; + if (entry.renderTime[j] != 0.f) + ++v[2]; + } + + if (v[0] != 0) + averages[i][0] /= static_cast(v[0]); + if (v[1] != 0) + averages[i][1] /= static_cast(v[1]); + if (v[2] != 0) + averages[i][2] /= static_cast(v[2]); } - if (v[0] != 0) - averages[i][0] /= static_cast(v[0]); - if (v[1] != 0) - averages[i][1] /= static_cast(v[1]); - if (v[2] != 0) - averages[i][2] /= static_cast(v[2]); - } + if (_sortingSelection != -1) { + int sortIndex = _sortingSelection; - if (_sortingSelection != -1) { - int sortIndex = _sortingSelection; + std::sort( + indices.begin(), + indices.end(), + [sortIndex, &averages](size_t a, size_t b) { + return averages[a][sortIndex] > averages[b][sortIndex]; + } + ); - std::sort( - indices.begin(), - indices.end(), - [sortIndex, &averages](size_t a, size_t b) { - return averages[a][sortIndex] > averages[b][sortIndex]; + } + + for (int i = 0; i < layout->nScaleGraphEntries; ++i) { + const PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[indices[i]]; + + if (ImGui::CollapsingHeader(entry.name)) { + std::string updateEphemerisTime = std::to_string(entry.updateEphemeris[entry.currentUpdateEphemeris - 1]) + "us"; + ; + ImGui::PlotLines( + fmt::format("UpdateEphemeris\nAverage: {}us", averages[i][0]).c_str(), + &entry.updateEphemeris[0], + PerformanceLayout::NumberValues, + 0, + updateEphemerisTime.c_str(), + _minMaxValues[0], + _minMaxValues[1], + ImVec2(0, 40) + ); + + std::string updateRenderableTime = std::to_string(entry.updateRenderable[entry.currentUpdateRenderable - 1]) + "us"; + ImGui::PlotLines( + fmt::format("UpdateRender\nAverage: {}us", averages[i][1]).c_str(), + &entry.updateRenderable[0], + PerformanceLayout::NumberValues, + 0, + updateRenderableTime.c_str(), + _minMaxValues[0], + _minMaxValues[1], + ImVec2(0, 40) + ); + + std::string renderTime = std::to_string(entry.renderTime[entry.currentRenderTime - 1]) + "us"; + ImGui::PlotLines( + fmt::format("RenderTime\nAverage: {}us", averages[i][2]).c_str(), + &entry.renderTime[0], + PerformanceLayout::NumberValues, + 0, + renderTime.c_str(), + _minMaxValues[0], + _minMaxValues[1], + ImVec2(0, 40) + ); } - ); - + } } + + if (ImGui::CollapsingHeader("Functions")) { + using namespace performance; + + if (!_performanceMemory) + _performanceMemory = new ghoul::SharedMemory(PerformanceManager::PerformanceMeasurementSharedData); + + void* ptr = _performanceMemory->memory(); + + PerformanceLayout* layout = reinterpret_cast(ptr); - for (int i = 0; i < layout->nEntries; ++i) { - const PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[indices[i]]; - - if (ImGui::CollapsingHeader(entry.name)) { - std::string updateEphemerisTime = std::to_string(entry.updateEphemeris[entry.currentUpdateEphemeris - 1]) + "us"; - ; + for (int i = 0; i < layout->nFunctionEntries; ++i) { + const PerformanceLayout::FunctionPerformanceLayout& entry = layout->functionEntries[i]; + + float avg = 0.f; + int count = 0; + for (int j = 0; j < PerformanceLayout::NumberValues; ++j) { + avg += layout->functionEntries[i].time[j]; + if (layout->functionEntries[i].time[j] != 0.f) + ++count; + } + avg /= count; + + const PerformanceLayout::FunctionPerformanceLayout& f = layout->functionEntries[i]; + + std::string renderTime = std::to_string(entry.time[entry.currentTime - 1]) + "us"; ImGui::PlotLines( - fmt::format("UpdateEphemeris\nAverage: {}us", averages[i][0]).c_str(), - &entry.updateEphemeris[0], - PerformanceLayout::NumberValues, - 0, - updateEphemerisTime.c_str(), - _minMaxValues[0], - _minMaxValues[1], - ImVec2(0, 40) - ); - - std::string updateRenderableTime = std::to_string(entry.updateRenderable[entry.currentUpdateRenderable - 1]) + "us"; - ImGui::PlotLines( - fmt::format("UpdateRender\nAverage: {}us", averages[i][1]).c_str(), - &entry.updateRenderable[0], - PerformanceLayout::NumberValues, - 0, - updateRenderableTime.c_str(), - _minMaxValues[0], - _minMaxValues[1], - ImVec2(0, 40) - ); - - std::string renderTime = std::to_string(entry.renderTime[entry.currentRenderTime - 1]) + "us"; - ImGui::PlotLines( - fmt::format("RenderTime\nAverage: {}us", averages[i][2]).c_str(), - &entry.renderTime[0], + fmt::format("{}\nAverage: {}us", entry.name, avg).c_str(), + &entry.time[0], PerformanceLayout::NumberValues, 0, renderTime.c_str(), @@ -167,6 +207,7 @@ void GuiPerformanceComponent::render() { ImVec2(0, 40) ); } + } } else { diff --git a/src/performance/performancehelper.cpp b/src/performance/performancehelper.cpp index 2858b3a91c..5bf6593912 100644 --- a/src/performance/performancehelper.cpp +++ b/src/performance/performancehelper.cpp @@ -36,9 +36,11 @@ PerformanceHelper::PerformanceHelper(std::string identifier, : _identifier(std::move(identifier)) , _manager(manager) { - glFinish(); + if (_manager) { + glFinish(); - _startTime = std::chrono::high_resolution_clock::now(); + _startTime = std::chrono::high_resolution_clock::now(); + } } PerformanceHelper::~PerformanceHelper() { @@ -46,7 +48,9 @@ PerformanceHelper::~PerformanceHelper() { auto duration = std::chrono::duration_cast( endTime - _startTime).count(); - _manager->storeIndividualPerformanceMeasurement(std::move(_identifier), duration); + if (_manager) { + _manager->storeIndividualPerformanceMeasurement(std::move(_identifier), duration); + } } diff --git a/src/performance/performancelayout.cpp b/src/performance/performancelayout.cpp index 803a577443..5856f9f7e4 100644 --- a/src/performance/performancelayout.cpp +++ b/src/performance/performancelayout.cpp @@ -29,8 +29,9 @@ namespace openspace { namespace performance { -PerformanceLayout::PerformanceLayout(int32_t nEntries) - : nEntries(nEntries) +PerformanceLayout::PerformanceLayout() + : nScaleGraphEntries(0) + , nFunctionEntries(0) { std::memset( sceneGraphEntries, diff --git a/src/performance/performancemanager.cpp b/src/performance/performancemanager.cpp index bb27fdc626..c7e7c2645b 100644 --- a/src/performance/performancemanager.cpp +++ b/src/performance/performancemanager.cpp @@ -43,6 +43,23 @@ const std::string PerformanceManager::PerformanceMeasurementSharedData = PerformanceManager::PerformanceManager() : _performanceMemory(nullptr) { + // Compute the total size + const int totalSize = sizeof(PerformanceLayout); + LINFO("Create shared memory of " << totalSize << " bytes"); + + try { + ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); + } + catch (const ghoul::SharedMemory::SharedMemoryError& e) { + LINFOC(e.component, e.what()); + } + + ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize); + _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); + void* ptr = _performanceMemory->memory(); + + // Using the placement-new to create a PerformanceLayout in the shared memory + PerformanceLayout* layout = new (ptr) PerformanceLayout; } PerformanceManager::~PerformanceManager() { @@ -50,12 +67,47 @@ PerformanceManager::~PerformanceManager() { ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); } +void PerformanceManager::resetPerformanceMeasurements() { + // Using the placement-new to create a PerformanceLayout in the shared memory + _performanceMemory->acquireLock(); + void* ptr = _performanceMemory->memory(); + new (ptr) PerformanceLayout; + _performanceMemory->releaseLock(); + + individualPerformanceLocations.clear(); +} + bool PerformanceManager::isMeasuringPerformance() const { return _doPerformanceMeasurements; } -void PerformanceManager::storeIndividualPerformanceMeasurement(std::string identifier, long long us) { +void PerformanceManager::storeIndividualPerformanceMeasurement + (std::string identifier, long long microseconds) +{ + void* ptr = _performanceMemory->memory(); + PerformanceLayout* layout = reinterpret_cast(ptr); + _performanceMemory->acquireLock(); + auto it = individualPerformanceLocations.find(identifier); + PerformanceLayout::FunctionPerformanceLayout* p = nullptr; + if (it == individualPerformanceLocations.end()) { + p = &(layout->functionEntries[layout->nFunctionEntries]); + individualPerformanceLocations[identifier] = layout->nFunctionEntries; + ++(layout->nFunctionEntries); + } + else { + p = &(layout->functionEntries[it->second]); + } +#ifdef _MSC_VER + strcpy_s(p->name, identifier.length() + 1, identifier.c_str()); +#else + strcpy(p->name, identifier.c_str()); +#endif + + p->time[p->currentTime] = static_cast(microseconds); + p->currentTime = (p->currentTime + 1) % PerformanceLayout::NumberValues; + + _performanceMemory->releaseLock(); } void PerformanceManager::storeScenePerformanceMeasurements( @@ -63,47 +115,22 @@ void PerformanceManager::storeScenePerformanceMeasurements( { using namespace performance; - int nNodes = static_cast(sceneNodes.size()); - if (!_performanceMemory) { - // Compute the total size - const int totalSize = sizeof(PerformanceLayout); - LINFO("Create shared memory of " << totalSize << " bytes"); - - try { - ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); - } - catch (const ghoul::SharedMemory::SharedMemoryError& e) { - LINFOC(e.component, e.what()); - } - - ghoul::SharedMemory::create(PerformanceMeasurementSharedData, totalSize); - _performanceMemory = new ghoul::SharedMemory(PerformanceMeasurementSharedData); - void* ptr = _performanceMemory->memory(); - - // Using the placement-new to create a PerformanceLayout in the shared memory - PerformanceLayout* layout = new (ptr) PerformanceLayout(nNodes); - - for (int i = 0; i < nNodes; ++i) { - SceneGraphNode* node = sceneNodes[i]; - - memset(layout->sceneGraphEntries[i].name, 0, PerformanceLayout::LengthName); -#ifdef _MSC_VER - strcpy_s(layout->sceneGraphEntries[i].name, node->name().length() + 1, node->name().c_str()); -#else - strcpy(layout->sceneGraphEntries[i].name, node->name().c_str()); -#endif - - layout->sceneGraphEntries[i].currentRenderTime = 0; - layout->sceneGraphEntries[i].currentUpdateRenderable = 0; - layout->sceneGraphEntries[i].currentUpdateEphemeris = 0; - } - } - void* ptr = _performanceMemory->memory(); PerformanceLayout* layout = reinterpret_cast(ptr); _performanceMemory->acquireLock(); + + int nNodes = static_cast(sceneNodes.size()); + layout->nScaleGraphEntries = nNodes; for (int i = 0; i < nNodes; ++i) { SceneGraphNode* node = sceneNodes[i]; + + memset(layout->sceneGraphEntries[i].name, 0, PerformanceLayout::LengthName); +#ifdef _MSC_VER + strcpy_s(layout->sceneGraphEntries[i].name, node->name().length() + 1, node->name().c_str()); +#else + strcpy(layout->sceneGraphEntries[i].name, node->name().c_str()); +#endif + SceneGraphNode::PerformanceRecord r = node->performanceRecord(); PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[i]; From 6af96c4ef34ad1bf0de18fca846dd5ae365d9253 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 07:09:54 +0200 Subject: [PATCH 55/61] Add macro for easy generation of PerformanceHelper --- include/openspace/performance/performancehelper.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/openspace/performance/performancehelper.h b/include/openspace/performance/performancehelper.h index 758be2d19a..79ff6e97c5 100644 --- a/include/openspace/performance/performancehelper.h +++ b/include/openspace/performance/performancehelper.h @@ -44,7 +44,13 @@ private: std::chrono::high_resolution_clock::time_point _startTime; }; + +#define __MERGE(a,b) a##b +#define __LABEL(a) __MERGE(unique_name_, a) +/// Declare a new variable for measuring the performance of the current block +#define PerformanceMeasurement(name) auto __LABEL(__LINE__) = openspace::performance::PerformanceHelper((name), OsEng.renderEngine().performanceManager()) + } // namespace performance } // namespace openspace From 5a81b1089a53cce58bba411ac9f14b9e26349d9c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 08:48:44 +0200 Subject: [PATCH 56/61] Rename PerformanceHelper to PerformanceMeasurement Add performance measurements to FramebufferRenderer --- ...erformancehelper.h => performancemeasurement.h} | 14 +++++++------- src/CMakeLists.txt | 4 ++-- ...rmancehelper.cpp => performancemeasurement.cpp} | 8 +++++--- src/rendering/framebufferrenderer.cpp | 12 ++++++++++++ src/rendering/renderengine.cpp | 1 - 5 files changed, 26 insertions(+), 13 deletions(-) rename include/openspace/performance/{performancehelper.h => performancemeasurement.h} (85%) rename src/performance/{performancehelper.cpp => performancemeasurement.cpp} (93%) diff --git a/include/openspace/performance/performancehelper.h b/include/openspace/performance/performancemeasurement.h similarity index 85% rename from include/openspace/performance/performancehelper.h rename to include/openspace/performance/performancemeasurement.h index 79ff6e97c5..f08dbb94b2 100644 --- a/include/openspace/performance/performancehelper.h +++ b/include/openspace/performance/performancemeasurement.h @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __PERFORMANCEHELPER_H__ -#define __PERFORMANCEHELPER_H__ +#ifndef __PERFORMANCEMEASUREMENT_H__ +#define __PERFORMANCEMEASUREMENT_H__ #include #include @@ -33,10 +33,10 @@ namespace performance { class PerformanceManager; -class PerformanceHelper { +class PerformanceMeasurement { public: - PerformanceHelper(std::string identifier, performance::PerformanceManager* manager); - ~PerformanceHelper(); + PerformanceMeasurement(std::string identifier, performance::PerformanceManager* manager); + ~PerformanceMeasurement(); private: std::string _identifier; @@ -49,9 +49,9 @@ private: #define __LABEL(a) __MERGE(unique_name_, a) /// Declare a new variable for measuring the performance of the current block -#define PerformanceMeasurement(name) auto __LABEL(__LINE__) = openspace::performance::PerformanceHelper((name), OsEng.renderEngine().performanceManager()) +#define PerfMeasure(name) auto __LABEL(__LINE__) = openspace::performance::PerformanceMeasurement((name), OsEng.renderEngine().performanceManager()) } // namespace performance } // namespace openspace -#endif // __PERFORMANCEHELPER_H__ +#endif // __PERFORMANCEMEASUREMENTHELPER_H__ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a9d1bf1732..1d7d1a7670 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -50,7 +50,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/network/networkengine.cpp ${OPENSPACE_BASE_DIR}/src/network/parallelconnection.cpp ${OPENSPACE_BASE_DIR}/src/network/parallelconnection_lua.inl - ${OPENSPACE_BASE_DIR}/src/performance/performancehelper.cpp + ${OPENSPACE_BASE_DIR}/src/performance/performancemeasurement.cpp ${OPENSPACE_BASE_DIR}/src/performance/performancelayout.cpp ${OPENSPACE_BASE_DIR}/src/performance/performancemanager.cpp ${OPENSPACE_BASE_DIR}/src/properties/matrixproperty.cpp @@ -122,7 +122,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/network/networkengine.h ${OPENSPACE_BASE_DIR}/include/openspace/network/parallelconnection.h ${OPENSPACE_BASE_DIR}/include/openspace/network/messagestructures.h - ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancehelper.h + ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancemeasurement.h ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancelayout.h ${OPENSPACE_BASE_DIR}/include/openspace/performance/performancemanager.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/matrixproperty.h diff --git a/src/performance/performancehelper.cpp b/src/performance/performancemeasurement.cpp similarity index 93% rename from src/performance/performancehelper.cpp rename to src/performance/performancemeasurement.cpp index 5bf6593912..a62a6d5d4e 100644 --- a/src/performance/performancehelper.cpp +++ b/src/performance/performancemeasurement.cpp @@ -22,16 +22,18 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #include #include +#include + namespace openspace { namespace performance { -PerformanceHelper::PerformanceHelper(std::string identifier, +PerformanceMeasurement::PerformanceMeasurement(std::string identifier, performance::PerformanceManager* manager) : _identifier(std::move(identifier)) , _manager(manager) @@ -43,7 +45,7 @@ PerformanceHelper::PerformanceHelper(std::string identifier, } } -PerformanceHelper::~PerformanceHelper() { +PerformanceMeasurement::~PerformanceMeasurement() { auto endTime = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast( endTime - _startTime).count(); diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 6d407d1646..103aac13a9 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -33,6 +33,8 @@ #include #include +#include + #include #include #include @@ -157,6 +159,8 @@ void FramebufferRenderer::raycastersChanged(VolumeRaycaster& raycaster, bool att } void FramebufferRenderer::update() { + PerfMeasure("FramebufferRenderer::update"); + if (_dirtyResolution) { updateResolution(); } @@ -197,6 +201,8 @@ void FramebufferRenderer::update() { } void FramebufferRenderer::updateResolution() { + PerfMeasure("FramebufferRenderer::updateResolution"); + int nSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); @@ -252,6 +258,8 @@ void FramebufferRenderer::updateResolution() { } void FramebufferRenderer::updateRaycastData() { + PerfMeasure("FramebufferRenderer::updateRaycastData"); + _raycastData.clear(); _exitPrograms.clear(); _raycastPrograms.clear(); @@ -296,6 +304,8 @@ void FramebufferRenderer::updateRaycastData() { } void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurements) { + PerfMeasure("FramebufferRenderer::render"); + if (!_scene) return; if (!_camera) @@ -398,6 +408,8 @@ void FramebufferRenderer::setResolution(glm::ivec2 res) { } void FramebufferRenderer::updateRendererData() { + PerfMeasure("FramebufferRenderer::updateRendererData"); + ghoul::Dictionary dict; dict.setValue("fragmentRendererPath", std::string(RenderFragmentShaderPath)); dict.setValue("postFragmentRendererPath", std::string(PostRenderFragmentShaderPath)); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 6fe69e311e..54b4fcdf04 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -223,7 +223,6 @@ bool RenderEngine::initializeGL() { // development OsEng.windowWrapper().setNearFarClippingPlane(0.001f, 1000.f); - try { const float fontSizeTime = 15.f; _fontDate = OsEng.fontManager().font(KeyFontMono, fontSizeTime); From 16559231bdceb1773c0d4da65d15bfa305574317 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 09:01:15 +0200 Subject: [PATCH 57/61] Move Performance ImGui components into separate windows --- .../include/guiperformancecomponent.h | 3 +++ .../src/guiperformancecomponent.cpp | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/modules/onscreengui/include/guiperformancecomponent.h b/modules/onscreengui/include/guiperformancecomponent.h index f7fde598ac..21577e7f61 100644 --- a/modules/onscreengui/include/guiperformancecomponent.h +++ b/modules/onscreengui/include/guiperformancecomponent.h @@ -45,6 +45,9 @@ protected: ghoul::SharedMemory* _performanceMemory = nullptr; float _minMaxValues[2]; int _sortingSelection; + + bool _sceneGraphIsEnabled; + bool _functionsIsEnabled; }; } // namespace gui diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index 8193ec9657..d5c6223731 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -48,6 +48,9 @@ void GuiPerformanceComponent::initialize() { _minMaxValues[0] = 100.f; _minMaxValues[1] = 250.f; _sortingSelection = -1; + + _sceneGraphIsEnabled = false; + _functionsIsEnabled = false; } void GuiPerformanceComponent::deinitialize() { @@ -62,10 +65,15 @@ void GuiPerformanceComponent::render() { if (OsEng.renderEngine().doesPerformanceMeasurements() && ghoul::SharedMemory::exists(PerformanceManager::PerformanceMeasurementSharedData)) { - ImGui::SliderFloat2("Min values, max Value", _minMaxValues, 0.f, 10000.f); + ImGui::SliderFloat2("Min values, max Value", _minMaxValues, 0.f, 250000.f); _minMaxValues[1] = fmaxf(_minMaxValues[0], _minMaxValues[1]); - if (ImGui::CollapsingHeader("SceneGraph")) { + ImGui::Checkbox("SceneGraph", &_sceneGraphIsEnabled); + ImGui::Checkbox("Functions", &_functionsIsEnabled); + + if (_sceneGraphIsEnabled) { + ImGui::Begin("SceneGraph", &_sceneGraphIsEnabled); + // The indices correspond to the index into the average array further below ImGui::Text("Sorting"); ImGui::RadioButton("No Sorting", &_sortingSelection, -1); @@ -169,9 +177,11 @@ void GuiPerformanceComponent::render() { ); } } + ImGui::End(); } - if (ImGui::CollapsingHeader("Functions")) { + if (_functionsIsEnabled) { + ImGui::Begin("Functions", &_functionsIsEnabled); using namespace performance; if (!_performanceMemory) @@ -207,7 +217,7 @@ void GuiPerformanceComponent::render() { ImVec2(0, 40) ); } - + ImGui::End(); } } else { From 742bfcfe86094e0cbc0568afd82854d02739f026 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 09:52:47 +0200 Subject: [PATCH 58/61] Remove static min/max values and compute scaling factors directly from data --- .../include/guiperformancecomponent.h | 1 - .../src/guiperformancecomponent.cpp | 75 ++++++++++++++----- 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/modules/onscreengui/include/guiperformancecomponent.h b/modules/onscreengui/include/guiperformancecomponent.h index 21577e7f61..882c277fe4 100644 --- a/modules/onscreengui/include/guiperformancecomponent.h +++ b/modules/onscreengui/include/guiperformancecomponent.h @@ -43,7 +43,6 @@ public: protected: ghoul::SharedMemory* _performanceMemory = nullptr; - float _minMaxValues[2]; int _sortingSelection; bool _sceneGraphIsEnabled; diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index d5c6223731..a81e8c6b85 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -45,8 +45,6 @@ namespace openspace { namespace gui { void GuiPerformanceComponent::initialize() { - _minMaxValues[0] = 100.f; - _minMaxValues[1] = 250.f; _sortingSelection = -1; _sceneGraphIsEnabled = false; @@ -65,9 +63,6 @@ void GuiPerformanceComponent::render() { if (OsEng.renderEngine().doesPerformanceMeasurements() && ghoul::SharedMemory::exists(PerformanceManager::PerformanceMeasurementSharedData)) { - ImGui::SliderFloat2("Min values, max Value", _minMaxValues, 0.f, 250000.f); - _minMaxValues[1] = fmaxf(_minMaxValues[0], _minMaxValues[1]); - ImGui::Checkbox("SceneGraph", &_sceneGraphIsEnabled); ImGui::Checkbox("Functions", &_functionsIsEnabled); @@ -96,7 +91,11 @@ void GuiPerformanceComponent::render() { // UpdateRender // RenderTime std::vector> averages(layout->nScaleGraphEntries, { 0.f, 0.f, 0.f }); - + + std::vector, 3>> minMax( + layout->nScaleGraphEntries + ); + for (int i = 0; i < layout->nScaleGraphEntries; ++i) { const PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[i]; @@ -105,13 +104,13 @@ void GuiPerformanceComponent::render() { for (int j = 0; j < PerformanceLayout::NumberValues; ++j) { averages[i][0] += entry.updateEphemeris[j]; if (entry.updateEphemeris[j] != 0.f) - ++v[0]; + ++(v[0]); averages[i][1] += entry.updateRenderable[j]; if (entry.updateRenderable[j] != 0.f) - ++v[1]; + ++(v[1]); averages[i][2] += entry.renderTime[j]; if (entry.renderTime[j] != 0.f) - ++v[2]; + ++(v[2]); } if (v[0] != 0) @@ -120,6 +119,37 @@ void GuiPerformanceComponent::render() { averages[i][1] /= static_cast(v[1]); if (v[2] != 0) averages[i][2] /= static_cast(v[2]); + + auto minmaxEphemeris = std::minmax_element( + std::begin(entry.updateEphemeris), + std::end(entry.updateEphemeris) + ); + minMax[i][0] = std::make_pair( + *(minmaxEphemeris.first), + *(minmaxEphemeris.second) + ); + + + auto minmaxUpdateRenderable = std::minmax_element( + std::begin(entry.updateRenderable), + std::end(entry.updateRenderable) + ); + minMax[i][1] = std::make_pair( + *(minmaxUpdateRenderable.first), + *(minmaxUpdateRenderable.second) + ); + + + auto minmaxRendering = std::minmax_element( + std::begin(entry.renderTime), + std::end(entry.renderTime) + ); + minMax[i][2] = std::make_pair( + *(minmaxRendering.first), + *(minmaxRendering.second) + ); + + } if (_sortingSelection != -1) { @@ -142,37 +172,37 @@ void GuiPerformanceComponent::render() { std::string updateEphemerisTime = std::to_string(entry.updateEphemeris[entry.currentUpdateEphemeris - 1]) + "us"; ; ImGui::PlotLines( - fmt::format("UpdateEphemeris\nAverage: {}us", averages[i][0]).c_str(), + fmt::format("UpdateEphemeris\nAverage: {}us", averages[indices[i]][0]).c_str(), &entry.updateEphemeris[0], PerformanceLayout::NumberValues, 0, updateEphemerisTime.c_str(), - _minMaxValues[0], - _minMaxValues[1], + minMax[indices[i]][0].first, + minMax[indices[i]][0].second, ImVec2(0, 40) ); std::string updateRenderableTime = std::to_string(entry.updateRenderable[entry.currentUpdateRenderable - 1]) + "us"; ImGui::PlotLines( - fmt::format("UpdateRender\nAverage: {}us", averages[i][1]).c_str(), + fmt::format("UpdateRender\nAverage: {}us", averages[indices[i]][1]).c_str(), &entry.updateRenderable[0], PerformanceLayout::NumberValues, 0, updateRenderableTime.c_str(), - _minMaxValues[0], - _minMaxValues[1], + minMax[indices[i]][1].first, + minMax[indices[i]][1].second, ImVec2(0, 40) ); std::string renderTime = std::to_string(entry.renderTime[entry.currentRenderTime - 1]) + "us"; ImGui::PlotLines( - fmt::format("RenderTime\nAverage: {}us", averages[i][2]).c_str(), + fmt::format("RenderTime\nAverage: {}us", averages[indices[i]][2]).c_str(), &entry.renderTime[0], PerformanceLayout::NumberValues, 0, renderTime.c_str(), - _minMaxValues[0], - _minMaxValues[1], + minMax[indices[i]][2].first, + minMax[indices[i]][2].second, ImVec2(0, 40) ); } @@ -203,6 +233,11 @@ void GuiPerformanceComponent::render() { } avg /= count; + auto minmax = std::minmax_element( + std::begin(layout->functionEntries[i].time), + std::end(layout->functionEntries[i].time) + ); + const PerformanceLayout::FunctionPerformanceLayout& f = layout->functionEntries[i]; std::string renderTime = std::to_string(entry.time[entry.currentTime - 1]) + "us"; @@ -212,8 +247,8 @@ void GuiPerformanceComponent::render() { PerformanceLayout::NumberValues, 0, renderTime.c_str(), - _minMaxValues[0], - _minMaxValues[1], + *(minmax.first), + *(minmax.second), ImVec2(0, 40) ); } From 55456ae2728d2a9ca81829aad155ffe8af45daa2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 6 Jun 2016 10:23:28 +0200 Subject: [PATCH 59/61] Add button to reset performance measurements Clang compile fix --- ext/ghoul | 2 +- include/openspace/util/transformationmanager.h | 5 ++++- modules/onscreengui/src/guiperformancecomponent.cpp | 6 ++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 735ed53cd2..3034cb3d3e 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 735ed53cd236a7a7cca36d6289ce95909e6a0c92 +Subproject commit 3034cb3d3ebe8474e21fe2bb8e4e6cc275213b63 diff --git a/include/openspace/util/transformationmanager.h b/include/openspace/util/transformationmanager.h index 2443004852..0bbe37c459 100644 --- a/include/openspace/util/transformationmanager.h +++ b/include/openspace/util/transformationmanager.h @@ -33,9 +33,12 @@ #include +namespace ccmc { + class Kameleon; +} // namespace ccmc + namespace openspace { #ifdef OPENSPACE_MODULE_KAMELEON_ENABLED -class ccmc::Kameleon; #endif class TransformationManager : public ghoul::Singleton { friend class ghoul::Singleton; diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index a81e8c6b85..78f875a91b 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -66,6 +66,12 @@ void GuiPerformanceComponent::render() { ImGui::Checkbox("SceneGraph", &_sceneGraphIsEnabled); ImGui::Checkbox("Functions", &_functionsIsEnabled); + ImGui::Spacing(); + + if (ImGui::Button("Reset measurements")) { + OsEng.renderEngine().performanceManager()->resetPerformanceMeasurements(); + } + if (_sceneGraphIsEnabled) { ImGui::Begin("SceneGraph", &_sceneGraphIsEnabled); From 146b71e1295e0303a570fa5b1975faecde20bce5 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 7 Jun 2016 11:16:27 +0200 Subject: [PATCH 60/61] Make performance widget graphs fill from right to left instead of circular --- ext/ghoul | 2 +- .../openspace/performance/performancelayout.h | 5 --- .../src/guiperformancecomponent.cpp | 8 ++--- src/performance/performancemanager.cpp | 36 ++++++++++++++----- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 3034cb3d3e..111c53c94c 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 3034cb3d3ebe8474e21fe2bb8e4e6cc275213b63 +Subproject commit 111c53c94cfe514122a71225bb9e903f0a367278 diff --git a/include/openspace/performance/performancelayout.h b/include/openspace/performance/performancelayout.h index 2348d765b8..70568e67e5 100644 --- a/include/openspace/performance/performancelayout.h +++ b/include/openspace/performance/performancelayout.h @@ -43,10 +43,6 @@ struct PerformanceLayout { float renderTime[NumberValues]; float updateRenderable[NumberValues]; float updateEphemeris[NumberValues]; - - int32_t currentRenderTime; - int32_t currentUpdateRenderable; - int32_t currentUpdateEphemeris; }; SceneGraphPerformanceLayout sceneGraphEntries[MaxValues]; int16_t nScaleGraphEntries; @@ -54,7 +50,6 @@ struct PerformanceLayout { struct FunctionPerformanceLayout { char name[LengthName]; float time[NumberValues]; - int32_t currentTime; }; FunctionPerformanceLayout functionEntries[MaxValues]; int16_t nFunctionEntries; diff --git a/modules/onscreengui/src/guiperformancecomponent.cpp b/modules/onscreengui/src/guiperformancecomponent.cpp index 78f875a91b..0bd4511ab3 100644 --- a/modules/onscreengui/src/guiperformancecomponent.cpp +++ b/modules/onscreengui/src/guiperformancecomponent.cpp @@ -175,7 +175,7 @@ void GuiPerformanceComponent::render() { const PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[indices[i]]; if (ImGui::CollapsingHeader(entry.name)) { - std::string updateEphemerisTime = std::to_string(entry.updateEphemeris[entry.currentUpdateEphemeris - 1]) + "us"; + std::string updateEphemerisTime = std::to_string(entry.updateEphemeris[PerformanceLayout::NumberValues - 1]) + "us"; ; ImGui::PlotLines( fmt::format("UpdateEphemeris\nAverage: {}us", averages[indices[i]][0]).c_str(), @@ -188,7 +188,7 @@ void GuiPerformanceComponent::render() { ImVec2(0, 40) ); - std::string updateRenderableTime = std::to_string(entry.updateRenderable[entry.currentUpdateRenderable - 1]) + "us"; + std::string updateRenderableTime = std::to_string(entry.updateRenderable[PerformanceLayout::NumberValues - 1]) + "us"; ImGui::PlotLines( fmt::format("UpdateRender\nAverage: {}us", averages[indices[i]][1]).c_str(), &entry.updateRenderable[0], @@ -200,7 +200,7 @@ void GuiPerformanceComponent::render() { ImVec2(0, 40) ); - std::string renderTime = std::to_string(entry.renderTime[entry.currentRenderTime - 1]) + "us"; + std::string renderTime = std::to_string(entry.renderTime[PerformanceLayout::NumberValues - 1]) + "us"; ImGui::PlotLines( fmt::format("RenderTime\nAverage: {}us", averages[indices[i]][2]).c_str(), &entry.renderTime[0], @@ -246,7 +246,7 @@ void GuiPerformanceComponent::render() { const PerformanceLayout::FunctionPerformanceLayout& f = layout->functionEntries[i]; - std::string renderTime = std::to_string(entry.time[entry.currentTime - 1]) + "us"; + std::string renderTime = std::to_string(entry.time[PerformanceLayout::NumberValues - 1]) + "us"; ImGui::PlotLines( fmt::format("{}\nAverage: {}us", entry.name, avg).c_str(), &entry.time[0], diff --git a/src/performance/performancemanager.cpp b/src/performance/performancemanager.cpp index c7e7c2645b..91731768a0 100644 --- a/src/performance/performancemanager.cpp +++ b/src/performance/performancemanager.cpp @@ -104,8 +104,13 @@ void PerformanceManager::storeIndividualPerformanceMeasurement strcpy(p->name, identifier.c_str()); #endif - p->time[p->currentTime] = static_cast(microseconds); - p->currentTime = (p->currentTime + 1) % PerformanceLayout::NumberValues; + std::rotate( + std::begin(p->time), + std::next(std::begin(p->time)), + std::end(p->time) + ); + p->time[PerformanceLayout::NumberValues - 1] = + static_cast(microseconds); _performanceMemory->releaseLock(); } @@ -134,13 +139,26 @@ void PerformanceManager::storeScenePerformanceMeasurements( SceneGraphNode::PerformanceRecord r = node->performanceRecord(); PerformanceLayout::SceneGraphPerformanceLayout& entry = layout->sceneGraphEntries[i]; - entry.renderTime[entry.currentRenderTime] = r.renderTime / 1000.f; - entry.updateEphemeris[entry.currentUpdateEphemeris] = r.updateTimeEphemeris / 1000.f; - entry.updateRenderable[entry.currentUpdateRenderable] = r.updateTimeRenderable / 1000.f; - - entry.currentRenderTime = (entry.currentRenderTime + 1) % PerformanceLayout::NumberValues; - entry.currentUpdateEphemeris = (entry.currentUpdateEphemeris + 1) % PerformanceLayout::NumberValues; - entry.currentUpdateRenderable = (entry.currentUpdateRenderable + 1) % PerformanceLayout::NumberValues; + std::rotate( + std::begin(entry.renderTime), + std::next(std::begin(entry.renderTime)), + std::end(entry.renderTime) + ); + entry.renderTime[PerformanceLayout::NumberValues - 1] = r.renderTime / 1000.f; + + std::rotate( + std::begin(entry.updateEphemeris), + std::next(std::begin(entry.updateEphemeris)), + std::end(entry.updateEphemeris) + ); + entry.updateEphemeris[PerformanceLayout::NumberValues - 1] = r.updateTimeEphemeris / 1000.f; + + std::rotate( + std::begin(entry.updateRenderable), + std::next(std::begin(entry.updateRenderable)), + std::end(entry.updateRenderable) + ); + entry.updateRenderable[PerformanceLayout::NumberValues - 1] = r.updateTimeRenderable / 1000.f; } _performanceMemory->releaseLock(); } From 8771a238d350e93f4e705285c4b2402e8b19c355 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Wed, 8 Jun 2016 15:00:03 +0200 Subject: [PATCH 61/61] improve galaxy rendering --- data/scene/enlilnh/enlilnh.mod | 2 +- data/scene/milkyway/milkyway.mod | 2 +- ext/ghoul | 2 +- include/openspace/rendering/abufferrenderer.h | 1 + .../openspace/rendering/framebufferrenderer.h | 2 + include/openspace/rendering/renderengine.h | 3 + include/openspace/rendering/renderer.h | 2 +- modules/base/rendering/renderablemodel.cpp | 1 + modules/base/rendering/renderablestars.cpp | 2 + modules/base/shaders/star_fs.glsl | 4 +- modules/galaxy/rendering/renderablegalaxy.cpp | 16 ++-- modules/galaxy/rendering/renderablegalaxy.h | 1 + modules/galaxy/shaders/galaxyraycast.glsl | 6 +- modules/galaxy/shaders/points.fs | 4 +- modules/galaxy/shaders/points.vs | 11 ++- modules/galaxy/shaders/raycasterbounds.vs | 5 +- .../rendering/renderablemultiresvolume.cpp | 2 +- shaders/abuffer/postrenderabuffer.frag | 9 +-- shaders/abuffer/resolveabuffer.frag | 23 ++++-- shaders/abuffer/resolveconstants.glsl | 4 +- shaders/abuffer/resolvehelpers.glsl | 42 +++++++---- shaders/framebuffer/raycastframebuffer.frag | 21 +++++- src/rendering/abufferrenderer.cpp | 32 ++++---- src/rendering/framebufferrenderer.cpp | 74 ++++++++++++++++--- src/rendering/renderengine.cpp | 16 ++++ src/rendering/renderengine_lua.inl | 17 +++++ 26 files changed, 220 insertions(+), 84 deletions(-) diff --git a/data/scene/enlilnh/enlilnh.mod b/data/scene/enlilnh/enlilnh.mod index d6e31699be..0cfb1abbb5 100644 --- a/data/scene/enlilnh/enlilnh.mod +++ b/data/scene/enlilnh/enlilnh.mod @@ -12,7 +12,7 @@ return { Translation = {0, 0, 0}, Rotation = {2.1, 0, 0}, Scaling = {1.1, 1.1, 1.1}, - ScalingExponent = 12, + ScalingExponent = 13, Source = "tsp/enlil_nh_128_128_16.tsp", ErrorHistogramsSource = "tsp/enlil_nh_128_128_16.errorHistograms", TransferFunction = "transferfunctions/fire.txt", diff --git a/data/scene/milkyway/milkyway.mod b/data/scene/milkyway/milkyway.mod index 824529977c..148ac2b331 100644 --- a/data/scene/milkyway/milkyway.mod +++ b/data/scene/milkyway/milkyway.mod @@ -7,7 +7,7 @@ return { }, Renderable = { Type = "RenderableSphere", - Size = {10, 25}, + Size = {10, 22}, Segments = 40, Texture = "textures/DarkUniverse_mellinger_8k.jpg", Orientation = "Inside/Outside" diff --git a/ext/ghoul b/ext/ghoul index 735ed53cd2..5cde645215 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 735ed53cd236a7a7cca36d6289ce95909e6a0c92 +Subproject commit 5cde64521525f9094b95a73bca6ca1ccac1a5541 diff --git a/include/openspace/rendering/abufferrenderer.h b/include/openspace/rendering/abufferrenderer.h index d6af2088d1..4a9689fa9f 100644 --- a/include/openspace/rendering/abufferrenderer.h +++ b/include/openspace/rendering/abufferrenderer.h @@ -69,6 +69,7 @@ public: void setCamera(Camera* camera) override; void setScene(Scene* scene) override; void setResolution(glm::ivec2 res) override; + void setNAaSamples(int nAaSamples) override; void preRaycast(ghoul::opengl::ProgramObject& programObject); void postRaycast(ghoul::opengl::ProgramObject& programObject); diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index fb65728005..df996e695f 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -68,6 +68,7 @@ public: void setCamera(Camera* camera) override; void setScene(Scene* scene) override; void setResolution(glm::ivec2 res) override; + void setNAaSamples(int nAaSamples) override; void update() override; void render(float blackoutFactor, bool doPerformanceMeasurements) override; @@ -84,6 +85,7 @@ private: std::map _raycastData; std::map> _exitPrograms; std::map> _raycastPrograms; + std::map> _insideRaycastPrograms; std::unique_ptr _resolveProgram; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 913ccd9c82..60ff02bc0b 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -105,6 +105,8 @@ public: float globalBlackOutFactor(); void setGlobalBlackOutFactor(float factor); + void setNAaSamples(int nAaSamples); + void setDisableRenderingOnMaster(bool enabled); @@ -203,6 +205,7 @@ private: float _fadeDuration; float _currentFadeTime; int _fadeDirection; + int _nAaSamples; std::vector _programs; std::vector> _screenSpaceRenderables; diff --git a/include/openspace/rendering/renderer.h b/include/openspace/rendering/renderer.h index 5835b4f8b8..3258be73c0 100644 --- a/include/openspace/rendering/renderer.h +++ b/include/openspace/rendering/renderer.h @@ -58,7 +58,7 @@ public: virtual void setCamera(Camera* camera) = 0; virtual void setScene(Scene* scene) = 0; virtual void setResolution(glm::ivec2 res) = 0; - + virtual void setNAaSamples(int nAaSamples) = 0; /** * Set raycasting uniforms on the program object, and setup raycasting. diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 76d16ff58e..bd1137554b 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -267,6 +267,7 @@ void RenderableModel::loadTexture() { if (_texture) { LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); _texture->uploadTexture(); + _texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); } } } diff --git a/modules/base/rendering/renderablestars.cpp b/modules/base/rendering/renderablestars.cpp index 9cc959270f..cf4c2bc3cd 100644 --- a/modules/base/rendering/renderablestars.cpp +++ b/modules/base/rendering/renderablestars.cpp @@ -316,10 +316,12 @@ void RenderableStars::update(const UpdateData& data) { _pointSpreadFunctionTexture = nullptr; if (_pointSpreadFunctionTexturePath.value() != "") { _pointSpreadFunctionTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_pointSpreadFunctionTexturePath))); + if (_pointSpreadFunctionTexture) { LDEBUG("Loaded texture from '" << absPath(_pointSpreadFunctionTexturePath) << "'"); _pointSpreadFunctionTexture->uploadTexture(); } + _pointSpreadFunctionTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); delete _psfTextureFile; _psfTextureFile = new ghoul::filesystem::File(_pointSpreadFunctionTexturePath); diff --git a/modules/base/shaders/star_fs.glsl b/modules/base/shaders/star_fs.glsl index 43f77a26b7..39cdcd0bc9 100644 --- a/modules/base/shaders/star_fs.glsl +++ b/modules/base/shaders/star_fs.glsl @@ -58,7 +58,7 @@ vec4 bv2rgb(float bv) { Fragment getFragment() { // Something in the color calculations need to be changed because before it was dependent // on the gl blend functions since the abuffer was not involved - + vec4 color = vec4(0.0); switch (colorOption) { case COLOROPTION_COLOR: @@ -79,7 +79,7 @@ Fragment getFragment() { vec4 position = vs_position; // This has to be fixed when the scale graph is in place ---emiax - position.w = 19; + position.w = 15; Fragment frag; frag.color = fullColor; diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index e1d1bbbd58..6ecfd1a46d 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -55,10 +55,11 @@ namespace openspace { RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) : Renderable(dictionary) - , _stepSize("stepSize", "Step Size", 0.001, 0.0005, 0.05) + , _stepSize("stepSize", "Step Size", 0.012, 0.0005, 0.05) , _pointStepSize("pointStepSize", "Point Step Size", 0.01, 0.01, 0.1) , _translation("translation", "Translation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0), glm::vec3(10.0)) - , _rotation("rotation", "Euler rotation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0), glm::vec3(6.28)) { + , _rotation("rotation", "Euler rotation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0), glm::vec3(6.28)) + , _enabledPointsRatio("nEnabledPointsRatio", "Enabled points", 0.2, 0, 1) { float stepSize; glm::vec3 scaling, translation, rotation; @@ -160,6 +161,7 @@ bool RenderableGalaxy::initialize() { addProperty(_pointStepSize); addProperty(_translation); addProperty(_rotation); + addProperty(_enabledPointsRatio); // initialize points. std::ifstream pointFile(_pointsFilename, std::ios::in | std::ios::binary); @@ -271,9 +273,13 @@ void RenderableGalaxy::update(const UpdateData& data) { glm::mat4 volumeTransform = glm::scale(transform, static_cast(_volumeSize)); _pointTransform = glm::scale(transform, static_cast(_pointScaling)); + glm::vec4 translation = glm::vec4(static_cast(_translation), 0.0); + // Todo: handle floating point overflow, to actually support translation. - volumeTransform = glm::translate(volumeTransform, static_cast(_translation)); - _pointTransform = glm::translate(_pointTransform, static_cast(_translation)); + + volumeTransform[3] += translation; + _pointTransform[3] += translation; + _raycaster->setStepSize(_stepSize); _raycaster->setAspect(_aspect); @@ -349,7 +355,7 @@ void RenderableGalaxy::postRender(const RenderData& data) { glDisable(GL_DEPTH_TEST); glDepthMask(false); glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glDrawArrays(GL_POINTS, 0, _nPoints); + glDrawArrays(GL_POINTS, 0, _nPoints * _enabledPointsRatio); glBindVertexArray(0); glDepthMask(true); glEnable(GL_DEPTH_TEST); diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index c60ab5fa3d..69b395a2dd 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -56,6 +56,7 @@ private: properties::FloatProperty _pointStepSize; properties::Vec3Property _translation; properties::Vec3Property _rotation; + properties::FloatProperty _enabledPointsRatio; std::string _volumeFilename; glm::ivec3 _volumeDimensions; diff --git a/modules/galaxy/shaders/galaxyraycast.glsl b/modules/galaxy/shaders/galaxyraycast.glsl index 1d4db0dbcb..7bdf9d9dd3 100644 --- a/modules/galaxy/shaders/galaxyraycast.glsl +++ b/modules/galaxy/shaders/galaxyraycast.glsl @@ -35,11 +35,11 @@ void sample#{id}(vec3 samplePos, inout float maxStepSize) { vec3 aspect = aspect#{id}; - maxStepSize = maxStepSize#{id} * length(dir * 1/aspect); + maxStepSize = maxStepSize#{id} / length(dir/aspect); vec4 sampledColor = texture(galaxyTexture#{id}, samplePos.xyz); - float STEP_SIZE = maxStepSize; + float STEP_SIZE = maxStepSize#{id}; vec3 alphaTint = vec3(0.3, 0.54, 0.85); //alphaTint = vec3(0.0, 0.5, 1.0); @@ -55,7 +55,7 @@ void sample#{id}(vec3 samplePos, //sampledColor.rgb = pow(sampledColor.rgb, vec3(10.0)); //sampledColor.a = pow(sampledColor.a, 10.0); //sampledColor.a = pow(sampledColor.a, 100000000.0); - sampledColor.rgb *= 4000.0; + sampledColor.rgb *= 500.0; sampledColor.a = sampledColor.a * 0.3; //1.0; diff --git a/modules/galaxy/shaders/points.fs b/modules/galaxy/shaders/points.fs index db7daa29e8..74548099fe 100644 --- a/modules/galaxy/shaders/points.fs +++ b/modules/galaxy/shaders/points.fs @@ -36,10 +36,10 @@ Fragment getFragment() { Fragment frag; float depth = pscDepth(vec4(vsPosition, 0.0)); - float coefficient = exp(1.27 * log(emittanceFactor) - 2*log(depth)); + float coefficient = exp(1.38 * log(emittanceFactor) - 2*log(depth)); frag.color = vec4(vsColor.rgb * coefficient, 1.0); - + frag.depth = depth; diff --git a/modules/galaxy/shaders/points.vs b/modules/galaxy/shaders/points.vs index d14f031033..2e1170fdcd 100644 --- a/modules/galaxy/shaders/points.vs +++ b/modules/galaxy/shaders/points.vs @@ -38,13 +38,16 @@ out vec3 vsColor; #include "PowerScaling/powerScaling_vs.hglsl" void main() { - vec4 p = vec4(inPosition, 0.0); + vec4 p = vec4(inPosition, 1.0); - vec4 tmp = p; - vec4 position = pscTransform(tmp, model); + vec4 worldPosition = model * p; + worldPosition.w = 0.0; + vec4 position = worldPosition; //pscTransform(worldPosition, model); + + + position = pscTransform(position, mat4(1.0)); vsPosition = position.xyz; position = projection * view * position; gl_Position = z_normalization(position); - vsColor = inColor; } diff --git a/modules/galaxy/shaders/raycasterbounds.vs b/modules/galaxy/shaders/raycasterbounds.vs index 37ae94349a..a304a22d03 100644 --- a/modules/galaxy/shaders/raycasterbounds.vs +++ b/modules/galaxy/shaders/raycasterbounds.vs @@ -37,8 +37,9 @@ out vec4 worldPosition; void main() { vPosition = vertPosition.xyz; - worldPosition = vec4(vertPosition.xyz, 0.0); - vec4 position = pscTransform(worldPosition, modelTransform); + worldPosition = modelTransform * vec4(vertPosition.xyz, 1.0); + worldPosition.w = 0.0; + vec4 position = pscTransform(worldPosition, mat4(1.0)); diff --git a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp index b37f0fa83c..0db6385d55 100644 --- a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp +++ b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp @@ -363,7 +363,7 @@ bool RenderableMultiresVolume::initialize() { } }; - + onEnabledChange(onChange); return success; } diff --git a/shaders/abuffer/postrenderabuffer.frag b/shaders/abuffer/postrenderabuffer.frag index 602a98ed67..53136ea591 100644 --- a/shaders/abuffer/postrenderabuffer.frag +++ b/shaders/abuffer/postrenderabuffer.frag @@ -43,10 +43,6 @@ void main() { Fragment newFrag = getFragment(); int sampleMask = gl_SampleMaskIn[0]; - - if (newFrag.depth < 0) { - discard; - } float fboDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x); vec4 fboRgba = texelFetch(mainColorTexture, ivec2(gl_FragCoord), 0); @@ -122,11 +118,10 @@ void main() { #endif } */ + + vec4 newColor = newFrag.color; vec3 contribution = newColor.rgb * blackoutFactor; - //vec3 contribution = newColor.rgb * blackoutFactor; - - _out_color_ = vec4(contribution, 1.0); // _out_color_ = vec4(1.0); diff --git a/shaders/abuffer/resolveabuffer.frag b/shaders/abuffer/resolveabuffer.frag index 59526cf138..38cb3269a5 100644 --- a/shaders/abuffer/resolveabuffer.frag +++ b/shaders/abuffer/resolveabuffer.frag @@ -91,7 +91,7 @@ void main() { //raycast to the first fragment // discard; float startDepth = 0; - float endDepth = _depth_(fragments[0]); + float endDepth = min(_depth_(fragments[0]), fboDepth); raycast(endDepth - startDepth, raycasterMask, accumulatedColor, accumulatedAlpha); //accumulatedColor = vec3(1.0); } @@ -134,7 +134,10 @@ void main() { // Ray cast to next fragment if (i + 1 < nFrags && raycasterMask != 0) { float startDepth = _depth_(fragments[i]); - float endDepth = _depth_(fragments[i + 1]); + float endDepth = min(_depth_(fragments[i + 1]), fboDepth); + if (endDepth < startDepth) { + break; + } raycast(endDepth - startDepth, raycasterMask, accumulatedColor, accumulatedAlpha); @@ -145,9 +148,8 @@ void main() { accumulatedAlpha = clamp(accumulatedAlpha, 0.0, 1.0); //maccumulatedAlpha = vec3(0.0); - accumulatedColor += (1 - accumulatedAlpha) * fboRgba.rgb; + accumulatedColor += (1 - accumulatedAlpha) * pow(fboRgba.rgb, vec3(gamma)); - finalColor = vec4(accumulatedColor.rgb, 1.0); // Gamma correction. @@ -156,17 +158,24 @@ void main() { finalColor = vec4(finalColor.rgb * blackoutFactor, 1.0); + + //finalColor = vec4(vec3(fboRgba.a), 1.0); + //finalColor = fboRgba; //finalColor = vec4(0.0); - //finalColor = vec4(vec3(acc/1000.0), 1.0); + + //finalColor = vec4(0.0, acc/1000.0, acc/1000.0, 1.0); + //finalColor = vec4(acc/1000.0, 0.0, 0.0, 01.0); //finalColor = vec4(vec3(float(nFrags) / 10), 1.0); //finalColor = vec4(vec3(float(_depth_(fragments[0])) / 10), 1.0); + //finalColor = vec4(vec3(nFilteredFrags - nFrags) * 0.2, 1.0); - //finalColor = vec4(vec3(nFrags) * 0.2, 1.0); + //finalColor = vec4(vec3(nFilteredFrags) * 0.2, 1.0); + //finalColor = vec4(vec3(nFrags) * 0.05, 1.0); //finalColor = vec4(raycasterData[0].position, 1.0); //finalColor = debugColor; //finalColor = vec4(gamma * 0.5); - + //finalColor = vec4(fboRgba); } diff --git a/shaders/abuffer/resolveconstants.glsl b/shaders/abuffer/resolveconstants.glsl index 65677a7cb4..78e9fcd8f0 100644 --- a/shaders/abuffer/resolveconstants.glsl +++ b/shaders/abuffer/resolveconstants.glsl @@ -1,7 +1,7 @@ #define RAYCASTING_ENABLED #{resolveData.raycastingEnabled} -#define STORE_SORTED false//#{resolveData.storeSorted} +#define STORE_SORTED false //#{resolveData.storeSorted} #define N_RAYCASTERS #{resolveData.nRaycasters} #define ALPHA_LIMIT 0.9 -#define RAYCAST_MAX_STEPS 10000 +#define RAYCAST_MAX_STEPS 1000 #define INT_MAX 2147483647 #define GAMMA 2.2 \ No newline at end of file diff --git a/shaders/abuffer/resolvehelpers.glsl b/shaders/abuffer/resolvehelpers.glsl index 713efcc109..b464550d7c 100644 --- a/shaders/abuffer/resolvehelpers.glsl +++ b/shaders/abuffer/resolvehelpers.glsl @@ -25,10 +25,13 @@ #ifndef _RESOLVEHELPERS_GLSL_ #define _RESOLVEHELPERS_GLSL_ + +float acc = 0; + #if RAYCASTING_ENABLED #include "raycasterdata.glsl" -float acc = 0; + // Include all ray caster helpers @@ -40,10 +43,14 @@ float acc = 0; // Include all ray casters #for id, raycaster in resolveData.raycasters #include <#{raycaster.raycastPath}> -uniform bool insideRaycaster#{id}; -uniform vec3 cameraPosInRaycaster#{id} #endfor +#for index in 1..#{resolveData.nRaycasters} +uniform bool insideRaycaster#{index}; +uniform vec3 cameraPosInRaycaster#{index} +#endfor + + #endif @@ -79,7 +86,7 @@ uint countSamples(uint mask) { uint depthFilterFragments(uint nFrags, float depthThreshold) { uint j = 0; for (uint i = 0; i < nFrags; i++) { - if (_depth_(fragments[i]) < depthThreshold) { + if (_type_(fragments[i]) != 0 || _depth_(fragments[i]) < depthThreshold) { fragments[j] = fragments[i]; j++; } @@ -129,16 +136,16 @@ j < nFrags && ((newMask = _msaa_(fragments[j])) & accumulatedMask) == 0 && _type */ void retrieveRaycasterData(uint nFrags) { float entryDepths[N_RAYCASTERS]; -#for i in 0..#{resolveData.nRaycasters} +#for i in 1..#{resolveData.nRaycasters} { - int i = #{i}; - entryDepths[i] = -1; - raycasterData[i].scale = -1; + int j = #{i} - 1; + entryDepths[j] = -1; + raycasterData[j].scale = -1; bool inside = insideRaycaster#{i}; if (inside) { - entryDepths[i] = 0; - raycasterData[i].position = cameraPosInRaycaster#{i}; - raycasterData[i].previousJitterDistance = 0; + entryDepths[j] = 0; + raycasterData[j].position = cameraPosInRaycaster#{i}; + raycasterData[j].previousJitterDistance = 0; } } #endfor @@ -167,6 +174,7 @@ void retrieveRaycasterData(uint nFrags) { } } + /** * Perform raycasting */ @@ -185,7 +193,6 @@ void raycast(float raycastDepth, uint raycasterMask, inout vec3 accumulatedColor #endfor float currentDepth = 0.0; - for (int steps = 0; (accumulatedAlpha.x < ALPHA_LIMIT || accumulatedAlpha.y < ALPHA_LIMIT || @@ -220,7 +227,7 @@ void raycast(float raycastDepth, uint raycasterMask, inout vec3 accumulatedColor accumulatedColor, accumulatedAlpha, maxStepSizeLocal); - + float sampleDistance = jitteredStepSizeLocal + data.previousJitterDistance; uint blend = raycasterData[#{raycaster.id}].blend; @@ -244,11 +251,14 @@ void raycast(float raycastDepth, uint raycasterMask, inout vec3 accumulatedColor bool initRaycasterMask(inout uint raycasterMask) { bool insideAnyRaycaster = false; raycasterMask = 0; -#for i in 0..#{resolveData.nRaycasters} { - if (insideRaycaster#{i} && raycasterData[#{i}].scale > 0) { - raycasterMask |= (1 << #{i}); +#for i in 1..#{resolveData.nRaycasters} + { + int j = #{i} - 1; + if (insideRaycaster#{i} && raycasterData[j].scale > 0) { + raycasterMask |= (1 << j); insideAnyRaycaster = true; } + } #endfor return insideAnyRaycaster; } diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag index 2ef798954d..0eab935531 100644 --- a/shaders/framebuffer/raycastframebuffer.frag +++ b/shaders/framebuffer/raycastframebuffer.frag @@ -28,11 +28,16 @@ uniform sampler2D exitColorTexture; uniform sampler2D exitDepthTexture; uniform sampler2DMS mainDepthTexture; +uniform bool insideRaycaster; +uniform vec3 cameraPosInRaycaster; + + #include "blending.glsl" #include "rand.glsl" #include "PowerScaling/powerScalingMath.hglsl" #include <#{fragmentPath}> + #for id, helperPath in helperPaths #include <#{helperPath}> #endfor @@ -68,10 +73,18 @@ void main() { float jitterFactor = 0.5 + 0.5 * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0 - // fetch entry point from rendered fragment - Fragment f = getFragment(); - vec3 entryPos = f.color.xyz; - float entryDepth = f.depth; + vec3 entryPos; + float entryDepth; + + if (insideRaycaster) { + entryPos = cameraPosInRaycaster; + entryDepth = 0; + } else { + // fetch entry point from rendered fragment + Fragment f = getFragment(); + entryPos = f.color.xyz; + entryDepth = f.depth; + } vec3 position = entryPos; vec3 diff = exitPos - entryPos; diff --git a/src/rendering/abufferrenderer.cpp b/src/rendering/abufferrenderer.cpp index 402b2cc37e..2620cb2a86 100644 --- a/src/rendering/abufferrenderer.cpp +++ b/src/rendering/abufferrenderer.cpp @@ -109,15 +109,7 @@ void ABufferRenderer::initialize() { GLint defaultFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo); - - _nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); - if (_nAaSamples == 0) { - _nAaSamples = 1; - } - if (_nAaSamples > 8) { - LERROR("ABuffer renderer does not support more than 8 MSAA samples."); - _nAaSamples = 8; - } + updateResolution(); updateRendererData(); @@ -335,9 +327,10 @@ void ABufferRenderer::preRaycast(ghoul::opengl::ProgramObject& program) { glm::vec3 localCameraPosition; bool cameraIsInside = raycastData.first->cameraIsInside(*_renderData, localCameraPosition); - program.setUniform("insideRaycaster" + std::to_string(raycastData.second.id), cameraIsInside); + int uniformIndex = raycastData.second.id + 1; // uniforms are indexed from 1 (not from 0) + program.setUniform("insideRaycaster" + std::to_string(uniformIndex), cameraIsInside); if (cameraIsInside) { - program.setUniform("cameraPosInRaycaster" + std::to_string(raycastData.second.id), localCameraPosition); + program.setUniform("cameraPosInRaycaster" + std::to_string(uniformIndex), localCameraPosition); } } @@ -367,6 +360,18 @@ void ABufferRenderer::setResolution(glm::ivec2 res) { } } +void ABufferRenderer::setNAaSamples(int nAaSamples) { + _nAaSamples = nAaSamples; + if (_nAaSamples == 0) { + _nAaSamples = 1; + } + if (_nAaSamples > 8) { + LERROR("Framebuffer renderer does not support more than 8 MSAA samples."); + _nAaSamples = 8; + } + _dirtyResolution = true; +} + void ABufferRenderer::clear() { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); @@ -406,12 +411,11 @@ void ABufferRenderer::updateResolution() { glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); - int nSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); glTexImage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, - nSamples, + _nAaSamples, GL_RGBA, GLsizei(_resolution.x), GLsizei(_resolution.y), @@ -420,7 +424,7 @@ void ABufferRenderer::updateResolution() { glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture); glTexImage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, - nSamples, + _nAaSamples, GL_DEPTH_COMPONENT32F, GLsizei(_resolution.x), GLsizei(_resolution.y), diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 6d407d1646..6798f6f6ed 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -123,14 +123,7 @@ void FramebufferRenderer::initialize() { OsEng.renderEngine().raycasterManager().addListener(*this); - _nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); - if (_nAaSamples == 0) { - _nAaSamples = 1; - } - if (_nAaSamples > 8) { - LERROR("Framebuffer renderer does not support more than 8 MSAA samples."); - _nAaSamples = 8; - } + } void FramebufferRenderer::deinitialize() { @@ -194,10 +187,21 @@ void FramebufferRenderer::update() { } } } + + for (auto &program : _insideRaycastPrograms) { + if (program.second->isDirty()) { + try { + program.second->rebuildFromFile(); + } + catch (ghoul::RuntimeError e) { + LERROR(e.message); + } + } + } } void FramebufferRenderer::updateResolution() { - int nSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); + int nSamples = _nAaSamples; glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); glTexImage2DMultisample( @@ -255,6 +259,7 @@ void FramebufferRenderer::updateRaycastData() { _raycastData.clear(); _exitPrograms.clear(); _raycastPrograms.clear(); + _insideRaycastPrograms.clear(); const std::vector& raycasters = OsEng.renderEngine().raycasterManager().raycasters(); int nextId = 0; @@ -291,6 +296,15 @@ void FramebufferRenderer::updateRaycastData() { } catch (ghoul::RuntimeError e) { LERROR(e.message); } + try { + _insideRaycastPrograms[raycaster] = ghoul::opengl::ProgramObject::Build( + "Volume " + std::to_string(data.id) + " inside raycast", + "${SHADERS}/framebuffer/resolveframebuffer.vert", + RaycastFragmentShaderPath, dict); + } + catch (ghoul::RuntimeError e) { + LERROR(e.message); + } } _dirtyRaycastData = false; } @@ -333,9 +347,25 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); - ghoul::opengl::ProgramObject* raycastProgram = _raycastPrograms[raycaster].get(); + + ghoul::opengl::ProgramObject* insideRaycastProgram = _raycastPrograms[raycaster].get(); + + glm::vec3 cameraPosition; + bool cameraIsInside = raycaster->cameraIsInside(raycasterTask.renderData, cameraPosition); + ghoul::opengl::ProgramObject* raycastProgram = nullptr; + + if (cameraIsInside) { + raycastProgram = _insideRaycastPrograms[raycaster].get(); + } else { + raycastProgram = _raycastPrograms[raycaster].get(); + } + if (raycastProgram) { raycastProgram->activate(); + + raycastProgram->setUniform("insideRaycaster", cameraIsInside); + raycastProgram->setUniform("cameraPosInRaycaster", cameraPosition); + raycaster->preRaycast(_raycastData[raycaster], *raycastProgram); ghoul::opengl::TextureUnit exitColorTextureUnit; @@ -355,12 +385,21 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure raycastProgram->setUniform("nAaSamples", _nAaSamples); + glDisable(GL_DEPTH_TEST); glDepthMask(false); - raycaster->renderEntryPoints(raycasterTask.renderData, *raycastProgram); + if (cameraIsInside) { + glBindVertexArray(_screenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + } else { + raycaster->renderEntryPoints(raycasterTask.renderData, *raycastProgram); + } glDepthMask(true); glEnable(GL_DEPTH_TEST); + + raycaster->postRaycast(_raycastData[raycaster], *raycastProgram); raycastProgram->deactivate(); } else { @@ -380,6 +419,7 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure _resolveProgram->setUniform("nAaSamples", _nAaSamples); glBindVertexArray(_screenQuad); glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); _resolveProgram->deactivate(); } @@ -397,6 +437,18 @@ void FramebufferRenderer::setResolution(glm::ivec2 res) { _dirtyResolution = true; } +void FramebufferRenderer::setNAaSamples(int nAaSamples) { + _nAaSamples = nAaSamples; + if (_nAaSamples == 0) { + _nAaSamples = 1; + } + if (_nAaSamples > 8) { + LERROR("Framebuffer renderer does not support more than 8 MSAA samples."); + _nAaSamples = 8; + } + _dirtyResolution = true; +} + void FramebufferRenderer::updateRendererData() { ghoul::Dictionary dict; dict.setValue("fragmentRendererPath", std::string(RenderFragmentShaderPath)); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 5dc84a7710..f781c16bae 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -191,6 +191,7 @@ bool RenderEngine::initialize() { } _raycasterManager = new RaycasterManager(); + _nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); LINFO("Seting renderer from string: " << renderingMethod); setRendererFromString(renderingMethod); @@ -649,11 +650,20 @@ void RenderEngine::setRenderer(std::unique_ptr renderer) { _renderer = std::move(renderer); _renderer->setResolution(res); + _renderer->setNAaSamples(_nAaSamples); _renderer->initialize(); _renderer->setCamera(_mainCamera); _renderer->setScene(_sceneGraph); } + +void RenderEngine::setNAaSamples(int nAaSamples) { + _nAaSamples = nAaSamples; + if (_renderer) { + _renderer->setNAaSamples(_nAaSamples); + } +} + scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { return { "", @@ -670,6 +680,12 @@ scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { "string", "Sets the renderer (ABuffer or FrameBuffer)" }, + { + "setNAaSamples", + &luascriptfunctions::setNAaSamples, + "int", + "Sets the number of anti-aliasing (msaa) samples" + }, { "showRenderInformation", &luascriptfunctions::showRenderInformation, diff --git a/src/rendering/renderengine_lua.inl b/src/rendering/renderengine_lua.inl index 18fc6235d0..5e3937aeb6 100644 --- a/src/rendering/renderengine_lua.inl +++ b/src/rendering/renderengine_lua.inl @@ -57,6 +57,23 @@ int setRenderer(lua_State* L) { return 0; } +/** +* \ingroup LuaScripts +* setNAaSamples(int): +* set the number of anti-aliasing samples (msaa) +*/ +int setNAaSamples(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + + double t = luaL_checknumber(L, -1); + + OsEng.renderEngine().setNAaSamples(static_cast(t)); + return 0; +} + + /** * \ingroup LuaScripts * visualizeABuffer(bool):