diff --git a/config/sgct/single.xml b/config/sgct/single.xml index 6e24842b3e..0507f9f5c0 100644 --- a/config/sgct/single.xml +++ b/config/sgct/single.xml @@ -4,7 +4,7 @@ - + @@ -14,7 +14,7 @@ - + @@ -32,4 +32,4 @@ - \ No newline at end of file + diff --git a/include/openspace/abuffer/abuffer.h b/include/openspace/rendering/abufferrenderer.h similarity index 57% rename from include/openspace/abuffer/abuffer.h rename to include/openspace/rendering/abufferrenderer.h index 03ff58e0c9..67c516d549 100644 --- a/include/openspace/abuffer/abuffer.h +++ b/include/openspace/rendering/abufferrenderer.h @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2015 * + * 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 * @@ -22,16 +22,22 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __ABUFFER_H__ -#define __ABUFFER_H__ +#ifndef __ABUFFERRENDERER_H__ +#define __ABUFFERRENDERER_H__ #include #include +#include #include #include +#include + +#include +#include namespace ghoul { + namespace filesystem { class File; } @@ -43,66 +49,62 @@ namespace ghoul { namespace openspace { -class ABuffer { +class RenderableVolume; +class Camera; +class Scene; + +class ABufferRenderer : public Renderer { public: - struct fragmentData { - GLfloat _position[3]; - GLfloat _color[4]; - GLfloat _padding; - }; + ABufferRenderer(); + virtual ~ABufferRenderer(); - static const int MAX_LAYERS = 32; + void initialize() override; + void deinitialize() override; - ABuffer(); - virtual ~ABuffer(); - virtual void resolve(float blackoutFactor); - virtual bool initialize() = 0; - virtual bool reinitialize(); + void setCamera(Camera* camera) override; + void setScene(Scene* scene) override; + void setResolution(glm::ivec2 res) override; - void addVolume(const std::string& tag,ghoul::opengl::Texture* volume); - void addTransferFunction(const std::string& tag,ghoul::opengl::Texture* transferFunction); - int addSamplerfile(const std::string& filename); + void update(); + void render(float blackoutFactor, bool doPerformanceMeasurements) override; - void invalidateABuffer(); + /** + * Update render data + * Responsible for calling renderEngine::setRenderData + */ + virtual void updateRendererData() override; + +private: + + void clear(); + void updateResolution(); + ghoul::Dictionary createResolveDictionary(); + ghoul::opengl::ProgramObject* createResolveProgram(const ghoul::Dictionary& dict); - virtual void clear() = 0; - virtual void preRender() = 0; - virtual void postRender() = 0; + Camera* _camera; + Scene* _scene; + glm::ivec2 _resolution; + bool _dirtyResolution; + + ghoul::opengl::ProgramObject* _resolveProgram; + + /** + * When a volume is attached or detached from the scene graph, + * the resolve program needs to be recompiled. + * The #volumes vector keeps track of which volumes that can + * be rendered using the current resolve program. + */ + std::vector _volumes; - virtual std::vector pixelData() = 0; + GLuint _screenQuad; + GLuint _anchorPointerTexture; + GLuint _anchorPointerTextureInitializer; + GLuint _atomicCounterBuffer; + GLuint _fragmentBuffer; + GLuint _fragmentTexture; -protected: - virtual bool reinitializeInternal() = 0; - - virtual bool initializeABuffer(); - - void generateShaderSource(); - bool updateShader(); - - void openspaceHeaders(); - void openspaceSamplerCalls(); - void openspaceSamplers(); - void openspaceTransferFunction(); - - int _width; - int _height; - int _totalPixels; - - void updateDimensions(); - - GLuint _screenQuad; - - bool _validShader; - ghoul::opengl::ProgramObject* _resolveShader; - - std::vector > _volumes; - std::vector > _transferFunctions; - std::vector _samplerFiles; - std::vector _samplers; - - float _volumeStepFactor; - -}; // ABuffer + ghoul::Dictionary _rendererData; +}; // ABufferRenderer } // openspace -#endif // __ABUFFER_H__ \ No newline at end of file +#endif // __RENDERER_H__ diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h new file mode 100644 index 0000000000..2651189b48 --- /dev/null +++ b/include/openspace/rendering/framebufferrenderer.h @@ -0,0 +1,84 @@ +/***************************************************************************************** + * * + * 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 __FRAMEBUFFERRENDERER_H__ +#define __FRAMEBUFFERRENDERER_H__ + +#include +#include + +#include +#include +#include + +#include +#include + +namespace ghoul { + class Dictionary; + + namespace filesystem { + class File; + } + namespace opengl { + class ProgramObject; + class Texture; + } +} + +namespace openspace { + +class RenderableVolume; +class Camera; +class Scene; + +class FramebufferRenderer : public Renderer { +public: + FramebufferRenderer(); + virtual ~FramebufferRenderer(); + + void initialize() override; + void deinitialize() override; + + void setCamera(Camera* camera) override; + void setScene(Scene* scene) override; + void setResolution(glm::ivec2 res) override; + + void update() override; + void render(float blackoutFactor, bool doPerformanceMeasurements) override; + + /** + * Update render data + * Responsible for calling renderEngine::setRenderData + */ + virtual void updateRendererData() override; +private: + + Camera* _camera; + Scene* _scene; + glm::vec2 _resolution; +}; // FramebufferRenderer +} // openspace + +#endif // __FRAMEBUFFERRENDERER_H__ diff --git a/include/openspace/rendering/renderable.h b/include/openspace/rendering/renderable.h index 6bd501cd26..c790f97a9d 100644 --- a/include/openspace/rendering/renderable.h +++ b/include/openspace/rendering/renderable.h @@ -29,9 +29,11 @@ #include #include #include +#include #include + // Forward declare to minimize dependencies namespace ghoul { namespace opengl { @@ -67,6 +69,7 @@ public: virtual void render(const RenderData& data) = 0; virtual void update(const UpdateData& data); + virtual std::vector volumesToRender(const RenderData& data) const; bool isVisible() const; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 5164ebd4da..60fb30e4af 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -34,7 +34,10 @@ namespace ghoul { namespace fontrendering { class Font; } - +namespace opengl { + class ProgramObject; +} +class Dictionary; class SharedMemory; } @@ -44,17 +47,14 @@ namespace openspace { class Camera; class SyncBuffer; class Scene; -class ABuffer; -class ABufferVisualizer; +class Renderer; class ScreenLog; class RenderEngine { public: - enum class ABufferImplementation { - FrameBuffer = 0, - SingleLinked, - Fixed, - Dynamic, + enum class RendererImplementation { + Framebuffer = 0, + ABuffer, Invalid }; @@ -69,8 +69,8 @@ public: Scene* scene(); Camera* camera() const; - ABuffer* aBuffer() const; - ABufferImplementation aBufferImplementation() const; + Renderer* renderer() const; + RendererImplementation rendererImplementation() const; // sgct wrapped functions bool initializeGL(); @@ -80,8 +80,6 @@ public: void postDraw(); void takeScreenshot(); - void toggleVisualizeABuffer(bool b); - void toggleInfoText(bool b); void setPerformanceMeasurements(bool performanceMeasurements); @@ -94,21 +92,40 @@ public: void setGlobalBlackOutFactor(float factor); void setDisableRenderingOnMaster(bool enabled); + + ghoul::opengl::ProgramObject* buildRenderProgram( + std::string name, + std::string vsPath, + std::string fsPath, + const ghoul::Dictionary& dictionary = ghoul::Dictionary()); + + ghoul::opengl::ProgramObject* buildRenderProgram( + std::string name, + std::string vsPath, + std::string fsPath, + std::string csPath, + const ghoul::Dictionary& dictionary = ghoul::Dictionary()); + + void removeRenderProgram(ghoul::opengl::ProgramObject* program); + + void setRendererFromString(const std::string& method); + + /** + * Let's 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); /** * Returns the Lua library that contains all Lua functions available to affect the - * rendering. The functions contained are - * - openspace::luascriptfunctions::printImage - * - openspace::luascriptfunctions::visualizeABuffer - * \return The Lua library that contains all Lua functions available to affect the - * rendering + * rendering. */ static scripting::ScriptEngine::LuaLibrary luaLibrary(); // This is a temporary method to change the origin of the coordinate system ---abock void changeViewPoint(std::string origin); - //temporaray fade functionality + // Temporary fade functionality void startFading(int direction, float fadeDuration); // This is temporary until a proper screenspace solution is found ---abock @@ -119,38 +136,37 @@ public: } _onScreenInformation; private: - ABufferImplementation aBufferFromString(const std::string& impl); - + void setRenderer(Renderer* renderer); + RendererImplementation rendererFromString(const std::string& method); void storePerformanceMeasurements(); + void renderInformation(); + void renderScreenLog(); Camera* _mainCamera; Scene* _sceneGraph; - ABuffer* _abuffer; - ABufferImplementation _abufferImplementation; + Renderer* _renderer; + RendererImplementation _rendererImplementation; + ghoul::Dictionary _rendererData; ScreenLog* _log; bool _showInfo; - bool _showScreenLog; + bool _showLog; bool _takeScreenshot; bool _doPerformanceMeasurements; ghoul::SharedMemory* _performanceMemory; - void generateGlslConfig(); - float _globalBlackOutFactor; float _fadeDuration; float _currentFadeTime; int _fadeDirection; -// bool _sgctRenderStatisticsVisible; + + std::vector _programs; ghoul::fontrendering::Font* _fontInfo = nullptr; ghoul::fontrendering::Font* _fontDate = nullptr; ghoul::fontrendering::Font* _fontLog = nullptr; - bool _visualizeABuffer; - ABufferVisualizer* _visualizer; - bool _disableMasterRendering = false; }; diff --git a/include/openspace/abuffer/abuffervisualizer.h b/include/openspace/rendering/renderer.h similarity index 75% rename from include/openspace/abuffer/abuffervisualizer.h rename to include/openspace/rendering/renderer.h index 7b776184d4..c47c1b7f82 100644 --- a/include/openspace/abuffer/abuffervisualizer.h +++ b/include/openspace/rendering/renderer.h @@ -22,47 +22,52 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __ABUFFERVISUALIZER_H__ -#define __ABUFFERVISUALIZER_H__ +#ifndef __RENDERER_H__ +#define __RENDERER_H__ -#include #include #include #include #include +#include namespace ghoul { + class Dictionary; + + namespace filesystem { + class File; + } namespace opengl { class ProgramObject; + class Texture; } } namespace openspace { -class ABufferVisualizer { +class RenderableVolume; +class Camera; +class Scene; + +class Renderer { public: + virtual void initialize() = 0; + virtual void deinitialize() = 0; + + virtual void setCamera(Camera* camera) = 0; + virtual void setScene(Scene* scene) = 0; + virtual void setResolution(glm::ivec2 res) = 0; - ABufferVisualizer(); - ~ABufferVisualizer(); + virtual void update() = 0; + virtual void render(float blackoutFactor, bool doPerformanceMeasurements) = 0; + /** + * Update render data + * Responsible for calling renderEngine::setRenderData + */ + virtual void updateRendererData() = 0; + +}; // Renderer +} // openspace - void updateData(const std::vector& data); - - void render(); - -private: - - void initializeMarkers(); - - GLuint _pointcloud; - GLsizei _pointcloudSize; - GLuint _markers; - GLsizei _markersSize; - GLuint _imarkers; - GLsizei _imarkersSize; - ghoul::opengl::ProgramObject* _pointcloudProgram; - -}; // ABufferVisualizer -} // namespace openspace - -#endif // __ABUFFER_H__ \ No newline at end of file +#endif // __RENDERER_H__ diff --git a/include/openspace/rendering/volume.h b/include/openspace/rendering/volume.h new file mode 100644 index 0000000000..4111705bea --- /dev/null +++ b/include/openspace/rendering/volume.h @@ -0,0 +1,132 @@ +/***************************************************************************************** + * * + * 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 __VOLUME_H__ +#define __VOLUME_H__ + +#include +#include + +namespace ghoul { + namespace opengl { + class Texture; + class ProgramObject; + } +} + +namespace openspace { + +class Volume { +public: + + /** + * Constructor + */ + Volume() {}; + + /** + * Destructor + */ + virtual ~Volume() {}; + + /** + * Render the volume's entry points (front face of the bounding geometry) + */ + //virtual void renderEntryPoints(const RenderData& data, ghoul::opengl::ProgramObject* program) = 0; + + /** + * Render the volume's exit points (back face of the bounding geometry) + */ + //virtual void renderExitPoints(const RenderData& data, ghoul::opengl::ProgramObject* program) = 0; + + /** + * Prepare the volume for the ABuffer's resolve step. + * Make sure textures are up to date, bind them to texture units, set program uniforms etc. + */ + //virtual void preRayCast(ghoul::opengl::ProgramObject* program) {}; + + /** + * Clean up for the volume after the ABuffer's resolve step. + * Make sure texture units are deinitialized, etc. + */ + //virtual void postRayCast(ghoul::opengl::ProgramObject* program) {}; + + /** + * Return a path to a file with the uniforms, per-vertex variables, functions etc + * required to transform the vertices of the bounding geometry to view space. + * It could also set other vertex out variables for the fragment shader to access. + * + * The shader preprocessor will have acceess to + * A #{namespace} variable (unique per helper file) + * + * Should define the function: + * vec4 getVertex() + */ + //virtual std::string getBoundsVsPath() = 0; + + /* + * Return a path to a file with the functions, uniforms and fragment shader in variables + * required to generate the fragment color and depth. + * + * Should define the function: + * Fragment getFragment() + * + * The shader preprocessor will have acceess to + * A #{namespace} variable (unique per helper file) + */ + //virtual std::string getBoundsFsPath() = 0; + + /** + * Return a path to a file with all the uniforms, functions etc + * required to perform ray casting through this volume. + * + * The header should define the following two functions: + * vec4 sampler#{id}(vec3 samplePos, vec3 dir, float occludingAlpha, inout float maxStepSize) + * (return color of sample) + * float stepSize#{id}(vec3 samplePos, vec3 dir) + * (return the preferred step size at this sample position) + * + * The shader preprocessor will have acceess to + * An #{id} variable (unique per volume) + * A #{namespace} variable (unique per helper file) + */ + //virtual std::string getRayCastPath() = 0; + + /** + * Return a path to a glsl file with helper functions required for the + * transformation and raycast steps. + * This file will be included once per shader program generated, + * regardless of how many volumes say they require the file. + * Ideal to avoid redefinitions of helper functions. + * + * The shader preprocessor will have access to the #{namespace} variable (unique per helper file) + * which should be a prefix to all symbols defined by the helper + */ + //virtual std::string getHelperPath() = 0; + +}; // Volume + +} // openspace + +#endif // __VOLUME_H__ diff --git a/include/openspace/scene/scene.h b/include/openspace/scene/scene.h index 8c1fa224d0..446135a653 100644 --- a/include/openspace/scene/scene.h +++ b/include/openspace/scene/scene.h @@ -41,7 +41,7 @@ namespace openspace { - +class Volume; class SceneGraphNode; // Notifications: @@ -85,6 +85,10 @@ public: */ void render(const RenderData& data); + /* + * Return a vector of volumes to render and their acciciated render data + */ + std::vector> volumesToRender(const RenderData& data) const; /* * Returns the root SceneGraphNode */ diff --git a/include/openspace/scene/scenegraph.h b/include/openspace/scene/scenegraph.h index 7a8111224e..a3b5b619cb 100644 --- a/include/openspace/scene/scenegraph.h +++ b/include/openspace/scene/scenegraph.h @@ -46,7 +46,7 @@ public: bool addSceneGraphNode(SceneGraphNode* node); bool removeSceneGraphNode(SceneGraphNode* node); - const std::vector& nodes(); + const std::vector& nodes() const; SceneGraphNode* rootNode() const; SceneGraphNode* sceneGraphNode(const std::string& name) const; diff --git a/include/openspace/scene/scenegraphnode.h b/include/openspace/scene/scenegraphnode.h index 306d8db371..c8dae57fae 100644 --- a/include/openspace/scene/scenegraphnode.h +++ b/include/openspace/scene/scenegraphnode.h @@ -90,6 +90,7 @@ public: void setRenderable(Renderable* renderable); const Renderable* renderable() const; Renderable* renderable(); + std::vector> volumesToRender(const RenderData& data) const; // @TODO Remove once the scalegraph is in effect ---abock void setEphemeris(Ephemeris* eph) { diff --git a/include/openspace/abuffer/abuffersinglelinked.h b/include/openspace/util/blockplaneintersectiongeometry.h similarity index 72% rename from include/openspace/abuffer/abuffersinglelinked.h rename to include/openspace/util/blockplaneintersectiongeometry.h index 9db4ab8744..8d3a1da983 100644 --- a/include/openspace/abuffer/abuffersinglelinked.h +++ b/include/openspace/util/blockplaneintersectiongeometry.h @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2015 * + * 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 * @@ -22,37 +22,39 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __ABUFFERSINGLELINKED_H__ -#define __ABUFFERSINGLELINKED_H__ +#ifndef __BLOCKPLANEINTERSECTIONGEOMETRY_H__ +#define __BLOCKPLANEINTERSECTIONGEOMETRY_H__ + +#include +#include -#include #include namespace openspace { -class ABufferSingleLinked: public ABuffer { +class BlockPlaneIntersectionGeometry { public: + // initializers + BlockPlaneIntersectionGeometry(glm::vec3 blockSize, glm::vec3 planeNormal, float planeDistance); + ~BlockPlaneIntersectionGeometry(); - ABufferSingleLinked(); - virtual ~ABufferSingleLinked(); - virtual bool initialize(); + bool initialize(); + void render(); - virtual void clear(); - virtual void preRender(); - virtual void postRender(); - - std::vector pixelData(); - -protected: - virtual bool reinitializeInternal(); + void setBlockSize(glm::vec3 size); + void setPlane(glm::vec3 normal, float distance); private: - GLuint _anchorPointerTexture; - GLuint _anchorPointerTextureInitializer; - GLuint _atomicCounterBuffer; - GLuint _fragmentBuffer; - GLuint _fragmentTexture; -}; // ABufferSingleLinked -} // openspace + void updateVertices(); + std::vector _vertices; + bool _initialized; + GLuint _vaoId; + GLuint _vBufferId; + glm::vec3 _size; + glm::vec3 _normal; + float _planeDistance; +}; -#endif // __ABUFFERSINGLELINKED_H__ \ No newline at end of file +} + +#endif // __BLOCKPLANEINTERSECTIONGEOMETRY_H__ diff --git a/include/openspace/abuffer/abufferframebuffer.h b/include/openspace/util/boxgeometry.h similarity index 77% rename from include/openspace/abuffer/abufferframebuffer.h rename to include/openspace/util/boxgeometry.h index 13b3f18f30..25eebe354a 100644 --- a/include/openspace/abuffer/abufferframebuffer.h +++ b/include/openspace/util/boxgeometry.h @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2015 * + * 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 * @@ -22,35 +22,28 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __ABUFFERFRAMEBUFFER_H__ -#define __ABUFFERFRAMEBUFFER_H__ +#ifndef __BOXGEOMETRY_H__ +#define __BOXGEOMETRY_H__ -#include +#include +#include namespace openspace { - -class ABufferFramebuffer: public ABuffer { + +class BoxGeometry { public: - - ABufferFramebuffer(); - virtual ~ABufferFramebuffer(); + // initializers + BoxGeometry(glm::vec3 size); + ~BoxGeometry(); + bool initialize(); - - void clear(); - void preRender(); - void postRender(); - void resolve(float blackoutFactor); - - std::vector pixelData(); -protected: - bool reinitializeInternal(); + void render(); + + GLuint _vaoId; + GLuint _vBufferId; + glm::vec3 _size; +}; - bool initializeABuffer(); +} // namespace openspace - -private: - -}; // ABufferSingleLinked -} // openspace - -#endif // __ABUFFERSINGLELINKED_H__ \ No newline at end of file +#endif // __BOXGEOMETRY_H__ diff --git a/include/openspace/util/camera.h b/include/openspace/util/camera.h index 39922715fb..cb525dcd82 100644 --- a/include/openspace/util/camera.h +++ b/include/openspace/util/camera.h @@ -111,7 +111,6 @@ public: void setProjectionMatrix(glm::mat4 projectionMatrix); const glm::mat4& projectionMatrix() const; - void setViewProjectionMatrix(glm::mat4 viewProjectionMatrix); const glm::mat4& viewProjectionMatrix() const; void setCameraDirection(glm::vec3 cameraDirection); @@ -148,10 +147,11 @@ public: private: float _maxFov; float _sinMaxFov; - glm::mat4 _viewProjectionMatrix; + mutable glm::mat4 _viewProjectionMatrix; glm::mat4 _modelMatrix; glm::mat4 _viewMatrix; glm::mat4 _projectionMatrix; + mutable bool _dirtyViewProjectionMatrix; glm::vec3 _viewDirection; glm::vec3 _cameraDirection; psc _focusPosition; @@ -159,7 +159,7 @@ private: glm::vec3 _lookUp; - std::mutex _mutex; + mutable std::mutex _mutex; //local variables glm::mat4 _localViewRotationMatrix; diff --git a/modules/base/rendering/renderableconstellationbounds.cpp b/modules/base/rendering/renderableconstellationbounds.cpp index 52fa9785a7..a5e97d72ac 100644 --- a/modules/base/rendering/renderableconstellationbounds.cpp +++ b/modules/base/rendering/renderableconstellationbounds.cpp @@ -23,6 +23,8 @@ ****************************************************************************************/ // openspace +#include +#include #include #include #include @@ -90,9 +92,11 @@ RenderableConstellationBounds::~RenderableConstellationBounds() { } bool RenderableConstellationBounds::initialize() { - _program = ghoul::opengl::ProgramObject::Build("ConstellationBounds", - "${MODULE_BASE}/shaders/constellationbounds_vs.glsl", - "${MODULE_BASE}/shaders/constellationbounds_fs.glsl"); + RenderEngine* renderEngine = OsEng.renderEngine(); + _program = renderEngine->buildRenderProgram("ConstellationBounds", + "${MODULE_BASE}/shaders/constellationbounds_vs.glsl", + "${MODULE_BASE}/shaders/constellationbounds_fs.glsl"); + if (!_program) return false; @@ -138,8 +142,11 @@ bool RenderableConstellationBounds::deinitialize() { glDeleteVertexArrays(1, &_vao); _vao = 0; - delete _program; - _program = nullptr; + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_program) { + renderEngine->removeRenderProgram(_program); + _program = nullptr; + } return true; } @@ -176,9 +183,6 @@ void RenderableConstellationBounds::render(const RenderData& data) { } void RenderableConstellationBounds::update(const UpdateData& data) { - if (_program->isDirty()) - _program->rebuildFromFile(); - SpiceManager::ref().getPositionTransformMatrix( _originReferenceFrame, "GALACTIC", diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 4fb5c67ee5..3996aa3a4f 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -26,6 +26,7 @@ // ie after I see model on screen) // open space includes +#include #include #include #include @@ -126,9 +127,12 @@ bool RenderableModel::initialize() { bool completeSuccess = true; if (_programObject == nullptr) { // NH shader - _programObject = ghoul::opengl::ProgramObject::Build("ModelProgram", + + RenderEngine* renderEngine = OsEng.renderEngine(); + _programObject = renderEngine->buildRenderProgram("ModelProgram", "${MODULE_BASE}/shaders/model_vs.glsl", "${MODULE_BASE}/shaders/model_fs.glsl"); + if (!_programObject) return false; } @@ -152,8 +156,12 @@ bool RenderableModel::deinitialize() { delete _texture; _texture = nullptr; - delete _programObject; - _programObject = nullptr; + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_programObject) { + renderEngine->removeRenderProgram(_programObject); + _programObject = nullptr; + } + return true; } diff --git a/modules/base/rendering/renderablepath.cpp b/modules/base/rendering/renderablepath.cpp index 300b34ecbf..ee382bb8bd 100644 --- a/modules/base/rendering/renderablepath.cpp +++ b/modules/base/rendering/renderablepath.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -99,10 +100,12 @@ bool RenderablePath::initialize() { } bool completeSuccess = true; - _programObject = ghoul::opengl::ProgramObject::Build("PathProgram", - "${MODULE_BASE}/shaders/path_vs.glsl", - "${MODULE_BASE}/shaders/path_fs.glsl" - ); + + + RenderEngine* renderEngine = OsEng.renderEngine(); + _programObject = renderEngine->buildRenderProgram("PathProgram", + "${MODULE_BASE}/shaders/path_vs.glsl", + "${MODULE_BASE}/shaders/path_fs.glsl"); if (!_programObject) return false; @@ -124,8 +127,11 @@ bool RenderablePath::deinitialize() { glDeleteBuffers(1, &_vBufferID); _vBufferID = 0; - delete _programObject; - _programObject = nullptr; + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_programObject) { + renderEngine->removeRenderProgram(_programObject); + _programObject = nullptr; + } return true; } diff --git a/modules/base/rendering/renderableplane.cpp b/modules/base/rendering/renderableplane.cpp index ef7108646b..70424516c3 100644 --- a/modules/base/rendering/renderableplane.cpp +++ b/modules/base/rendering/renderableplane.cpp @@ -144,9 +144,12 @@ bool RenderablePlane::initialize() { if (_shader == nullptr) { // Plane Program - _shader = ghoul::opengl::ProgramObject::Build("PlaneProgram", + + RenderEngine* renderEngine = OsEng.renderEngine(); + _shader = renderEngine->buildRenderProgram("PlaneProgram", "${MODULE_BASE}/shaders/plane_vs.glsl", - "${MODULE_BASE}/shaders/plane_fs.glsl"); + "${MODULE_BASE}/shaders/plane_fs.glsl" + ); if (!_shader) return false; } @@ -173,8 +176,11 @@ bool RenderablePlane::deinitialize() { delete _textureFile; _textureFile = nullptr; - delete _shader; - _shader = nullptr; + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_shader) { + renderEngine->removeRenderProgram(_shader); + _shader = nullptr; + } return true; } diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 19f03e4c37..23de51c04b 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -122,10 +123,26 @@ RenderablePlanet::~RenderablePlanet() { } bool RenderablePlanet::initialize() { - if (_programObject == nullptr && _hasNightTexture) - OsEng.ref().configurationManager()->getValue("nightTextureProgram", _programObject); - else if (_programObject == nullptr) - OsEng.ref().configurationManager()->getValue("pscShader", _programObject); + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_programObject == nullptr && _hasNightTexture) { + // Night texture program + _programObject = renderEngine->buildRenderProgram( + "nightTextureProgram", + "${SHADERS}/nighttexture_vs.glsl", + "${SHADERS}/nighttexture_fs.glsl"); + if (!_programObject) return false; + } + else if (_programObject == nullptr) { + // pscstandard + _programObject = renderEngine->buildRenderProgram( + "pscstandard", + "${SHADERS}/pscstandard_vs.glsl", + "${SHADERS}/pscstandard_fs.glsl"); + if (!_programObject) return false; + + } + _programObject->setIgnoreSubroutineUniformLocationError(true); + loadTexture(); _geometry->initialize(this); @@ -143,6 +160,12 @@ bool RenderablePlanet::deinitialize() { if (_nightTexture) delete _nightTexture; + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_programObject) { + renderEngine->removeRenderProgram(_programObject); + _programObject = nullptr; + } + _geometry = nullptr; _texture = nullptr; _nightTexture = nullptr; @@ -206,6 +229,10 @@ void RenderablePlanet::render(const RenderData& data) _nightTexture->bind(); _programObject->setUniform("nightTex", nightUnit); } + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + // render _geometry->render(); diff --git a/modules/base/rendering/renderablesphere.cpp b/modules/base/rendering/renderablesphere.cpp index 18ee8780e4..4c7016d3f9 100644 --- a/modules/base/rendering/renderablesphere.cpp +++ b/modules/base/rendering/renderablesphere.cpp @@ -22,10 +22,12 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ + #include #include #include +#include #include #include #include @@ -116,7 +118,8 @@ bool RenderableSphere::initialize() { _sphere->initialize(); // pscstandard - _shader = ghoul::opengl::ProgramObject::Build("Sphere", + RenderEngine* renderEngine = OsEng.renderEngine(); + _shader = renderEngine->buildRenderProgram("Sphere", "${MODULES}/base/shaders/sphere_vs.glsl", "${MODULES}/base/shaders/sphere_fs.glsl"); if (!_shader) @@ -134,8 +137,11 @@ bool RenderableSphere::deinitialize() { delete _texture; _texture = nullptr; - delete _shader; - _shader = nullptr; + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_shader) { + renderEngine->removeRenderProgram(_shader); + _shader = nullptr; + } return true; } @@ -154,7 +160,6 @@ void RenderableSphere::render(const RenderData& data) { _shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); _shader->setUniform("ModelTransform", transform); setPscUniforms(_shader, &data.camera, data.position); - _shader->setUniform("alpha", _transparency); ghoul::opengl::TextureUnit unit; @@ -162,6 +167,9 @@ void RenderableSphere::render(const RenderData& data) { _texture->bind(); _shader->setUniform("texture1", unit); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + _sphere->render(); _shader->setIgnoreUniformLocationError(false); diff --git a/modules/base/rendering/renderablestars.cpp b/modules/base/rendering/renderablestars.cpp index a9a4cc8832..b4ad09151f 100644 --- a/modules/base/rendering/renderablestars.cpp +++ b/modules/base/rendering/renderablestars.cpp @@ -25,6 +25,8 @@ #include #include +#include +#include #include #include @@ -90,8 +92,8 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) , _colorTextureIsDirty(true) , _colorOption("colorOption", "Color Option") , _dataIsDirty(true) - , _scaleFactor("scaleFactor", "Scale Factor", 5.f, 0.f, 10.f) - , _minBillboardSize("minBillboardSize", "Min Billboard Size", 15.f, 1.f, 100.f) + , _scaleFactor("scaleFactor", "Scale Factor", 1.f, 0.f, 10.f) + , _minBillboardSize("minBillboardSize", "Min Billboard Size", 1.f, 1.f, 100.f) , _program(nullptr) , _speckFile("") , _nValuesPerStar(0) @@ -147,10 +149,12 @@ bool RenderableStars::isReady() const { bool RenderableStars::initialize() { bool completeSuccess = true; - _program = ghoul::opengl::ProgramObject::Build("Star", + RenderEngine* renderEngine = OsEng.renderEngine(); + _program = renderEngine->buildRenderProgram("Star", "${MODULE_BASE}/shaders/star_vs.glsl", "${MODULE_BASE}/shaders/star_fs.glsl", "${MODULE_BASE}/shaders/star_ge.glsl"); + if (!_program) return false; completeSuccess &= loadData(); @@ -168,17 +172,16 @@ bool RenderableStars::deinitialize() { delete _pointSpreadFunctionTexture; _pointSpreadFunctionTexture = nullptr; - if(_program) - delete _program; - _program = nullptr; - return true; + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_program) { + renderEngine->removeRenderProgram(_program); + _program = nullptr; + } + return true; } void RenderableStars::render(const RenderData& data) { - //glEnable(GL_BLEND); - //glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); - glDisable(GL_DEPTH_TEST); - + glDepthMask(false); _program->activate(); // @Check overwriting the scaling from the camera; error as parsec->meter conversion @@ -223,16 +226,10 @@ void RenderableStars::render(const RenderData& data) { _program->setIgnoreUniformLocationError(false); _program->deactivate(); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_DEPTH_TEST); + glDepthMask(true); } void RenderableStars::update(const UpdateData& data) { - if (_program->isDirty()) { - _program->rebuildFromFile(); - _dataIsDirty = true; - } - if (_dataIsDirty) { const int value = _colorOption; LDEBUG("Regenerating data"); diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index e9bdfa2e25..aece38b2cf 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -119,9 +120,13 @@ bool RenderableTrail::initialize() { } bool completeSuccess = true; - _programObject = ghoul::opengl::ProgramObject::Build("EphemerisProgram", + + RenderEngine* renderEngine = OsEng.renderEngine(); + _programObject = renderEngine->buildRenderProgram("EphemerisProgram", "${MODULE_BASE}/shaders/ephemeris_vs.glsl", "${MODULE_BASE}/shaders/ephemeris_fs.glsl"); + + if (!_programObject) return false; @@ -131,6 +136,13 @@ bool RenderableTrail::initialize() { bool RenderableTrail::deinitialize() { glDeleteVertexArrays(1, &_vaoID); glDeleteBuffers(1, &_vBufferID); + + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_programObject) { + renderEngine->removeRenderProgram(_programObject); + _programObject = nullptr; + } + return true; } @@ -198,8 +210,6 @@ void RenderableTrail::update(const UpdateData& data) { return; } - if (_programObject->isDirty()) - _programObject->rebuildFromFile(); double lightTime = 0.0; psc pscPos; diff --git a/modules/base/shaders/constellationbounds_fs.glsl b/modules/base/shaders/constellationbounds_fs.glsl index 803e0bd79b..0c217770f6 100644 --- a/modules/base/shaders/constellationbounds_fs.glsl +++ b/modules/base/shaders/constellationbounds_fs.glsl @@ -22,24 +22,23 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - uniform vec4 campos; uniform vec4 objpos; //uniform vec3 camdir; // add this for specular in vec4 vs_position; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -//#include "PowerScaling/powerScaling_vs.hglsl" -void main() +Fragment getFragment() { vec4 position = vs_position; float depth = pscDepth(position); + Fragment frag; - ABufferStruct_t frag = createGeometryFragment(vec4(1.0, 0.0, 0.0, 1.0), position, depth); - addToBuffer(frag); -} \ No newline at end of file + frag.color = vec4(1.0, 0.0, 0.0, 1.0); + frag.depth = depth; + + return frag; +} diff --git a/modules/base/shaders/ephemeris_fs.glsl b/modules/base/shaders/ephemeris_fs.glsl index c9a8c5f111..d589c5e6e8 100644 --- a/modules/base/shaders/ephemeris_fs.glsl +++ b/modules/base/shaders/ephemeris_fs.glsl @@ -22,8 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - in vec4 vs_point_position; in vec4 vs_point_velocity; in float fade; @@ -31,15 +29,17 @@ uniform float forceFade; uniform vec3 color; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -void main() { +Fragment getFragment() { vec4 position = vs_point_position; float depth = pscDepth(position); vec4 c = vec4(color, fade*forceFade); - ABufferStruct_t frag = createGeometryFragment(c, position, depth); - addToBuffer(frag); -} \ No newline at end of file + Fragment frag; + frag.color = c; + frag.depth = depth; + + return frag; +} diff --git a/modules/base/shaders/imageplane_fs.glsl b/modules/base/shaders/imageplane_fs.glsl index 9f4447eabe..9afd5f6967 100644 --- a/modules/base/shaders/imageplane_fs.glsl +++ b/modules/base/shaders/imageplane_fs.glsl @@ -22,19 +22,16 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - uniform float time; uniform sampler2D texture1; in vec2 vs_st; in vec4 vs_position; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -void main() +Fragment getFragment() { vec4 position = vs_position; float depth = pscDepth(position); @@ -44,7 +41,9 @@ void main() else { diffuse = vec4(0.8); } - - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); -} \ No newline at end of file + + Fragment frag; + frag.color = diffuse; + frag.depth = depth; + return frag; +} diff --git a/modules/base/shaders/model_fs.glsl b/modules/base/shaders/model_fs.glsl index bf3b904c97..634b6c0db7 100644 --- a/modules/base/shaders/model_fs.glsl +++ b/modules/base/shaders/model_fs.glsl @@ -22,8 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - uniform vec4 campos; uniform vec4 objpos; uniform vec3 cam_dir; // add this for specular @@ -43,20 +41,16 @@ in vec2 vs_st; in vec4 vs_normal; in vec4 vs_position; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -//#include "PowerScaling/powerScaling_vs.hglsl" -void main() -{ +Fragment getFragment() { vec4 position = vs_position; float depth = pscDepth(position); //depth = length(campos - position); vec4 diffuse = texture(texture1, vs_st); - + diffuse[3] = fading; - if (_performShading) { vec4 spec = vec4(0.0); @@ -79,16 +73,12 @@ void main() spec = specular * pow(intSpec, shine); } diffuse = vec4(max(intensity * diffuse , ambient).xyz,1) +spec*1.5*diffuse ; - - diffuse[3] = fading*transparency; - - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); - } - else { - diffuse[3] = fading*transparency; - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); } -} \ No newline at end of file + diffuse[3] = fading*transparency; + + Fragment frag; + frag.color = diffuse; + frag.depth = depth; + return frag; +} diff --git a/modules/base/shaders/path_fs.glsl b/modules/base/shaders/path_fs.glsl index 37d5423e2a..c1270d9ad5 100644 --- a/modules/base/shaders/path_fs.glsl +++ b/modules/base/shaders/path_fs.glsl @@ -22,24 +22,23 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - in vec4 vs_point_position; flat in int isHour; in vec4 vs_point_color; uniform vec3 color; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -void main() { +Fragment getFragment() { vec4 position = vs_point_position; float depth = pscDepth(position); vec4 diffuse = vs_point_color; - - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); + + Fragment frag; + frag.color = diffuse; + frag.depth = depth; + return frag; } diff --git a/modules/base/shaders/plane_fs.glsl b/modules/base/shaders/plane_fs.glsl index 9e572651db..bcf9f35707 100644 --- a/modules/base/shaders/plane_fs.glsl +++ b/modules/base/shaders/plane_fs.glsl @@ -22,20 +22,16 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - uniform float time; uniform sampler2D texture1; in vec2 vs_st; in vec4 vs_position; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -void main() -{ +Fragment getFragment() { vec4 position = vs_position; float depth = pscDepth(position); vec4 diffuse; @@ -50,10 +46,12 @@ void main() // diffuse = vec4(1,0,0,1); // } - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); - - gl_FragDepth = depth; if (diffuse.a == 0.0) discard; -} \ No newline at end of file + + Fragment frag; + frag.color = diffuse; + frag.depth = depth; + return frag; + +} diff --git a/modules/base/shaders/sphere_fs.glsl b/modules/base/shaders/sphere_fs.glsl index 3008e06ae5..93090b18b8 100644 --- a/modules/base/shaders/sphere_fs.glsl +++ b/modules/base/shaders/sphere_fs.glsl @@ -22,8 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - uniform float time; uniform sampler2D texture1; uniform float alpha; @@ -31,16 +29,14 @@ uniform float alpha; in vec2 vs_st; in vec4 vs_position; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" +#include "fragment.glsl" #include "PowerScaling/powerScaling_fs.hglsl" -void main() +Fragment getFragment() { vec4 position = vs_position; // This has to be fixed with the ScaleGraph in place (precision deficiency in depth buffer) ---abock - // float depth = pscDepth(position); - float depth = 200; + float depth = pscDepth(position); vec4 diffuse; vec2 texCoord = vs_st; @@ -75,7 +71,8 @@ void main() //diffuse = vec4(1.0, 0.0, 0.0, 1.0); - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); - -} \ No newline at end of file + Fragment frag; + frag.color = diffuse; + frag.depth = depth; + return frag; +} diff --git a/modules/base/shaders/star_fs.glsl b/modules/base/shaders/star_fs.glsl index d791a21b74..7cac841e20 100644 --- a/modules/base/shaders/star_fs.glsl +++ b/modules/base/shaders/star_fs.glsl @@ -22,7 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ // keep in sync with renderablestars.h:ColorOption enum const int COLOROPTION_COLOR = 0; @@ -42,8 +41,7 @@ in float ge_speed; in vec2 texCoord; in float billboardSize; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" +#include "fragment.glsl" #include "PowerScaling/powerScaling_fs.hglsl" uniform vec2 magnitudeClamp; @@ -56,7 +54,7 @@ vec4 bv2rgb(float bv) { return texture(colorTexture, t); } -void main() { +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 @@ -77,21 +75,17 @@ void main() { vec4 textureColor = texture(psfTexture, texCoord); vec4 fullColor = vec4(color.rgb, textureColor.a); - if (minBillboardSize != 1.0) { - float normSize = (billboardSize - 1.0) / (minBillboardSize - 1.0); - normSize = pow(normSize, 3); - fullColor *= clamp(normSize, 0.0, 1.0); + vec4 position = vs_position; + // This has to be fixed when the scale graph is in place ---emiax + position.w = 19; + + Fragment frag; + frag.color = fullColor; + frag.depth = pscDepth(position); + + if (fullColor.a == 0) { + discard; } - vec4 position = vs_position; - // This has to be fixed when the scale graph is in place ---abock - float depth = pscDepth(position) + 1; - // float depth = 10000.0; - // gl_FragDepth = depth; - - ABufferStruct_t frag = createGeometryFragment(fullColor, position, depth); - addToBuffer(frag); - - if (fullColor.a == 0) - discard; + return frag; } diff --git a/modules/base/shaders/star_ge.glsl b/modules/base/shaders/star_ge.glsl index 252ca50a79..b1d75ce938 100644 --- a/modules/base/shaders/star_ge.glsl +++ b/modules/base/shaders/star_ge.glsl @@ -53,6 +53,7 @@ out float billboardSize; uniform mat4 projection; uniform float scaleFactor; +uniform float minBillboardSize; void main() { if ((psc_position[0].x == 0.0) && (psc_position[0].y == 0.0) && (psc_position[0].z == 0.0)) @@ -68,8 +69,8 @@ void main() { vec4 projPos[4]; for (int i = 0; i < 4; ++i) { - vec4 p1 = gl_in[0].gl_Position; - p1.xy += vec2(modifiedSpriteSize * (corners[i] - vec2(0.5))); + vec4 p1 = gl_in[0].gl_Position; + p1.xy += vec2(modifiedSpriteSize * (corners[i] - vec2(0.5))); projPos[i] = projection * p1; } @@ -82,7 +83,7 @@ void main() { // The billboard is smaller than one pixel, we can discard it vec2 distance = abs(ll - ur); float sizeInPixels = length(distance); - if (sizeInPixels < 5) + if (sizeInPixels < minBillboardSize) return; for(int i = 0; i < 4; i++){ diff --git a/modules/newhorizons/rendering/renderablecrawlingline.cpp b/modules/newhorizons/rendering/renderablecrawlingline.cpp index cfe9d7d6a2..e504d1e615 100644 --- a/modules/newhorizons/rendering/renderablecrawlingline.cpp +++ b/modules/newhorizons/rendering/renderablecrawlingline.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include //#include @@ -76,10 +77,13 @@ bool RenderableCrawlingLine::isReady() const { bool RenderableCrawlingLine::initialize() { _frameCounter = 0; bool completeSuccess = true; - _program = ghoul::opengl::ProgramObject::Build("RenderableCrawlingLine", + + RenderEngine* renderEngine = OsEng.renderEngine(); + _program = renderEngine->buildRenderProgram("RenderableCrawlingLine", "${MODULE_NEWHORIZONS}/shaders/crawlingline_vs.glsl", - "${MODULE_NEWHORIZONS}/shaders/crawlingline_fs.glsl" - ); + "${MODULE_NEWHORIZONS}/shaders/crawlingline_fs.glsl"); + + if (!_program) return false; @@ -103,6 +107,13 @@ bool RenderableCrawlingLine::deinitialize(){ _vao = 0; glDeleteBuffers(1, &_vbo); _vbo = 0; + + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_program) { + renderEngine->removeRenderProgram(_program); + _program = nullptr; + } + return true; } @@ -179,4 +190,4 @@ void RenderableCrawlingLine::update(const UpdateData& data) { } -} \ No newline at end of file +} diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index 51ddcdcc13..5fe679519b 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -125,9 +126,12 @@ RenderableFov::~RenderableFov() { bool RenderableFov::initialize() { bool completeSuccess = true; if (_programObject == nullptr) { - _programObject = ghoul::opengl::ProgramObject::Build("FovProgram", + + RenderEngine* renderEngine = OsEng.renderEngine(); + _programObject = renderEngine->buildRenderProgram("FovProgram", "${MODULE_NEWHORIZONS}/shaders/fov_vs.glsl", "${MODULE_NEWHORIZONS}/shaders/fov_fs.glsl"); + if (!_programObject) return false; } @@ -137,6 +141,12 @@ bool RenderableFov::initialize() { } bool RenderableFov::deinitialize() { + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_programObject) { + renderEngine->removeRenderProgram(_programObject); + _programObject = nullptr; + } + return true; } diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 2214121792..07af002044 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -34,6 +34,7 @@ #include #include +#include #include "imgui.h" #define _USE_MATH_DEFINES @@ -186,9 +187,11 @@ bool RenderableModelProjection::initialize() { bool completeSuccess = true; if (_programObject == nullptr) { - _programObject = ghoul::opengl::ProgramObject::Build("ModelShader", - "${MODULES}/newhorizons/shaders/modelShader_vs.glsl", - "${MODULES}/newhorizons/shaders/modelShader_fs.glsl"); + RenderEngine* renderEngine = OsEng.renderEngine(); + _programObject = renderEngine->buildRenderProgram("ModelShader", + "${MODULES}/newhorizons/shaders/modelShader_vs.glsl", + "${MODULES}/newhorizons/shaders/modelShader_fs.glsl"); + if (!_programObject) return false; } @@ -290,6 +293,12 @@ bool RenderableModelProjection::deinitialize() { glDeleteBuffers(1, &_vbo); + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_programObject) { + renderEngine->removeRenderProgram(_programObject); + _programObject = nullptr; + } + return true; } @@ -527,4 +536,4 @@ void RenderableModelProjection::loadProjectionTexture() { } -} // namespace openspace \ No newline at end of file +} // namespace openspace diff --git a/modules/newhorizons/rendering/renderableplaneprojection.cpp b/modules/newhorizons/rendering/renderableplaneprojection.cpp index d4d335b881..2ead62817b 100644 --- a/modules/newhorizons/rendering/renderableplaneprojection.cpp +++ b/modules/newhorizons/rendering/renderableplaneprojection.cpp @@ -101,7 +101,8 @@ bool RenderablePlaneProjection::initialize() { // Plane program if (_shader == nullptr) { // Image Plane Program - _shader = ghoul::opengl::ProgramObject::Build("ImagePlaneProgram", + RenderEngine* renderEngine = OsEng.renderEngine(); + _shader = renderEngine->buildRenderProgram("Image Plane", "${MODULE_BASE}/shaders/imageplane_vs.glsl", "${MODULE_BASE}/shaders/imageplane_fs.glsl"); if (!_shader) return false; @@ -113,6 +114,12 @@ bool RenderablePlaneProjection::initialize() { } bool RenderablePlaneProjection::deinitialize() { + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_shader) { + renderEngine->removeRenderProgram(_shader); + _shader = nullptr; + } + glDeleteVertexArrays(1, &_quad); _quad = 0; glDeleteBuffers(1, &_vertexPositionBuffer); diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 7f3ee36aa1..5b7773c364 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -236,9 +237,12 @@ bool RenderablePlanetProjection::initialize() { bool completeSuccess = true; if (_programObject == nullptr) { // projection program - _programObject = ghoul::opengl::ProgramObject::Build("projectiveProgram", + + RenderEngine* renderEngine = OsEng.renderEngine(); + _programObject = renderEngine->buildRenderProgram("projectiveProgram", "${MODULES}/newhorizons/shaders/projectiveTexture_vs.glsl", "${MODULES}/newhorizons/shaders/projectiveTexture_fs.glsl"); + if (!_programObject) return false; } @@ -313,6 +317,13 @@ bool RenderablePlanetProjection::deinitialize(){ _textureWhiteSquare = nullptr; delete _geometry; _geometry = nullptr; + + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_programObject) { + renderEngine->removeRenderProgram(_programObject); + _programObject = nullptr; + } + return true; } bool RenderablePlanetProjection::isReady() const { @@ -320,6 +331,9 @@ bool RenderablePlanetProjection::isReady() const { } void RenderablePlanetProjection::imageProjectGPU(){ + + glDisable(GL_DEPTH_TEST); + // keep handle to the current bound FBO GLint defaultFBO; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); @@ -340,7 +354,7 @@ void RenderablePlanetProjection::imageProjectGPU(){ unitFbo.activate(); _textureProj->bind(); _fboProgramObject->setUniform("texture1" , unitFbo); - + ghoul::opengl::TextureUnit unitFbo2; unitFbo2.activate(); _textureOriginal->bind(); @@ -372,13 +386,12 @@ 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){ @@ -542,7 +555,11 @@ void RenderablePlanetProjection::update(const UpdateData& data){ openspace::ImageSequencer2::ref().updateSequencer(_time); _capture = openspace::ImageSequencer2::ref().getImagePaths(_imageTimes, _projecteeID, _instrumentID); } - + + if (_fboProgramObject && _fboProgramObject->isDirty()) { + _fboProgramObject->rebuildFromFile(); + } + // remove these lines if not using queue ------------------------ // @mm //_capture = true; diff --git a/modules/newhorizons/rendering/renderableshadowcylinder.cpp b/modules/newhorizons/rendering/renderableshadowcylinder.cpp index e0cda86132..c4ebba9781 100644 --- a/modules/newhorizons/rendering/renderableshadowcylinder.cpp +++ b/modules/newhorizons/rendering/renderableshadowcylinder.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -91,21 +92,28 @@ bool RenderableShadowCylinder::initialize() { createCylinder(); bool completeSuccess = true; - _shader = ghoul::opengl::ProgramObject::Build("ShadowProgram", - "${MODULE_NEWHORIZONS}/shaders/terminatorshadow_vs.glsl", - "${MODULE_NEWHORIZONS}/shaders/terminatorshadow_fs.glsl"); + + RenderEngine* renderEngine = OsEng.renderEngine(); + _shader = renderEngine->buildRenderProgram("ShadowProgram", + "${MODULE_NEWHORIZONS}/shaders/terminatorshadow_vs.glsl", + "${MODULE_NEWHORIZONS}/shaders/terminatorshadow_fs.glsl"); + if (!_shader) return false; return completeSuccess; } bool RenderableShadowCylinder::deinitialize() { + RenderEngine* renderEngine = OsEng.renderEngine(); + if (_shader) { + renderEngine->removeRenderProgram(_shader); + _shader = nullptr; + } + glDeleteVertexArrays(1, &_vao); _vao = 0; glDeleteBuffers(1, &_vbo); _vbo = 0; - delete _shader; - _shader = nullptr; return true; } @@ -116,6 +124,8 @@ void RenderableShadowCylinder::render(const RenderData& data){ _transform[i][j] = static_cast(_stateMatrix[i][j]); } } + + glDepthMask(false); // Activate shader _shader->activate(); @@ -128,6 +138,8 @@ void RenderableShadowCylinder::render(const RenderData& data){ glBindVertexArray(0); _shader->deactivate(); + + glDepthMask(true); } void RenderableShadowCylinder::update(const UpdateData& data) { diff --git a/modules/newhorizons/shaders/crawlingline_fs.glsl b/modules/newhorizons/shaders/crawlingline_fs.glsl index 71cb6332d1..34fb3b517e 100644 --- a/modules/newhorizons/shaders/crawlingline_fs.glsl +++ b/modules/newhorizons/shaders/crawlingline_fs.glsl @@ -22,8 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - uniform vec4 campos; uniform vec4 objpos; uniform vec3 color; @@ -32,16 +30,17 @@ uniform float _alpha; in vec4 vs_position; in vec4 vs_color; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -void main() { +Fragment getFragment() { vec4 position = vs_position; vec4 diffuse = vs_color; float depth = pscDepth(position); diffuse.a = _alpha; - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); -} \ No newline at end of file + Fragment frag; + frag.color = diffuse; + frag.depth = depth; + return frag; +} diff --git a/modules/newhorizons/shaders/fov_fs.glsl b/modules/newhorizons/shaders/fov_fs.glsl index 61631f3e77..b237b7be71 100644 --- a/modules/newhorizons/shaders/fov_fs.glsl +++ b/modules/newhorizons/shaders/fov_fs.glsl @@ -22,8 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - uniform mat4 ViewProjection; uniform mat4 ModelTransform; @@ -33,12 +31,10 @@ in vec4 vs_point_velocity; //out vec4 diffuse; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -void main() -{ +Fragment getFragment() { vec4 position = vs_point_position; float depth = pscDepth(position); @@ -50,7 +46,8 @@ void main() vec4 diffuse = vs_point_velocity; - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); - -} \ No newline at end of file + Fragment frag; + frag.color = diffuse; + frag.depth = depth; + return frag; +} diff --git a/modules/newhorizons/shaders/modelShader_fs.glsl b/modules/newhorizons/shaders/modelShader_fs.glsl index 12a513c725..7221adadf9 100644 --- a/modules/newhorizons/shaders/modelShader_fs.glsl +++ b/modules/newhorizons/shaders/modelShader_fs.glsl @@ -22,8 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - uniform vec4 campos; uniform vec4 objpos; uniform vec3 camdir; @@ -41,13 +39,10 @@ in vec4 ProjTexCoord; uniform vec3 boresight; uniform vec3 sun_pos; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -//#include "PowerScaling/powerScaling_vs.hglsl" -void main() -{ +Fragment getFragment() { vec4 position = vs_position; float depth = pscDepth(position); vec4 diffuse = texture(currentTexture, vs_st); @@ -89,8 +84,8 @@ void main() diffuse = shaded; } - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); - + Fragment frag; + frag.color = diffuse; + frag.depth = depth; + return frag; } - diff --git a/modules/newhorizons/shaders/projectiveTexture_fs.glsl b/modules/newhorizons/shaders/projectiveTexture_fs.glsl index 6f34a71974..1c2195e69c 100644 --- a/modules/newhorizons/shaders/projectiveTexture_fs.glsl +++ b/modules/newhorizons/shaders/projectiveTexture_fs.glsl @@ -22,8 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - uniform vec4 campos; uniform vec4 objpos; //uniform vec3 camdir; // add this for specular @@ -41,17 +39,14 @@ in vec4 ProjTexCoord; uniform vec3 boresight; uniform vec3 sun_pos; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -//#include "PowerScaling/powerScaling_vs.hglsl" -void main() -{ +Fragment getFragment() { vec4 position = vs_position; float depth = pscDepth(position); vec4 diffuse = texture(texture1, vs_st); - + // directional lighting vec3 origin = vec3(0.0); vec4 spec = vec4(0.0); @@ -81,20 +76,21 @@ void main() // 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; - } - - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); + 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.depth = depth; + //frag.color = vec4(vs_st, 0.0, 1.0); + return frag; } - diff --git a/modules/newhorizons/shaders/terminatorshadow_fs.glsl b/modules/newhorizons/shaders/terminatorshadow_fs.glsl index 6fcfc4d90c..967e1ad03e 100644 --- a/modules/newhorizons/shaders/terminatorshadow_fs.glsl +++ b/modules/newhorizons/shaders/terminatorshadow_fs.glsl @@ -22,8 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - in vec4 vs_point_position; in vec4 vs_point_velocity; //in float fade; @@ -33,15 +31,16 @@ uniform vec3 color; in vec4 vs_color; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -void main() { +Fragment getFragment() { vec4 position = vs_point_position; float depth = pscDepth(position); - vec4 c = vs_color; - ABufferStruct_t frag = createGeometryFragment(c, position, depth); - addToBuffer(frag); -} \ No newline at end of file + Fragment frag; + frag.color = vs_color; + frag.depth = depth; + + return frag; +} diff --git a/openspace.cfg b/openspace.cfg index cad9aaf1f8..194b370051 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -55,5 +55,5 @@ return { File = "${BASE_PATH}/Properties.txt" }, DownloadRequestURL = "http://openspace.itn.liu.se/request.cgi", - -- RenderingMethod = "ABufferFrameBuffer" + RenderingMethod = "ABuffer" } \ No newline at end of file diff --git a/scripts/bind_keys.lua b/scripts/bind_keys.lua index 8d40c3df9e..d173ab32a4 100644 --- a/scripts/bind_keys.lua +++ b/scripts/bind_keys.lua @@ -99,4 +99,8 @@ openspace.bindKey("p", "local b = openspace.getPropertyValue('Callisto.renderabl 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("c", "openspace.parallel.setAddress('130.236.142.51');openspace.parallel.setPassword('newhorizons-20150714');openspace.parallel.connect();") \ No newline at end of file +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/shaders/ABuffer/abufferAddToBuffer.hglsl b/shaders/ABuffer/abufferAddToBuffer.hglsl deleted file mode 100644 index 2a3e658130..0000000000 --- a/shaders/ABuffer/abufferAddToBuffer.hglsl +++ /dev/null @@ -1,160 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014 * - * * - * 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. * - ****************************************************************************************/ - -#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED -layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; -layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; -layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; -#endif - -#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED -layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; -layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; - - #define _MAX_LAYERS_ MAX_LAYERS - #define _SCREEN_WIDTH_ SCREEN_WIDTH - #define _SCREEN_HEIGHT_ SCREEN_HEIGHT -#endif - -layout(location = 0) out vec4 framebuffer_output_color; - -ABufferStruct_t createGeometryFragment(vec4 fragColor, vec4 position) { - ABufferStruct_t frag; - _col_(frag, fragColor); - _z_(frag, gl_FragCoord.z); - _type_(frag, 0); - _pos_(frag, position); - return frag; -} - -ABufferStruct_t createGeometryFragment(vec4 fragColor, vec4 position, float z) { - ABufferStruct_t frag; - _col_(frag, fragColor); - _z_(frag, z); - _type_(frag, 0); - _pos_(frag, position); - return frag; -} - -void addToBuffer(ABufferStruct_t frag) { -#if ABUFFER_IMPLEMENTATION == ABUFFER_FRAMEBUFFER - framebuffer_output_color = _col_(frag); - gl_FragDepth = _z_(frag); -#endif - -#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED - -#ifdef ABUFFER_INCLUDE_POSITION - uint index = atomicCounterIncrement(atomicCounterBuffer); - index *= 2; - uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); - _next_(frag,old_head); - uvec4 p1 = uvec4(frag.z, frag.id, frag.rg, frag.ba); - uvec4 p2 = uvec4(floatBitsToUint(frag.position.x),floatBitsToUint(frag.position.y),floatBitsToUint(frag.position.z),floatBitsToUint(frag.position.w)); - imageStore(fragmentTexture, int(index), p1); - imageStore(fragmentTexture, int(index+1), p2); -#else - uint index = atomicCounterIncrement(atomicCounterBuffer); - uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); - _next_(frag,old_head); - uvec4 p1 = uvec4(frag.z, frag.id, frag.rg, frag.ba); - imageStore(fragmentTexture, int(index), p1); -#endif - discard; -#endif - -#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED - -#ifdef ABUFFER_INCLUDE_POSITION - uint index = imageAtomicAdd(anchorPointerTexture, ivec2(gl_FragCoord.xy), 1); - if(index < _MAX_LAYERS_) { - int offset = (int(gl_FragCoord.y) * _SCREEN_WIDTH_ + int(gl_FragCoord.x))*_MAX_LAYERS_ + int(index)*2; - - uvec4 p1 = uvec4(frag.z, frag.id, frag.rg, frag.ba); - uvec4 p2 = uvec4(floatBitsToUint(frag.position.x),floatBitsToUint(frag.position.y),floatBitsToUint(frag.position.z),floatBitsToUint(frag.position.w)); - - imageStore(fragmentTexture, int(offset), p1); - imageStore(fragmentTexture, int(offset+1), p2); - } else { - imageAtomicAdd(anchorPointerTexture, ivec2(gl_FragCoord.xy), -1); - } - -#else - uint index = imageAtomicAdd(anchorPointerTexture, ivec2(gl_FragCoord.xy), 1); - if(index < _MAX_LAYERS_) { - int offset = (int(gl_FragCoord.y) * _SCREEN_WIDTH_ + int(gl_FragCoord.x))*_MAX_LAYERS_ + int(index); - uvec4 p1 = uvec4(frag.z, frag.id, frag.rg, frag.ba); - imageStore(fragmentTexture, int(offset), p1); - } else { - imageAtomicAdd(anchorPointerTexture, ivec2(gl_FragCoord.xy), -1); - } -#endif - discard; - -#endif -} - -ABufferStruct_t loadFromBuffer(uint id) { - -#ifdef ABUFFER_INCLUDE_POSITION -#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED - uvec4 u1 = imageLoad(fragmentTexture, int(id)); - uvec4 u2 = imageLoad(fragmentTexture, int(id+1)); -#endif - -#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED - int offset = (int(gl_FragCoord.y) * _SCREEN_WIDTH_ + int(gl_FragCoord.x))*_MAX_LAYERS_ + int(id); - uvec4 u1 = imageLoad(fragmentTexture, int(offset)); - uvec4 u2 = imageLoad(fragmentTexture, int(offset+1)); -#endif - -#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED || ABUFFER_IMPLEMENTATION == ABUFFER_FIXED - vec4 position = vec4( uintBitsToFloat(u2.x), - uintBitsToFloat(u2.y), - uintBitsToFloat(u2.z), - uintBitsToFloat(u2.w)); - - return ABufferStruct_t(u1.x, u1.y, u1.z, u1.w, position); -#endif -#else -#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED - uvec4 u1 = imageLoad(fragmentTexture, int(id)); - //uvec4 u2 = imageLoad(fragmentTexture, int(id+1)); -#endif - -#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED - int offset = (int(gl_FragCoord.y) * _SCREEN_WIDTH_ + int(gl_FragCoord.x))*_MAX_LAYERS_ + int(id); - uvec4 u1 = imageLoad(fragmentTexture, int(offset)); - //uvec4 u2 = imageLoad(fragmentTexture, int(offset+1)); -#endif - -#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED || ABUFFER_IMPLEMENTATION == ABUFFER_FIXED - return ABufferStruct_t(u1.x, u1.y, u1.z, u1.w); -#endif -#endif - - ABufferStruct_t frag; - return frag; - -} diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl deleted file mode 100644 index c03ef9039d..0000000000 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ /dev/null @@ -1,322 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014 * - * * - * 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__ - -// ================================================================================ -// Settings -// ================================================================================ -//#pragma openspace insert SETTINGS -//#include <${SHADERS_GENERATED}/ABufferSettings.hglsl>:notrack - -// Select type of depth calculations -#define PSCDEPTH 1 -#define ZDEPTH 2 -#define ZTYPE ZDEPTH - -// Maximum number of fragments -#ifdef MAX_LAYERS -#define MAX_FRAGMENTS MAX_LAYERS -#else -#define MAX_FRAGMENTS 16 // The size of the local fragment list -#endif -// #define VISUALIZE_TRANSFERFUNCTIONS // -#define USE_JITTERING // -// #define USE_COLORNORMALIZATION // - -// If you need to render a volume box but not sample the volume (debug purpose) -// #define SKIP_VOLUME_0 -// #define SKIP_VOLUME_1 -// #define SKIP_VOLUME_2 -// #define SKIP_VOLUME_3 - -// constants -const float stepSize = 0.01; -const float samplingRate = 1.0; -uniform float ALPHA_LIMIT = 0.7; - -uniform float blackoutFactor = 0.0; - - -// Math defintions -#define M_E 2.7182818284590452354 -#define M_LOG2E 1.4426950408889634074 /* log_2 e */ -#define M_LOG10E 0.43429448190325182765 /* log_10 e */ -#define M_LN2 0.69314718055994530942 /* log_e 2 */ -#define M_LN10 2.30258509299404568402 /* log_e 10 */ -#define M_PI 3.14159265358979323846 /* pi */ -#define M_PI_2 1.57079632679489661923 /* pi/2 */ -#define M_PI_4 0.78539816339744830962 /* pi/4 */ -#define M_1_PI 0.31830988618379067154 /* 1/pi */ -#define M_2_PI 0.63661977236758134308 /* 2/pi */ -#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ -#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ -#define M_SQRT1_3 0.57735026919 /* 1/sqrt(3) */ - -in vec2 texCoord; -out vec4 out_color; - -// ================================================================================ -// Headers, -// volume and transferfunctions uniforms -// ================================================================================ -//#pragma openspace insert HEADERS -#include <${SHADERS_GENERATED}/ABufferHeaders.hglsl>:notrack - -// ================================================================================ -// The ABuffer specific includes and definitions -// ================================================================================ -#include "abufferStruct.hglsl" -ABufferStruct_t fragments[MAX_FRAGMENTS]; - -#if MAX_VOLUMES > 0 - vec3 volume_direction[MAX_VOLUMES]; - float volume_length[MAX_VOLUMES]; - vec3 volume_position[MAX_VOLUMES]; - int volumes_in_fragment[MAX_VOLUMES]; - int volume_count = 0; - - #if ZTYPE == ZDEPTH - vec2 volume_zlength[MAX_VOLUMES]; - #elif ZTYPE == PSCDEPTH - float volume_zlength[MAX_VOLUMES]; - #endif -#endif -#include "abufferSort.hglsl" - -// ================================================================================ -// Helper functions functions -// ================================================================================ -vec3 CartesianToSpherical(vec3 _cartesian) { - // Put cartesian in [-1..1] range first - vec3 cartesian = vec3(-1.0,-1.0,-1.0) + _cartesian * 2.0f; - - float r = length(cartesian); - float theta, phi; - - if (r == 0.0) { - theta = phi = 0.0; - } else { - theta = acos(cartesian.z/r) / M_PI; - phi = (M_PI + atan(cartesian.y, cartesian.x)) / (2.0*M_PI ); - } - r *= M_SQRT1_3; - // r = r / sqrt(3.0f); - - // Sampler ignores w component - return vec3(r, theta, phi); -} - -vec4 blend(vec4 src, vec4 dst) { - #if 0 - vec4 o; - o.a = src.a + dst.a * (1.0f - src.a); - o.rgb = (src.rgb*src.a + dst.rgb*dst.a* (1.0f - src.a)); - return o; - #else - return mix(src, dst, dst.a*(1.0f - src.a)); - #endif -} - -void blendStep(inout vec4 dst, in vec4 src, in float stepSize) { - src.a = 1.0 - pow(1.0 - src.a, stepSize ); - // src.a = 1.0 -(1.0 - src.a*stepSize); - dst.rgb = dst.rgb + (1.0 - dst.a) * src.a * src.rgb; - dst.a = dst.a + (1.0 -dst.a) * src.a; -} - -float volumeRaycastingDistance(in int id, in ABufferStruct_t startFrag, in ABufferStruct_t endFrag) { -#if MAX_VOLUMES > 0 -#if ZTYPE == ZDEPTH - const float S1 = volume_zlength[id].x; - const float S2 = volume_zlength[id].y; - const float L = S1 - S2; - // const float z1 = globz(_z_(startFrag)); - // const float z2 = globz(_z_(endFrag)); - const float z1 = _z_(startFrag); - const float z2 = _z_(endFrag); - return ((z1 - S1) / L - (z2 - S1) / L) * volume_length[id]; -#elif ZTYPE == PSCDEPTH - const float L = volume_zlength[id]; - const vec4 p1 = _pos_(startFrag); - const vec4 p2 = _pos_(endFrag); - const float dist = pscLength(p1, p2); - // const float z1 = _z_(startFrag); - // const float z2 = _z_(endFrag); - return (dist / L) * volume_length[id]; -#endif -#else - return 0.f; -#endif -} - -vec4 calculate_final_color(uint frag_count) { - // volumeStepSize[volID] = 0.01; - int currentVolumeBitmask = 0; - vec4 final_color = vec4(0); - - if(frag_count == 1 && _type_(fragments[0]) == 0) { - final_color = blend(final_color, _col_(fragments[0])); - return final_color; - } - - int frag_count_1 = int(frag_count)-1; - for(int i = 0; i < frag_count_1 && final_color.a < ALPHA_LIMIT; i++) { - - ABufferStruct_t startFrag = fragments[i]; - ABufferStruct_t endFrag = fragments[i+1]; - int type = int(_type_(startFrag)); - - if(type == 0) { - //blendStep(final_color, _col_(startFrag), stepSize); - final_color = blend(final_color, _col_(startFrag)); - } else { - currentVolumeBitmask = currentVolumeBitmask ^ (1 << (type-1)); - } - - -#if MAX_VOLUMES > 0 - if(currentVolumeBitmask > 0) { - - - int volID; - float myMaxSteps = 0.0000001; - if(volume_count > 1) { - for(int v = 0; v < volume_count; ++v) { - int vol = volumes_in_fragment[v]; - float l = volumeRaycastingDistance(vol, startFrag, endFrag); - myMaxSteps = max(myMaxSteps, l/volumeStepSizeOriginal[vol]); - } - - for(int v = 0; v < volume_count; ++v) { - int vol = volumes_in_fragment[v]; - float l = volumeRaycastingDistance(vol, startFrag, endFrag); - float aaa = l/myMaxSteps; - volumeStepSize[vol] = aaa; - volID = vol; - } - } else { - volID = type -1; - } - - float l = volumeRaycastingDistance(volID, startFrag, endFrag); - int max_iterations = int(l / volumeStepSize[volID]); - - // TransferFunction - vec4 color = vec4(0); - for(int k = 0; k < max_iterations && final_color.a < ALPHA_LIMIT && k < LOOP_LIMIT; ++k) { - -// #pragma openspace insert SAMPLERCALLS -#include <${SHADERS_GENERATED}/ABufferSamplerCalls.hglsl>:notrack - - - - - - } - - } -#endif - - - - - //blendGeometry(final_color, startFrag); - //if(i == maxFrags -1 && _type_(endFrag) == 0) - // blendGeometry(final_color, endFrag); - - // final_color = blend(final_color, frag_color); - if(i == frag_count_1 -1 && _type_(endFrag) == 0) - // if(i == frag_count_1 -1) - final_color = blend(final_color, _col_(endFrag)); - - } - // final_color = vec4(0); - // int id =3; - // if(id < frag_count)final_color = blend(final_color, _col_(fragments[id])); - - // if(frag_count > 0) - // final_color = _col_(fragments[0]); - -// ================================================================================ -// Transferfunction visualizer -// ================================================================================ -#ifdef VISUALIZE_TRANSFERFUNCTIONS -// #pragma openspace insert TRANSFERFUNC -#include <${SHADERS_GENERATED}/ABufferTransferFunctionVisualizer.hglsl>:notrack -#endif - - - - - // if(frag_count == 0) { - // final_color = vec4(0.5,0.5,0.5,1.0); - // } else if(frag_count == 1) { - // final_color = vec4(1.0,0.0,0.0,1.0); - // } else if(frag_count == 2) { - // final_color = vec4(0.0,1.0,0.0,1.0); - // // final_color = vec4(volume_direction[0],1.0); - // } else if(frag_count == 3) { - // final_color = vec4(0.0,0.0,1.0,1.0); - // // final_color = vec4(volume_direction[0],1.0); - // } else if(frag_count == 4) { - // final_color = vec4(1.0,1.0,0.0,1.0); - // // final_color = vec4(volume_direction[0],1.0); - // } else { - // final_color = vec4(1.0,1.0,1.0,1.0); - // } - - // if(frag_count > 12) { - // final_color = vec4(1.0,0.0,1.0,1.0); - // } - - -#ifdef USE_COLORNORMALIZATION - final_color.rgb = final_color.rgb * final_color.a; - final_color.a = 1.0; -#endif - - return final_color; - -} - -// ================================================================================ -// Main function -// ================================================================================ -void main() { - out_color = vec4(texCoord,0.0,1.0); - int frag_count = build_local_fragments_list(); - sort_fragments_list(frag_count); - out_color = blackoutFactor * calculate_final_color(frag_count); -} - -// ================================================================================ -// The samplers implementations -// ================================================================================ -//#pragma openspace insert SAMPLERS -#include <${SHADERS_GENERATED}/ABufferSamplers.hglsl>:notrack - - - diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl deleted file mode 100644 index 8be2180e0a..0000000000 --- a/shaders/ABuffer/abufferSort.hglsl +++ /dev/null @@ -1,144 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014 * - * * - * 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 "abufferAddToBuffer.hglsl" - -uniform float volumeStepFactor = 1.0f; - -int build_local_fragments_list() { - -#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED - uint current; - int frag_count = 0; - - current = imageLoad(anchorPointerTexture, ivec2(gl_FragCoord.xy)).x; - - while(current != 0 && frag_count < MAX_FRAGMENTS) { - ABufferStruct_t item = loadFromBuffer(current); - current = _next_(item); - - fragments[frag_count] = item; - - frag_count++; - } - - return frag_count; -#endif - -#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED - uint frag_count = imageLoad(anchorPointerTexture, ivec2(gl_FragCoord.xy)).x; - - int i; - for(i = 0; i < frag_count && i < MAX_FRAGMENTS; ++i) { - fragments[i] = loadFromBuffer(i); - } - - return int(frag_count); -#endif - -// #if ABUFFER_IMPLEMENTATION == ABUFFER_FRAMEBUFFER - return 0; -// #endif -} - -float pscLength(vec4 v1, vec4 v2) { - const float k = 10.0; - float ds = v2.w - v1.w; - vec4 vector; - if(ds >= 0) { - float p = pow(k,-ds); - vector = vec4(v1.x*p - v2.x, v1.y*p - v2.y, v1.z*p - v2.z, v2.w); - } else { - float p = pow(k,ds); - vector = vec4(v1.x - v2.x*p, v1.y - v2.y*p, v1.z - v2.z*p, v1.w); - } - return length(vector.xyz)*pow(k,vector.w); -} - -float permute(float i) { - return mod((62.0*i*i + i), 961.0); // permutation polynomial; 62=2*31; 961=31*31 -} - -void sort_fragments_list(uint frag_count) { - uint i,j; - ABufferStruct_t tmp; - - // INSERTION SORT - for(i = 1; i < frag_count; ++i) { - tmp = fragments[i]; - for(j = i; j > 0 && _z_(tmp) < _z_(fragments[j-1]); --j) { - fragments[j] = fragments[j-1]; - } - fragments[j] = tmp; - } - -#if MAX_VOLUMES > 0 - int ii, jj; - for(ii = 0; ii < MAX_VOLUMES; ++ii) { - bool start = true; - vec3 startColor; - vec4 startPosition; - for(jj = 0; jj < frag_count; ++jj) { - int type = int(_type_(fragments[jj])) - 1; - if(type== ii) { - if(start) { - startColor = _col_(fragments[jj]).rgb; - startPosition = _pos_(fragments[jj]); -#if ZTYPE == ZDEPTH - volume_zlength[ii].x = _z_(fragments[jj]); -#endif - start = false; - } else { - volumes_in_fragment[volume_count++] = ii; - vec3 dir = _col_(fragments[jj]).rgb - startColor; - volume_position[ii] = startColor; - volume_length[ii] = length(dir); - volume_direction[ii] = normalize(dir); - volumeStepSize[ii] = 1.0/(volumeStepFactor * length(volume_direction[ii]*volume_dim[ii])); - volumeStepSizeOriginal[ii] = volumeStepSize[ii]; -#if ZTYPE == ZDEPTH - volume_zlength[ii].y = _z_(fragments[jj]); -#elif ZTYPE == PSCDEPTH - volume_zlength[ii] = pscLength(_pos_(fragments[jj]), startPosition); -#endif -#ifdef USE_JITTERING - if(volumeStepSize[ii] < volume_length[ii]) { - // jittering - float x = gl_FragCoord.x; - float y = gl_FragCoord.y; - float jitterValue = float(permute(x + permute(y))) / 961.0; - vec3 frontPosNew = startColor + (jitterValue*volumeStepSize[ii])*volume_direction[ii]; - volume_position[ii] = frontPosNew; - } -#endif - - break; - } - } - } - } -#endif - //volume_direction[0] = vec3(1.0,0.0,0.0); - //volume_direction[0] = _col_(fragments[0]).rgb; -} diff --git a/shaders/ABuffer/abufferStruct.hglsl b/shaders/ABuffer/abufferStruct.hglsl deleted file mode 100644 index ce17dffd94..0000000000 --- a/shaders/ABuffer/abufferStruct.hglsl +++ /dev/null @@ -1,166 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014 * - * * - * 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 ABUFFERSTRUCT_H_HGLSL -#define ABUFFERSTRUCT_H_HGLSL - -#include <${SHADERS_GENERATED}/constants.hglsl>:notrack - -#define ABUFFER_INCLUDE_POSITION - -//======================================================================================== -// ABufferStruct_t declaration -//======================================================================================== -// struct ABufferStruct_t { -// uint z; // the depth value -// uint id; // bits 0-28 next, bits 29-32 type -// vec4 color; // packed rgba -// //vec4 position; // packed position -// // uint padding1; -// // uint padding2; -// }; -struct ABufferStruct_t { - uint z; // the depth value - uint id; // bits 0-28 next, bits 29-32 type - uint rg; // packed red green color - uint ba; // packed blue alpha color -#ifdef ABUFFER_INCLUDE_POSITION - vec4 position; // position -#endif -}; - - -//======================================================================================== -// Bitwise operations -//======================================================================================== -#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED -const uint mask_1 = uint(1); -const uint mask_8 = uint(255); -const uint mask_16 = uint(65535); -const uint mask_24 = uint(16777215); -const uint mask_29 = uint(536870911); -const uint mask_30 = uint(1073741823); -const uint mask_31 = uint(2147483647); -const uint mask_32 = uint(4294967295); -const uint mask_id = mask_16; -const uint shift_id = 0; -const uint mask_type = mask_24 - mask_16; -const uint shift_type = 16; -/* -const uint mask_zid_z = mask_24; -const uint shift_zid_z = 0; -const uint mask_zid_id = mask_29 - mask_24; -const uint shift_zid_id = 24; -const uint mask_zid_type = mask_31 - mask_29; -const uint shift_zid_type = 29; -const uint mask_zid_xxx = mask_32 - mask_31; -const uint shift_zid_xxx = 31; -*/ - -const uint mask_id_next = mask_29; -const uint shift_id_next = 0; -const uint mask_id_type = mask_32 - mask_29; -const uint shift_id_type = 29; -#endif - -void bitinsert_u(inout uint pack, uint val, uint mask, uint shift) { - pack &= ~mask; - pack |= (val << shift) & mask; -} -uint bitextract_u(in uint pack, uint mask, uint shift) { - return (pack >> shift) & (mask >> shift); -} -void bitinsert_i(inout int pack, int val, uint mask, uint shift) { - pack &= int( ~mask ); - pack |= int( (uint(val) << shift) & mask ); -} -int bitextract_i(in int pack, uint mask, uint shift) { - return int( (uint(pack) >> shift) & (mask >> shift) ); -} - -//======================================================================================== -// Access functions -//======================================================================================== -float _z_(ABufferStruct_t frag) { - return uintBitsToFloat(frag.z); -} -void _z_(inout ABufferStruct_t frag, float z) { - frag.z = floatBitsToUint(z); -} - -vec4 _pos_(ABufferStruct_t frag) { -#ifdef ABUFFER_INCLUDE_POSITION - return frag.position; -#else - return vec4(0.0,0.0,0.0,0.0); -#endif -} -void _pos_(inout ABufferStruct_t frag, vec4 position) { -#ifdef ABUFFER_INCLUDE_POSITION - frag.position = position; -#endif -} - -vec4 _col_(ABufferStruct_t frag) { - return vec4(unpackUnorm2x16(frag.rg),unpackUnorm2x16(frag.ba)); - //return unpackUnorm4x8(frag.color); -} -void _col_(inout ABufferStruct_t frag, vec4 color) { - frag.rg = packUnorm2x16(color.rg); - frag.ba = packUnorm2x16(color.ba); - //frag.color = packUnorm4x8(color); -} - -uint _type_(ABufferStruct_t frag) { -#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED - return bitextract_u(frag.id, mask_id_type, shift_id_type); -#else - return frag.id; -#endif -} -void _type_(inout ABufferStruct_t frag, uint type) { -#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED - bitinsert_u(frag.id, type, mask_id_type, shift_id_type); -#else - frag.id = type; -#endif -} - -//======================================================================================== -// Implementation specific functions -//======================================================================================== - -// _next_ is only needed for the single linked implementation -#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED -uint _next_(ABufferStruct_t frag) { - return bitextract_u(frag.id, mask_id_next, shift_id_next); - //return frag.id; -} -void _next_(inout ABufferStruct_t frag, uint id) { - bitinsert_u(frag.id, id, mask_id_next, shift_id_next); - //frag.id = id; -} -#endif - -#endif \ No newline at end of file diff --git a/shaders/PowerScaling/powerScalingMath.hglsl b/shaders/PowerScaling/powerScalingMath.hglsl index 583ff34f36..9c72f299e3 100644 --- a/shaders/PowerScaling/powerScalingMath.hglsl +++ b/shaders/PowerScaling/powerScalingMath.hglsl @@ -25,6 +25,7 @@ #ifndef POWERSCALING_MATH_HGLSL #define POWERSCALING_MATH_HGLSL + const float k = 10.0; const float FLT_MAX = 1e38; // Not max but large enough for the purpose @@ -51,6 +52,28 @@ vec4 psc_addition(vec4 v1, vec4 v2) { } } +vec4 psc_subtraction(vec4 v1, vec4 v2) { + vec4 negV2 = vec4(-v2.xyz, v2.w); + return psc_addition(v1, negV2); +} + +vec2 psc_addition(vec2 v1, vec2 v2) { + float ds = v2.y - v1.y; + if(ds >= 0) { + float p = pow(k,-ds); + return vec2(v1.x*p + v2.x, v2.y); + } else { + float p = pow(k,ds); + return vec2(v1.x + v2.x*p, v1.y); + } +} + +vec2 psc_subtraction(vec2 v1, vec2 v2) { + vec2 negV2 = vec2(-v2.x, v2.y); + return psc_addition(v1, negV2); +} + + vec4 z_normalization(vec4 v_in) { vec4 v_out = v_in; if(v_out.z > 0.0) { @@ -65,4 +88,4 @@ vec4 z_normalization(vec4 v_in) { return v_out; } -#endif \ No newline at end of file +#endif diff --git a/shaders/PowerScaling/powerScaling_fs.hglsl b/shaders/PowerScaling/powerScaling_fs.hglsl index 9841ea5f28..2971be8d6a 100644 --- a/shaders/PowerScaling/powerScaling_fs.hglsl +++ b/shaders/PowerScaling/powerScaling_fs.hglsl @@ -27,7 +27,7 @@ // Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD! -const float k = 10.0; +#include "powerScalingMath.hglsl" const float s_far = 27.0f; //= gl_DepthRange.far; // 40 const float s_farcutoff = 12.0f; @@ -48,46 +48,10 @@ vec4 psc_normlization(vec4 invec) { } float pscDepth(vec4 position) { - float depth = 0.0f; - if(position.w <= 0.5) { - //depth = abs(position.z * pow(10, position.w)) / pow(k,s_far); - depth = (position.w+log(abs(position.z)))/pow(k, position.w); - } else if(position.w < 3.0) { - depth = position.w+log(abs(position.z))/pow(k, position.w); - } else { - depth = position.w+log(abs(position.z)); - } - depth = (position.w+log(abs(position.z)))/pow(k, position.w); - // depth = (position.w+log(abs(position.z)))/pow(k, position.w); - - // DEBUG - float depth_orig = depth; - float x = 0.0f; - float cutoffs = 0.0; - float orig_z = position.z; - - // calculate a normalized depth [0.0 1.0] - if((depth > s_near && depth <= s_nearcutoff) || (depth > s_farcutoff && depth < s_far)) { - - // completely linear interpolation [s_near .. depth .. s_far] - depth = (depth - s_near) / (s_far - s_near); - - } else if(depth > s_nearcutoff && depth < s_farcutoff) { - - // DEBUG - cutoffs = 1.0; - - // interpolate [10^s_nearcutoff .. 10^depth .. 10^s_farcutoff] - // calculate between 0..1 where the depth is - x = (pow(10,depth) - pow(10, s_nearcutoff)) / (pow(10,s_farcutoff) - pow(10, s_nearcutoff)); - - // remap the depth to the 0..1 depth buffer - depth = s_nearcutoff + x * (s_farcutoff - s_nearcutoff); - depth = (depth - s_near) / (s_far - s_near); - - } - // return 1.0; - return depth; + // 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; } -#endif \ No newline at end of file + +#endif diff --git a/shaders/abuffer/abufferfragment.glsl b/shaders/abuffer/abufferfragment.glsl new file mode 100644 index 0000000000..77c68cc87d --- /dev/null +++ b/shaders/abuffer/abufferfragment.glsl @@ -0,0 +1,155 @@ +/***************************************************************************************** + * * + * 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 _ABUFFERFRAGMENT_GLSL_ +#define _ABUFFERFRAGMENT_GLSL_ + +struct ABufferFragment { + uint rgba; + uint depth; + uint data; + uint composition; +}; + +// Values stored in abuffer: +// -------RGBA-------- +// r 8 bits +// g 8 bits +// b 8 bits +// a 8 bits +// -------DEPTH------- +// depth 32 bits +// -------DATA-------- +// type 8 bits 0: geometry, >0: volume, <0: reserved +// msaa 8 bits +// reserved 16 bits +// ----COMPOSITION---- +// reserved 4 bits (may be suitable for blend modes) +// next 28 bits +// ------------------- +// in total: 16 + 4 = 20 reserved bits for future use. + +const uint mask_1 = uint(1); +const uint mask_8 = uint(255); +const uint mask_16 = uint(65535); +const uint mask_24 = uint(16777215); +const uint mask_28 = uint(268435455); +const uint mask_31 = uint(2147483647); +const uint mask_32 = uint(4294967295); + +const uint mask_type = mask_32 - mask_24; +const uint shift_type = 24; + +const uint mask_msaa = mask_24 - mask_16; +const uint shift_msaa = 16; + +const uint mask_blend = mask_32 - mask_31; +const uint shift_blend = 31; + +const uint mask_next = mask_28; +const uint shift_next = 0; + +void bitinsert(inout uint pack, uint val, uint mask, uint shift) { + pack &= ~mask; + pack |= (val << shift) & mask; +} +uint bitextract(in uint pack, uint mask, uint shift) { + return (pack >> shift) & (mask >> shift); +} + +/** + * Color + */ +void _color_(inout ABufferFragment frag, vec4 color) { + frag.rgba = packUnorm4x8(color); +} + +vec4 _color_(ABufferFragment frag) { + return unpackUnorm4x8(frag.rgba); +} + +/** + * Depth + */ +void _depth_(inout ABufferFragment frag, float depth) { + frag.depth = floatBitsToUint(depth); +} + +float _depth_(ABufferFragment frag) { + return uintBitsToFloat(frag.depth); +} + +/** + * Type + */ +void _type_(inout ABufferFragment frag, int type) { + uint val = uint(type); + bitinsert(frag.data, val, mask_type, shift_type); +} + +int _type_(ABufferFragment frag) { + uint val = bitextract(frag.data, mask_type, shift_type); + return int(val); +} + +/** + * Msaa + */ +void _msaa_(inout ABufferFragment frag, int type) { + uint val = uint(type); + bitinsert(frag.data, val, mask_msaa, shift_msaa); +} + +int _msaa_(ABufferFragment frag) { + uint val = bitextract(frag.data, mask_msaa, shift_msaa); + return int(val); +} + +/** + * Next + */ +void _next_(inout ABufferFragment frag, uint val) { + bitinsert(frag.composition, val, mask_next, shift_next); +} + +uint _next_(ABufferFragment frag) { + uint val = bitextract(frag.composition, mask_next, shift_next); + return val; +} + +/** + * Raw data + */ +void _raw_(inout ABufferFragment frag, uvec4 raw) { + frag.rgba = raw.x; + frag.depth = raw.y; + frag.data = raw.z; + frag.composition = raw.w; +} + +uvec4 _raw_(inout ABufferFragment frag) { + return uvec4(frag.rgba, frag.depth, frag.data, frag.composition); +} + +#endif diff --git a/shaders/abuffer/abufferresources.glsl b/shaders/abuffer/abufferresources.glsl new file mode 100644 index 0000000000..cea67bb69a --- /dev/null +++ b/shaders/abuffer/abufferresources.glsl @@ -0,0 +1,68 @@ +/***************************************************************************************** + * * + * 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 _ABUFFERRESOURCES_GLSL_ +#define _ABUFFERRESOURCES_GLSL_ + +#define MAX_LAYERS #{rendererData.maxLayers} + +#include "abufferfragment.glsl" + +layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; +layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; +layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; + +ABufferFragment fragments[MAX_LAYERS]; +uint indices[MAX_LAYERS]; +const uint NULL_POINTER = 0; + +void storeFragment(uint index, ABufferFragment aBufferFrag) { + imageStore(fragmentTexture, int(index), _raw_(aBufferFrag)); +} + +ABufferFragment loadFragment(uint index) { + uvec4 raw = imageLoad(fragmentTexture, int(index)); + ABufferFragment aBufferFragment; + _raw_(aBufferFragment, raw); + return aBufferFragment; +} + +/** + * Load fragments into the #fragments array. + * Also set #indices to the used indices. + */ +uint loadFragments() { + uint currentIndex = imageLoad(anchorPointerTexture, ivec2(gl_FragCoord.xy)).x; + int nFrags = 0; + while (currentIndex != NULL_POINTER && nFrags < MAX_LAYERS) { + ABufferFragment frag = loadFragment(currentIndex); + indices[nFrags] = currentIndex; + fragments[nFrags] = frag; + nFrags++; + currentIndex = _next_(frag); + } + return nFrags; +} + +#endif diff --git a/include/openspace/abuffer/abufferfixed.h b/shaders/abuffer/renderabuffer.frag similarity index 72% rename from include/openspace/abuffer/abufferfixed.h rename to shaders/abuffer/renderabuffer.frag index cefdf10806..f698b39720 100644 --- a/include/openspace/abuffer/abufferfixed.h +++ b/shaders/abuffer/renderabuffer.frag @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2015 * + * 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 * @@ -22,39 +22,28 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __ABUFFERFIXED_H__ -#define __ABUFFERFIXED_H__ +#include "fragment.glsl" +#include <#{fragmentPath}> +#include "abufferfragment.glsl" +#include "abufferresources.glsl" -#include +out vec4 _out_color_; -namespace openspace { +void main() { + Fragment frag = getFragment(); -class ABufferFixed: public ABuffer { -public: + int sampleMask = gl_SampleMaskIn[0]; - ABufferFixed(); - ~ABufferFixed(); - bool initialize() override; + uint newHead = atomicCounterIncrement(atomicCounterBuffer); + uint prevHead = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), newHead); + + ABufferFragment aBufferFrag; + _color_(aBufferFrag, frag.color); + _depth_(aBufferFrag, frag.depth); + _type_(aBufferFrag, 0); // 0 = geometry type + _msaa_(aBufferFrag, gl_SampleMaskIn[0]); + _next_(aBufferFrag, prevHead); - void clear() override; - void preRender() override; - void postRender() override; - - std::vector pixelData() override; - -protected: - virtual bool reinitializeInternal() override; - -private: - GLuint *_data; - GLuint _anchorPointerTexture; - GLuint _anchorPointerTextureInitializer; - GLuint _atomicCounterBuffer; - GLuint _atomicCounterTexture; - GLuint _fragmentBuffer; - GLuint _fragmentTexture; -}; // ABufferFixed - -} // openspace - -#endif // __ABUFFERFIXED_H__ \ No newline at end of file + storeFragment(newHead, aBufferFrag); + discard; +} diff --git a/shaders/ABuffer/abufferResolveVertex.glsl b/shaders/abuffer/renderabuffer.vert similarity index 97% rename from shaders/ABuffer/abufferResolveVertex.glsl rename to shaders/abuffer/renderabuffer.vert index 354fef316c..d691d5208d 100644 --- a/shaders/ABuffer/abufferResolveVertex.glsl +++ b/shaders/abuffer/renderabuffer.vert @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014 * + * 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 * diff --git a/shaders/abuffer/resolveabuffer.frag b/shaders/abuffer/resolveabuffer.frag new file mode 100644 index 0000000000..23a4d14c3f --- /dev/null +++ b/shaders/abuffer/resolveabuffer.frag @@ -0,0 +1,105 @@ +/***************************************************************************************** + * * + * 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__ + +#include "abufferfragment.glsl" +#include "abufferresources.glsl" +#include "fragment.glsl" + +layout (location = 0) out vec4 finalColor; + +uniform float blackoutFactor; + + +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; + } +} + +vec4 blend(vec4 front, vec4 back) { + vec4 result; + result.a = front.a + (1.0 - front.a) * back.a; + result.rgb = ((front.rgb * front.a) + (back.rgb * back.a * (1.0 - front.a))) / result.a; + result = clamp(result, 0.0, 1.0); + return result; +} + +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); +} + + +void main() { + finalColor = vec4(0.0); + uint nFrags = loadFragments(); + + sortFragments(nFrags); + + int realFrags = 0; + + for (uint i = 0; i < nFrags; i++) { + ABufferFragment frag = fragments[i]; + + uint accumulatedMask = _msaa_(fragments[i]); + uint newMask = _msaa_(fragments[i]); + + vec4 color = vec4(0.0); + float totalAlpha = 0.0; + + for (uint j = i + 1; + j < nFrags + && ((newMask = _msaa_(fragments[j])) & accumulatedMask) == 0 + && ((_depth_(fragments[j]) - _depth_(fragments[j - 1]) < 0.00001)); + j++) { + + accumulatedMask |= newMask; + i = j; + } + + uint nSamples = countSamples(accumulatedMask); + color = _color_(fragments[i]); // TODO: Possibly weigh all samples together? + color.a *= float(nSamples) * 0.125; + + finalColor = blend(finalColor, color); + } + + finalColor.a *= blackoutFactor; +} diff --git a/include/openspace/abuffer/abufferdynamic.h b/shaders/abuffer/resolveabuffer.vert similarity index 73% rename from include/openspace/abuffer/abufferdynamic.h rename to shaders/abuffer/resolveabuffer.vert index c8e036234c..d691d5208d 100644 --- a/include/openspace/abuffer/abufferdynamic.h +++ b/shaders/abuffer/resolveabuffer.vert @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2015 * + * 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 * @@ -22,39 +22,12 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __ABUFFERDYNAMIC_H__ -#define __ABUFFERDYNAMIC_H__ +#version __CONTEXT__ -#include +in vec4 position; +out vec2 texCoord; -namespace openspace { - -class ABufferDynamic: public ABuffer { -public: - - ABufferDynamic(); - virtual ~ABufferDynamic(); - virtual bool initialize(); - - virtual void clear(); - virtual void preRender(); - virtual void postRender(); - - std::vector pixelData(); - -protected: - virtual bool reinitializeInternal(); - -private: - - GLuint *_data; - GLuint _anchorPointerTexture; - GLuint _anchorPointerTextureInitializer; - GLuint _atomicCounterBuffer; - GLuint _fragmentBuffer; - GLuint _fragmentTexture; - -}; // ABufferDynamic -} // openspace - -#endif // __ABUFFERDYNAMIC_H__ \ No newline at end of file +void main() { + gl_Position = position; + texCoord = 0.5 + position.xy / 2.0; +} diff --git a/shaders/fragment.glsl b/shaders/fragment.glsl new file mode 100644 index 0000000000..76ecfccbd5 --- /dev/null +++ b/shaders/fragment.glsl @@ -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. * + ****************************************************************************************/ + +#ifndef _FRAGMENT_GLSL_ +#define _FRAGMENT_GLSL_ + +struct Fragment { + vec4 color; + float depth; + int blend; +}; + +#endif diff --git a/shaders/nighttexture_fs.glsl b/shaders/nighttexture_fs.glsl index 5c6278838d..d61c0e0f38 100644 --- a/shaders/nighttexture_fs.glsl +++ b/shaders/nighttexture_fs.glsl @@ -22,8 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - uniform vec4 campos; uniform vec4 objpos; @@ -42,17 +40,16 @@ in vec2 vs_nightTex; in vec4 vs_normal; in vec4 vs_position; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" -void main() -{ +Fragment getFragment() { vec4 position = vs_position; float depth = pscDepth(position); vec4 diffuse = texture(texture1, vs_st); vec4 diffuse2 = texture(nightTex, vs_st); + Fragment frag; if (_performShading) { // directional lighting vec3 origin = vec3(0.0); @@ -74,14 +71,12 @@ void main() vec4 mixtex = mix(diffuse, diffuse2, (1+dot(n,-l_dir))/2); diffuse = (daytex*2 + mixtex)/3; - - diffuse[3] = transparency; - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); } - else { - diffuse[3] = transparency; - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); - } -} \ No newline at end of file + + diffuse[3] = transparency; + frag.color = diffuse; + frag.depth = depth; + + return frag; +} + diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index dc1445801a..786ddedce2 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -22,8 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#version __CONTEXT__ - uniform vec4 campos; uniform vec4 objpos; //uniform vec3 camdir; // add this for specular @@ -41,17 +39,16 @@ in vec2 vs_st; in vec4 vs_normal; in vec4 vs_position; -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" +#include "fragment.glsl" #include "PowerScaling/powerScaling_fs.hglsl" //#include "PowerScaling/powerScaling_vs.hglsl" -void main() -{ +Fragment getFragment() { vec4 position = vs_position; float depth = pscDepth(position); vec4 diffuse = texture(texture1, vs_st); + Fragment frag; if (_performShading) { // directional lighting vec3 origin = vec3(0.0); @@ -77,14 +74,11 @@ void main() } */ diffuse = max(intensity * diffuse, ambient); - - diffuse[3] = transparency; - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); } - else { - diffuse[3] = transparency; - ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); - addToBuffer(frag); - } -} \ No newline at end of file + + diffuse[3] = transparency; + frag.color = diffuse; + frag.depth = depth; + + return frag; +} diff --git a/shaders/render.frag b/shaders/render.frag new file mode 100644 index 0000000000..6e6d99f69f --- /dev/null +++ b/shaders/render.frag @@ -0,0 +1,2 @@ +#version __CONTEXT__ +#include <#{rendererData.fragmentRendererPath}> \ No newline at end of file diff --git a/shaders/renderframebuffer.frag b/shaders/renderframebuffer.frag new file mode 100644 index 0000000000..f6f000019e --- /dev/null +++ b/shaders/renderframebuffer.frag @@ -0,0 +1,9 @@ +#include <#{fragmentPath}> + +out vec4 _out_color_; + +void main() { + Fragment f = getFragment(); + _out_color_ = f.color; + gl_FragDepth = f.depth; +} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7de686959d..9b56f7472f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,12 +23,6 @@ ######################################################################################### set(OPENSPACE_SOURCE - ${OPENSPACE_BASE_DIR}/src/abuffer/abuffer.cpp - ${OPENSPACE_BASE_DIR}/src/abuffer/abufferdynamic.cpp - ${OPENSPACE_BASE_DIR}/src/abuffer/abufferfixed.cpp - ${OPENSPACE_BASE_DIR}/src/abuffer/abufferframebuffer.cpp - ${OPENSPACE_BASE_DIR}/src/abuffer/abuffersinglelinked.cpp - ${OPENSPACE_BASE_DIR}/src/abuffer/abuffervisualizer.cpp ${OPENSPACE_BASE_DIR}/src/engine/configurationmanager.cpp ${OPENSPACE_BASE_DIR}/src/engine/downloadmanager.cpp ${OPENSPACE_BASE_DIR}/src/engine/logfactory.cpp @@ -64,6 +58,8 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/properties/triggerproperty.cpp ${OPENSPACE_BASE_DIR}/src/properties/vectorproperty.cpp ${OPENSPACE_BASE_DIR}/src/query/query.cpp + ${OPENSPACE_BASE_DIR}/src/rendering/abufferrenderer.cpp + ${OPENSPACE_BASE_DIR}/src/rendering/framebufferrenderer.cpp ${OPENSPACE_BASE_DIR}/src/rendering/renderable.cpp ${OPENSPACE_BASE_DIR}/src/rendering/renderengine.cpp ${OPENSPACE_BASE_DIR}/src/rendering/renderengine_lua.inl @@ -74,6 +70,8 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/scene/scenegraphnode.cpp ${OPENSPACE_BASE_DIR}/src/scripting/scriptengine.cpp ${OPENSPACE_BASE_DIR}/src/scripting/scriptengine_lua.inl + ${OPENSPACE_BASE_DIR}/src/util/blockplaneintersectiongeometry.cpp + ${OPENSPACE_BASE_DIR}/src/util/boxgeometry.cpp ${OPENSPACE_BASE_DIR}/src/util/camera.cpp ${OPENSPACE_BASE_DIR}/src/util/factorymanager.cpp ${OPENSPACE_BASE_DIR}/src/util/openspacemodule.cpp @@ -89,12 +87,6 @@ set(OPENSPACE_SOURCE ) set(OPENSPACE_HEADER - ${OPENSPACE_BASE_DIR}/include/openspace/abuffer/abuffer.h - ${OPENSPACE_BASE_DIR}/include/openspace/abuffer/abufferdynamic.h - ${OPENSPACE_BASE_DIR}/include/openspace/abuffer/abufferfixed.h - ${OPENSPACE_BASE_DIR}/include/openspace/abuffer/abufferframebuffer.h - ${OPENSPACE_BASE_DIR}/include/openspace/abuffer/abuffersinglelinked.h - ${OPENSPACE_BASE_DIR}/include/openspace/abuffer/abuffervisualizer.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/configurationmanager.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/downloadmanager.h ${OPENSPACE_BASE_DIR}/include/openspace/engine/logfactory.h @@ -135,14 +127,20 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/properties/triggerproperty.h ${OPENSPACE_BASE_DIR}/include/openspace/properties/vectorproperty.h ${OPENSPACE_BASE_DIR}/include/openspace/query/query.h + ${OPENSPACE_BASE_DIR}/include/openspace/rendering/abufferrenderer.h + ${OPENSPACE_BASE_DIR}/include/openspace/rendering/framebufferrenderer.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderable.h + ${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderer.h ${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderengine.h + ${OPENSPACE_BASE_DIR}/include/openspace/rendering/volume.h ${OPENSPACE_BASE_DIR}/include/openspace/scene/ephemeris.h ${OPENSPACE_BASE_DIR}/include/openspace/scene/scene.h ${OPENSPACE_BASE_DIR}/include/openspace/scene/scenegraph.h ${OPENSPACE_BASE_DIR}/include/openspace/scene/scenegraphnode.h ${OPENSPACE_BASE_DIR}/include/openspace/scripting/script_helper.h ${OPENSPACE_BASE_DIR}/include/openspace/scripting/scriptengine.h + ${OPENSPACE_BASE_DIR}/include/openspace/util/blockplaneintersectiongeometry.h + ${OPENSPACE_BASE_DIR}/include/openspace/util/boxgeometry.h ${OPENSPACE_BASE_DIR}/include/openspace/util/camera.h ${OPENSPACE_BASE_DIR}/include/openspace/util/constants.h ${OPENSPACE_BASE_DIR}/include/openspace/util/factorymanager.h diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp deleted file mode 100644 index 9af9eda690..0000000000 --- a/src/abuffer/abuffer.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/***************************************************************************************** - * * - * 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 -#include -#include - -#include -#include -#include - -namespace { - - const std::string generatedSettingsPath = "${SHADERS_GENERATED}/ABufferSettings.hglsl"; - const std::string generatedHeadersPath = "${SHADERS_GENERATED}/ABufferHeaders.hglsl"; - const std::string generatedSamplerCallsPath = "${SHADERS_GENERATED}/ABufferSamplerCalls.hglsl"; - const std::string generatedTransferFunctionVisualizerPath = - "${SHADERS_GENERATED}/ABufferTransferFunctionVisualizer.hglsl"; - const std::string generatedSamplersPath = "${SHADERS_GENERATED}/ABufferSamplers.hglsl"; - - const std::string _loggerCat = "ABuffer"; - -} - -namespace openspace { - -ABuffer::ABuffer() - : _validShader(false) - , _resolveShader(nullptr) - , _volumeStepFactor(0.f) -{ - - updateDimensions(); -} - -ABuffer::~ABuffer() { - delete _resolveShader; - - for (auto file: _samplerFiles) - delete file; -} - -bool ABuffer::initializeABuffer() { - // ============================ - // SHADERS - // ============================ - auto shaderCallback = [this](ghoul::opengl::ProgramObject* program) { - // Error for visibility in log - _validShader = false; - }; - - generateShaderSource(); - _resolveShader = ghoul::opengl::ProgramObject::Build( - "ABufferResolve", - "${SHADERS}/ABuffer/abufferResolveVertex.glsl", - "${SHADERS}/ABuffer/abufferResolveFragment.glsl"); - if (!_resolveShader) - return false; - _resolveShader->setProgramObjectCallback(shaderCallback); - // Remove explicit callback and use programobject isDirty instead ---abock - - // ============================ - // GEOMETRY (quad) - // ============================ - const GLfloat size = 1.0f; - const GLfloat vertex_data[] = { - // x y s t - -size, -size, 0.0f, 1.0f, - size, size, 0.0f, 1.0f, - -size, size, 0.0f, 1.0f, - -size, -size, 0.0f, 1.0f, - size, -size, 0.0f, 1.0f, - size, size, 0.0f, 1.0f, - }; - GLuint vertexPositionBuffer; - glGenVertexArrays(1, &_screenQuad); // generate array - glBindVertexArray(_screenQuad); // bind array - glGenBuffers(1, &vertexPositionBuffer); // generate buffer - glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, reinterpret_cast(0)); - glEnableVertexAttribArray(0); - return true; -} - -bool ABuffer::reinitialize() { - // set the total resolution for all viewports - updateDimensions(); - return reinitializeInternal(); -} - -void ABuffer::resolve(float blackoutFactor) { - if (!_validShader) { - generateShaderSource(); - updateShader(); - _validShader = true; - } - - if (!_resolveShader) - return; - - _resolveShader->activate(); - _resolveShader->setUniform("blackoutFactor", blackoutFactor); - int startAt = 0; - for (int i = 0; i < _volumes.size(); ++i) { - glActiveTexture(GL_TEXTURE0 + i); - _volumes.at(i).second->bind(); - startAt = i + 1; - } - for (int i = 0; i < _transferFunctions.size(); ++i) { - glActiveTexture(GL_TEXTURE0 + startAt + i); - _transferFunctions.at(i).second->bind(); - } - - glBindVertexArray(_screenQuad); - glDrawArrays(GL_TRIANGLES, 0, 6); - - _resolveShader->deactivate(); -} - -void ABuffer::addVolume(const std::string& tag,ghoul::opengl::Texture* volume) { - _volumes.push_back(std::make_pair(tag, volume)); -} - -void ABuffer::addTransferFunction(const std::string& tag,ghoul::opengl::Texture* transferFunction) { - _transferFunctions.push_back(std::make_pair(tag, transferFunction)); -} - -int ABuffer::addSamplerfile(const std::string& filename) { - if( ! FileSys.fileExists(filename)) - return -1; - - auto fileCallback = [this](const ghoul::filesystem::File& file) { - _validShader = false; - }; - ghoul::filesystem::File* file = new ghoul::filesystem::File(filename); - file->setCallback(fileCallback); - _samplerFiles.push_back(file); - _samplers.push_back(""); - - // ID is one more than "actual" position since ID=0 is considered geometry - //return 1 << (_samplers.size()-1); - return static_cast(_samplers.size()); -} - -bool ABuffer::updateShader() { - if (_resolveShader == nullptr) - return false; - bool s = _resolveShader->rebuildFromFile(); - if (s) { - int startAt = 0; - for (int i = 0; i < _volumes.size(); ++i) { - _resolveShader->setUniform(_volumes.at(i).first, i); - startAt = i + 1; - } - for (int i = 0; i < _transferFunctions.size(); ++i) { - _resolveShader->setUniform(_transferFunctions.at(i).first, startAt + i); - } - LINFO("Successfully updated ABuffer resolve shader!"); - } - else { - LWARNING("Couldn't update ABuffer resolve shader"); - } - return s; -} - -void ABuffer::generateShaderSource() { - for (int i = 0; i < _samplerFiles.size(); ++i) { - std::string line, source = ""; - std::ifstream samplerFile(_samplerFiles.at(i)->path()); - if(samplerFile.is_open()) { - while(std::getline(samplerFile, line)) { - source += line + "\n"; - } - } - samplerFile.close(); - _samplers.at(i) = source; - } - - LDEBUG("Generating shader includes"); - openspaceHeaders(); - openspaceSamplerCalls(); - openspaceSamplers(); - openspaceTransferFunction(); -} - -void ABuffer::openspaceHeaders() { - std::ofstream f(absPath(generatedHeadersPath)); - f << "#define MAX_VOLUMES " << std::to_string(_samplers.size()) << "\n" - << "#define MAX_TF " << _transferFunctions.size() << "\n"; - for (int i = 0; i < _volumes.size(); ++i) { - f << "uniform sampler3D " << _volumes.at(i).first << ";\n"; - } - for (int i = 0; i < _transferFunctions.size(); ++i) { - f << "uniform sampler1D " << _transferFunctions.at(i).first << ";\n"; - } - - for (int i = 0; i < _samplers.size(); ++i) { - auto found = _samplers.at(i).find_first_of('{'); - if (found != std::string::npos) { - f << _samplers.at(i).substr(0, found) << ";\n"; - } - } - - if (_volumes.size() < 1) { - f.close(); - return; - } - - size_t maxLoop = 0; - f << "const vec3 volume_dim[] = {\n"; - for (int i = 0; i < _volumes.size(); ++i) { - glm::size3_t size = _volumes.at(i).second->dimensions(); - for (int k = 0; k < 3; ++k) - maxLoop = glm::max(maxLoop, size[k]); - f << " vec3(" << std::to_string(size[0]) << ".0," + std::to_string(size[1]) << ".0," - << std::to_string(size[2]) + ".0),\n"; - } - f << "};\n"; - - f << "#define LOOP_LIMIT " << maxLoop << "\n"; - - f << "float volumeStepSize[] = {\n"; - for (int i = 0; i < _volumes.size(); ++i) { - glm::size3_t size = _volumes.at(i).second->dimensions(); - f << " stepSize,\n"; - } - f << "};\n"; - - f << "float volumeStepSizeOriginal[] = {\n"; - for (int i = 0; i < _volumes.size(); ++i) { - glm::size3_t size = _volumes.at(i).second->dimensions(); - f << " stepSize,\n"; - } - f << "};\n"; - - f.close(); -} - -void ABuffer::openspaceSamplerCalls() { - std::ofstream f(absPath(generatedSamplerCallsPath)); - for (int i = 0; i < _samplers.size(); ++i) { - auto found1 = _samplers.at(i).find_first_not_of("vec4 "); - auto found2 = _samplers.at(i).find_first_of("(", found1); - if (found1 != std::string::npos && found2 != std::string::npos) { - std::string functionName = _samplers.at(i).substr(found1, found2 - found1); - f << "#ifndef SKIP_VOLUME_" << i << "\n" - << "if((currentVolumeBitmask & (1 << " << i << ")) == " << std::to_string(1 << i) << ") {\n" - << " vec4 c = " << functionName << "(final_color,volume_position[" << i << "]);\n" - << " blendStep(final_color, c, volumeStepSize[" << i << "]);\n" - << " volume_position[" << i << "] += volume_direction[" << i << "]*volumeStepSize[" << i << "];\n" - << "}\n" - << "#endif\n"; - } - } - f.close(); -} - -void ABuffer::openspaceSamplers() { - std::ofstream f(absPath(generatedSamplersPath)); - for (const std::string& sampler : _samplers) - f << sampler << std::endl; - f.close(); -} - -void ABuffer::openspaceTransferFunction() { - std::ofstream f(absPath(generatedTransferFunctionVisualizerPath)); - f << "float showfunc_size = 20.0;\n" - << "float SCREEN_HEIGHTf = float(SCREEN_HEIGHT);\n" - << "float SCREEN_WIDTHf = float(SCREEN_WIDTH);\n"; - for (int i = 0; i < _transferFunctions.size(); ++i) { - f << "if( gl_FragCoord.y > SCREEN_HEIGHTf-showfunc_size*" << i + 1 - << " && gl_FragCoord.y < SCREEN_HEIGHTf-showfunc_size*" << std::to_string(i) << ") {\n" - << " float normalizedIntensity = gl_FragCoord.x / (SCREEN_WIDTHf-1) ;\n" - << " vec4 tfc = texture(" << _transferFunctions.at(i).first << ", normalizedIntensity);\n" - << " final_color = tfc;\n" - << " float cmpf = SCREEN_HEIGHTf-showfunc_size*" << i + 1 << " + tfc.a*showfunc_size;\n" - << " if(gl_FragCoord.y > cmpf) {\n" - << " final_color = vec4(0,0,0,0);\n" - << " } else {\n" - << " final_color.a = 1.0;\n" - << " }\n" - << "} else if(ceil(gl_FragCoord.y) == SCREEN_HEIGHTf - showfunc_size*" << i + 1 << ") {\n" - << " const float intensity = 0.4;\n" - << " final_color = vec4(intensity,intensity,intensity,1.0);\n" - << "}\n"; - } - f.close(); -} - -void ABuffer::invalidateABuffer() { - LDEBUG("Shader invalidated"); - _validShader = false; -} - -void ABuffer::updateDimensions() { - glm::ivec2 res = OsEng.windowWrapper().currentWindowResolution(); - _width = res.x; - _height = res.y; - - _totalPixels = _width * _height; -} - - -} // openspace \ No newline at end of file diff --git a/src/abuffer/abufferdynamic.cpp b/src/abuffer/abufferdynamic.cpp deleted file mode 100644 index 6b46883f7d..0000000000 --- a/src/abuffer/abufferdynamic.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/***************************************************************************************** - * * - * 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 -#include -#include -#include - -namespace { - std::string _loggerCat = "ABufferDynamic"; -} - -namespace openspace { - -ABufferDynamic::ABufferDynamic(): _data(0), _anchorPointerTexture(0), - _anchorPointerTextureInitializer(0), _atomicCounterBuffer(0), _fragmentBuffer(0), - _fragmentTexture(0) -{} - -ABufferDynamic::~ABufferDynamic() { - if(_data != 0) - delete _data; - - glDeleteTextures(1,&_anchorPointerTexture); - glDeleteTextures(1,&_fragmentTexture); - glDeleteBuffers(1,&_anchorPointerTextureInitializer); - glDeleteBuffers(1,&_atomicCounterBuffer); - glDeleteBuffers(1,&_anchorPointerTextureInitializer); -} - -bool ABufferDynamic::initialize() { - // ============================ - // BUFFERS - // ============================ - glGenTextures(1, &_anchorPointerTexture); - glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); - - glGenBuffers(1, &_anchorPointerTextureInitializer); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); - glBufferData(GL_PIXEL_UNPACK_BUFFER, _totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW); - - _data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); - memset(_data, 0x00, _totalPixels * sizeof(GLuint)); - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - - glGenBuffers(1, &_atomicCounterBuffer); - glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, _atomicCounterBuffer); - glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY); - - glGenBuffers(1, &_fragmentBuffer); - glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer); - glBufferData(GL_TEXTURE_BUFFER, MAX_LAYERS*_totalPixels*sizeof(GLfloat)*4, NULL, GL_DYNAMIC_COPY); - - glGenTextures(1, &_fragmentTexture); - glBindTexture(GL_TEXTURE_BUFFER, _fragmentTexture); - glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, _fragmentBuffer); - glBindTexture(GL_TEXTURE_BUFFER, 0); - - glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); - - return initializeABuffer(); -} - -bool ABufferDynamic::reinitializeInternal() { - return false; -} - -void ABufferDynamic::clear() { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); - glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - - static const GLuint zero = 1; - glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); - glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(zero), &zero); - glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0); -} - -void ABufferDynamic::preRender() { - - // Bind head-pointer image for read-write - glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); - glBindImageTexture(0, _anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); - glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); -} - -void ABufferDynamic::postRender() { - -} - -std::vector ABufferDynamic::pixelData() { - std::vector d; - return d; -} - -} // openspace \ No newline at end of file diff --git a/src/abuffer/abufferfixed.cpp b/src/abuffer/abufferfixed.cpp deleted file mode 100644 index 37455ac16a..0000000000 --- a/src/abuffer/abufferfixed.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/***************************************************************************************** - * * - * 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 -#include -#include -#include - -namespace { - std::string _loggerCat = "ABufferFixed"; -} - -namespace openspace { - -ABufferFixed::ABufferFixed(): _data(0), _anchorPointerTexture(0), - _anchorPointerTextureInitializer(0), _atomicCounterBuffer(0), _fragmentBuffer(0), - _fragmentTexture(0) -{} - -ABufferFixed::~ABufferFixed() { - glDeleteTextures(1,&_anchorPointerTexture); - glDeleteTextures(1,&_fragmentTexture); - // glDeleteTextures(1,&_atomicCounterTexture); - glDeleteBuffers(1,&_anchorPointerTextureInitializer); - // glDeleteBuffers(1,&_atomicCounterBuffer); - //glDeleteBuffers(1,&_anchorPointerTextureInitializer); -} - -bool ABufferFixed::initialize() { - // ============================ - // BUFFERS - // ============================ - glGenTextures(1, &_anchorPointerTexture); - glGenBuffers(1, &_anchorPointerTextureInitializer); - glGenBuffers(1, &_fragmentBuffer); - glGenTextures(1, &_fragmentTexture); - - reinitialize(); - - return initializeABuffer(); -} - -bool ABufferFixed::reinitializeInternal() { - glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); - - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); - glBufferData(GL_PIXEL_UNPACK_BUFFER, _totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW); - - _data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); - memset(_data, 0x00, _totalPixels * sizeof(GLuint)); - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - - - // glGenBuffers(1, &_atomicCounterBuffer); - // glBindBuffer(GL_TEXTURE_BUFFER, _atomicCounterBuffer); - // glBufferData(GL_TEXTURE_BUFFER, _totalPixels*sizeof(GLuint), NULL, GL_DYNAMIC_COPY); - - // glGenTextures(1, &_atomicCounterTexture); - // glBindTexture(GL_TEXTURE_2D, _atomicCounterTexture); - // glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, _atomicCounterBuffer); - // glBindTexture(GL_TEXTURE_BUFFER, 0); - - - glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer); - glBufferData(GL_TEXTURE_BUFFER, MAX_LAYERS*_totalPixels*sizeof(GLuint) * 4, NULL, GL_DYNAMIC_COPY); - - glBindTexture(GL_TEXTURE_BUFFER, _fragmentTexture); - glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, _fragmentBuffer); - glBindTexture(GL_TEXTURE_BUFFER, 0); - - glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); - return false; -} - -void ABufferFixed::clear() { - - // Bind texture initializer - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); - - // clear _anchorPointerTexture - glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); - - // // clear _atomicCounterTexture - // glBindTexture(GL_TEXTURE_2D, _atomicCounterTexture); - // glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); - - // reset GL_PIXEL_UNPACK_BUFFER - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - -} - -void ABufferFixed::preRender() { - - // Bind head-pointer image for read-write - glBindImageTexture(0, _anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); - glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); - // glBindImageTexture(2, _atomicCounterTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); -} - -void ABufferFixed::postRender() { - -} - -std::vector ABufferFixed::pixelData() { - LWARNING("pixelData() not working properly for ABufferFixed"); - std::vector d; - - unsigned int* anchorTexture = new unsigned int[_totalPixels]; - unsigned int* fragmentBuffer = new unsigned int[_totalPixels*MAX_LAYERS * 4]; - - glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, anchorTexture); - - glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer); - glGetBufferSubData(GL_TEXTURE_BUFFER, 0, _totalPixels*MAX_LAYERS * 4, fragmentBuffer); - - // iterate over every pixel - for (size_t x = 0; x < _width; ++x){ - const float fx = static_cast(x) / _width; - for (size_t y = 0; y < _height; ++y){ - const float fy = static_cast(y) / _height; - unsigned int fragments = anchorTexture[y*_width + x]; - - // loop until last in list - for (size_t current = 0; current < fragments; ++current) { - //LDEBUG("(" << x << ", " << y << "): " << current); - size_t index = (y * _width + x)*MAX_LAYERS + current; - // RGBA - index *= 4; - - glm::uvec4 fragment; - for (size_t j = 0; j < 4; ++j) { - fragment[j] = fragmentBuffer[index + j]; - } - - float z = glm::uintBitsToFloat(fragment[0]); - glm::vec4 color(glm::unpackUnorm2x16(fragment[2]), glm::unpackUnorm2x16(fragment[3])); - - fragmentData fd; - fd._position[0] = fx; - fd._position[1] = fy; - fd._position[2] = z; - fd._color[0] = color[0]; - fd._color[1] = color[1]; - fd._color[2] = color[2]; - fd._color[3] = color[3]; - d.emplace_back(fd); - } - - } - } - - delete[] anchorTexture; - delete[] fragmentBuffer; - return d; -} - -} // openspace diff --git a/src/abuffer/abuffersinglelinked.cpp b/src/abuffer/abuffersinglelinked.cpp deleted file mode 100644 index 35305bbced..0000000000 --- a/src/abuffer/abuffersinglelinked.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/***************************************************************************************** - * * - * 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 - -#include -#include -#include -#include - -namespace { - std::string _loggerCat = "ABufferSingleLinked"; - - const unsigned int mask_29 = 536870911; - const unsigned int mask_id_next = mask_29; - const unsigned int shift_id_next = 0; - unsigned int bitextract_u(unsigned int pack, unsigned int mask, unsigned int shift) { - return (pack >> shift) & (mask >> shift); - } -} - -namespace openspace { - -ABufferSingleLinked::ABufferSingleLinked() - : _anchorPointerTexture(0) - , _anchorPointerTextureInitializer(0) - , _atomicCounterBuffer(0) - , _fragmentBuffer(0) - , _fragmentTexture(0) -{} - -ABufferSingleLinked::~ABufferSingleLinked() { - glDeleteTextures(1, &_anchorPointerTexture); - glDeleteTextures(1, &_fragmentTexture); - glDeleteBuffers(1, &_anchorPointerTextureInitializer); - glDeleteBuffers(1, &_atomicCounterBuffer); - glDeleteBuffers(1, &_anchorPointerTextureInitializer); -} - -bool ABufferSingleLinked::initialize() { - // ============================ - // BUFFERS - // ============================ - glGenTextures(1, &_anchorPointerTexture); - LDEBUG("AnchorPointerTexture ID: " << _anchorPointerTexture); - glGenBuffers(1, &_anchorPointerTextureInitializer); - LDEBUG("AnchorPointerTextureInitializer ID: " << _anchorPointerTextureInitializer); - glGenBuffers(1, &_atomicCounterBuffer); - LDEBUG("AtomicCounterBuffer ID: " << _atomicCounterBuffer); - glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, _atomicCounterBuffer); - glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY); - glGenBuffers(1, &_fragmentBuffer); - LDEBUG("FragmentBuffer ID: " << _fragmentBuffer); - glGenTextures(1, &_fragmentTexture); - LDEBUG("FragmentTexture ID: " << _fragmentTexture); - - reinitialize(); - - return initializeABuffer(); -} - -bool ABufferSingleLinked::reinitializeInternal() { - glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); - glBufferData(GL_PIXEL_UNPACK_BUFFER, _totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW); - - GLuint* _data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); - memset(_data, 0x00, _totalPixels * sizeof(GLuint)); - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - - glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer); - glBufferData(GL_TEXTURE_BUFFER, MAX_LAYERS*_totalPixels*sizeof(GLuint) * 4, NULL, GL_DYNAMIC_COPY); - - glBindTexture(GL_TEXTURE_BUFFER, _fragmentTexture); - glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, _fragmentBuffer); - glBindTexture(GL_TEXTURE_BUFFER, 0); - - glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); - - return true; -} - -void ABufferSingleLinked::clear() { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); - glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - - static const GLuint zero = 1; - glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); - glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(zero), &zero); - glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0); -} - -void ABufferSingleLinked::preRender() { - // Bind head-pointer image for read-write - glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); - glBindImageTexture(0, _anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); - glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); -} - -void ABufferSingleLinked::postRender() { - -} - -std::vector ABufferSingleLinked::pixelData() { - unsigned int* anchorTexture = new unsigned int[_totalPixels]; - unsigned int* fragmentBuffer = new unsigned int[_totalPixels*MAX_LAYERS*4]; - - glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, anchorTexture); - - glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer); - glGetBufferSubData(GL_TEXTURE_BUFFER, 0, _totalPixels*MAX_LAYERS * 4, fragmentBuffer); - - std::vector d; - - // iterate over every pixel - for (size_t x = 0; x < _width; ++x){ - const float fx = static_cast(x) / _width; - for (size_t y = 0; y < _height; ++y){ - const float fy = static_cast(y) / _height; - unsigned int current = anchorTexture[y*_width+x]; - - // loop until last in list - while (current != 0) { - //LDEBUG("(" << x << ", " << y << "): " << current); - - // RGBA - current *= 4; - - glm::uvec4 fragment; - for (size_t j = 0; j < 4; ++j) { - fragment[j] = fragmentBuffer[current + j]; - } - - float z = glm::uintBitsToFloat(fragment[0]); - unsigned int next = bitextract_u(fragment[1], mask_id_next, shift_id_next); - glm::vec4 color(glm::unpackUnorm2x16(fragment[2]), glm::unpackUnorm2x16(fragment[3])); - //LDEBUG("(" << x << ", " << y << "): " << z); - - fragmentData fd; - fd._position[0] = fx; - fd._position[1] = fy; - fd._position[2] = z; - fd._color[0] = color[0]; - fd._color[1] = color[1]; - fd._color[2] = color[2]; - fd._color[3] = color[3]; - d.emplace_back(fd); - - if (next >= _totalPixels*MAX_LAYERS * 4) { - LWARNING("Getting index out of bounds, ignoring"); - //LDEBUG("(" << x << ", " << y << "): fragment[1]: " << fragment[1]); - //LDEBUG("(" << x << ", " << y << "): next: " << next); - current = 0; - } - else { - current = next; - } - } - - } - } - - delete[] anchorTexture; - delete[] fragmentBuffer; - - return d; -} - -} // openspace diff --git a/src/abuffer/abuffervisualizer.cpp b/src/abuffer/abuffervisualizer.cpp deleted file mode 100644 index d96868daa7..0000000000 --- a/src/abuffer/abuffervisualizer.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/***************************************************************************************** - * * - * 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 -#include - -#include - -#define MARKER_POINTS -#define MARKER_LINES -#define COLOR_BOX - -namespace { - const std::string _loggerCat = "ABufferVisualizer"; -} - -namespace openspace { - -ABufferVisualizer::ABufferVisualizer() - : _pointcloud(0) - , _pointcloudSize(0) - , _markers(0) - , _markersSize(0) - , _pointcloudProgram(nullptr) -{ - -} - -ABufferVisualizer::~ABufferVisualizer() { - if (_pointcloud) - glDeleteVertexArrays(1, &_pointcloud); - if (_markers) - glDeleteVertexArrays(1, &_markers); - if (_pointcloudProgram) - delete _pointcloudProgram; -} - -void ABufferVisualizer::updateData(const std::vector& data) { - - if (_pointcloud) - glDeleteVertexArrays(1, &_pointcloud); - - _pointcloudSize = static_cast(data.size()); - GLuint vertexPositionBuffer; - glGenVertexArrays(1, &_pointcloud); // generate array - glBindVertexArray(_pointcloud); // bind array - glGenBuffers(1, &vertexPositionBuffer); // generate buffer - glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer - glBufferData(GL_ARRAY_BUFFER, sizeof(ABuffer::fragmentData)*_pointcloudSize, data.data(), GL_STATIC_DRAW); - - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ABuffer::fragmentData), - reinterpret_cast(offsetof(ABuffer::fragmentData, _position))); - glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(ABuffer::fragmentData), - reinterpret_cast(offsetof(ABuffer::fragmentData, _color))); - - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - - - - if (!_markers) - initializeMarkers(); - - if (!_pointcloudProgram) { - _pointcloudProgram = ghoul::opengl::ProgramObject::Build( - "pointcloudProgram", - "${SHADERS}/pointcloud_vs.glsl", - "${SHADERS}/pointcloud_fs.glsl"); - if (!_pointcloudProgram) - LERROR("Could not compile _pointcloudProgram"); - } -} - -void ABufferVisualizer::render() { - if (!_pointcloudProgram) - return; - - glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); - _pointcloudProgram->activate(); - - glm::mat4 modelMatrix = glm::mat4(1.0); - static glm::mat4 rotation = glm::mat4(1.0); - rotation = glm::rotate(rotation, 0.3f, glm::vec3(0, 1, 0)); - static glm::mat4 rotationText = glm::mat4(1.0); - rotationText = glm::rotate(rotationText, -0.3f, glm::vec3(0, 1, 0)); - - modelMatrix = glm::translate(modelMatrix, glm::vec3(0, 0, -1)); - modelMatrix = modelMatrix * rotation; - - _pointcloudProgram->setUniform("ViewProjection", OsEng.windowWrapper().viewProjectionMatrix()); - _pointcloudProgram->setUniform("ModelTransform", modelMatrix); - -#if defined(MARKER_POINTS) - glPointSize(2.0); - glBindVertexArray(_markers); - glDrawArrays(GL_POINTS, 0, _markersSize); - glBindVertexArray(0); -#endif - -#if defined(MARKER_LINES) - glBindVertexArray(_markers); // select first VAO - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _imarkers); - glDrawElements(GL_LINES, _imarkersSize, GL_UNSIGNED_INT, 0); - glBindVertexArray(0); -#endif - - - glPointSize(1.0); - glBindVertexArray(_pointcloud); - glDrawArrays(GL_POINTS, 0, _pointcloudSize); - glBindVertexArray(0); - - - _pointcloudProgram->deactivate(); - - const int font_size_light = 8; - const sgct_text::Font* fontLight = sgct_text::FontManager::instance()->getFont(constants::fonts::keyLight, font_size_light); - - const glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(0.04, 0.04, 0.04)); - glm::mat4 translate, mvp; - - const glm::mat4 viewProjMatrix = OsEng.windowWrapper().viewProjectionMatrix(); - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 0)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,0,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 0, 1)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,0,1)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 0)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,1,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 0)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,0,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(0, 1, 1)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(0,1,1)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 0, 1)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,0,1)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 0)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,1,0)"); - translate = glm::translate(glm::mat4(1.0), glm::vec3(1, 1, 1)); - mvp = viewProjMatrix*modelMatrix*translate*rotationText*scale; - Freetype::print3d(fontLight, mvp, "(1,1,1)"); -} - -void ABufferVisualizer::initializeMarkers() { - ABuffer::fragmentData fd; - fd._color[0] = 0.3f; - fd._color[1] = 0.3f; - fd._color[2] = 0.3f; - fd._color[3] = 1.0f; - std::vector markers(8, fd); - -#ifdef COLOR_BOX - // First 4 - markers.at(0)._position[0] = 0.0f; markers.at(0)._color[0] = 0.0f; - markers.at(0)._position[1] = 0.0f; markers.at(0)._color[1] = 0.0f; - markers.at(0)._position[2] = 0.0f; markers.at(0)._color[2] = 0.0f; - - markers.at(1)._position[0] = 1.0f; markers.at(1)._color[0] = 1.0f; - markers.at(1)._position[1] = 0.0f; markers.at(1)._color[1] = 0.0f; - markers.at(1)._position[2] = 0.0f; markers.at(1)._color[2] = 0.0f; - - markers.at(2)._position[0] = 1.0f; markers.at(2)._color[0] = 1.0f; - markers.at(2)._position[1] = 1.0f; markers.at(2)._color[1] = 1.0f; - markers.at(2)._position[2] = 0.0f; markers.at(2)._color[2] = 0.0f; - - markers.at(3)._position[0] = 0.0f; markers.at(3)._color[0] = 0.0f; - markers.at(3)._position[1] = 1.0f; markers.at(3)._color[1] = 1.0f; - markers.at(3)._position[2] = 0.0f; markers.at(3)._color[2] = 0.0f; - - - // last 4 - markers.at(4)._position[0] = 0.0f; markers.at(4)._color[0] = 0.0f; - markers.at(4)._position[1] = 0.0f; markers.at(4)._color[1] = 0.0f; - markers.at(4)._position[2] = 1.0f; markers.at(4)._color[2] = 1.0f; - - markers.at(5)._position[0] = 1.0f; markers.at(5)._color[0] = 1.0f; - markers.at(5)._position[1] = 0.0f; markers.at(5)._color[1] = 0.0f; - markers.at(5)._position[2] = 1.0f; markers.at(5)._color[2] = 1.0f; - - markers.at(6)._position[0] = 1.0f; markers.at(6)._color[0] = 1.0f; - markers.at(6)._position[1] = 1.0f; markers.at(6)._color[1] = 1.0f; - markers.at(6)._position[2] = 1.0f; markers.at(6)._color[2] = 1.0f; - - markers.at(7)._position[0] = 0.0f; markers.at(7)._color[0] = 0.0f; - markers.at(7)._position[1] = 1.0f; markers.at(7)._color[1] = 1.0f; - markers.at(7)._position[2] = 1.0f; markers.at(7)._color[2] = 1.0f; -#else - // First 4 - markers.at(0)._position[0] = 0.0f; - markers.at(0)._position[1] = 0.0f; - markers.at(0)._position[2] = 0.0f; - - markers.at(1)._position[0] = 1.0f; - markers.at(1)._position[1] = 0.0f; - markers.at(1)._position[2] = 0.0f; - - markers.at(2)._position[0] = 1.0f; - markers.at(2)._position[1] = 1.0f; - markers.at(2)._position[2] = 0.0f; - - markers.at(3)._position[0] = 0.0f; - markers.at(3)._position[1] = 1.0f; - markers.at(3)._position[2] = 0.0f; - - - // last 4 - markers.at(4)._position[0] = 0.0f; - markers.at(4)._position[1] = 0.0f; - markers.at(4)._position[2] = 1.0f; - - markers.at(5)._position[0] = 1.0f; - markers.at(5)._position[1] = 0.0f; - markers.at(5)._position[2] = 1.0f; - - markers.at(6)._position[0] = 1.0f; - markers.at(6)._position[1] = 1.0f; - markers.at(6)._position[2] = 1.0f; - - markers.at(7)._position[0] = 0.0f; - markers.at(7)._position[1] = 1.0f; - markers.at(7)._position[2] = 1.0f; -#endif - - _markersSize = static_cast(markers.size()); - GLuint vertexPositionBuffer; - glGenVertexArrays(1, &_markers); // generate array - glBindVertexArray(_markers); // bind array - glGenBuffers(1, &vertexPositionBuffer); // generate buffer - glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer - glBufferData(GL_ARRAY_BUFFER, sizeof(ABuffer::fragmentData)*_markersSize, markers.data(), GL_STATIC_DRAW); - - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ABuffer::fragmentData), - reinterpret_cast(offsetof(ABuffer::fragmentData, _position))); - glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(ABuffer::fragmentData), - reinterpret_cast(offsetof(ABuffer::fragmentData, _color))); - - //glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, reinterpret_cast(0)); - //glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, reinterpret_cast(sizeof(GLfloat) * 3)); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - - std::vector ivector; - // front - ivector.push_back(0); - ivector.push_back(1); - - ivector.push_back(1); - ivector.push_back(2); - - ivector.push_back(2); - ivector.push_back(3); - - ivector.push_back(3); - ivector.push_back(0); - - // back - ivector.push_back(4); - ivector.push_back(5); - - ivector.push_back(5); - ivector.push_back(6); - - ivector.push_back(6); - ivector.push_back(7); - - ivector.push_back(7); - ivector.push_back(4); - - // connections between front and back - ivector.push_back(0); - ivector.push_back(4); - - ivector.push_back(3); - ivector.push_back(7); - - ivector.push_back(1); - ivector.push_back(5); - - ivector.push_back(2); - ivector.push_back(6); - - - _imarkersSize = static_cast(ivector.size()); - glBindVertexArray(0); - - glGenBuffers(1, &_imarkers); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _imarkers); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, _imarkersSize * sizeof(GLsizei), ivector.data(), GL_STATIC_DRAW); -} - -} // openspace \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 071dea96b5..7eb9ed9791 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -271,7 +271,7 @@ bool OpenSpaceEngine::create( _engine->_console->initialize(); // Register the provided shader directories - ghoul::opengl::ShaderObject::addIncludePath("${SHADERS}"); + ghoul::opengl::ShaderPreprocessor::addIncludePath("${SHADERS}"); _engine->_syncBuffer = new SyncBuffer(1024); diff --git a/src/engine/wrapper/sgctwindowwrapper.cpp b/src/engine/wrapper/sgctwindowwrapper.cpp index d24920f091..a125d28f83 100644 --- a/src/engine/wrapper/sgctwindowwrapper.cpp +++ b/src/engine/wrapper/sgctwindowwrapper.cpp @@ -99,8 +99,8 @@ glm::mat4 SGCTWindowWrapper::viewProjectionMatrix() const { return sgct::Engine::instance()->getCurrentModelViewProjectionMatrix(); } -void SGCTWindowWrapper::setNearFarClippingPlane(float near, float far) { - sgct::Engine::instance()->setNearAndFarClippingPlanes(near, far); +void SGCTWindowWrapper::setNearFarClippingPlane(float nearPlane, float farPlane) { + sgct::Engine::instance()->setNearAndFarClippingPlanes(nearPlane, farPlane); } glm::ivec4 SGCTWindowWrapper::viewportPixelCoordinates() const { diff --git a/src/rendering/abufferrenderer.cpp b/src/rendering/abufferrenderer.cpp new file mode 100644 index 0000000000..d1cb9e1690 --- /dev/null +++ b/src/rendering/abufferrenderer.cpp @@ -0,0 +1,252 @@ +/***************************************************************************************** + * * + * 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 + +namespace { + const std::string _loggerCat = "ABufferRenderer"; + const int MaxLayers = 16; +} + +namespace openspace { + + + ABufferRenderer::ABufferRenderer() + : _camera(nullptr) + , _scene(nullptr) + , _resolution(glm::ivec2(0)) + , _dirtyResolution(true) + , _resolveProgram(nullptr) { } + +ABufferRenderer::~ABufferRenderer() {} + + +void ABufferRenderer::initialize() { + LINFO("Initializing abuffer renderer"); + + const GLfloat size = 1.0f; + const GLfloat vertex_data[] = { + // x y s t + -size, -size, 0.0f, 1.0f, + size, size, 0.0f, 1.0f, + -size, size, 0.0f, 1.0f, + -size, -size, 0.0f, 1.0f, + size, -size, 0.0f, 1.0f, + size, size, 0.0f, 1.0f, + }; + GLuint vertexPositionBuffer; + glGenVertexArrays(1, &_screenQuad); // generate array + glBindVertexArray(_screenQuad); // bind array + glGenBuffers(1, &vertexPositionBuffer); // generate buffer + glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, reinterpret_cast(0)); + glEnableVertexAttribArray(0); + + glGenTextures(1, &_anchorPointerTexture); + LDEBUG("AnchorPointerTexture ID: " << _anchorPointerTexture); + glGenBuffers(1, &_anchorPointerTextureInitializer); + LDEBUG("AnchorPointerTextureInitializer ID: " << _anchorPointerTextureInitializer); + glGenBuffers(1, &_atomicCounterBuffer); + LDEBUG("AtomicCounterBuffer ID: " << _atomicCounterBuffer); + glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, _atomicCounterBuffer); + glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY); + glGenBuffers(1, &_fragmentBuffer); + LDEBUG("FragmentBuffer ID: " << _fragmentBuffer); + glGenTextures(1, &_fragmentTexture); + LDEBUG("FragmentTexture ID: " << _fragmentTexture); + + if (_dirtyResolution) { + updateResolution(); + } + updateRendererData(); + ghoul::Dictionary dict = createResolveDictionary(); + _resolveProgram = createResolveProgram(dict); + + +} + +void ABufferRenderer::deinitialize() { + +} + +void ABufferRenderer::update() { + bool dirtyRendererData = false; + bool dirtyResolveDictionary = false; + + if (_dirtyResolution) { + dirtyRendererData = true; + updateResolution(); + } + + if (dirtyRendererData) { + dirtyResolveDictionary = true; + updateRendererData(); + } + + // TODO: Collect volumes from scene graph. + // Diff against cache, update cache. + // possibly mark resolve dictionary as dirty + + if (dirtyResolveDictionary) { + ghoul::Dictionary dict = createResolveDictionary(); + _resolveProgram->setDictionary(dict); + } + + if (_resolveProgram->isDirty()) { + _resolveProgram->rebuildFromFile(); + } +} + + +void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurements) { + if (_scene == nullptr) return; + if (_camera == nullptr) return; + + // Reset + glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + clear(); + + // Step 1: Render geometries to the fragment buffer + + // Bind head-pointer image for read-write + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); + glBindImageTexture(0, _anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); + + _scene->render({ *_camera, psc(), doPerformanceMeasurements }); + + // Step 2: Render volumes to the fragment buffer + //TODO: Implement this + + // Step 3: Resolve the buffer + _resolveProgram->activate(); + _resolveProgram->setUniform("blackoutFactor", blackoutFactor); + // todo: pre-ray-cast for each volume + glBindVertexArray(_screenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + // todo: post-ray-cast for each volume + _resolveProgram->deactivate(); +} + + +void ABufferRenderer::setScene(Scene* scene) { + _scene = scene; +} + +void ABufferRenderer::setCamera(Camera* camera) { + _camera = camera; +} + +void ABufferRenderer::setResolution(glm::ivec2 res) { + if (res != _resolution) { + _resolution = res; + _dirtyResolution = true; + } +} + +void ABufferRenderer::clear() { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _resolution.x, _resolution.y, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + static const GLuint zero = 1; + 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() { + int totalPixels = _resolution.x * _resolution.y; + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _resolution.x, _resolution.y, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + glBufferData(GL_PIXEL_UNPACK_BUFFER, totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW); + + GLuint* data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); + memset(data, 0x00, totalPixels * sizeof(GLuint)); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer); + glBufferData(GL_TEXTURE_BUFFER, MaxLayers*totalPixels*sizeof(GLuint) * 4, NULL, GL_DYNAMIC_COPY); + + glBindTexture(GL_TEXTURE_BUFFER, _fragmentTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, _fragmentBuffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); + + + _dirtyResolution = false; + +} + +ghoul::Dictionary ABufferRenderer::createResolveDictionary() { + ghoul::Dictionary dict; + + dict.setValue("rendererData", _rendererData); + // TODO: Add volume data to dictionary + // such as id, bitmask, path to raycaster frag shader, helpers, nVolumes... + return dict; +} + +ghoul::opengl::ProgramObject* ABufferRenderer::createResolveProgram(const ghoul::Dictionary& dict) { + return ghoul::opengl::ProgramObject::Build("ABuffer Resolve", + "${SHADERS}/abuffer/resolveabuffer.vert", + "${SHADERS}/abuffer/resolveabuffer.frag", + dict); +} + + + +void ABufferRenderer::updateRendererData() { + ghoul::Dictionary dict; + dict.setValue("windowWidth", _resolution.x); + dict.setValue("windowHeight", _resolution.y); + dict.setValue("maxLayers", MaxLayers); + dict.setValue("fragmentRendererPath", std::string("${SHADERS}/abuffer/renderabuffer.frag")); + _rendererData = dict; + + OsEng.renderEngine()->setRendererData(dict); +} + +} diff --git a/src/abuffer/abufferframebuffer.cpp b/src/rendering/framebufferrenderer.cpp similarity index 56% rename from src/abuffer/abufferframebuffer.cpp rename to src/rendering/framebufferrenderer.cpp index 007ded525c..58a133850b 100644 --- a/src/abuffer/abufferframebuffer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2015 * + * 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 * @@ -21,70 +21,75 @@ * 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 namespace { - std::string _loggerCat = "ABufferFrameBuffer"; + const std::string _loggerCat = "FramebufferRenderer"; + const std::string FragmentRendererPath = "${SHADERS}/renderframebuffer.frag"; } namespace openspace { -ABufferFramebuffer::ABufferFramebuffer() {} -ABufferFramebuffer::~ABufferFramebuffer() {} + FramebufferRenderer::FramebufferRenderer() + : _camera(nullptr) + , _scene(nullptr) + , _resolution(glm::vec2(0)) { + } -bool ABufferFramebuffer::initialize() { - return initializeABuffer(); -} -bool ABufferFramebuffer::reinitializeInternal() { - return true; -} - -void ABufferFramebuffer::clear() { -} - -void ABufferFramebuffer::preRender() { -} - -void ABufferFramebuffer::postRender() { - -} + FramebufferRenderer::~FramebufferRenderer() { + + } -void ABufferFramebuffer::resolve(float blackoutFactor) { + + void FramebufferRenderer::initialize() { + updateRendererData(); + } + + void FramebufferRenderer::deinitialize() { + } + + + void FramebufferRenderer::update() { + // no need to update anything. + } + + void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurements) { + if (_scene == nullptr) return; + if (_camera == nullptr) return; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + _scene->render({ *_camera, psc(), doPerformanceMeasurements });; + + } + + void FramebufferRenderer::setScene(Scene* scene) { + _scene = scene; + } + + void FramebufferRenderer::setCamera(Camera* camera) { + _camera = camera; + } + + void FramebufferRenderer::setResolution(glm::ivec2 res) { + _resolution = res; + } + + void FramebufferRenderer::updateRendererData() { + ghoul::Dictionary dict; + dict.setValue("fragmentRendererPath", FragmentRendererPath); + OsEng.renderEngine()->setRendererData(dict); + } + + } -std::vector ABufferFramebuffer::pixelData() { - return std::vector(); -} - -bool ABufferFramebuffer::initializeABuffer() { - // ============================ - // SHADERS - // ============================ - auto shaderCallback = [this](ghoul::opengl::ProgramObject* program) { - // Error for visibility in log - _validShader = false; - }; - - generateShaderSource(); - _resolveShader = ghoul::opengl::ProgramObject::Build( - "ABufferResolve", - "${SHADERS}/ABuffer/abufferResolveVertex.glsl", - "${SHADERS}/ABuffer/abufferResolveFragment.glsl"); - if (!_resolveShader) - return false; - _resolveShader->setProgramObjectCallback(shaderCallback); -} - -} // openspace diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 7de7c556e4..fd4102eda5 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -166,4 +166,8 @@ bool Renderable::isEnabled() const { return _enabled; } +std::vector Renderable::volumesToRender(const RenderData& data) const { + return std::vector(); +} + } // namespace openspace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 6e440b9c70..b8eccb5072 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -28,12 +28,10 @@ #include #endif -#include -#include -#include -#include -#include -#include +#include +#include +#include + #include #include #include @@ -72,10 +70,8 @@ #include // ABuffer defines -#define ABUFFER_FRAMEBUFFER 0 -#define ABUFFER_SINGLE_LINKED 1 -#define ABUFFER_FIXED 2 -#define ABUFFER_DYNAMIC 3 +#define RENDERER_FRAMEBUFFER 0 +#define RENDERER_ABUFFER 1 #include "renderengine_lua.inl" @@ -83,7 +79,8 @@ namespace { const std::string _loggerCat = "RenderEngine"; const std::string KeyRenderingMethod = "RenderingMethod"; - const std::string DefaultRenderingMethod = "ABufferSingleLinked"; + const std::string DefaultRenderingMethod = "ABuffer"; + const std::string RenderFsPath = "${SHADERS}/render.frag"; } namespace openspace { @@ -94,11 +91,11 @@ const std::string RenderEngine::PerformanceMeasurementSharedData = RenderEngine::RenderEngine() : _mainCamera(nullptr) , _sceneGraph(nullptr) - , _abuffer(nullptr) - , _abufferImplementation(ABufferImplementation::Invalid) + , _renderer(nullptr) + , _rendererImplementation(RendererImplementation::Invalid) , _log(nullptr) , _showInfo(true) - , _showScreenLog(true) + , _showLog(true) , _takeScreenshot(false) , _doPerformanceMeasurements(false) , _performanceMemory(nullptr) @@ -107,8 +104,6 @@ RenderEngine::RenderEngine() , _currentFadeTime(0.f) , _fadeDirection(0) // , _sgctRenderStatisticsVisible(false) - , _visualizeABuffer(false) - , _visualizer(nullptr) { _onScreenInformation = { glm::vec2(0.f), @@ -118,68 +113,82 @@ RenderEngine::RenderEngine() } RenderEngine::~RenderEngine() { - delete _abuffer; - _abuffer = nullptr; + delete _renderer; + _renderer = nullptr; delete _sceneGraph; _sceneGraph = nullptr; delete _mainCamera; - delete _visualizer; + + if (!_programs.empty()) { + for (int i = 0; i < _programs.size(); i++) { + delete _programs[i]; + _programs[i] = nullptr; + } + _programs.clear(); + } delete _performanceMemory; if (ghoul::SharedMemory::exists(PerformanceMeasurementSharedData)) ghoul::SharedMemory::remove(PerformanceMeasurementSharedData); } +void RenderEngine::setRendererFromString(const std::string& renderingMethod) { + _rendererImplementation = rendererFromString(renderingMethod); + + Renderer* newRenderer = nullptr; + switch (_rendererImplementation) { + case RendererImplementation::Framebuffer: + LINFO("Creating Framebuffer renderer"); + newRenderer = new FramebufferRenderer; + break; + case RendererImplementation::ABuffer: + LINFO("Creating ABuffer renderer"); + newRenderer = new ABufferRenderer(); + break; + case RendererImplementation::Invalid: + LFATAL("Rendering method '" << renderingMethod << "' not among the available " + << "rendering methods"); + } + + if (_renderer) { + _renderer->deinitialize(); + delete _renderer; + _renderer = nullptr; + } + setRenderer(newRenderer); +} + bool RenderEngine::initialize() { std::string renderingMethod = DefaultRenderingMethod; // If the user specified a rendering method that he would like to use, use that - if (OsEng.configurationManager()->hasKeyAndValue(KeyRenderingMethod)) + if (OsEng.configurationManager()->hasKeyAndValue(KeyRenderingMethod)) { renderingMethod = OsEng.configurationManager()->value(KeyRenderingMethod); - else { + } else { using Version = ghoul::systemcapabilities::OpenGLCapabilitiesComponent::Version; // The default rendering method has a requirement of OpenGL 4.3, so if we are // below that, we will fall back to frame buffer operation if (OpenGLCap.openGLVersion() < Version(4,3)) { LINFO("Falling back to framebuffer implementation due to OpenGL limitations"); - renderingMethod = "ABufferFrameBuffer"; + renderingMethod = "Framebuffer"; } } - _abufferImplementation = aBufferFromString(renderingMethod); - switch (_abufferImplementation) { - case ABufferImplementation::FrameBuffer: - LINFO("Creating ABufferFramebuffer implementation"); - _abuffer = new ABufferFramebuffer; - break; - case ABufferImplementation::SingleLinked: - LINFO("Creating ABufferSingleLinked implementation"); - _abuffer = new ABufferSingleLinked(); - break; - case ABufferImplementation::Fixed: - LINFO("Creating ABufferFixed implementation"); - _abuffer = new ABufferFixed(); - break; - case ABufferImplementation::Dynamic: - LINFO("Creating ABufferDynamic implementation"); - _abuffer = new ABufferDynamic(); - break; - case ABufferImplementation::Invalid: - LFATAL("Rendering method '" << renderingMethod << "' not among the available " - << "rendering methods"); - return false; - } - - generateGlslConfig(); + LINFO("Seting renderer from string: " << renderingMethod); + setRendererFromString(renderingMethod); // init camera and set temporary position and scaling _mainCamera = new Camera(); _mainCamera->setScaling(glm::vec2(1.0, -8.0)); _mainCamera->setPosition(psc(0.f, 0.f, 1.499823f, 11.f)); OsEng.interactionHandler()->setCamera(_mainCamera); + if (_renderer) { + _renderer->setCamera(_mainCamera); + } + #ifdef GHOUL_USE_DEVIL ghoul::io::TextureReader::ref().addReader(new ghoul::io::impl::TextureReaderDevIL); @@ -208,7 +217,7 @@ bool RenderEngine::initializeGL() { const float fontSizeMono = 10.f; _fontInfo = OsEng.fontManager().font(constants::fonts::keyMono, fontSizeMono); const float fontSizeLight = 8.f; - _fontLog = OsEng.fontManager().font(constants::fonts::keyLight, fontSizeLight); + _fontLog = OsEng.fontManager().font(constants::fonts::keyMono, fontSizeMono); @@ -286,16 +295,13 @@ bool RenderEngine::initializeGL() { _mainCamera->setMaxFov(maxFov); //} - LINFO("Initializing ABuffer"); - _abuffer->initialize(); + //LINFO("Initializing Renderer"); + //_renderer->initialize(); LINFO("Initializing Log"); _log = new ScreenLog(); ghoul::logging::LogManager::ref().addLog(_log); - LINFO("Initializing Visualizer"); - _visualizer = new ABufferVisualizer(); - LINFO("Finished initializing GL"); return true; } @@ -325,9 +331,10 @@ void RenderEngine::postSynchronizationPreDraw() { _mainCamera->postSynchronizationPreDraw(); bool windowResized = OsEng.windowWrapper().windowHasResized(); + if (windowResized) { - generateGlslConfig(); - _abuffer->reinitialize(); + glm::ivec2 res = OsEng.windowWrapper().currentWindowResolution(); + _renderer->setResolution(res); } // converts the quaternion used to rotation matrices @@ -343,8 +350,13 @@ void RenderEngine::postSynchronizationPreDraw() { }); _sceneGraph->evaluate(_mainCamera); - // clear the abuffer before rendering the scene - _abuffer->clear(); + _renderer->update(); + + for (auto program : _programs) { + if (program->isDirty()) { + program->rebuildFromFile(); + } + } //Allow focus node to update camera (enables camera-following) //FIX LATER: THIS CAUSES MASTER NODE TO BE ONE FRAME AHEAD OF SLAVES @@ -355,342 +367,22 @@ void RenderEngine::postSynchronizationPreDraw() { } void RenderEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix) { - // We need the window pointer -// sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); + _mainCamera->setViewMatrix(viewMatrix); + _mainCamera->setProjectionMatrix(projectionMatrix); - if (!OsEng.windowWrapper().isSimpleRendering()) -// if (sgct::Engine::instance()->getCurrentRenderTarget() == sgct::Engine::NonLinearBuffer) - _abuffer->clear(); - // SGCT resets certain settings - - if (_abufferImplementation == ABufferImplementation::FrameBuffer) { - glEnable(GL_DEPTH_TEST); - // glDisable(GL_CULL_FACE); - glEnable(GL_CULL_FACE); - // glDisable(GL_BLEND); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else { - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - glDisable(GL_BLEND); - } - // setup the camera for the current frame - - _mainCamera->setViewMatrix( - viewMatrix ); - _mainCamera->setProjectionMatrix( - projectionMatrix); - //Is this really necessary to store? @JK - _mainCamera->setViewProjectionMatrix(projectionMatrix * viewMatrix); - - // We only want to skip the rendering if we are the master and we want to - // disable the rendering for the master - if (!(OsEng.isMaster() && _disableMasterRendering)) { - if (!_visualizeABuffer) { - _abuffer->preRender(); - _sceneGraph->render({ - *_mainCamera, - psc(), - _doPerformanceMeasurements - }); - _abuffer->postRender(); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - _abuffer->resolve(_globalBlackOutFactor); - glDisable(GL_BLEND); - } - else { - _visualizer->render(); - } - } + if (!(OsEng.isMaster() && _disableMasterRendering)) { + _renderer->render(_globalBlackOutFactor, _doPerformanceMeasurements); + } // Print some useful information on the master viewport - if (OsEng.ref().isMaster() && OsEng.windowWrapper().isSimpleRendering()) { - // TODO: Adjust font_size properly when using retina screen - const float fontSizeMono = 10.f; - const float fontSizeTime = 15.f; - - using Font = ghoul::fontrendering::Font; - using ghoul::fontrendering::RenderFont; - - - if (_showInfo && _fontDate && _fontInfo) { - double currentTime = Time::ref().currentTime(); - - glm::vec2 penPosition = glm::vec2( - 10.f, - OsEng.windowWrapper().viewportPixelCoordinates().w - ); - penPosition.y -= _fontDate->height(); - - RenderFontCr(_fontDate, - penPosition, - "Date: %s", - Time::ref().currentTimeUTC().c_str() - ); - - RenderFontCr(_fontInfo, - penPosition, - "Simulation increment (s): %.0f", - Time::ref().deltaTime() - ); - - RenderFontCr(_fontInfo, - penPosition, - "Avg. Frametime: %.5f", - OsEng.windowWrapper().averageDeltaTime() - ); - -#ifdef OPENSPACE_MODULE_NEWHORIZONS_ENABLED - if (openspace::ImageSequencer2::ref().isReady()) { - penPosition.y -= 25.f; - - glm::vec4 targetColor(0.00, 0.75, 1.00, 1); - - psc nhPos; - double lt; - SpiceManager::ref().getTargetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", "NONE", currentTime, nhPos, lt); - float a, b, c; - SpiceManager::ref().getPlanetEllipsoid("PLUTO", a, b, c); - float radius = (a + b) / 2.f; - float distToSurf = glm::length(nhPos.vec3()) - radius; - - RenderFont(_fontInfo, - penPosition, - "Distance to Pluto: % .1f (KM)", - distToSurf - ); - penPosition.y -= _fontInfo->height(); - - - double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - currentTime; - float t = static_cast(1.0 - remaining / openspace::ImageSequencer2::ref().getIntervalLength()); - std::string progress = "|"; - int g = static_cast((t* 24) + 1); - g = std::max(g, 0); - for (int i = 0; i < g; i++) - progress.append("-"); - progress.append(">"); - for (int i = 0; i < 25 - g; i++) - progress.append(" "); - - std::string str = ""; - openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer2::ref().getNextCaptureTime(), str, "YYYY MON DD HR:MN:SC"); - - glm::vec4 active(0.6, 1, 0.00, 1); - glm::vec4 brigther_active(0.9, 1, 0.75, 1); - - progress.append("|"); - if (remaining > 0) { - brigther_active *= (1 - t); - - RenderFontCr(_fontInfo, - penPosition, - active * t + brigther_active, - "Next instrument activity:" - ); - - RenderFontCr(_fontInfo, - penPosition, - active * t + brigther_active, - "%.0f s %s %.1f %%", - remaining, progress.c_str(), t * 100 - ); - - RenderFontCr(_fontInfo, - penPosition, - active, - "Data acquisition time: %s", - str.c_str() - ); - } - std::pair nextTarget = ImageSequencer2::ref().getNextTarget(); - std::pair currentTarget = ImageSequencer2::ref().getCurrentTarget(); - - if (currentTarget.first > 0.0) { - int timeleft = static_cast(nextTarget.first - currentTime); - - int hour = timeleft / 3600; - int second = timeleft % 3600; - int minute = second / 60; - second = second % 60; - - std::string hh, mm, ss, coundtown; - - if (hour < 10) hh.append("0"); - if (minute < 10) mm.append("0"); - if (second < 10) ss.append("0"); - - hh.append(std::to_string(hour)); - mm.append(std::to_string(minute)); - ss.append(std::to_string(second)); - - RenderFontCr(_fontInfo, - penPosition, - targetColor, - "Data acquisition adjacency: [%s:%s:%s]", - hh.c_str(), mm.c_str(), ss.c_str() - ); - - - std::pair> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2); - std::string space; - glm::vec4 color; - size_t isize = incidentTargets.second.size(); - for (size_t p = 0; p < isize; p++){ - double t = static_cast(p + 1) / static_cast(isize + 1); - t = (p > isize / 2) ? 1 - t : t; - t += 0.3; - color = (p == isize / 2) ? targetColor : glm::vec4(t, t, t, 1); - - RenderFont(_fontInfo, - penPosition, - color, - "%s%s", - space.c_str(), incidentTargets.second[p].c_str() - ); - - - for (int k = 0; k < incidentTargets.second[p].size() + 2; k++) - space += " "; - } - penPosition.y -= _fontInfo->height(); - - std::map activeMap = ImageSequencer2::ref().getActiveInstruments(); - glm::vec4 firing(0.58-t, 1-t, 1-t, 1); - glm::vec4 notFiring(0.5, 0.5, 0.5, 1); - - RenderFontCr(_fontInfo, - penPosition, - active, - "Active Instruments:" - ); - - for (auto t : activeMap){ - if (t.second == false) { - RenderFont(_fontInfo, - penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - "| |" - ); - RenderFontCr(_fontInfo, - penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - " %5s", - t.first.c_str() - ); - - } - else{ - RenderFont(_fontInfo, - penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - "|" - ); - if (t.first == "NH_LORRI") { - RenderFont(_fontInfo, - penPosition, - firing, - " + " - ); - } - RenderFont(_fontInfo, - penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - " |" - ); - RenderFontCr(_fontInfo, - penPosition, - active, - " %5s", - t.first.c_str() - ); - } - } - } - } -#endif - } - if (_showScreenLog) { - const int max = 10; - const int category_length = 20; - const int msg_length = 140; - const float ttl = 15.f; - const float fade = 5.f; - auto entries = _log->last(max); - - const glm::vec4 white(0.9, 0.9, 0.9, 1); - const glm::vec4 red(1, 0, 0, 1); - const glm::vec4 yellow(1, 1, 0, 1); - const glm::vec4 green(0, 1, 0, 1); - const glm::vec4 blue(0, 0, 1, 1); - - size_t nr = 1; - for (auto& it = entries.first; it != entries.second; ++it) { - const ScreenLog::LogEntry* e = &(*it); - - const double t = OsEng.windowWrapper().time(); - float diff = static_cast(t - e->timeStamp); - - // Since all log entries are ordered, once one is exceeding TTL, all have -// if (diff > ttl) -// break; - - float alpha = 1; - float ttf = ttl - fade; - if (diff > ttf) { - diff = diff - ttf; - float p = 0.8f - diff / fade; - alpha = (p <= 0.f) ? 0.f : pow(p, 0.3f); - } - - alpha = 1.f; - - // Since all log entries are ordered, once one exceeds alpha, all have - if (alpha <= 0.0) - break; - - const std::string lvl = "(" + ghoul::logging::LogManager::stringFromLevel(e->level) + ")"; - const std::string& message = e->message.substr(0, msg_length); - nr += std::count(message.begin(), message.end(), '\n'); - - RenderFont(_fontLog, - glm::vec2(10.f, _fontLog->pointSize() * nr * 2), - white * alpha, - "%-14s %s%s", // Format - e->timeString.c_str(), // Time string - e->category.substr(0, category_length).c_str(), // Category string (up to category_length) - e->category.length() > 20 ? "..." : ""); // Pad category with "..." if exceeds category_length - - glm::vec4 color = white; - if (e->level == ghoul::logging::LogManager::LogLevel::Debug) - color = green; - if (e->level == ghoul::logging::LogManager::LogLevel::Warning) - color = yellow; - if (e->level == ghoul::logging::LogManager::LogLevel::Error) - color = red; - if (e->level == ghoul::logging::LogManager::LogLevel::Fatal) - color = blue; - -// const float font_with_light = 5; - RenderFont(_fontLog, - glm::vec2(static_cast(10 + 39 * _fontLog->pointSize()), _fontLog->pointSize() * nr * 2), - color * alpha, - "%s", // Format - lvl.c_str()); // Pad category with "..." if exceeds category_length - - RenderFont(_fontLog, - glm::vec2(static_cast(10 + 53 * _fontLog->pointSize()), _fontLog->pointSize() * nr * 2), - white * alpha, - "%s", // Format - message.c_str()); // Pad category with "..." if exceeds category_length - ++nr; - } - } + if (OsEng.isMaster() && OsEng.windowWrapper().isSimpleRendering()) { + if (_showInfo) { + renderInformation(); + } + if (_showLog) { + renderScreenLog(); + } } } @@ -710,16 +402,6 @@ void RenderEngine::takeScreenshot() { _takeScreenshot = true; } -void RenderEngine::toggleVisualizeABuffer(bool b) { - _visualizeABuffer = b; - if (!_visualizeABuffer) - return; - - std::vector _d = _abuffer->pixelData(); - _visualizer->updateData(_d); -} - - void RenderEngine::toggleInfoText(bool b) { _showInfo = b; } @@ -761,12 +443,12 @@ Camera* RenderEngine::camera() const { return _mainCamera; } -ABuffer* RenderEngine::aBuffer() const { - return _abuffer; +Renderer* RenderEngine::renderer() const { + return _renderer; } -RenderEngine::ABufferImplementation RenderEngine::aBufferImplementation() const { - return _abufferImplementation; +RenderEngine::RendererImplementation RenderEngine::rendererImplementation() const { + return _rendererImplementation; } float RenderEngine::globalBlackOutFactor() { @@ -783,38 +465,104 @@ void RenderEngine::startFading(int direction, float fadeDuration) { _currentFadeTime = 0.f; } -void RenderEngine::generateGlslConfig() { - ghoul_assert(_abuffer != nullptr, "ABuffer not initialized"); - LDEBUG("Generating GLSLS config, expect shader recompilation"); - glm::ivec2 size = OsEng.windowWrapper().currentWindowResolution(); +/** + * Build a program object for rendering with the used renderer + */ +ghoul::opengl::ProgramObject* RenderEngine::buildRenderProgram( + std::string name, + std::string vsPath, + std::string fsPath, + const ghoul::Dictionary& data) { - // TODO: Make this file creation dynamic and better in every way - // TODO: If the screen size changes it is enough if this file is regenerated to - // recompile all necessary files - std::ofstream os(absPath("${SHADERS_GENERATED}/constants.hglsl")); - os << "#ifndef CONSTANTS_HGLSL\n" - << "#define CONSTANTS_HGLSL\n" - << "#define SCREEN_WIDTH " << size.x << "\n" - << "#define SCREEN_HEIGHT " << size.y << "\n" - << "#define MAX_LAYERS " << ABuffer::MAX_LAYERS << "\n" - << "#define ABUFFER_FRAMEBUFFER " << ABUFFER_FRAMEBUFFER << "\n" - << "#define ABUFFER_SINGLE_LINKED " << ABUFFER_SINGLE_LINKED << "\n" - << "#define ABUFFER_FIXED " << ABUFFER_FIXED << "\n" - << "#define ABUFFER_DYNAMIC " << ABUFFER_DYNAMIC << "\n" - << "#define ABUFFER_IMPLEMENTATION " << int(_abufferImplementation) << "\n"; - // System specific -#ifdef WIN32 - os << "#define WIN32\n"; -#endif -#ifdef __APPLE__ - os << "#define APPLE\n"; -#endif -#ifdef __linux__ - os << "#define linux\n"; -#endif - os << "#endif\n"; + ghoul::Dictionary dict = data; - os.close(); + // set path to the current renderer's main fragment shader + dict.setValue("rendererData", _rendererData); + // 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); + + ghoul::opengl::ProgramObject* program = ghoul::opengl::ProgramObject::Build(name, + vsPath, + RenderFsPath, + dict); + if (program) { + _programs.push_back(program); + } + return program; +} + +/** + * Build a program object for rendering with the used renderer + */ +ghoul::opengl::ProgramObject* RenderEngine::buildRenderProgram( + std::string name, + std::string vsPath, + std::string fsPath, + std::string csPath, + const ghoul::Dictionary& data) { + + ghoul::Dictionary dict = data; + dict.setValue("rendererData", _rendererData); + + // 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); + + ghoul::opengl::ProgramObject* program = ghoul::opengl::ProgramObject::Build(name, + vsPath, + RenderFsPath, + csPath, + dict); + if (program) { + _programs.push_back(program); + } + return program; +} + +void RenderEngine::removeRenderProgram(ghoul::opengl::ProgramObject* program) { + if (program == nullptr) + return; + std::vector::iterator it = std::find(_programs.begin(), + _programs.end(), + program); + if (it != _programs.end()) { + _programs.erase(it); + } + delete program; +} + +/** + * Set renderer data + * Called from the renderer, whenever it needs to update + * the dictionary of all rendering programs. + */ +void RenderEngine::setRendererData(const ghoul::Dictionary& data) { + _rendererData = data; + for (auto program : _programs) { + ghoul::Dictionary dict = program->getDictionary(); + dict.setValue("rendererData", _rendererData); + program->setDictionary(dict); + } +} + +/** + * Set renderer + */ +void RenderEngine::setRenderer(Renderer* renderer) { + glm::ivec2 res = OsEng.windowWrapper().currentWindowResolution(); + + if (_renderer) { + _renderer->deinitialize(); + } + + _renderer = renderer; + _renderer->setResolution(res); + _renderer->initialize(); + _renderer->setCamera(_mainCamera); + _renderer->setScene(_sceneGraph); } scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { @@ -828,11 +576,10 @@ scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { "Renders the current image to a file on disk" }, { - "visualizeABuffer", - &luascriptfunctions::visualizeABuffer, - "bool", - "Toggles the visualization of the ABuffer", - true + "setRenderer", + &luascriptfunctions::setRenderer, + "string", + "Sets the renderer (ABuffer or FrameBuffer)" }, { "showRenderInformation", @@ -1340,18 +1087,305 @@ void RenderEngine::setDisableRenderingOnMaster(bool enabled) { _disableMasterRendering = enabled; } -RenderEngine::ABufferImplementation RenderEngine::aBufferFromString(const std::string& impl) { - const std::map RenderingMethods = { - { "ABufferFrameBuffer", ABufferImplementation::FrameBuffer }, - { "ABufferSingleLinked", ABufferImplementation::SingleLinked }, - { "ABufferFixed", ABufferImplementation::Fixed }, - { "ABufferDynamic", ABufferImplementation::Dynamic } +RenderEngine::RendererImplementation RenderEngine::rendererFromString(const std::string& impl) { + const std::map RenderingMethods = { + { "ABuffer", RendererImplementation::ABuffer }, + { "Framebuffer", RendererImplementation::Framebuffer } }; if (RenderingMethods.find(impl) != RenderingMethods.end()) return RenderingMethods.at(impl); else - return ABufferImplementation::Invalid; + return RendererImplementation::Invalid; +} + +void RenderEngine::renderInformation() { + // TODO: Adjust font_size properly when using retina screen + const float fontSizeMono = 10.f; + const float fontSizeTime = 15.f; + + using Font = ghoul::fontrendering::Font; + using ghoul::fontrendering::RenderFont; + + + if (!_fontDate || !_fontInfo) { + return; + } + double currentTime = Time::ref().currentTime(); + + glm::vec2 penPosition = glm::vec2( + 10.f, + OsEng.windowWrapper().viewportPixelCoordinates().w + ); + penPosition.y -= _fontDate->height(); + + RenderFontCr(_fontDate, + penPosition, + "Date: %s", + Time::ref().currentTimeUTC().c_str() + ); + + RenderFontCr(_fontInfo, + penPosition, + "Simulation increment (s): %.0f", + Time::ref().deltaTime() + ); + + RenderFontCr(_fontInfo, + penPosition, + "Avg. Frametime: %.5f", + OsEng.windowWrapper().averageDeltaTime() + ); + +#ifdef OPENSPACE_MODULE_NEWHORIZONS_ENABLED + if (openspace::ImageSequencer2::ref().isReady()) { + penPosition.y -= 25.f; + + glm::vec4 targetColor(0.00, 0.75, 1.00, 1); + + psc nhPos; + double lt; + SpiceManager::ref().getTargetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", "NONE", currentTime, nhPos, lt); + float a, b, c; + SpiceManager::ref().getPlanetEllipsoid("PLUTO", a, b, c); + float radius = (a + b) / 2.f; + float distToSurf = glm::length(nhPos.vec3()) - radius; + + RenderFont(_fontInfo, + penPosition, + "Distance to Pluto: % .1f (KM)", + distToSurf + ); + penPosition.y -= _fontInfo->height(); + + + double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - currentTime; + float t = static_cast(1.0 - remaining / openspace::ImageSequencer2::ref().getIntervalLength()); + std::string progress = "|"; + int g = static_cast((t* 24) + 1); + g = std::max(g, 0); + for (int i = 0; i < g; i++) + progress.append("-"); + progress.append(">"); + for (int i = 0; i < 25 - g; i++) + progress.append(" "); + + std::string str = ""; + openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer2::ref().getNextCaptureTime(), str, "YYYY MON DD HR:MN:SC"); + + glm::vec4 active(0.6, 1, 0.00, 1); + glm::vec4 brigther_active(0.9, 1, 0.75, 1); + + progress.append("|"); + if (remaining > 0) { + brigther_active *= (1 - t); + + RenderFontCr(_fontInfo, + penPosition, + active * t + brigther_active, + "Next instrument activity:" + ); + + RenderFontCr(_fontInfo, + penPosition, + active * t + brigther_active, + "%.0f s %s %.1f %%", + remaining, progress.c_str(), t * 100 + ); + + RenderFontCr(_fontInfo, + penPosition, + active, + "Data acquisition time: %s", + str.c_str() + ); + } + std::pair nextTarget = ImageSequencer2::ref().getNextTarget(); + std::pair currentTarget = ImageSequencer2::ref().getCurrentTarget(); + + if (currentTarget.first > 0.0) { + int timeleft = static_cast(nextTarget.first - currentTime); + + int hour = timeleft / 3600; + int second = timeleft % 3600; + int minute = second / 60; + second = second % 60; + + std::string hh, mm, ss, coundtown; + + if (hour < 10) hh.append("0"); + if (minute < 10) mm.append("0"); + if (second < 10) ss.append("0"); + + hh.append(std::to_string(hour)); + mm.append(std::to_string(minute)); + ss.append(std::to_string(second)); + + RenderFontCr(_fontInfo, + penPosition, + targetColor, + "Data acquisition adjacency: [%s:%s:%s]", + hh.c_str(), mm.c_str(), ss.c_str() + ); + + + std::pair> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2); + std::string space; + glm::vec4 color; + size_t isize = incidentTargets.second.size(); + for (size_t p = 0; p < isize; p++){ + double t = static_cast(p + 1) / static_cast(isize + 1); + t = (p > isize / 2) ? 1 - t : t; + t += 0.3; + color = (p == isize / 2) ? targetColor : glm::vec4(t, t, t, 1); + + RenderFont(_fontInfo, + penPosition, + color, + "%s%s", + space.c_str(), incidentTargets.second[p].c_str() + ); + + + for (int k = 0; k < incidentTargets.second[p].size() + 2; k++) + space += " "; + } + penPosition.y -= _fontInfo->height(); + + std::map activeMap = ImageSequencer2::ref().getActiveInstruments(); + glm::vec4 firing(0.58-t, 1-t, 1-t, 1); + glm::vec4 notFiring(0.5, 0.5, 0.5, 1); + + RenderFontCr(_fontInfo, + penPosition, + active, + "Active Instruments:" + ); + + for (auto t : activeMap){ + if (t.second == false) { + RenderFont(_fontInfo, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + "| |" + ); + RenderFontCr(_fontInfo, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + " %5s", + t.first.c_str() + ); + + } else { + RenderFont(_fontInfo, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + "|" + ); + if (t.first == "NH_LORRI") { + RenderFont(_fontInfo, + penPosition, + firing, + " + " + ); + } + RenderFont(_fontInfo, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + " |" + ); + RenderFontCr(_fontInfo, + penPosition, + active, + " %5s", + t.first.c_str() + ); + } + } + } + } +#endif +} + +void RenderEngine::renderScreenLog() { + + if (!_fontLog) { + return; + } + + const int max = 10; + const int category_length = 20; + const int msg_length = 140; + const float ttl = 15.f; + const float fade = 5.f; + auto entries = _log->last(max); + + const glm::vec4 white(0.9, 0.9, 0.9, 1); + const glm::vec4 red(1, 0, 0, 1); + const glm::vec4 yellow(1, 1, 0, 1); + const glm::vec4 green(0, 1, 0, 1); + const glm::vec4 blue(0, 0, 1, 1); + + size_t nr = 1; + for (auto& it = entries.first; it != entries.second; ++it) { + const ScreenLog::LogEntry* e = &(*it); + + const double t = OsEng.windowWrapper().time(); + float diff = static_cast(t - e->timeStamp); + + // Since all log entries are ordered, once one is exceeding TTL, all have +// if (diff > ttl) +// break; + + float alpha = 1; + float ttf = ttl - fade; + if (diff > ttf) { + diff = diff - ttf; + float p = 0.8f - diff / fade; + alpha = (p <= 0.f) ? 0.f : pow(p, 0.3f); + } + + alpha = 1.f; + + // Since all log entries are ordered, once one exceeds alpha, all have + if (alpha <= 0.0) + break; + + const std::string lvl = "(" + ghoul::logging::LogManager::stringFromLevel(e->level) + ")"; + const std::string& message = e->message.substr(0, msg_length); + nr += std::count(message.begin(), message.end(), '\n'); + + RenderFont(_fontLog, + glm::vec2(10.f, _fontLog->pointSize() * nr * 2), + white * alpha, + "%-14s %s%s", // Format + e->timeString.c_str(), // Time string + e->category.substr(0, category_length).c_str(), // Category string (up to category_length) + e->category.length() > 20 ? "..." : ""); // Pad category with "..." if exceeds category_length + + glm::vec4 color = white; + if (e->level == ghoul::logging::LogManager::LogLevel::Debug) + color = green; + if (e->level == ghoul::logging::LogManager::LogLevel::Warning) + color = yellow; + if (e->level == ghoul::logging::LogManager::LogLevel::Error) + color = red; + if (e->level == ghoul::logging::LogManager::LogLevel::Fatal) + color = blue; + + RenderFont(_fontLog, + glm::vec2(static_cast(10 + 39 * _fontLog->pointSize()), _fontLog->pointSize() * nr * 2), + color * alpha, + "%s", // Format + lvl.c_str()); // Pad category with "..." if exceeds category_length + + RenderFont(_fontLog, + glm::vec2(static_cast(10 + 53 * _fontLog->pointSize()), _fontLog->pointSize() * nr * 2), + white * alpha, + "%s", // Format + message.c_str()); // Pad category with "..." if exceeds category_length + ++nr; + } } }// namespace openspace diff --git a/src/rendering/renderengine_lua.inl b/src/rendering/renderengine_lua.inl index 7d0ea22a00..d529c644bd 100644 --- a/src/rendering/renderengine_lua.inl +++ b/src/rendering/renderengine_lua.inl @@ -53,19 +53,19 @@ int takeScreenshot(lua_State* L) { /** * \ingroup LuaScripts -* visualizeABuffer(bool): -* Toggle the visualization of the ABuffer +* setRenderer(string): +* Set renderer */ -int visualizeABuffer(lua_State* L) { +int setRenderer(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_TBOOLEAN) + if (type != LUA_TSTRING) return luaL_error(L, "Expected argument of type 'bool'"); - bool b = lua_toboolean(L, -1) != 0; - OsEng.renderEngine()->toggleVisualizeABuffer(b); + std::string r = lua_tostring(L, -1); + OsEng.renderEngine()->setRendererFromString(r); return 0; } diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index 4dd7d32384..10fd0ffecf 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -84,61 +84,24 @@ bool Scene::initialize() { using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; + RenderEngine* renderEngine = OsEng.renderEngine(); + ProgramObject* tmpProgram; - ghoul::opengl::ProgramObject::ProgramObjectCallback cb = [this](ghoul::opengl::ProgramObject* program) { - _programUpdateLock.lock(); - _programsToUpdate.insert(program); - _programUpdateLock.unlock(); - }; - // fboPassthrough program - tmpProgram = ProgramObject::Build("fboPassProgram", + tmpProgram = ProgramObject::Build( + "fboPassProgram", "${SHADERS}/fboPass_vs.glsl", "${SHADERS}/fboPass_fs.glsl"); if (!tmpProgram) return false; - tmpProgram->setProgramObjectCallback(cb); - _programs.push_back(tmpProgram); + tmpProgram->setIgnoreSubroutineUniformLocationError(true); OsEng.ref().configurationManager()->setValue("fboPassProgram", tmpProgram); - // pscstandard - tmpProgram = ProgramObject::Build("pscstandard", - "${SHADERS}/pscstandard_vs.glsl", - "${SHADERS}/pscstandard_fs.glsl"); - if( ! tmpProgram) return false; - tmpProgram->setProgramObjectCallback(cb); - _programs.push_back(tmpProgram); - OsEng.ref().configurationManager()->setValue("pscShader", tmpProgram); - - // Night texture program - tmpProgram = ProgramObject::Build("nightTextureProgram", - "${SHADERS}/nighttexture_vs.glsl", - "${SHADERS}/nighttexture_fs.glsl"); - if (!tmpProgram) return false; - tmpProgram->setProgramObjectCallback(cb); - _programs.push_back(tmpProgram); - OsEng.ref().configurationManager()->setValue("nightTextureProgram", tmpProgram); - - // RaycastProgram - tmpProgram = ProgramObject::Build("RaycastProgram", - "${SHADERS}/exitpoints.vert", - "${SHADERS}/exitpoints.frag"); - if (!tmpProgram) return false; - tmpProgram->setProgramObjectCallback(cb); - _programs.push_back(tmpProgram); - OsEng.ref().configurationManager()->setValue("RaycastProgram", tmpProgram); - return true; } bool Scene::deinitialize() { clearSceneGraph(); - - // clean up all programs - _programsToUpdate.clear(); - for (ghoul::opengl::ProgramObject* program : _programs) - delete program; - _programs.clear(); return true; } @@ -149,7 +112,6 @@ void Scene::update(const UpdateData& data) { _sceneGraphToLoad = ""; if (!success) return; - OsEng.renderEngine()->aBuffer()->invalidateABuffer(); } for (SceneGraphNode* node : _graph.nodes()) node->update(data); @@ -162,27 +124,18 @@ void Scene::evaluate(Camera* camera) { } void Scene::render(const RenderData& data) { - bool emptyProgramsToUpdate = _programsToUpdate.empty(); - - _programUpdateLock.lock(); - for (ghoul::opengl::ProgramObject* program : _programsToUpdate) { - LDEBUG("Attempting to recompile " << program->name()); - program->rebuildFromFile(); - } - _programsToUpdate.erase(_programsToUpdate.begin(), _programsToUpdate.end()); - _programUpdateLock.unlock(); - - if (!emptyProgramsToUpdate) { - LDEBUG("Setting uniforms"); - // Ignore attribute locations - for (ghoul::opengl::ProgramObject* program : _programs) - program->setIgnoreSubroutineUniformLocationError(true); - } - for (SceneGraphNode* node : _graph.nodes()) node->render(data); - //if (_root) - // _root->render(data); +} + +std::vector> Scene::volumesToRender(const RenderData& data) const { + std::vector> volumes; + + for (const SceneGraphNode* node : _graph.nodes()) { + std::vector> newVolumes = node->volumesToRender(data); + std::copy(newVolumes.begin(), newVolumes.end(), std::back_inserter(volumes)); + } + return volumes; } void Scene::scheduleLoadSceneFile(const std::string& sceneDescriptionFilePath) { diff --git a/src/scene/scenegraph.cpp b/src/scene/scenegraph.cpp index 33a9bf607d..3f4e23adbc 100644 --- a/src/scene/scenegraph.cpp +++ b/src/scene/scenegraph.cpp @@ -336,7 +336,7 @@ bool SceneGraph::sortTopologically() { } } - + /* RenderEngine::ABufferImplementation i = OsEng.renderEngine()->aBufferImplementation(); if (i == RenderEngine::ABufferImplementation::FrameBuffer) { auto it = std::find_if( @@ -361,7 +361,7 @@ bool SceneGraph::sortTopologically() { _topologicalSortedNodes.erase(it); _topologicalSortedNodes.insert(_topologicalSortedNodes.begin() + 2, n); } - + */ return true; } @@ -390,7 +390,7 @@ SceneGraph::SceneGraphNodeInternal* SceneGraph::nodeByName(const std::string& na return *it; } -const std::vector& SceneGraph::nodes() { +const std::vector& SceneGraph::nodes() const { return _topologicalSortedNodes; } diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index 40d3817230..e8bf9c3208 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -272,6 +272,19 @@ void SceneGraphNode::render(const RenderData& data) { // child->render(newData); } +std::vector> SceneGraphNode::volumesToRender(const RenderData& data) const { + const psc thisPosition = worldPosition(); + RenderData newData = {data.camera, thisPosition, data.doPerformanceMeasurement}; + std::vector> toRender; + if (_renderableVisible && _renderable->isVisible() && _renderable->isReady() && _renderable->isEnabled()) { + std::vector volumes = _renderable->volumesToRender(newData); + for (Volume* v : volumes) { + toRender.push_back(std::make_pair(v, newData)); + } + } + return toRender; +} + // not used anymore @AA //void SceneGraphNode::addNode(SceneGraphNode* child) //{ diff --git a/src/util/blockplaneintersectiongeometry.cpp b/src/util/blockplaneintersectiongeometry.cpp new file mode 100644 index 0000000000..e48a87701a --- /dev/null +++ b/src/util/blockplaneintersectiongeometry.cpp @@ -0,0 +1,177 @@ +/***************************************************************************************** + * * + * 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 = "BlockPlaneIntersectionGeometry"; +} + + + +namespace openspace { + + +BlockPlaneIntersectionGeometry::BlockPlaneIntersectionGeometry( + glm::vec3 blockSize, + glm::vec3 planeNormal, + float planeDistance) + : _initialized(false) + , _vaoId(0) + , _vBufferId(0) + , _size(blockSize) {} + +BlockPlaneIntersectionGeometry::~BlockPlaneIntersectionGeometry() { + glDeleteBuffers(1, &_vBufferId); + glDeleteVertexArrays(1, &_vaoId); +} + + +void BlockPlaneIntersectionGeometry::setBlockSize(glm::vec3 size) { + _size = size; + updateVertices(); +} + +void BlockPlaneIntersectionGeometry::setPlane(glm::vec3 normal, float distance) { + _normal = glm::normalize(normal); + _planeDistance = distance; + updateVertices(); +} + +void BlockPlaneIntersectionGeometry::updateVertices() { + _vertices.clear(); + + const int cornersInLines[24] = { + 0,1, + 1,5, + 5,4, + 4,0, + + 2,3, + 3,7, + 7,6, + 6,2, + + 0,2, + 1,3, + 5,7, + 4,6 + }; + + glm::vec3 halfSize = _size * 0.5f; + glm::vec3 intersections[12]; + int nIntersections = 0; + + for (int i = 0; i < 12; i++) { + int iCorner0 = cornersInLines[i * 2]; + int iCorner1 = cornersInLines[i * 2 + 1]; + + glm::vec3 corner0 = glm::vec3(iCorner0 % 2, (iCorner0 / 2) % 2, iCorner0 / 4) - halfSize; + glm::vec3 corner1 = glm::vec3(iCorner1 % 2, (iCorner1 / 2) % 2, iCorner1 / 4) - halfSize; + + glm::vec3 line = corner1 - corner0; + + float t = (_planeDistance - glm::dot(corner0, _normal)) / glm::dot(line, _normal); + if (t >= 0.0 && t <= 1.0) { + intersections[nIntersections++] = corner0 + t * line; + } + } + + if (nIntersections <3) return; // Gotta love intersections + + // Construct vectors vectors (vectors1 .. vectorsN) between the N points + + std::vector< std::pair > angles(nIntersections-1); + + glm::vec3 vector1 = glm::normalize(intersections[1] - intersections[0]); + angles[0] = std::pair(1, 0.0); + + for (int i = 2; i < nIntersections; i++) { + glm::vec3 vectorI = glm::normalize(intersections[i] - intersections[0]); + float sinA = glm::dot(glm::cross(vector1, vectorI), _normal); + float cosA = glm::dot(vector1, vectorI); + angles[i-1] = std::pair(i, glm::sign(sinA) * (1.0 - cosA)); + } + + // Sort the vectors by angle in the plane + std::sort(angles.begin(), angles.end(), + [](const std::pair& a, const std::pair& b) -> bool { + return a.second > b.second; + } + ); + + _vertices.push_back(intersections[0].x); + _vertices.push_back(intersections[0].y); + _vertices.push_back(intersections[0].z); + //_vertices.push_back(_w); + for (int i = 0; i < nIntersections - 1; i++) { + int j = angles[i].first; + _vertices.push_back(intersections[j].x); + _vertices.push_back(intersections[j].y); + _vertices.push_back(intersections[j].z); + //_vertices.push_back(_w); + } +} + +bool BlockPlaneIntersectionGeometry::initialize() { + if (_vaoId == 0) + glGenVertexArrays(1, &_vaoId); + + if (_vBufferId == 0) { + glGenBuffers(1, &_vBufferId); + + if (_vBufferId == 0) { + LERROR("Could not create vertex buffer"); + return false; + } + } + + updateVertices(); + // First VAO setup + glBindVertexArray(_vaoId); + + glBindBuffer(GL_ARRAY_BUFFER, _vBufferId); + glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(GLfloat), _vertices.data(), GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0); + + glBindVertexArray(0); + return true; +} + +void BlockPlaneIntersectionGeometry::render() { + glBindVertexArray(_vaoId); // select first VAO + glDrawArrays(GL_TRIANGLES, 0, 6*6); + glBindVertexArray(0); +} + +} + diff --git a/src/util/boxgeometry.cpp b/src/util/boxgeometry.cpp new file mode 100644 index 0000000000..1a47ceced7 --- /dev/null +++ b/src/util/boxgeometry.cpp @@ -0,0 +1,128 @@ +/***************************************************************************************** + * * + * 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 + +namespace { +const std::string _loggerCat = "BoxGeometry"; +} + +namespace openspace { + +BoxGeometry::BoxGeometry(glm::vec3 size) + : _vaoId(0) + , _vBufferId(0) + , _size(size) +{} + +BoxGeometry::~BoxGeometry() { + glDeleteBuffers(1, &_vBufferId); + glDeleteVertexArrays(1, &_vaoId); +} + + +bool BoxGeometry::initialize() { + // Initialize and upload to graphics card + float x = _size.x * 0.5; + float y = _size.y * 0.5; + float z = _size.z * 0.5; + + const GLfloat vertices[] = { + -x, y, z, + x, y, z, + -x, y, z, + -x, -y, z, + x, -y, z, + x, y, z, + + -x, -y, -z, + x, y, -z, + -x, y, -z, + -x, -y, -z, + x, -y, -z, + x, y, -z, + + x, -y, -z, + x, y, z, + x, -y, z, + x, -y, -z, + x, y, -z, + x, y, z, + + -x, -y, -z, + -x, y, z, + -x, -y, z, + -x, -y, -z, + -x, y, -z, + -x, y, z, + + -x, y, -z, + x, y, z, + -x, y, z, + -x, y, -z, + x, y, -z, + x, y, z, + + -x, -y, -z, + x, -y, z, + -x, -y, z, + -x, -y, -z, + x, -y, -z, + x, -y, z + }; + + if (_vaoId == 0) + glGenVertexArrays(1, &_vaoId); + + if (_vBufferId == 0) { + glGenBuffers(1, &_vBufferId); + + if (_vBufferId == 0) { + LERROR("Could not create vertex buffer"); + return false; + } + } + + // First VAO setup + glBindVertexArray(_vaoId); + + glBindBuffer(GL_ARRAY_BUFFER, _vBufferId); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3, 0); + + glBindVertexArray(0); + return true; +} + +void BoxGeometry::render() { + glBindVertexArray(_vaoId); // select first VAO + glDrawArrays(GL_TRIANGLES, 0, 6*6); + glBindVertexArray(0); +} + +} diff --git a/src/util/camera.cpp b/src/util/camera.cpp index c67170f5b3..dcdb131352 100644 --- a/src/util/camera.cpp +++ b/src/util/camera.cpp @@ -38,6 +38,7 @@ Camera::Camera() , _modelMatrix() , _viewMatrix() , _projectionMatrix() + , _dirtyViewProjectionMatrix(true) , _viewDirection(0,0,-1) , _cameraDirection(0.f, 0.f, 0.f) , _focusPosition() @@ -85,6 +86,7 @@ const glm::mat4& Camera::modelMatrix() const{ void Camera::setViewMatrix(glm::mat4 viewMatrix){ std::lock_guard _lock(_mutex); _viewMatrix = std::move(viewMatrix); + _dirtyViewProjectionMatrix = true; } const glm::mat4& Camera::viewMatrix() const{ @@ -94,20 +96,19 @@ const glm::mat4& Camera::viewMatrix() const{ void Camera::setProjectionMatrix(glm::mat4 projectionMatrix){ std::lock_guard _lock(_mutex); _projectionMatrix = std::move(projectionMatrix); + _dirtyViewProjectionMatrix = true; } const glm::mat4& Camera::projectionMatrix() const{ return _projectionMatrix; } - -void Camera::setViewProjectionMatrix(glm::mat4 viewProjectionMatrix) -{ - std::lock_guard _lock(_mutex); - _viewProjectionMatrix = std::move(viewProjectionMatrix); -} - -const glm::mat4& Camera::viewProjectionMatrix() const -{ + +const glm::mat4& Camera::viewProjectionMatrix() const { + if (_dirtyViewProjectionMatrix) { + std::lock_guard _lock(_mutex); + _viewProjectionMatrix = _projectionMatrix * _viewMatrix; + _dirtyViewProjectionMatrix = false; + } return _viewProjectionMatrix; }