diff --git a/data/scene/milkyway-eso/milkyway-eso.mod b/data/scene/milkyway-eso/milkyway-eso.mod index 86902a48e7..60c6f71696 100644 --- a/data/scene/milkyway-eso/milkyway-eso.mod +++ b/data/scene/milkyway-eso/milkyway-eso.mod @@ -4,7 +4,7 @@ return { Parent = "SolarSystem", Renderable = { Type = "RenderableSphere", - Size = { 10, 20 }, + Size = 10E20, Segments = 40, Texture = "textures/eso0932a_blend.png", Orientation = "Inside/Outside" diff --git a/data/scene/milkyway/milkyway.mod b/data/scene/milkyway/milkyway.mod index 8fa37be7a5..49c07a217c 100644 --- a/data/scene/milkyway/milkyway.mod +++ b/data/scene/milkyway/milkyway.mod @@ -4,7 +4,7 @@ return { Parent = "SolarSystem", Renderable = { Type = "RenderableSphere", - Size = { 10, 22 }, + Size = 10E22, Segments = 40, Texture = "textures/DarkUniverse_mellinger_8k.jpg", Orientation = "Inside/Outside" diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt index 751cb25587..4d3ae2b0fe 100644 --- a/modules/base/CMakeLists.txt +++ b/modules/base/CMakeLists.txt @@ -28,7 +28,6 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/modelgeometry.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/multimodelgeometry.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablemodel.h - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablepath.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplane.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablesphere.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablesphericalgrid.h @@ -47,7 +46,6 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/modelgeometry.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/multimodelgeometry.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablemodel.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablepath.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplane.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablesphere.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablesphericalgrid.cpp diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index d0138eb781..47af9e3ec5 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -32,7 +32,6 @@ #include #include -#include #include #include #include @@ -77,7 +76,6 @@ void BaseModule::internalInitialize() { ghoul_assert(fRenderable, "Renderable factory was not created"); fRenderable->registerClass("RenderableModel"); - fRenderable->registerClass("RenderablePath"); fRenderable->registerClass("RenderablePlane"); fRenderable->registerClass("RenderableSphere"); fRenderable->registerClass("RenderableSphericalGrid"); @@ -107,13 +105,15 @@ void BaseModule::internalInitialize() { std::vector BaseModule::documentations() const { return { RenderableModel::Documentation(), + RenderablePlane::Documentation(), + RenderableSphere::Documentation(), + RenderableTrailOrbit::Documentation(), + RenderableTrailTrajectory::Documentation(), ScreenSpaceFramebuffer::Documentation(), ScreenSpaceImage::Documentation(), StaticRotation::Documentation(), StaticScale::Documentation(), StaticTranslation::Documentation(), - RenderableTrailOrbit::Documentation(), - RenderableTrailTrajectory::Documentation(), modelgeometry::ModelGeometry::Documentation(), }; } diff --git a/modules/base/rendering/renderablepath.cpp b/modules/base/rendering/renderablepath.cpp deleted file mode 100644 index 081abb3b9f..0000000000 --- a/modules/base/rendering/renderablepath.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2017 * - * * - * 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 - -/* TODO for this class: -* In order to add geometry shader (for pretty-draw), -* need to pack each consecutive point pair into a vec2 -* in order to draw quad between them. -*/ - -namespace { - const std::string _loggerCat = "RenderableTrail"; - //constants - const char* keyName = "Name"; - const char* keyBody = "Body"; - const char* keyObserver = "Observer"; - const char* keyFrame = "Frame"; - const char* keyPathModule = "ModulePath"; - const char* keyColor = "RGB"; - const char* keyTimeSteps = "TimeSteps"; - const char* keyPointSteps = "PointSteps"; - const char* keyDrawLine = "DrawLine"; - const char* keRenderDistanceInterval = "RenderDistanceInterval"; -} - -namespace openspace { - -RenderablePath::RenderablePath(const ghoul::Dictionary& dictionary) - : Renderable(dictionary) - , _lineWidth("lineWidth", "Line Width", 2.f, 1.f, 20.f) - , _drawLine("drawline", "Draw Line", false) - , _programObject(nullptr) - , _successfullDictionaryFetch(true) - , _vaoID(0) - , _vBufferID(0) - , _needsSweep(true) - , _start(0.0) - , _stop(0.0) -{ - _successfullDictionaryFetch &= dictionary.getValue(keyBody, _target); - _successfullDictionaryFetch &= dictionary.getValue(keyObserver, _observer); - _successfullDictionaryFetch &= dictionary.getValue(keyFrame, _frame); - _successfullDictionaryFetch &= dictionary.getValue(keyTimeSteps, _increment); - - float fPointSteps; // Dictionary can not pick out ints... - if (!dictionary.getValue(keyPointSteps, fPointSteps)) - fPointSteps = 4; - _pointSteps = static_cast(fPointSteps); - - glm::vec3 color(0.f); - if (dictionary.hasKeyAndValue(keyColor)) - dictionary.getValue(keyColor, color); - _lineColor = color; - - bool drawLine = false; - if (dictionary.hasKeyAndValue(keyDrawLine)) - dictionary.getValue(keyDrawLine, drawLine); - _drawLine = drawLine; - addProperty(_drawLine); - addProperty(_lineWidth); - _distanceFade = 1.0; -} - -bool RenderablePath::initialize() { - if (!_successfullDictionaryFetch) { - LERROR("The following keys need to be set in the Dictionary. Cannot initialize!"); - LERROR(keyBody << ": " << _target); - LERROR(keyObserver << ": " << _observer); - LERROR(keyFrame << ": " << _frame); - return false; - } - - bool completeSuccess = true; - - - RenderEngine& renderEngine = OsEng.renderEngine(); - _programObject = renderEngine.buildRenderProgram("PathProgram", - "${MODULE_BASE}/shaders/path_vs.glsl", - "${MODULE_BASE}/shaders/path_fs.glsl"); - if (!_programObject) - return false; - - bool intervalSet = hasTimeInterval(); - if (intervalSet) { - completeSuccess &= getInterval(_start, _stop); - } - - return completeSuccess; -} - -bool RenderablePath::deinitialize() { - glDeleteVertexArrays(1, &_vaoID); - _vaoID = 0; - - glDeleteBuffers(1, &_vBufferID); - _vBufferID = 0; - - RenderEngine& renderEngine = OsEng.renderEngine(); - if (_programObject) { - renderEngine.removeRenderProgram(_programObject); - _programObject = nullptr; - } - - return true; -} - -bool RenderablePath::isReady() const { - return (_programObject != nullptr) && _successfullDictionaryFetch; -} - -void RenderablePath::render(const RenderData& data) { - double time = openspace::Time::ref().j2000Seconds(); - if (_start > time || _stop < time) - return; - - - size_t nPointsToDraw = _vertexArray.size();// (time - _start) / (_stop - _start) * (_vertexArray.size()) + 1 + 0.5; - - _programObject->activate(); - - // Calculate variables to be used as uniform variables in shader - glm::dvec3 bodyPosition = data.modelTransform.translation; - - // Model transform and view transform needs to be in double precision - glm::dmat4 modelTransform = - glm::translate(glm::dmat4(1.0), bodyPosition); // Translation - glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform; - - _programObject->setUniform("modelViewTransform", glm::mat4(modelViewTransform)); - _programObject->setUniform("projectionTransform", data.camera.projectionMatrix()); - _programObject->setUniform("pointSteps", _pointSteps); - _programObject->setUniform("color", _lineColor); - - if (_drawLine) { - glLineWidth(_lineWidth); - glBindVertexArray(_vaoID); - glDrawArrays(GL_LINE_STRIP, 0, static_cast(nPointsToDraw)); - glBindVertexArray(0); - glLineWidth(1.f); - } - - glEnable(GL_PROGRAM_POINT_SIZE); - - glBindVertexArray(_vaoID); - glDrawArrays(GL_POINTS, 0, static_cast(nPointsToDraw)); - glBindVertexArray(0); - - glDisable(GL_PROGRAM_POINT_SIZE); - - _programObject->deactivate(); -} - -void RenderablePath::update(const UpdateData& data) { - if (data.isTimeJump) - _needsSweep = true; - - if (_needsSweep) { - calculatePath(_observer); - sendToGPU(); - _needsSweep = false; - } - - if (_programObject->isDirty()) - _programObject->rebuildFromFile(); -} - -void RenderablePath::calculatePath(std::string observer) { - double interval = (_stop - _start); - int segments = static_cast(interval /_increment); - - if (segments == 0) - return; - - double lightTime; -// bool correctPosition = true; - - double currentTime = _start; - _vertexArray.resize(segments); - - //psc pscPos; - //float r, g, b; - //float g = _lineColor[1]; - //float b = _lineColor[2]; - glm::vec3 position; - for (int i = 0; i < segments; i++) { - position = - glm::vec3(SpiceManager::ref().targetPosition(_target, observer, _frame, {}, currentTime, lightTime)); - - // Convert from 100 m to m - position *= 10e2; - - //pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); - //pscPos[3] += 3; - - //if (!correctPosition) { - // r = 1.f; - // g = b = 0.5f; - //} - //else if ((i % 8) == 0) { - // r = _lineColor[0]; - // g = _lineColor[1]; - // b = _lineColor[2]; - //} - //else { - // r = g = b = 0.6f; - //} - //add position - _vertexArray[i] = { position[0], position[1], position[2], 1.0f }; - //add color for position - //_vertexArray[i + 1] = { r, g, b, a }; - currentTime += _increment; - } - _lastPosition = glm::vec4(position, 1.0f); - - glBindBuffer(GL_ARRAY_BUFFER, _vBufferID); - glBufferSubData(GL_ARRAY_BUFFER, 0, _vertexArray.size() * sizeof(VertexInfo), &_vertexArray[0]); -} - -void RenderablePath::sendToGPU() { - glGenVertexArrays(1, &_vaoID); - glGenBuffers(1, &_vBufferID); - - glBindVertexArray(_vaoID); - - glBindBuffer(GL_ARRAY_BUFFER, _vBufferID); - glBufferData(GL_ARRAY_BUFFER, _vertexArray.size() * sizeof(VertexInfo), NULL, GL_STREAM_DRAW); // orphaning the buffer, sending NULL data. - glBufferSubData(GL_ARRAY_BUFFER, 0, _vertexArray.size() * sizeof(VertexInfo), &_vertexArray[0]); - - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); - //glEnableVertexAttribArray(1); - //glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexInfo) * 2, (void*)(sizeof(VertexInfo))); - - glBindVertexArray(0); -} - -} // namespace openspace diff --git a/modules/base/rendering/renderablepath.h b/modules/base/rendering/renderablepath.h deleted file mode 100644 index 44c7dfb1b8..0000000000 --- a/modules/base/rendering/renderablepath.h +++ /dev/null @@ -1,94 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2017 * - * * - * 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 __OPENSPACE_MODULE_BASE___RENDERABLEPATH___H__ -#define __OPENSPACE_MODULE_BASE___RENDERABLEPATH___H__ - -#include -#include -#include - -#include - -namespace ghoul { - namespace opengl { - class ProgramObject; - class Texture; - } -} - -namespace openspace { - -class RenderablePath : public Renderable { -public: - RenderablePath(const ghoul::Dictionary& dictionary); - - bool initialize() override; - bool deinitialize() override; - - bool isReady() const override; - - void render(const RenderData& data) override; - void update(const UpdateData& data) override; - - void calculatePath(std::string observer); -private: - struct VertexInfo { - float x, y, z, e; - //float r, g, b, a; - }; - void sendToGPU(); - void addPosition(glm::vec3 pos); - void addColor(glm::vec4 col); - - glm::vec3 _lineColor; - glm::vec4 _lastPosition; - properties::FloatProperty _lineWidth; - properties::BoolProperty _drawLine; - - std::unique_ptr _programObject; - - bool _successfullDictionaryFetch; - - std::string _target; - std::string _observer; - std::string _frame; - - GLuint _vaoID; - GLuint _vBufferID; - - bool _needsSweep; - - std::vector _vertexArray; - - float _increment; - double _start; - double _stop; - float _distanceFade; - int _pointSteps; -}; - -} // namespace openspace - -#endif // __OPENSPACE_MODULE_BASE___RENDERABLEPATH___H__ diff --git a/modules/base/rendering/renderableplane.cpp b/modules/base/rendering/renderableplane.cpp index 25e80ffd59..cb7e9129bb 100644 --- a/modules/base/rendering/renderableplane.cpp +++ b/modules/base/rendering/renderableplane.cpp @@ -22,8 +22,11 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include #include + +#include +#include +#include #include #include @@ -38,7 +41,11 @@ #include namespace { - static const std::string _loggerCat = "RenderablePlane"; + const char* KeySize = "Size"; + const char* KeyBillboard = "Billboard"; + const char* KeyBlendMode = "BlendMode"; + const char* KeyTexture = "Texture"; + const char* keyFieldlines = "Fieldlines"; const char* keyFilename = "File"; @@ -46,17 +53,54 @@ namespace { const char* keyShaders = "Shaders"; const char* keyVertexShader = "VertexShader"; const char* keyFragmentShader = "FragmentShader"; -} +} // namespace namespace openspace { +documentation::Documentation RenderablePlane::Documentation() { + using namespace documentation; + return { + "Renderable Plane", + "base_renderable_plane", + { + { + KeySize, + new DoubleVerifier, + "Specifies the size of the square plane in meters.", + Optional::No + }, + { + KeyBillboard, + new BoolVerifier, + "Specifies whether the plane is a billboard, which means that it is " + "always facing the camera. If this is false, it can be oriented using " + "other transformations. The default is 'false'.", + Optional::Yes + }, + { + KeyBlendMode, + new StringInListVerifier({ "Normal", "Additive" }), + "Specifies the blend mode that is applied to this plane. The default " + "value is 'Normal'.", + Optional::Yes + }, + { + KeyTexture, + new StringVerifier, + "Specifies the texture that is applied to this plane. This image has to " + "be a square image.", + Optional::No + } + } + }; +} + + RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _texturePath("texture", "Texture") , _billboard("billboard", "Billboard", false) - , _projectionListener("projectionListener", "DisplayProjections", false) , _size("size", "Size", 10, 0, std::pow(10, 25)) - , _origin(Origin::Center) , _shader(nullptr) , _textureIsDirty(false) , _texture(nullptr) @@ -64,65 +108,39 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) , _quad(0) , _vertexPositionBuffer(0) { - dictionary.getValue("Size", _size); + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "RenderablePlane" + ); - if (dictionary.hasKey("Name")) { - dictionary.getValue("Name", _nodeName); + _size = dictionary.value(KeySize); + + if (dictionary.hasKey(KeyBillboard)) { + _billboard = dictionary.value(KeyBillboard); } - std::string origin; - if (dictionary.getValue("Origin", origin)) { - if (origin == "LowerLeft") { - _origin = Origin::LowerLeft; + if (dictionary.hasKey(KeyBlendMode)) { + const std::string v = dictionary.value(KeyBlendMode); + if (v == "Normal") { + _blendMode = BlendMode::Normal; } - else if (origin == "LowerRight") { - _origin = Origin::LowerRight; - } - else if (origin == "UpperLeft") { - _origin = Origin::UpperLeft; - } - else if (origin == "UpperRight") { - _origin = Origin::UpperRight; - } - else if (origin == "Center") { - _origin = Origin::Center; - } - } - - // Attempt to get the billboard value - bool billboard = false; - if (dictionary.getValue("Billboard", billboard)) { - _billboard = billboard; - } - if (dictionary.hasKey("ProjectionListener")){ - bool projectionListener = false; - if (dictionary.getValue("ProjectionListener", projectionListener)) { - _projectionListener = projectionListener; - } - } - - std::string blendMode; - if (dictionary.getValue("BlendMode", blendMode)) { - if (blendMode == "Additive") { + else if (v == "Additive") { _blendMode = BlendMode::Additive; setRenderBin(Renderable::RenderBin::Transparent); } } - - std::string texturePath = ""; - bool success = dictionary.getValue("Texture", texturePath); - if (success) { - _texturePath = absPath(texturePath); - _textureFile = new ghoul::filesystem::File(_texturePath); - } + _texturePath = absPath(dictionary.value(KeyTexture)); + _textureFile = new ghoul::filesystem::File(_texturePath); addProperty(_billboard); addProperty(_texturePath); - _texturePath.onChange(std::bind(&RenderablePlane::loadTexture, this)); - _textureFile->setCallback([&](const ghoul::filesystem::File&) { _textureIsDirty = true; }); + _texturePath.onChange([this]() {loadTexture(); }); + _textureFile->setCallback( + [this](const ghoul::filesystem::File&) { _textureIsDirty = true; } + ); addProperty(_size); - //_size.onChange(std::bind(&RenderablePlane::createPlane, this)); _size.onChange([this](){ _planeIsDirty = true; }); setBoundingSphere(_size); @@ -134,12 +152,7 @@ RenderablePlane::~RenderablePlane() { } bool RenderablePlane::isReady() const { - bool ready = true; - if (!_shader) - ready &= false; - if(!_texture) - ready &= false; - return ready; + return _shader && _texture; } bool RenderablePlane::initialize() { @@ -147,17 +160,10 @@ bool RenderablePlane::initialize() { glGenBuffers(1, &_vertexPositionBuffer); // generate buffer createPlane(); - if (_shader == nullptr) { - // Plane Program - - RenderEngine& renderEngine = OsEng.renderEngine(); - _shader = renderEngine.buildRenderProgram("PlaneProgram", - "${MODULE_BASE}/shaders/plane_vs.glsl", - "${MODULE_BASE}/shaders/plane_fs.glsl" - ); - if (!_shader) - return false; - } + _shader = OsEng.renderEngine().buildRenderProgram("PlaneProgram", + "${MODULE_BASE}/shaders/plane_vs.glsl", + "${MODULE_BASE}/shaders/plane_fs.glsl" + ); loadTexture(); @@ -171,16 +177,9 @@ bool RenderablePlane::deinitialize() { glDeleteBuffers(1, &_vertexPositionBuffer); _vertexPositionBuffer = 0; - if (!_projectionListener){ - // its parents job to kill texture - // iff projectionlistener - _texture = nullptr; - } - delete _textureFile; _textureFile = nullptr; - RenderEngine& renderEngine = OsEng.renderEngine(); if (_shader) { renderEngine.removeRenderProgram(_shader); @@ -195,25 +194,27 @@ void RenderablePlane::render(const RenderData& data) { // Activate shader _shader->activate(); - if (_projectionListener){ - //get parent node-texture and set with correct dimensions - SceneGraphNode* textureNode = OsEng.renderEngine().scene()->sceneGraphNode(_nodeName)->parent(); - if (textureNode != nullptr){ - RenderablePlanetProjection* t = static_cast(textureNode->renderable()); - _texture = std::unique_ptr(&(t->baseTexture())); - unsigned int h = _texture->height(); - unsigned int w = _texture->width(); - float scale = static_cast(h) / static_cast(w); - scaleTransform = glm::scale(glm::mat4(1.0), glm::vec3(1.f, scale, 1.f)); - } - } + //if (_projectionListener){ + // //get parent node-texture and set with correct dimensions + // SceneGraphNode* textureNode = OsEng.renderEngine().scene()->sceneGraphNode(_nodeName)->parent(); + // if (textureNode != nullptr){ + // RenderablePlanetProjection* t = static_cast(textureNode->renderable()); + // _texture = std::unique_ptr(&(t->baseTexture())); + // unsigned int h = _texture->height(); + // unsigned int w = _texture->width(); + // float scale = static_cast(h) / static_cast(w); + // scaleTransform = glm::scale(glm::mat4(1.0), glm::vec3(1.f, scale, 1.f)); + // } + //} // Model transform and view transform needs to be in double precision glm::dmat4 rotationTransform; - if (_billboard) + if (_billboard) { rotationTransform = glm::inverse(glm::dmat4(data.camera.viewRotationMatrix())); - else + } + else { rotationTransform = glm::dmat4(data.modelTransform.rotation); + } glm::dmat4 modelTransform = glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * @@ -276,9 +277,14 @@ void RenderablePlane::update(const UpdateData&) { void RenderablePlane::loadTexture() { if (_texturePath.value() != "") { - std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); + std::unique_ptr texture = + ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); + if (texture) { - LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'"); + LDEBUGC( + "RenderablePlane", + "Loaded texture from '" << absPath(_texturePath) << "'" + ); texture->uploadTexture(); // Textures of planets looks much smoother with AnisotropicMipMap rather than linear diff --git a/modules/base/rendering/renderableplane.h b/modules/base/rendering/renderableplane.h index a14e340f9e..ef937da10a 100644 --- a/modules/base/rendering/renderableplane.h +++ b/modules/base/rendering/renderableplane.h @@ -42,14 +42,13 @@ namespace ghoul { } namespace openspace { - struct LinePoint; + +namespace documentation { struct Documentation; } + +struct LinePoint; class RenderablePlane : public Renderable { - enum class Origin { - LowerLeft, LowerRight, UpperLeft, UpperRight, Center - }; - public: enum class BlendMode : int { Normal = 0, @@ -67,18 +66,16 @@ public: void render(const RenderData& data) override; void update(const UpdateData& data) override; + static documentation::Documentation Documentation(); + private: void loadTexture(); void createPlane(); properties::StringProperty _texturePath; properties::BoolProperty _billboard; - properties::BoolProperty _projectionListener; properties::FloatProperty _size; - Origin _origin; - std::string _nodeName; - bool _planeIsDirty; std::unique_ptr _shader; diff --git a/modules/base/rendering/renderablesphere.cpp b/modules/base/rendering/renderablesphere.cpp index 3383aa594b..b720d482f3 100644 --- a/modules/base/rendering/renderablesphere.cpp +++ b/modules/base/rendering/renderablesphere.cpp @@ -24,38 +24,75 @@ #include +#include +#include + #include #include #include #include #include -#include - #define _USE_MATH_DEFINES #include namespace { - static const std::string _loggerCat = "RenderableSphere"; + const char* KeySize = "Size"; + const char* KeySegments = "Segments"; + const char* KeyTexture = "Texture"; + const char* KeyOrientation = "Orientation"; + - const char* keySize = "Size"; - const char* keySegments = "Segments"; - const char* keyTexture = "Texture"; - const char* keyOrientation = "Orientation"; enum Orientation { Outside = 1, Inside = 2 }; -} +} // namespace namespace openspace { +documentation::Documentation RenderableSphere::Documentation() { + using namespace documentation; + return { + "RenderableSphere", + "base_renderable_sphere", + { + { + KeySize, + new DoubleVerifier, + "Specifies the radius of the sphere in meters.", + Optional::No + }, + { + KeySegments, + new IntVerifier, + "Specifies the number of segments the sphere is separated in.", + Optional::No + }, + { + KeyTexture, + new StringVerifier, + "Specifies the texture that is applied to the sphere.", + Optional::No + }, + { + KeyOrientation, + new StringInListVerifier({ "Inside", "Outside", "Inside/Outside" }), + "Specifies whether the texture is applied to the inside of the sphere, " + "the outside of the sphere, or both. The default value is 'Outside'.", + Optional::Yes + } + } + }; +} + + RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _texturePath("texture", "Texture") , _orientation("orientation", "Orientation") - , _size("size", "Size", glm::vec2(1.f, 1.f), glm::vec2(0.f), glm::vec2(100.f)) + , _size("size", "Size", 1.f, 0.f, std::pow(10.f, 45)) , _segments("segments", "Segments", 8, 4, 100) , _transparency("transparency", "Transparency", 1.f, 0.f, 1.f) , _shader(nullptr) @@ -63,67 +100,68 @@ RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary) , _sphere(nullptr) , _sphereIsDirty(false) { - if (dictionary.hasKeyAndValue(keySize)) { - glm::vec2 size; - dictionary.getValue(keySize, size); - _size = size; - } + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "RenderableSphere" + ); - if (dictionary.hasKeyAndValue(keySegments)) { - int segments; - dictionary.getValue(keySegments, segments); - _segments = segments; - } - - if (dictionary.hasKeyAndValue(keyTexture)) { - std::string texture; - dictionary.getValue(keyTexture, texture); - _texturePath = absPath(texture); - } + _size = dictionary.value(KeySize); + _segments = static_cast(dictionary.value(KeySegments)); + _texturePath = absPath(dictionary.value(KeyTexture)); _orientation.addOption(Outside, "Outside"); _orientation.addOption(Inside, "Inside"); - _orientation.addOption(Outside | Inside, "Outside + Inside"); + _orientation.addOption(Outside | Inside, "Inside/Outside"); - if (dictionary.hasKeyAndValue(keyOrientation)) { - std::string orientation; - dictionary.getValue(keyOrientation, orientation); - if (orientation == "Outside") - _orientation = Outside; - else if (orientation == "Inside") + if (dictionary.hasKey(KeyOrientation)) { + const std::string v = dictionary.value(KeyOrientation); + if (v == "Inside") { _orientation = Inside; - else + } + else if (v == "Outside") { + _orientation = Outside; + } + else if (v == "Inside/Outside") { _orientation = Outside | Inside; + } + else { + ghoul_assert(false, "Missing 'case' label"); + } + } + else { + _orientation = Outside; } - addProperty(_orientation); + addProperty(_size); _size.onChange([this](){ _sphereIsDirty = true; }); + addProperty(_segments); _segments.onChange([this](){ _sphereIsDirty = true; }); addProperty(_transparency); - addProperty(_texturePath); - _texturePath.onChange(std::bind(&RenderableSphere::loadTexture, this)); + _texturePath.onChange([this]() {loadTexture(); }); + + + setRenderBin(Renderable::RenderBin::Transparent); } bool RenderableSphere::isReady() const { - return (_sphere != nullptr) && (_shader != nullptr) && (_texture != nullptr); + return _shader && _texture; } bool RenderableSphere::initialize() { - delete _sphere; - _sphere = new PowerScaledSphere(_size.value(), _segments); + _sphere = std::make_unique( + PowerScaledScalar::CreatePSS(_size), _segments + ); _sphere->initialize(); // pscstandard - RenderEngine& renderEngine = OsEng.renderEngine(); - _shader = renderEngine.buildRenderProgram("Sphere", + _shader = OsEng.renderEngine().buildRenderProgram("Sphere", "${MODULE_BASE}/shaders/sphere_vs.glsl", "${MODULE_BASE}/shaders/sphere_fs.glsl"); - if (!_shader) - return false; loadTexture(); @@ -131,28 +169,21 @@ bool RenderableSphere::initialize() { } bool RenderableSphere::deinitialize() { - delete _sphere; - _sphere = nullptr; - _texture = nullptr; - RenderEngine& renderEngine = OsEng.renderEngine(); if (_shader) { - renderEngine.removeRenderProgram(_shader); + OsEng.renderEngine().removeRenderProgram(_shader); _shader = nullptr; } - return true; } void RenderableSphere::render(const RenderData& data) { - glm::mat4 transform = glm::mat4(1.0); transform = glm::rotate(transform, static_cast(M_PI_2), glm::vec3(1, 0, 0)); - // Activate shader using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; _shader->activate(); @@ -171,20 +202,40 @@ void RenderableSphere::render(const RenderData& data) { glEnable(GL_CULL_FACE); glCullFace(GL_BACK); + + bool usingFramebufferRenderer = + OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::Framebuffer; + + bool usingABufferRenderer = + OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::ABuffer; + + if (usingABufferRenderer) { + _shader->setUniform("additiveBlending", true); + } + + if (usingFramebufferRenderer) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } _sphere->render(); + if (usingFramebufferRenderer) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + _shader->setIgnoreUniformLocationError(IgnoreError::No); _shader->deactivate(); } void RenderableSphere::update(const UpdateData&) { - if (_shader->isDirty()) + if (_shader->isDirty()) { _shader->rebuildFromFile(); + } if (_sphereIsDirty) { - delete _sphere; - _sphere = new PowerScaledSphere(_size.value(), _segments); + _sphere = std::make_unique( + PowerScaledScalar::CreatePSS(_size), _segments + ); _sphere->initialize(); _sphereIsDirty = false; } @@ -194,7 +245,10 @@ void RenderableSphere::loadTexture() { if (_texturePath.value() != "") { std::unique_ptr texture = ghoul::io::TextureReader::ref().loadTexture(_texturePath); if (texture) { - LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'"); + LDEBUGC( + "RenderableSphere", + "Loaded texture from '" << absPath(_texturePath) << "'" + ); texture->uploadTexture(); // Textures of planets looks much smoother with AnisotropicMipMap rather than linear diff --git a/modules/base/rendering/renderablesphere.h b/modules/base/rendering/renderablesphere.h index e697ca7f5a..3f6fa1e3ca 100644 --- a/modules/base/rendering/renderablesphere.h +++ b/modules/base/rendering/renderablesphere.h @@ -35,10 +35,11 @@ #include #include #include +#include namespace openspace { -class PowerScaledSphere; +namespace documentation { struct Documentation; } class RenderableSphere : public Renderable { public: @@ -52,13 +53,15 @@ public: void render(const RenderData& data) override; void update(const UpdateData& data) override; + static documentation::Documentation Documentation(); + private: void loadTexture(); properties::StringProperty _texturePath; properties::OptionProperty _orientation; - properties::Vec2Property _size; + properties::FloatProperty _size; properties::IntProperty _segments; properties::FloatProperty _transparency; @@ -66,7 +69,7 @@ private: std::unique_ptr _shader; std::unique_ptr _texture; - PowerScaledSphere* _sphere; + std::unique_ptr _sphere; bool _sphereIsDirty; }; diff --git a/modules/base/rendering/renderablesphericalgrid.cpp b/modules/base/rendering/renderablesphericalgrid.cpp index 7a3ad7d2e6..b6a8f0f7e5 100644 --- a/modules/base/rendering/renderablesphericalgrid.cpp +++ b/modules/base/rendering/renderablesphericalgrid.cpp @@ -61,7 +61,8 @@ RenderableSphericalGrid::RenderableSphericalGrid(const ghoul::Dictionary& dictio staticGrid = dictionary.getValue(KeyGridParentsRotation, _parentsRotation); } - dictionary.getValue(KeyGridSegments, _segments); + _segments = static_cast(dictionary.value(KeyGridSegments)); + //dictionary.getValue(KeyGridSegments, _segments); /*glm::vec2 radius;