diff --git a/data/assets/scene/digitaluniverse/stars.asset b/data/assets/scene/digitaluniverse/stars.asset index 4203a6b8c7..7f87ad6ea8 100644 --- a/data/assets/scene/digitaluniverse/stars.asset +++ b/data/assets/scene/digitaluniverse/stars.asset @@ -29,10 +29,7 @@ local object = { Type = "RenderableStars", File = speck .. "/stars.speck", Texture = textures .. "/halo.png", - ColorMap = colorLUT .. "/colorbv.cmap", - MagnitudeExponent = 19, - BillboardSize = 30, - Sharpness = 1.3 + ColorMap = colorLUT .. "/colorbv.cmap" }, GUI = { Path = "/Milky Way/Stars" @@ -41,4 +38,4 @@ local object = { -assetHelper.registerSceneGraphNodesAndExport(asset, { object }) +assetHelper.registerSceneGraphNodesAndExport(asset, { object }) \ No newline at end of file diff --git a/modules/space/rendering/renderablestars.cpp b/modules/space/rendering/renderablestars.cpp index dfb5e1394a..7a2e9e2a5e 100644 --- a/modules/space/rendering/renderablestars.cpp +++ b/modules/space/rendering/renderablestars.cpp @@ -1,33 +1,32 @@ /***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2018 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ +* * +* OpenSpace * +* * +* Copyright (c) 2014-2018 * +* * +* 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 @@ -42,9 +41,6 @@ #include #include #include -#include - -//#define USING_STELLAR_TEST_GRID namespace { constexpr const char* _loggerCat = "RenderableStars"; @@ -104,34 +100,35 @@ namespace { "stars." }; - static const openspace::properties::Property::PropertyInfo MagnitudeExponentInfo = { - "MagnitudeExponent", - "MagnitudeExponent", - "Adjust star magnitude by 10^MagnitudeExponent. " - "Stars closer than this distance are given full opacity. " - "Farther away, stars dim proportionally to the logarithm of their distance." + static const openspace::properties::Property::PropertyInfo TransparencyInfo = { + "Transparency", + "Transparency", + "This value is a multiplicative factor that is applied to the transparency of " + "all stars." }; - static const openspace::properties::Property::PropertyInfo SharpnessInfo = { - "Sharpness", - "Sharpness", - "Adjust star sharpness" + static const openspace::properties::Property::PropertyInfo ScaleFactorInfo = { + "ScaleFactor", + "Scale Factor", + "This value is used as a multiplicative factor that is applied to the apparent " + "size of each star." }; - static const openspace::properties::Property::PropertyInfo BillboardSizeInfo = { - "BillboardSize", - "Billboard Size", - "Set the billboard size of all stars" + static const openspace::properties::Property::PropertyInfo MinBillboardSizeInfo = { + "MinBillboardSize", + "Min Billboard Size", + "This value is used as a lower limit on the size of stars that are rendered. Any " + "stars that have a smaller apparent size will be discarded entirely." }; } // namespace namespace openspace { -documentation::Documentation RenderableStars::Documentation() { - using namespace documentation; - return { - "RenderableStars", - "space_renderablestars", + documentation::Documentation RenderableStars::Documentation() { + using namespace documentation; + return { + "RenderableStars", + "space_renderablestars", { { "Type", @@ -160,286 +157,276 @@ documentation::Documentation RenderableStars::Documentation() { { ColorOptionInfo.identifier, new StringInListVerifier({ - "Color", "Velocity", "Speed" - }), - Optional::Yes, - ColorOptionInfo.description + "Color", "Velocity", "Speed" + }), + Optional::Yes, + ColorOptionInfo.description }, { - MagnitudeExponentInfo.identifier, + TransparencyInfo.identifier, new DoubleVerifier, Optional::Yes, - MagnitudeExponentInfo.description + TransparencyInfo.description }, { - SharpnessInfo.identifier, + ScaleFactorInfo.identifier, new DoubleVerifier, Optional::Yes, - SharpnessInfo.description + ScaleFactorInfo.description }, { - BillboardSizeInfo.identifier, + MinBillboardSizeInfo.identifier, new DoubleVerifier, Optional::Yes, - BillboardSizeInfo.description + MinBillboardSizeInfo.description } } - }; -} + }; + } -RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) - : Renderable(dictionary) - , _pointSpreadFunctionTexturePath(PsfTextureInfo) - , _pointSpreadFunctionTexture(nullptr) - , _pointSpreadFunctionTextureIsDirty(true) - , _colorTexturePath(ColorTextureInfo) - , _colorTexture(nullptr) - , _colorTextureIsDirty(true) - , _colorOption(ColorOptionInfo, properties::OptionProperty::DisplayType::Dropdown) - , _dataIsDirty(true) - , _magnitudeExponent(MagnitudeExponentInfo, 19.f, 0.f, 30.f) - , _sharpness(SharpnessInfo, 1.f, 0.f, 5.f) - , _billboardSize(BillboardSizeInfo, 30.f, 1.f, 100.f) - , _program(nullptr) - , _speckFile("") - , _nValuesPerStar(0) - , _vao(0) - , _vbo(0) -{ - using File = ghoul::filesystem::File; + RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) + , _pointSpreadFunctionTexturePath(PsfTextureInfo) + , _pointSpreadFunctionTexture(nullptr) + , _pointSpreadFunctionTextureIsDirty(true) + , _colorTexturePath(ColorTextureInfo) + , _colorTexture(nullptr) + , _colorTextureIsDirty(true) + , _colorOption(ColorOptionInfo, properties::OptionProperty::DisplayType::Dropdown) + , _dataIsDirty(true) + , _alphaValue(TransparencyInfo, 1.f, 0.f, 1.f) + , _scaleFactor(ScaleFactorInfo, 1.f, 0.f, 10.f) + , _minBillboardSize(MinBillboardSizeInfo, 1.f, 1.f, 100.f) + , _program(nullptr) + , _speckFile("") + , _nValuesPerStar(0) + , _vao(0) + , _vbo(0) + { + using File = ghoul::filesystem::File; - documentation::testSpecificationAndThrow( - Documentation(), - dictionary, - "RenderableStars" - ); - - _pointSpreadFunctionTexturePath = absPath(dictionary.value( - PsfTextureInfo.identifier - )); - _pointSpreadFunctionFile = std::make_unique(_pointSpreadFunctionTexturePath); - - _colorTexturePath = absPath(dictionary.value( - ColorTextureInfo.identifier - )); - _colorTextureFile = std::make_unique(_colorTexturePath); - - _speckFile = absPath(dictionary.value(KeyFile)); - - _colorOption.addOptions({ - { ColorOption::Color, "Color" }, - { ColorOption::Velocity, "Velocity" }, - { ColorOption::Speed, "Speed" } - }); - if (dictionary.hasKey(ColorOptionInfo.identifier)) { - const std::string colorOption = dictionary.value( - ColorOptionInfo.identifier + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "RenderableStars" ); - if (colorOption == "Color") { - _colorOption = ColorOption::Color; - } - else if (colorOption == "Velocity") { - _colorOption = ColorOption::Velocity; - } - else { - _colorOption = ColorOption::Speed; - } - } - _colorOption.onChange([&] { _dataIsDirty = true; }); - addProperty(_colorOption); - _pointSpreadFunctionTexturePath.onChange( - [&]{ _pointSpreadFunctionTextureIsDirty = true; } - ); - _pointSpreadFunctionFile->setCallback( - [&](const File&) { _pointSpreadFunctionTextureIsDirty = true; } - ); - addProperty(_pointSpreadFunctionTexturePath); + _pointSpreadFunctionTexturePath = absPath(dictionary.value( + PsfTextureInfo.identifier + )); + _pointSpreadFunctionFile = std::make_unique(_pointSpreadFunctionTexturePath); - _colorTexturePath.onChange([&]{ _colorTextureIsDirty = true; }); - _colorTextureFile->setCallback( - [&](const File&) { _colorTextureIsDirty = true; } - ); - addProperty(_colorTexturePath); + _colorTexturePath = absPath(dictionary.value( + ColorTextureInfo.identifier + )); + _colorTextureFile = std::make_unique(_colorTexturePath); - if (dictionary.hasKey(MagnitudeExponentInfo.identifier)) { - _magnitudeExponent = static_cast( - dictionary.value(MagnitudeExponentInfo.identifier) + _speckFile = absPath(dictionary.value(KeyFile)); + + _colorOption.addOptions({ + { ColorOption::Color, "Color" }, + { ColorOption::Velocity, "Velocity" }, + { ColorOption::Speed, "Speed" } + }); + if (dictionary.hasKey(ColorOptionInfo.identifier)) { + const std::string colorOption = dictionary.value( + ColorOptionInfo.identifier + ); + if (colorOption == "Color") { + _colorOption = ColorOption::Color; + } + else if (colorOption == "Velocity") { + _colorOption = ColorOption::Velocity; + } + else { + _colorOption = ColorOption::Speed; + } + } + _colorOption.onChange([&] { _dataIsDirty = true; }); + addProperty(_colorOption); + + _pointSpreadFunctionTexturePath.onChange( + [&] { _pointSpreadFunctionTextureIsDirty = true; } ); - } - addProperty(_magnitudeExponent); - - if (dictionary.hasKey(SharpnessInfo.identifier)) { - _sharpness = static_cast( - dictionary.value(SharpnessInfo.identifier) - ); - } - addProperty(_sharpness); - - if (dictionary.hasKey(BillboardSizeInfo.identifier)) { - _billboardSize = static_cast( - dictionary.value(BillboardSizeInfo.identifier) + _pointSpreadFunctionFile->setCallback( + [&](const File&) { _pointSpreadFunctionTextureIsDirty = true; } ); - } - addProperty(_billboardSize); -} + addProperty(_pointSpreadFunctionTexturePath); -RenderableStars::~RenderableStars() {} + _colorTexturePath.onChange([&] { _colorTextureIsDirty = true; }); + _colorTextureFile->setCallback( + [&](const File&) { _colorTextureIsDirty = true; } + ); + addProperty(_colorTexturePath); -bool RenderableStars::isReady() const { - return (_program != nullptr) && (!_fullData.empty()); -} - -void RenderableStars::initializeGL() { - RenderEngine& renderEngine = OsEng.renderEngine(); - _program = renderEngine.buildRenderProgram("Star", - absPath("${MODULE_SPACE}/shaders/star_vs.glsl"), - absPath("${MODULE_SPACE}/shaders/star_fs.glsl"), - absPath("${MODULE_SPACE}/shaders/star_ge.glsl") - ); - - _uniformCache.model = _program->uniformLocation("model"); - _uniformCache.view = _program->uniformLocation("view"); - _uniformCache.viewScaling = _program->uniformLocation("viewScaling"); - _uniformCache.projection = _program->uniformLocation("projection"); - _uniformCache.colorOption = _program->uniformLocation("colorOption"); - _uniformCache.magnitudeExponent = _program->uniformLocation("magnitudeExponent"); - _uniformCache.sharpness = _program->uniformLocation("sharpness"); - _uniformCache.billboardSize = _program->uniformLocation("billboardSize"); - _uniformCache.screenSize = _program->uniformLocation("screenSize"); - _uniformCache.psfTexture = _program->uniformLocation("psfTexture"); - _uniformCache.colorTexture = _program->uniformLocation("colorTexture"); - - bool success = loadData(); - if (!success) { - throw ghoul::RuntimeError("Error loading data"); - } -} - -void RenderableStars::deinitializeGL() { - glDeleteBuffers(1, &_vbo); - _vbo = 0; - glDeleteVertexArrays(1, &_vao); - _vao = 0; - - _pointSpreadFunctionTexture = nullptr; - _colorTexture = nullptr; - - RenderEngine& renderEngine = OsEng.renderEngine(); - if (_program) { - renderEngine.removeRenderProgram(_program.get()); - _program = nullptr; - } -} - -void RenderableStars::render(const RenderData& data, RendererTasks&) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glDepthMask(false); - - _program->activate(); - - glm::mat4 model = - glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * - glm::dmat4(data.modelTransform.rotation) * - glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); - - glm::mat4 view = data.camera.combinedViewMatrix(); - glm::mat4 projection = data.camera.projectionMatrix(); - float viewScaling = data.camera.scaling(); - - _program->setUniform(_uniformCache.model, model); - _program->setUniform(_uniformCache.view, view); - _program->setUniform(_uniformCache.projection, projection); - _program->setUniform(_uniformCache.viewScaling, viewScaling); - - _program->setUniform(_uniformCache.colorOption, _colorOption); - _program->setUniform(_uniformCache.magnitudeExponent, _magnitudeExponent); - _program->setUniform(_uniformCache.sharpness, _sharpness); - _program->setUniform(_uniformCache.billboardSize, _billboardSize); - _program->setUniform( - _uniformCache.screenSize, - glm::vec2(OsEng.renderEngine().renderingResolution()) - ); - - _program->setUniform("eyePosition", glm::vec3(data.camera.eyePositionVec3())); - - ghoul::opengl::TextureUnit psfUnit; - psfUnit.activate(); - _pointSpreadFunctionTexture->bind(); - _program->setUniform(_uniformCache.psfTexture, psfUnit); - - ghoul::opengl::TextureUnit colorUnit; - colorUnit.activate(); - _colorTexture->bind(); - _program->setUniform(_uniformCache.colorTexture, colorUnit); - - glBindVertexArray(_vao); - const GLsizei nStars = static_cast(_fullData.size() / _nValuesPerStar); - glDrawArrays(GL_POINTS, 0, nStars); - - glBindVertexArray(0); - _program->deactivate(); - - glDepthMask(true); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -} - -void RenderableStars::update(const UpdateData&) { - if (_dataIsDirty) { - const int value = _colorOption; - LDEBUG("Regenerating data"); - - createDataSlice(ColorOption(value)); - - int size = static_cast(_slicedData.size()); - - if (_vao == 0) { - glGenVertexArrays(1, &_vao); + if (dictionary.hasKey(TransparencyInfo.identifier)) { + _alphaValue = static_cast( + dictionary.value(TransparencyInfo.identifier) + ); } - if (_vbo == 0) { - glGenBuffers(1, &_vbo); + addProperty(_alphaValue); + + if (dictionary.hasKey(ScaleFactorInfo.identifier)) { + _scaleFactor = static_cast( + dictionary.value(ScaleFactorInfo.identifier) + ); } + addProperty(_scaleFactor); + + if (dictionary.hasKey(MinBillboardSizeInfo.identifier)) { + _minBillboardSize = static_cast( + dictionary.value(MinBillboardSizeInfo.identifier) + ); + } + addProperty(_minBillboardSize); + } + + RenderableStars::~RenderableStars() {} + + bool RenderableStars::isReady() const { + return (_program != nullptr) && (!_fullData.empty()); + } + + void RenderableStars::initializeGL() { + RenderEngine& renderEngine = OsEng.renderEngine(); + _program = renderEngine.buildRenderProgram("Star", + absPath("${MODULE_SPACE}/shaders/star_vs.glsl"), + absPath("${MODULE_SPACE}/shaders/star_fs.glsl"), + absPath("${MODULE_SPACE}/shaders/star_ge.glsl") + ); + + _uniformCache.view = _program->uniformLocation("view"); + _uniformCache.projection = _program->uniformLocation("projection"); + _uniformCache.colorOption = _program->uniformLocation("colorOption"); + _uniformCache.alphaValue = _program->uniformLocation("alphaValue"); + _uniformCache.scaleFactor = _program->uniformLocation("scaleFactor"); + _uniformCache.minBillboardSize = _program->uniformLocation("minBillboardSize"); + _uniformCache.screenSize = _program->uniformLocation("screenSize"); + _uniformCache.scaling = _program->uniformLocation("scaling"); + _uniformCache.psfTexture = _program->uniformLocation("psfTexture"); + _uniformCache.colorTexture = _program->uniformLocation("colorTexture"); + + bool success = loadData(); + if (!success) { + throw ghoul::RuntimeError("Error loading data"); + } + } + + void RenderableStars::deinitializeGL() { + glDeleteBuffers(1, &_vbo); + _vbo = 0; + glDeleteVertexArrays(1, &_vao); + _vao = 0; + + _pointSpreadFunctionTexture = nullptr; + _colorTexture = nullptr; + + RenderEngine& renderEngine = OsEng.renderEngine(); + if (_program) { + renderEngine.removeRenderProgram(_program.get()); + _program = nullptr; + } + } + + void RenderableStars::render(const RenderData& data, RendererTasks&) { + glDepthMask(false); + _program->activate(); + + // @Check overwriting the scaling from the camera; error as parsec->meter conversion + // is done twice? ---abock + glm::vec2 scaling = glm::vec2(1, -19); + + _program->setUniform(_uniformCache.view, data.camera.viewMatrix()); + _program->setUniform(_uniformCache.projection, data.camera.projectionMatrix()); + + _program->setUniform(_uniformCache.colorOption, _colorOption); + _program->setUniform(_uniformCache.alphaValue, _alphaValue); + _program->setUniform(_uniformCache.scaleFactor, _scaleFactor); + _program->setUniform(_uniformCache.minBillboardSize, _minBillboardSize); + _program->setUniform( + _uniformCache.screenSize, + glm::vec2(OsEng.renderEngine().renderingResolution()) + ); + + setPscUniforms(*_program.get(), data.camera, data.position); + _program->setUniform(_uniformCache.scaling, scaling); + + ghoul::opengl::TextureUnit psfUnit; + psfUnit.activate(); + _pointSpreadFunctionTexture->bind(); + _program->setUniform(_uniformCache.psfTexture, psfUnit); + + ghoul::opengl::TextureUnit colorUnit; + colorUnit.activate(); + _colorTexture->bind(); + _program->setUniform(_uniformCache.colorTexture, colorUnit); + glBindVertexArray(_vao); - glBindBuffer(GL_ARRAY_BUFFER, _vbo); - glBufferData( - GL_ARRAY_BUFFER, - size * sizeof(GLfloat), - &_slicedData[0], - GL_STATIC_DRAW - ); + const GLsizei nStars = static_cast(_fullData.size() / _nValuesPerStar); + glDrawArrays(GL_POINTS, 0, nStars); - GLint positionAttrib = _program->attributeLocation("in_position"); - GLint brightnessDataAttrib = _program->attributeLocation("in_brightness"); + glBindVertexArray(0); + _program->deactivate(); - const size_t nStars = _fullData.size() / _nValuesPerStar; - const size_t nValues = _slicedData.size() / nStars; + glDepthMask(true); + } - GLsizei stride = static_cast(sizeof(GLfloat) * nValues); + void RenderableStars::update(const UpdateData&) { + if (_dataIsDirty) { + const int value = _colorOption; + LDEBUG("Regenerating data"); - glEnableVertexAttribArray(positionAttrib); - glEnableVertexAttribArray(brightnessDataAttrib); - const int colorOption = _colorOption; - switch (colorOption) { - case ColorOption::Color: - glVertexAttribPointer( - positionAttrib, - 4, - GL_FLOAT, - GL_FALSE, - stride, - nullptr // = offsetof(ColorVBOLayout, position) - ); - glVertexAttribPointer( - brightnessDataAttrib, - 3, - GL_FLOAT, - GL_FALSE, - stride, - reinterpret_cast(offsetof(ColorVBOLayout, bvColor)) + createDataSlice(ColorOption(value)); + + int size = static_cast(_slicedData.size()); + + if (_vao == 0) { + glGenVertexArrays(1, &_vao); + } + if (_vbo == 0) { + glGenBuffers(1, &_vbo); + } + glBindVertexArray(_vao); + glBindBuffer(GL_ARRAY_BUFFER, _vbo); + glBufferData( + GL_ARRAY_BUFFER, + size * sizeof(GLfloat), + &_slicedData[0], + GL_STATIC_DRAW ); - break; - case ColorOption::Velocity: + GLint positionAttrib = _program->attributeLocation("in_position"); + GLint brightnessDataAttrib = _program->attributeLocation("in_brightness"); + + const size_t nStars = _fullData.size() / _nValuesPerStar; + const size_t nValues = _slicedData.size() / nStars; + + GLsizei stride = static_cast(sizeof(GLfloat) * nValues); + + glEnableVertexAttribArray(positionAttrib); + glEnableVertexAttribArray(brightnessDataAttrib); + const int colorOption = _colorOption; + switch (colorOption) { + case ColorOption::Color: + glVertexAttribPointer( + positionAttrib, + 4, + GL_FLOAT, + GL_FALSE, + stride, + nullptr // = offsetof(ColorVBOLayout, position) + ); + glVertexAttribPointer( + brightnessDataAttrib, + 3, + GL_FLOAT, + GL_FALSE, + stride, + reinterpret_cast(offsetof(ColorVBOLayout, bvColor)) + ); + + break; + case ColorOption::Velocity: { glVertexAttribPointer( positionAttrib, @@ -471,7 +458,7 @@ void RenderableStars::update(const UpdateData&) { break; } - case ColorOption::Speed: + case ColorOption::Speed: { glVertexAttribPointer( positionAttrib, @@ -501,293 +488,310 @@ void RenderableStars::update(const UpdateData&) { reinterpret_cast(offsetof(SpeedVBOLayout, speed)) ); } + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + _dataIsDirty = false; } - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); - - _dataIsDirty = false; - } - - if (_pointSpreadFunctionTextureIsDirty) { - LDEBUG("Reloading Point Spread Function texture"); - _pointSpreadFunctionTexture = nullptr; - if (_pointSpreadFunctionTexturePath.value() != "") { - _pointSpreadFunctionTexture = ghoul::io::TextureReader::ref().loadTexture( - absPath(_pointSpreadFunctionTexturePath) - ); - - if (_pointSpreadFunctionTexture) { - LDEBUG(fmt::format( - "Loaded texture from '{}'", + if (_pointSpreadFunctionTextureIsDirty) { + LDEBUG("Reloading Point Spread Function texture"); + _pointSpreadFunctionTexture = nullptr; + if (_pointSpreadFunctionTexturePath.value() != "") { + _pointSpreadFunctionTexture = ghoul::io::TextureReader::ref().loadTexture( absPath(_pointSpreadFunctionTexturePath) - )); - _pointSpreadFunctionTexture->uploadTexture(); - } - _pointSpreadFunctionTexture->setFilter( - ghoul::opengl::Texture::FilterMode::AnisotropicMipMap - ); + ); - _pointSpreadFunctionFile = std::make_unique( - _pointSpreadFunctionTexturePath - ); - _pointSpreadFunctionFile->setCallback( - [&](const ghoul::filesystem::File&) { + if (_pointSpreadFunctionTexture) { + LDEBUG(fmt::format( + "Loaded texture from '{}'", + absPath(_pointSpreadFunctionTexturePath) + )); + _pointSpreadFunctionTexture->uploadTexture(); + } + _pointSpreadFunctionTexture->setFilter( + ghoul::opengl::Texture::FilterMode::AnisotropicMipMap + ); + + _pointSpreadFunctionFile = std::make_unique( + _pointSpreadFunctionTexturePath + ); + _pointSpreadFunctionFile->setCallback( + [&](const ghoul::filesystem::File&) { _pointSpreadFunctionTextureIsDirty = true; } - ); - } - _pointSpreadFunctionTextureIsDirty = false; - } - - if (_colorTextureIsDirty) { - LDEBUG("Reloading Color Texture"); - _colorTexture = nullptr; - if (_colorTexturePath.value() != "") { - _colorTexture = ghoul::io::TextureReader::ref().loadTexture( - absPath(_colorTexturePath) - ); - if (_colorTexture) { - LDEBUG(fmt::format( - "Loaded texture from '{}'", - absPath(_colorTexturePath) - )); - _colorTexture->uploadTexture(); + ); } - - _colorTextureFile = std::make_unique( - _colorTexturePath - ); - _colorTextureFile->setCallback( - [&](const ghoul::filesystem::File&) { _colorTextureIsDirty = true; } - ); + _pointSpreadFunctionTextureIsDirty = false; + } + + if (_colorTextureIsDirty) { + LDEBUG("Reloading Color Texture"); + _colorTexture = nullptr; + if (_colorTexturePath.value() != "") { + _colorTexture = ghoul::io::TextureReader::ref().loadTexture( + absPath(_colorTexturePath) + ); + if (_colorTexture) { + LDEBUG(fmt::format( + "Loaded texture from '{}'", + absPath(_colorTexturePath) + )); + _colorTexture->uploadTexture(); + } + + _colorTextureFile = std::make_unique( + _colorTexturePath + ); + _colorTextureFile->setCallback( + [&](const ghoul::filesystem::File&) { _colorTextureIsDirty = true; } + ); + } + _colorTextureIsDirty = false; + } + + if (_program->isDirty()) { + _program->rebuildFromFile(); + + _uniformCache.view = _program->uniformLocation("view"); + _uniformCache.projection = _program->uniformLocation("projection"); + _uniformCache.colorOption = _program->uniformLocation("colorOption"); + _uniformCache.alphaValue = _program->uniformLocation("alphaValue"); + _uniformCache.scaleFactor = _program->uniformLocation("scaleFactor"); + _uniformCache.minBillboardSize = _program->uniformLocation("minBillboardSize"); + _uniformCache.screenSize = _program->uniformLocation("screenSize"); + _uniformCache.scaling = _program->uniformLocation("scaling"); + _uniformCache.psfTexture = _program->uniformLocation("psfTexture"); + _uniformCache.colorTexture = _program->uniformLocation("colorTexture"); } - _colorTextureIsDirty = false; } - if (_program->isDirty()) { - _program->rebuildFromFile(); + bool RenderableStars::loadData() { + std::string _file = _speckFile; + std::string cachedFile = FileSys.cacheManager()->cachedFilename( + _file, + ghoul::filesystem::CacheManager::Persistent::Yes + ); - _uniformCache.model = _program->uniformLocation("model"); - _uniformCache.view = _program->uniformLocation("view"); - _uniformCache.viewScaling = _program->uniformLocation("viewScaling"); - _uniformCache.projection = _program->uniformLocation("projection"); - _uniformCache.colorOption = _program->uniformLocation("colorOption"); - _uniformCache.magnitudeExponent = _program->uniformLocation("magnitudeExponent"); - _uniformCache.sharpness = _program->uniformLocation("sharpness"); - _uniformCache.billboardSize = _program->uniformLocation("billboardSize"); - _uniformCache.screenSize = _program->uniformLocation("screenSize"); - _uniformCache.psfTexture = _program->uniformLocation("psfTexture"); - _uniformCache.colorTexture = _program->uniformLocation("colorTexture"); - } -} + bool hasCachedFile = FileSys.fileExists(cachedFile); + if (hasCachedFile) { + LINFO(fmt::format( + "Cached file '{}' used for Speck file '{}'", + cachedFile, + _file + )); -bool RenderableStars::loadData() { - std::string _file = _speckFile; - std::string cachedFile = FileSys.cacheManager()->cachedFilename( - _file, - ghoul::filesystem::CacheManager::Persistent::Yes - ); - - bool hasCachedFile = FileSys.fileExists(cachedFile); - if (hasCachedFile) { - LINFO(fmt::format( - "Cached file '{}' used for Speck file '{}'", - cachedFile, - _file - )); - - bool success = loadCachedFile(cachedFile); - if (success) { - return true; + bool success = loadCachedFile(cachedFile); + if (success) { + return true; + } + else { + FileSys.cacheManager()->removeCacheFile(_file); + // Intentional fall-through to the 'else' computation to generate the cache + // file for the next run + } } else { - FileSys.cacheManager()->removeCacheFile(_file); - // Intentional fall-through to the 'else' computation to generate the cache - // file for the next run + LINFO(fmt::format("Cache for Speck file '{}' not found", _file)); } - } - else { - LINFO(fmt::format("Cache for Speck file '{}' not found", _file)); - } - LINFO(fmt::format("Loading Speck file '{}'", _file)); + LINFO(fmt::format("Loading Speck file '{}'", _file)); - bool success = readSpeckFile(); - if (!success) { - return false; - } - - LINFO("Saving cache"); - success = saveCachedFile(cachedFile); - - return success; -} - -bool RenderableStars::readSpeckFile() { - std::string _file = _speckFile; - std::ifstream file(_file); - if (!file.good()) { - LERROR(fmt::format("Failed to open Speck file '{}'", _file)); - return false; - } - - _nValuesPerStar = 0; - - // The beginning of the speck file has a header that either contains comments - // (signaled by a preceding '#') or information about the structure of the file - // (signaled by the keywords 'datavar', 'texturevar', and 'texture') - std::string line = ""; - while (true) { - std::streampos position = file.tellg(); - std::getline(file, line); - - if (line[0] == '#' || line.empty()) { - continue; + bool success = readSpeckFile(); + if (!success) { + return false; } - if (line.substr(0, 7) != "datavar" && - line.substr(0, 10) != "texturevar" && - line.substr(0, 7) != "texture") - { - // we read a line that doesn't belong to the header, so we have to jump back - // before the beginning of the current line - file.seekg(position); - break; - } - - if (line.substr(0, 7) == "datavar") { - // datavar lines are structured as follows: - // datavar # description - // where # is the index of the data variable; so if we repeatedly overwrite - // the 'nValues' variable with the latest index, we will end up with the total - // number of values (+3 since X Y Z are not counted in the Speck file index) - std::stringstream str(line); + LINFO("Saving cache"); + success = saveCachedFile(cachedFile); - std::string dummy; - str >> dummy; - str >> _nValuesPerStar; - _nValuesPerStar += 1; // We want the number, but the index is 0 based - } + return success; } - _nValuesPerStar += 3; // X Y Z are not counted in the Speck file indices - - float minLumValue = std::numeric_limits::max(); - float maxLumValue = std::numeric_limits::min(); - - do { - std::vector values(_nValuesPerStar); - - std::getline(file, line); - std::stringstream str(line); - - for (int i = 0; i < _nValuesPerStar; ++i) { - str >> values[i]; + bool RenderableStars::readSpeckFile() { + std::string _file = _speckFile; + std::ifstream file(_file); + if (!file.good()) { + LERROR(fmt::format("Failed to open Speck file '{}'", _file)); + return false; } - bool nullArray = true; - for (size_t i = 0; i < values.size(); ++i) { - if (values[i] != 0.0) { - nullArray = false; + + _nValuesPerStar = 0; + + // The beginning of the speck file has a header that either contains comments + // (signaled by a preceding '#') or information about the structure of the file + // (signaled by the keywords 'datavar', 'texturevar', and 'texture') + std::string line = ""; + while (true) { + std::streampos position = file.tellg(); + std::getline(file, line); + + if (line[0] == '#' || line.empty()) { + continue; + } + + if (line.substr(0, 7) != "datavar" && + line.substr(0, 10) != "texturevar" && + line.substr(0, 7) != "texture") + { + // we read a line that doesn't belong to the header, so we have to jump back + // before the beginning of the current line + file.seekg(position); break; } - } - minLumValue = std::min(values[4], minLumValue); - maxLumValue = std::max(values[4], minLumValue); - if (!nullArray) { - _fullData.insert(_fullData.end(), values.begin(), values.end()); - } - } while (!file.eof()); - // Normalize Luminosity: - int luminosityVarColumnPos = 4; - for (size_t i = 0; i < _fullData.size(); i += _nValuesPerStar) { - _fullData[i + luminosityVarColumnPos] = - (_fullData[i + luminosityVarColumnPos] - minLumValue) / - (maxLumValue - minLumValue); + if (line.substr(0, 7) == "datavar") { + // datavar lines are structured as follows: + // datavar # description + // where # is the index of the data variable; so if we repeatedly overwrite + // the 'nValues' variable with the latest index, we will end up with the total + // number of values (+3 since X Y Z are not counted in the Speck file index) + std::stringstream str(line); + + std::string dummy; + str >> dummy; + str >> _nValuesPerStar; + _nValuesPerStar += 1; // We want the number, but the index is 0 based + } + } + + _nValuesPerStar += 3; // X Y Z are not counted in the Speck file indices + + do { + std::vector values(_nValuesPerStar); + + std::getline(file, line); + std::stringstream str(line); + + for (int i = 0; i < _nValuesPerStar; ++i) { + str >> values[i]; + } + bool nullArray = true; + for (size_t i = 0; i < values.size(); ++i) { + if (values[i] != 0.0) { + nullArray = false; + break; + } + } + if (!nullArray) { + _fullData.insert(_fullData.end(), values.begin(), values.end()); + } + } while (!file.eof()); + + return true; } - return true; -} + bool RenderableStars::loadCachedFile(const std::string& file) { + std::ifstream fileStream(file, std::ifstream::binary); + if (fileStream.good()) { + int8_t version = 0; + fileStream.read(reinterpret_cast(&version), sizeof(int8_t)); + if (version != CurrentCacheVersion) { + LINFO("The format of the cached file has changed: deleting old cache"); + fileStream.close(); + FileSys.deleteFile(file); + return false; + } -bool RenderableStars::loadCachedFile(const std::string& file) { - std::ifstream fileStream(file, std::ifstream::binary); - if (fileStream.good()) { - int8_t version = 0; - fileStream.read(reinterpret_cast(&version), sizeof(int8_t)); - if (version != CurrentCacheVersion) { - LINFO("The format of the cached file has changed: deleting old cache"); - fileStream.close(); - FileSys.deleteFile(file); + int32_t nValues = 0; + fileStream.read(reinterpret_cast(&nValues), sizeof(int32_t)); + fileStream.read(reinterpret_cast(&_nValuesPerStar), sizeof(int32_t)); + + _fullData.resize(nValues); + fileStream.read(reinterpret_cast(&_fullData[0]), + nValues * sizeof(_fullData[0])); + + bool success = fileStream.good(); + return success; + } + else { + LERROR(fmt::format("Error opening file '{}' for loading cache file", file)); return false; } - - int32_t nValues = 0; - fileStream.read(reinterpret_cast(&nValues), sizeof(int32_t)); - fileStream.read(reinterpret_cast(&_nValuesPerStar), sizeof(int32_t)); - - _fullData.resize(nValues); - fileStream.read(reinterpret_cast(&_fullData[0]), - nValues * sizeof(_fullData[0])); - - bool success = fileStream.good(); - return success; } - else { - LERROR(fmt::format("Error opening file '{}' for loading cache file", file)); - return false; - } -} -bool RenderableStars::saveCachedFile(const std::string& file) const { - std::ofstream fileStream(file, std::ofstream::binary); - if (fileStream.good()) { - fileStream.write(reinterpret_cast(&CurrentCacheVersion), - sizeof(int8_t)); + bool RenderableStars::saveCachedFile(const std::string& file) const { + std::ofstream fileStream(file, std::ofstream::binary); + if (fileStream.good()) { + fileStream.write(reinterpret_cast(&CurrentCacheVersion), + sizeof(int8_t)); - int32_t nValues = static_cast(_fullData.size()); - if (nValues == 0) { - LERROR("Error writing cache: No values were loaded"); + int32_t nValues = static_cast(_fullData.size()); + if (nValues == 0) { + LERROR("Error writing cache: No values were loaded"); + return false; + } + fileStream.write(reinterpret_cast(&nValues), sizeof(int32_t)); + + int32_t nValuesPerStar = static_cast(_nValuesPerStar); + fileStream.write(reinterpret_cast(&nValuesPerStar), sizeof(int32_t)); + + size_t nBytes = nValues * sizeof(_fullData[0]); + fileStream.write(reinterpret_cast(&_fullData[0]), nBytes); + + bool success = fileStream.good(); + return success; + } + else { + LERROR(fmt::format("Error opening file '{}' for save cache file", file)); return false; } - fileStream.write(reinterpret_cast(&nValues), sizeof(int32_t)); - - int32_t nValuesPerStar = static_cast(_nValuesPerStar); - fileStream.write(reinterpret_cast(&nValuesPerStar), sizeof(int32_t)); - - size_t nBytes = nValues * sizeof(_fullData[0]); - fileStream.write(reinterpret_cast(&_fullData[0]), nBytes); - - bool success = fileStream.good(); - return success; } - else { - LERROR(fmt::format("Error opening file '{}' for save cache file", file)); - return false; - } -} -void RenderableStars::createDataSlice(ColorOption option) { - _slicedData.clear(); + void RenderableStars::createDataSlice(ColorOption option) { + _slicedData.clear(); - for (size_t i = 0; i < _fullData.size(); i+=_nValuesPerStar) { - glm::vec3 p = glm::vec3(_fullData[i + 0], _fullData[i + 1], _fullData[i + 2]); - p *= openspace::distanceconstants::Parsec; + // This is only temporary until the scalegraph is in place ---abock + float minDistance = std::numeric_limits::max(); + float maxDistance = -std::numeric_limits::max(); - switch (option) { - case ColorOption::Color: + for (size_t i = 0; i < _fullData.size(); i += _nValuesPerStar) { + float distLy = _fullData[i + 6]; + //if (distLy < 20.f) { + minDistance = std::min(minDistance, distLy); + maxDistance = std::max(maxDistance, distLy); + //} + } + + for (size_t i = 0; i < _fullData.size(); i += _nValuesPerStar) { + glm::vec3 p = glm::vec3(_fullData[i + 0], _fullData[i + 1], _fullData[i + 2]); + + // This is only temporary until the scalegraph is in place. It places all stars + // on a sphere with a small variation in the distance to account for blending + // issues ---abock + //if (p != glm::vec3(0.f)) + // p = glm::normalize(p); + + //float distLy = _fullData[i + 6]; + //float normalizedDist = (distLy - minDistance) / (maxDistance - minDistance); + //float distance = 18.f - normalizedDist / 1.f ; + + + //psc position = psc(glm::vec4(p, distance)); + + // Convert parsecs -> meter + psc position = psc(glm::vec4(p * 0.308567756f, 17)); + + //position[1] *= parsecsToMetersFactor[0]; + //position[2] *= parsecsToMetersFactor[0]; + //position[3] += parsecsToMetersFactor[1]; + + switch (option) { + case ColorOption::Color: { union { ColorVBOLayout value; - std::array data; + std::array data; } layout; layout.value.position = { { - p[0], p[1], p[2], 1.0 - } }; + position[0], position[1], position[2], position[3] + } }; #ifdef USING_STELLAR_TEST_GRID - layout.value.bvColor = 0.650;// _fullData[i + 3]; - layout.value.luminance = _fullData[i + 4]; + layout.value.bvColor = _fullData[i + 3]; + layout.value.luminance = _fullData[i + 3]; layout.value.absoluteMagnitude = _fullData[i + 3]; #else layout.value.bvColor = _fullData[i + 3]; @@ -796,20 +800,20 @@ void RenderableStars::createDataSlice(ColorOption option) { #endif _slicedData.insert(_slicedData.end(), - layout.data.begin(), - layout.data.end()); + layout.data.begin(), + layout.data.end()); break; } - case ColorOption::Velocity: + case ColorOption::Velocity: { union { VelocityVBOLayout value; - std::array data; + std::array data; } layout; layout.value.position = { { - p[0], p[1], p[2], 1.0 + position[0], position[1], position[2], position[3] } }; layout.value.bvColor = _fullData[i + 3]; @@ -821,19 +825,19 @@ void RenderableStars::createDataSlice(ColorOption option) { layout.value.vz = _fullData[i + 14]; _slicedData.insert(_slicedData.end(), - layout.data.begin(), - layout.data.end()); + layout.data.begin(), + layout.data.end()); break; } - case ColorOption::Speed: + case ColorOption::Speed: { union { SpeedVBOLayout value; - std::array data; + std::array data; } layout; layout.value.position = { { - p[0], p[1], p[2], 1.0 + position[0], position[1], position[2], position[3] } }; layout.value.bvColor = _fullData[i + 3]; @@ -843,12 +847,12 @@ void RenderableStars::createDataSlice(ColorOption option) { layout.value.speed = _fullData[i + 15]; _slicedData.insert(_slicedData.end(), - layout.data.begin(), - layout.data.end()); + layout.data.begin(), + layout.data.end()); break; } + } } } -} } // namespace openspace diff --git a/modules/space/rendering/renderablestars.h b/modules/space/rendering/renderablestars.h index 3e8ced2282..e6fd355f5e 100644 --- a/modules/space/rendering/renderablestars.h +++ b/modules/space/rendering/renderablestars.h @@ -1,26 +1,26 @@ /***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2018 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ +* * +* OpenSpace * +* * +* Copyright (c) 2014-2018 * +* * +* 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_SPACE___RENDERABLESTARS___H__ #define __OPENSPACE_MODULE_SPACE___RENDERABLESTARS___H__ @@ -42,68 +42,68 @@ namespace ghoul::opengl { namespace openspace { -namespace documentation { struct Documentation; } + namespace documentation { struct Documentation; } -class RenderableStars : public Renderable { -public: - explicit RenderableStars(const ghoul::Dictionary& dictionary); - ~RenderableStars(); + class RenderableStars : public Renderable { + public: + explicit RenderableStars(const ghoul::Dictionary& dictionary); + ~RenderableStars(); - void initializeGL() override; - void deinitializeGL() override; + void initializeGL() override; + void deinitializeGL() override; - bool isReady() const override; + bool isReady() const override; - void render(const RenderData& data, RendererTasks& rendererTask) override; - void update(const UpdateData& data) override; + void render(const RenderData& data, RendererTasks& rendererTask) override; + void update(const UpdateData& data) override; - static documentation::Documentation Documentation(); + static documentation::Documentation Documentation(); -private: - enum ColorOption { - Color = 0, - Velocity = 1, - Speed = 2 + private: + enum ColorOption { + Color = 0, + Velocity = 1, + Speed = 2 + }; + + void createDataSlice(ColorOption option); + + bool loadData(); + bool readSpeckFile(); + bool loadCachedFile(const std::string& file); + bool saveCachedFile(const std::string& file) const; + + properties::StringProperty _pointSpreadFunctionTexturePath; + std::unique_ptr _pointSpreadFunctionTexture; + std::unique_ptr _pointSpreadFunctionFile; + bool _pointSpreadFunctionTextureIsDirty; + + properties::StringProperty _colorTexturePath; + std::unique_ptr _colorTexture; + std::unique_ptr _colorTextureFile; + bool _colorTextureIsDirty; + + properties::OptionProperty _colorOption; + bool _dataIsDirty; + + properties::FloatProperty _alphaValue; + properties::FloatProperty _scaleFactor; + properties::FloatProperty _minBillboardSize; + + std::unique_ptr _program; + UniformCache(view, projection, colorOption, alphaValue, scaleFactor, + minBillboardSize, screenSize, scaling, psfTexture, colorTexture) _uniformCache; + + std::string _speckFile; + + std::vector _slicedData; + std::vector _fullData; + int _nValuesPerStar; + + GLuint _vao; + GLuint _vbo; }; - void createDataSlice(ColorOption option); - - bool loadData(); - bool readSpeckFile(); - bool loadCachedFile(const std::string& file); - bool saveCachedFile(const std::string& file) const; - - properties::StringProperty _pointSpreadFunctionTexturePath; - std::unique_ptr _pointSpreadFunctionTexture; - std::unique_ptr _pointSpreadFunctionFile; - bool _pointSpreadFunctionTextureIsDirty; - - properties::StringProperty _colorTexturePath; - std::unique_ptr _colorTexture; - std::unique_ptr _colorTextureFile; - bool _colorTextureIsDirty; - - properties::OptionProperty _colorOption; - bool _dataIsDirty; - - properties::FloatProperty _magnitudeExponent; - properties::FloatProperty _sharpness; - properties::FloatProperty _billboardSize; - - std::unique_ptr _program; - UniformCache(model, view, viewScaling, projection, colorOption, magnitudeExponent, sharpness, - billboardSize, screenSize, scaling, psfTexture, colorTexture) _uniformCache; - - std::string _speckFile; - - std::vector _slicedData; - std::vector _fullData; - int _nValuesPerStar; - - GLuint _vao; - GLuint _vbo; -}; - } // namespace openspace #endif // __OPENSPACE_MODULE_SPACE___RENDERABLESTARS___H__ diff --git a/modules/space/shaders/star_fs.glsl b/modules/space/shaders/star_fs.glsl index a128debca7..57cc7fd866 100644 --- a/modules/space/shaders/star_fs.glsl +++ b/modules/space/shaders/star_fs.glsl @@ -23,7 +23,7 @@ ****************************************************************************************/ #include "fragment.glsl" -#include "floatoperations.glsl" +#include "PowerScaling/powerScaling_fs.hglsl" // keep in sync with renderablestars.h:ColorOption enum const int COLOROPTION_COLOR = 0; @@ -32,11 +32,10 @@ const int COLOROPTION_SPEED = 2; uniform sampler2D psfTexture; uniform sampler1D colorTexture; +uniform float minBillboardSize; -uniform float magnitudeExponent; -uniform float sharpness; +uniform float alphaValue; uniform int colorOption; -uniform vec3 eyePosition; in vec4 vs_position; in vec4 ge_gPosition; @@ -44,8 +43,13 @@ in vec3 ge_brightness; in vec3 ge_velocity; in float ge_speed; in vec2 texCoord; -in float ge_observationDistance; -in vec4 ge_worldPosition; +in float billboardSize; + +#include "fragment.glsl" +//#include "PowerScaling/powerScaling_fs.hglsl" + +uniform vec2 magnitudeClamp; + vec4 bv2rgb(float bv) { // BV is [-0.4,2.0] @@ -56,7 +60,7 @@ vec4 bv2rgb(float bv) { Fragment getFragment() { // Something in the color calculations need to be changed because before it was dependent // on the gl blend functions since the abuffer was not involved - + vec4 color = vec4(0.0); switch (colorOption) { case COLOROPTION_COLOR: @@ -73,15 +77,19 @@ Fragment getFragment() { vec4 textureColor = texture(psfTexture, texCoord); vec4 fullColor = vec4(color.rgb, textureColor.a); - fullColor.a = pow(fullColor.a, sharpness); + fullColor.a *= alphaValue; - float d = magnitudeExponent - log(ge_observationDistance) / log(10.0); - fullColor.a *= clamp(d, 0.0, 1.0); + vec4 position = vs_position; + // This has to be fixed when the scale graph is in place ---emiax + position.w = 15; Fragment frag; frag.color = fullColor; - frag.depth = safeLength(vs_position); + frag.depth = pscDepth(position); + + // G-Buffer frag.gPosition = ge_gPosition; + // There is no normal here frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); if (fullColor.a == 0) { @@ -89,4 +97,4 @@ Fragment getFragment() { } return frag; -} +} \ No newline at end of file diff --git a/modules/space/shaders/star_ge.glsl b/modules/space/shaders/star_ge.glsl index 64389c6e5d..4dd4ad6378 100644 --- a/modules/space/shaders/star_ge.glsl +++ b/modules/space/shaders/star_ge.glsl @@ -24,15 +24,15 @@ #version __CONTEXT__ -#include "floatoperations.glsl" +#include "PowerScaling/powerScalingMath.hglsl" layout(points) in; - +in vec4 psc_position[]; in vec3 vs_brightness[]; in vec3 vs_velocity[]; in vec4 vs_gPosition[]; in float vs_speed[]; -in vec4 vs_worldPosition[]; +in vec4 cam_position[]; layout(triangle_strip, max_vertices = 4) out; @@ -42,14 +42,13 @@ out vec3 ge_brightness; out vec3 ge_velocity; out float ge_speed; out vec2 texCoord; -out float ge_observationDistance; -out vec4 ge_worldPosition; +out float billboardSize; + +uniform mat4 projection; -uniform float viewScaling; uniform float scaleFactor; -uniform float billboardSize; +uniform float minBillboardSize; uniform vec2 screenSize; -uniform vec3 eyePosition; const vec2 corners[4] = vec2[4]( vec2(0.0, 1.0), @@ -58,77 +57,52 @@ const vec2 corners[4] = vec2[4]( vec2(1.0, 0.0) ); -void main() { - if ((vs_worldPosition[0].x == 0.0) && - (vs_worldPosition[0].y == 0.0) && - (vs_worldPosition[0].z == 0.0)) - { - return; - } +void main() { + // JCC: We want to display the Sun. + // if ((psc_position[0].x == 0.0) && + // (psc_position[0].y == 0.0) && + // (psc_position[0].z == 0.0)) + // { + // return; + // } ge_brightness = vs_brightness[0]; ge_velocity = vs_velocity[0]; ge_speed = vs_speed[0]; - ge_worldPosition = vs_worldPosition[0]; - vec4 projectedPoint = gl_in[0].gl_Position; - - float distanceToStarInParsecs = length(ge_worldPosition.xyz / 3.0856776E16 - eyePosition / 3.0856776E16); + float absoluteMagnitude = vs_brightness[0].z; + float modifiedSpriteSize = + exp((-30.623 - absoluteMagnitude) * 0.462) * scaleFactor * 2000; - float luminosity = ge_brightness.y; - - // Working like Partiview - float pSize = 3.0E5; - float slum = 1.0; - float samplingFactor = 1.0; - float apparentBrightness = (pSize * slum * samplingFactor * luminosity) / (distanceToStarInParsecs * distanceToStarInParsecs); - - vec2 multiplier = vec2(apparentBrightness * projectedPoint.w); - - // Max Star Sizes: - // Fragment Coords: - vec2 bottomLeft = screenSize * ((projectedPoint.xy + vec2(multiplier) * corners[1])/projectedPoint.w + vec2(1.0)) - vec2(0.5); - vec2 topRight = screenSize * ((projectedPoint.xy + vec2(multiplier) * corners[2])/projectedPoint.w + vec2(1.0)) - vec2(0.5); + 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))); + projPos[i] = projection * p1; + } - float height = abs(topRight.y - bottomLeft.y); - float width = abs(topRight.x - bottomLeft.x); - float var = (height + width); + // Calculate the positions of the lower left and upper right corners of the + // billboard in screen-space + vec2 ll = (((projPos[1].xy / projPos[1].w) + 1.0) / 2.0) * screenSize; + vec2 ur = (((projPos[2].xy / projPos[2].w) + 1.0) / 2.0) * screenSize; - float maxBillboardSize = billboardSize; - float minBillboardSize = 1.0; + // The billboard is smaller than one pixel, we can discard it + float sizeInPixels = length(ll - ur); + if (sizeInPixels < minBillboardSize) { + return; + } - if ((height > maxBillboardSize) || - (width > maxBillboardSize)) { - //if (height > maxBillboardSize) { - float correctionScale = height > maxBillboardSize ? maxBillboardSize / (topRight.y - bottomLeft.y) : - maxBillboardSize / (topRight.x - bottomLeft.x); - multiplier *= correctionScale; - } else { - if (width < 2.0f * minBillboardSize) { - float maxVar = 2.0f * minBillboardSize; - float minVar = minBillboardSize; - float ta = ( (var - minVar)/(maxVar - minVar) ); - if (ta == 0.0f) - return; - } - } - - vec2 starSize = multiplier; - for (int i = 0; i < 4; i++) { vs_position = gl_in[0].gl_Position; - gl_Position = projectedPoint + vec4(starSize * (corners[i] - 0.5), 0.0, 0.0); - gl_Position.z = 0.0; - + gl_Position = projPos[i]; texCoord = corners[i]; // G-Buffer ge_gPosition = vs_gPosition[0]; - ge_observationDistance = safeLength(vs_gPosition[0] / viewScaling); - + billboardSize = sizeInPixels; EmitVertex(); } EndPrimitive(); -} +} \ No newline at end of file diff --git a/modules/space/shaders/star_vs.glsl b/modules/space/shaders/star_vs.glsl index f204842af3..be301601a5 100644 --- a/modules/space/shaders/star_vs.glsl +++ b/modules/space/shaders/star_vs.glsl @@ -31,25 +31,30 @@ in vec3 in_brightness; in vec3 in_velocity; in float in_speed; +out vec4 psc_position; out vec3 vs_brightness; out vec3 vs_velocity; out float vs_speed; out vec4 vs_gPosition; -out vec4 vs_worldPosition; -uniform mat4 model; uniform mat4 view; uniform mat4 projection; + void main() { + vec4 p = in_position; + psc_position = p; vs_brightness = in_brightness; vs_velocity = in_velocity; vs_speed = in_speed; - vec3 modelPosition = in_position.xyz; - vs_worldPosition = model * vec4(modelPosition, 1.0); - vec4 viewPosition = view * vs_worldPosition; - - vs_gPosition = viewPosition; - gl_Position = projection * vs_gPosition; -} + vec4 tmp = p; + vec4 position = pscTransform(tmp, mat4(1.0)); + + // G-Buffer + vs_gPosition = view * (vec4(1E19, 1E19, 1E19, 1.0) * position); + + position = view * position; + + gl_Position = position; +} \ No newline at end of file