From 561aa221d3b313e5a895fb06580531914e0f9320 Mon Sep 17 00:00:00 2001 From: jonasstrandstedt Date: Thu, 20 Nov 2014 09:33:07 +0100 Subject: [PATCH 01/19] Linux fixes - Commented out the tinythread hack from src/CMakeLists.txt --- include/openspace/interaction/keys.h | 2 +- include/openspace/interaction/mouse.h | 16 ++++++++-------- src/CMakeLists.txt | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/openspace/interaction/keys.h b/include/openspace/interaction/keys.h index b380a7b789..e92f41c620 100644 --- a/include/openspace/interaction/keys.h +++ b/include/openspace/interaction/keys.h @@ -37,7 +37,7 @@ enum class KeyAction { }; enum class KeyModifier { - None = 0, + NoModifier = 0, Shift = GLFW_MOD_SHIFT, Control = GLFW_MOD_CONTROL, Alt = GLFW_MOD_ALT, diff --git a/include/openspace/interaction/mouse.h b/include/openspace/interaction/mouse.h index 2a4cca19d6..605a5be699 100644 --- a/include/openspace/interaction/mouse.h +++ b/include/openspace/interaction/mouse.h @@ -40,14 +40,14 @@ enum class MouseButton { Left = SGCT_MOUSE_BUTTON_LEFT, Right = SGCT_MOUSE_BUTTON_RIGHT, Middle = SGCT_MOUSE_BUTTON_MIDDLE, - Button1 = SGCT_MOUSE_BUTTON_1, - Button2 = SGCT_MOUSE_BUTTON_2, - Button3 = SGCT_MOUSE_BUTTON_3, - Button4 = SGCT_MOUSE_BUTTON_4, - Button5 = SGCT_MOUSE_BUTTON_5, - Button6 = SGCT_MOUSE_BUTTON_6, - Button7 = SGCT_MOUSE_BUTTON_7, - Button8 = SGCT_MOUSE_BUTTON_8, + //Button1 = SGCT_MOUSE_BUTTON_1, + //Button2 = SGCT_MOUSE_BUTTON_2, + //Button3 = SGCT_MOUSE_BUTTON_3, + //Button4 = SGCT_MOUSE_BUTTON_4, + //Button5 = SGCT_MOUSE_BUTTON_5, + //Button6 = SGCT_MOUSE_BUTTON_6, + //Button7 = SGCT_MOUSE_BUTTON_7, + //Button8 = SGCT_MOUSE_BUTTON_8, ButtonLast = SGCT_MOUSE_BUTTON_LAST, }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ed8c4f4491..86d3831cdf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -129,7 +129,7 @@ source_group(Interface FILES ${INTERFACE_SOURCE} ${INTERFACE_HEADER}) include_directories(${HEADER_ROOT_DIR}) # hack: -set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${OPENSPACE_EXT_DIR}/tinythread.cpp) +#set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${OPENSPACE_EXT_DIR}/tinythread.cpp) include_directories(${GHOUL_ROOT_DIR}/ext/boost) find_package(OpenCL REQUIRED) From 815fc3b348807c4a2cbc4331583b8eee5a10be64 Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Fri, 21 Nov 2014 10:37:01 +0100 Subject: [PATCH 02/19] Fixed depth, position, scale and shader issues with fieldlines. Added passthrough geometry shader --- .../rendering/renderablefieldlines.h | 12 +- shaders/fieldline_fs.glsl | 40 ++++++ shaders/fieldline_gs.glsl | 90 +++++++++++++ shaders/fieldline_vs.glsl | 51 ++++++++ src/rendering/renderablefieldlines.cpp | 123 +++++------------- src/scenegraph/scenegraph.cpp | 10 ++ src/util/kameleonwrapper.cpp | 4 +- 7 files changed, 225 insertions(+), 105 deletions(-) create mode 100644 shaders/fieldline_fs.glsl create mode 100644 shaders/fieldline_gs.glsl create mode 100644 shaders/fieldline_vs.glsl diff --git a/include/openspace/rendering/renderablefieldlines.h b/include/openspace/rendering/renderablefieldlines.h index c0b54c0f16..b74523ce2a 100644 --- a/include/openspace/rendering/renderablefieldlines.h +++ b/include/openspace/rendering/renderablefieldlines.h @@ -45,7 +45,6 @@ public: bool deinitialize(); void render(const RenderData& data) override; - void update(const UpdateData& data) override; private: std::vector > getFieldlinesData(std::string filename, ghoul::Dictionary hintsDictionary); @@ -54,18 +53,11 @@ private: std::vector _filenames; std::vector _seedPoints; - ghoul::opengl::ProgramObject *_fieldlinesProgram; - GLuint _VAO, _seedpointVAO; - - ghoul::filesystem::File* _vertexSourceFile; - ghoul::filesystem::File* _fragmentSourceFile; + ghoul::opengl::ProgramObject* _shader; + GLuint _fieldlineVAO, _seedpointVAO; std::vector _lineStart; std::vector _lineCount; - - bool _programUpdateOnSave; - bool _update; - void safeShaderCompilation(); }; } // namespace openspace diff --git a/shaders/fieldline_fs.glsl b/shaders/fieldline_fs.glsl new file mode 100644 index 0000000000..d5d89d8cfa --- /dev/null +++ b/shaders/fieldline_fs.glsl @@ -0,0 +1,40 @@ +/***************************************************************************************** + * * + * 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__ + +in vec4 gs_color; +in vec4 gs_position; + +#include "ABuffer/abufferStruct.hglsl" +#include "ABuffer/abufferAddToBuffer.hglsl" +#include "PowerScaling/powerScaling_fs.hglsl" + +void main() { + vec4 fragColor = gs_color; + + float depth = pscDepth(gs_position); + ABufferStruct_t frag = createGeometryFragment(fragColor, gs_position, depth); + addToBuffer(frag); +} \ No newline at end of file diff --git a/shaders/fieldline_gs.glsl b/shaders/fieldline_gs.glsl new file mode 100644 index 0000000000..6338dda9b9 --- /dev/null +++ b/shaders/fieldline_gs.glsl @@ -0,0 +1,90 @@ + +#version __CONTEXT__ + +uniform mat4 modelViewProjection; +uniform mat4 modelTransform; + +layout(lines) in; +layout(line_strip, max_vertices = 2) out; + +in vec4 vs_color[]; +in vec4 vs_position[]; +out vec4 gs_color; +out vec4 gs_position; + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() { + gs_color = vs_color[0]; + for(int i = 0; i < 2; i++) { + // gs_position = gl_in[i].gl_Position; + // gl_Position = gl_in[i].gl_Position; + + // calculate psc position + vec4 tmp = gl_in[i].gl_Position; + vec4 position = pscTransform(tmp, modelTransform); + gs_position = tmp; + + // project the position to view space + position = modelViewProjection * position; + gl_Position = z_normalization(position); + EmitVertex(); + } + EndPrimitive(); +} + +// uniform mat4 ModelviewProjection; +// layout(lines_adjacency) in; +// layout(location = 0) in vec3 vPosition[4]; // Four inputs since we're using GL_LINE_STRIP_ADJACENCY +// // layout(location = 2) in vec3 vNormal[4]; // Orientation vectors are necessary for consistent alignment +// layout(triangle_strip, max_vertices = 24) out; + +// out vec4 in_color; + +// vec4 prismoid[8]; // Scratch space for the eight corners of the prismoid + +// void emit(int a, int b, int c, int d) { +// gl_Position = prismoid[a]; EmitVertex(); +// gl_Position = prismoid[b]; EmitVertex(); +// gl_Position = prismoid[c]; EmitVertex(); +// gl_Position = prismoid[d]; EmitVertex(); +// EndPrimitive(); +// } + +// void main() { +// // Compute orientation vectors for the two connecting faces: +// vec3 vNormal = vec3(0, 0, 1); + +// vec3 p0, p1, p2, p3; +// p0 = vPosition[0]; p1 = vPosition[1]; +// p2 = vPosition[2]; p3 = vPosition[3]; +// vec3 n0 = normalize(p1-p0); +// vec3 n1 = normalize(p2-p1); +// vec3 n2 = normalize(p3-p2); +// vec3 u = normalize(n0+n1); +// vec3 v = normalize(n1+n2); + +// // Declare scratch variables for basis vectors: +// vec3 i,j,k; float r = 0.1; + +// // Compute face 1 of 2: +// // j = u; i = vNormal[1]; k = cross(i, j); i *= r; k *= r; +// j = u; i = vNormal; k = cross(i, j); i *= r; k *= r; +// prismoid[0] = ModelviewProjection * vec4(p1 + i + k, 1); +// prismoid[1] = ModelviewProjection * vec4(p1 + i - k, 1); +// prismoid[2] = ModelviewProjection * vec4(p1 - i - k, 1); +// prismoid[3] = ModelviewProjection * vec4(p1 - i + k, 1); + +// // Compute face 2 of 2: +// // j = v; i = vNormal[2]; k = cross(i, j); i *= r; k *= r; +// j = v; i = vNormal; k = cross(i, j); i *= r; k *= r; +// prismoid[4] = ModelviewProjection * vec4(p2 + i + k, 1); +// prismoid[5] = ModelviewProjection * vec4(p2 + i - k, 1); +// prismoid[6] = ModelviewProjection * vec4(p2 - i - k, 1); +// prismoid[7] = ModelviewProjection * vec4(p2 - i + k, 1); + +// // Emit the six faces of the prismoid: +// emit(0,1,3,2); emit(5,4,6,7); +// emit(4,5,0,1); emit(3,2,7,6); +// emit(0,3,4,7); emit(2,1,6,5); +// } diff --git a/shaders/fieldline_vs.glsl b/shaders/fieldline_vs.glsl new file mode 100644 index 0000000000..97b3455db6 --- /dev/null +++ b/shaders/fieldline_vs.glsl @@ -0,0 +1,51 @@ +/***************************************************************************************** + * * + * 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__ + +uniform mat4 modelViewProjection; +uniform mat4 modelTransform; + +layout(location = 0) in vec3 in_position; +layout(location = 1) in vec4 in_color; + +out vec4 vs_color; +// out vec4 vs_position; + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() { + vs_color = in_color; + + // // calculate psc position + // vec4 tmp = vec4(in_position, 0); + // vec4 position = pscTransform(tmp, modelTransform); + // // vs_position = tmp; + + // // project the position to view space + // position = modelViewProjection * position; + // gl_Position = z_normalization(position); + + gl_Position = vec4(in_position, 0); +} \ No newline at end of file diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index d0db9225a4..49256d0163 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -35,18 +35,14 @@ namespace { const std::string keyFieldlines = "Fieldlines"; const std::string keyFilename = "File"; const std::string keyHints = "Hints"; - const std::string keyShaders = "Shaders"; - const std::string keyVertexShader = "VertexShader"; - const std::string keyFragmentShader = "FragmentShader"; } namespace openspace { RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) : Renderable(dictionary) - , _VAO(0) - , _programUpdateOnSave(false) - , _update(false) + , _fieldlineVAO(0) + , _shader(nullptr) { std::string name; bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); @@ -84,41 +80,7 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) } } - ghoul::Dictionary shaderDictionary; - success = dictionary.getValue(keyShaders, shaderDictionary); - if (!success) { - LERROR("RenderableFieldlines '" << name << "' does not contain a '" << - keyShaders << "' table"); - return; - } - - std::string vshaderpath; - success = shaderDictionary.getValue(keyVertexShader, vshaderpath); - if (!success) { - LERROR("RenderableFieldlines '" << name << "' does not have a '" << - keyVertexShader << "'"); - return; - } - vshaderpath = findPath(vshaderpath); - - std::string fshaderpath; - success = shaderDictionary.getValue(keyFragmentShader, fshaderpath); - if (!success) { - LERROR("RenderableFieldlines '" << name << "' does not have a '" << - keyFragmentShader << "'"); - return; - } - fshaderpath = findPath(fshaderpath); - - _vertexSourceFile = new ghoul::filesystem::File(vshaderpath, false); - _fragmentSourceFile = new ghoul::filesystem::File(fshaderpath, false); - - - _fieldlinesProgram = ghoul::opengl::ProgramObject::Build("FieldlinesProgram", vshaderpath, fshaderpath); - - dictionary.getValue("UpdateOnSave", _programUpdateOnSave); - - setBoundingSphere(PowerScaledScalar::CreatePSS(5)); // FIXME a non-magic number perhaps + setBoundingSphere(PowerScaledScalar::CreatePSS(250.f*6371000.f)); // FIXME a non-magic number perhaps } RenderableFieldlines::~RenderableFieldlines() { @@ -151,8 +113,8 @@ bool RenderableFieldlines::initialize() { // ------ FIELDLINES ----------------- GLuint vertexPositionBuffer; - glGenVertexArrays(1, &_VAO); // generate array - glBindVertexArray(_VAO); // bind array + glGenVertexArrays(1, &_fieldlineVAO); // generate array + glBindVertexArray(_fieldlineVAO); // bind array glGenBuffers(1, &vertexPositionBuffer); // generate buffer glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer glBufferData(GL_ARRAY_BUFFER, vertexData.size()*sizeof(LinePoint), &vertexData.front(), GL_STATIC_DRAW); @@ -162,10 +124,10 @@ bool RenderableFieldlines::initialize() { glEnableVertexAttribArray(vertexLocation); glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(LinePoint), reinterpret_cast(0)); - // Texture coordinates - GLuint texcoordLocation = 1; - glEnableVertexAttribArray(texcoordLocation); - glVertexAttribPointer(texcoordLocation, 4, GL_FLOAT, GL_FALSE, sizeof(LinePoint), (void*)(sizeof(glm::vec3))); + // Vertex colors + GLuint colorLocation = 1; + glEnableVertexAttribArray(colorLocation); + glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(LinePoint), (void*)(sizeof(glm::vec3))); glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer glBindVertexArray(0); //unbind array @@ -182,26 +144,21 @@ bool RenderableFieldlines::initialize() { glEnableVertexAttribArray(vertexLocation); glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(LinePoint), reinterpret_cast(0)); - // Texture coordinates - glEnableVertexAttribArray(texcoordLocation); - glVertexAttribPointer(texcoordLocation, 4, GL_FLOAT, GL_FALSE, sizeof(LinePoint), (void*)(3*sizeof(float))); + // Vertex colors + glEnableVertexAttribArray(colorLocation); + glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(LinePoint), (void*)(sizeof(glm::vec3))); glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer glBindVertexArray(0); //unbind array glPointSize(5); // size of seedpoints + //glEnable(GL_LINE_SMOOTH); + //glEnable(GL_POLYGON_SMOOTH); + //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + //glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); - // ------ SETUP SHADERS ----------------- - auto privateCallback = [this](const ghoul::filesystem::File& file) { - _update = true; - }; - if(_programUpdateOnSave) { - _vertexSourceFile->setCallback(privateCallback); - _fragmentSourceFile->setCallback(privateCallback); - } - - _fieldlinesProgram->compileShaderObjects(); - _fieldlinesProgram->linkProgramObject(); + OsEng.ref().configurationManager().getValue("FieldlineProgram", _shader); + assert(_shader); return true; } @@ -211,46 +168,24 @@ bool RenderableFieldlines::deinitialize() { } void RenderableFieldlines::render(const RenderData& data) { - if(_update) { - _update = false; - safeShaderCompilation(); - } + if (!_shader) + return; - glm::mat4 transform = data.camera.viewProjectionMatrix(); - glm::mat4 camTransform = data.camera.viewRotationMatrix(); - //psc relative = data.position - data.camera.position(); + _shader->activate(); + _shader->setUniform("modelViewProjection", data.camera.viewProjectionMatrix()); + _shader->setUniform("modelTransform", glm::mat4(1.0)); + setPscUniforms(_shader, &data.camera, data.position); - transform = transform*camTransform; - transform = glm::mat4(1.0); - transform = glm::scale(transform, glm::vec3(0.01)); - - // Activate shader - _fieldlinesProgram->activate(); - - _fieldlinesProgram->setUniform("modelViewProjection", data.camera.viewProjectionMatrix()); - _fieldlinesProgram->setUniform("modelTransform", transform); - setPscUniforms(_fieldlinesProgram, &data.camera, data.position); - - // ------ FIELDLINES ----------------- - glBindVertexArray(_VAO); + // ------ DRAW FIELDLINES ----------------- + glBindVertexArray(_fieldlineVAO); glMultiDrawArrays(GL_LINE_STRIP, &_lineStart[0], &_lineCount[0], _lineStart.size()); -// // ------ SEEDPOINTS ----------------- +// // ------ DRAW SEEDPOINTS ----------------- // glBindVertexArray(_seedpointVAO); // glMultiDrawArrays(GL_POINTS, &_lineStart[0], &_lineCount[0], _seedPoints.size()); + glBindVertexArray(0); - - // Deactivate shader - _fieldlinesProgram->deactivate(); -} - -void RenderableFieldlines::update(const UpdateData& data) { -} - -void RenderableFieldlines::safeShaderCompilation() { - _fieldlinesProgram->rebuildFromFile(); - _fieldlinesProgram->compileShaderObjects(); - _fieldlinesProgram->linkProgramObject(); + _shader->deactivate(); } std::vector > RenderableFieldlines::getFieldlinesData(std::string filename, ghoul::Dictionary hintsDictionary) { diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 9f5f6f2e40..ec4918471d 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -231,6 +231,16 @@ bool SceneGraph::initialize() _programs.push_back(tmpProgram); OsEng.ref().configurationManager().setValue("PlaneProgram", tmpProgram); + // Fieldline program + tmpProgram = ProgramObject::Build("Fieldline", + "${SHADERS}/fieldline_vs.glsl", + "${SHADERS}/fieldline_fs.glsl", + "${SHADERS}/fieldline_gs.glsl", + cb); + if (!tmpProgram) return false; + _programs.push_back(tmpProgram); + OsEng.ref().configurationManager().setValue("FieldlineProgram", tmpProgram); + // Done building shaders double elapsed = std::chrono::duration_cast(clock_::now()-beginning).count(); LINFO("Time to load shaders: " << elapsed); diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 753d13da53..8fba5b4147 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -395,6 +395,8 @@ KameleonWrapper::Fieldlines KameleonWrapper::getClassifiedFieldLines( glm::vec4 color; FieldlineEnd forwardEnd, backEnd; + float ReToMeter = 6371000; + if (_type == Model::BATSRUS) { for (glm::vec3 seedPoint : seedPoints) { fLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::FORWARD, forwardEnd); @@ -408,7 +410,7 @@ KameleonWrapper::Fieldlines KameleonWrapper::getClassifiedFieldLines( // write colors std::vector line; for (glm::vec3 position : bLine) { - line.push_back(LinePoint(position, color)); + line.push_back(LinePoint(ReToMeter*position, color)); } fieldLines.push_back(line); From 337ce2dd92061f4b8f89b81d3d9a11bd4b5c9567 Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Mon, 24 Nov 2014 17:18:55 +0100 Subject: [PATCH 03/19] Added support for rendering fieldlines as textured view-aligned billboards --- .../rendering/renderablefieldlines.h | 10 + shaders/fieldline_fs.glsl | 10 +- shaders/fieldline_gs.glsl | 173 +++++++++++------- shaders/fieldline_vs.glsl | 11 -- src/rendering/renderablefieldlines.cpp | 52 ++++-- src/util/kameleonwrapper.cpp | 4 +- 6 files changed, 170 insertions(+), 90 deletions(-) diff --git a/include/openspace/rendering/renderablefieldlines.h b/include/openspace/rendering/renderablefieldlines.h index b74523ce2a..2d986fd146 100644 --- a/include/openspace/rendering/renderablefieldlines.h +++ b/include/openspace/rendering/renderablefieldlines.h @@ -33,6 +33,12 @@ #include #include +namespace ghoul { + namespace opengl { + class Texture; + } +} + namespace openspace { struct LinePoint; @@ -58,6 +64,10 @@ private: std::vector _lineStart; std::vector _lineCount; + + //TEST + ghoul::opengl::Texture* _texture; + void loadTexture(std::string path); }; } // namespace openspace diff --git a/shaders/fieldline_fs.glsl b/shaders/fieldline_fs.glsl index d5d89d8cfa..c7f8f0d173 100644 --- a/shaders/fieldline_fs.glsl +++ b/shaders/fieldline_fs.glsl @@ -24,15 +24,23 @@ #version __CONTEXT__ +uniform vec3 cameraViewDir; +uniform sampler2D texture1; + in vec4 gs_color; in vec4 gs_position; +in vec3 gs_normal; +in vec2 gs_texcoord; #include "ABuffer/abufferStruct.hglsl" #include "ABuffer/abufferAddToBuffer.hglsl" #include "PowerScaling/powerScaling_fs.hglsl" +float EARTH_RADIUS = 6371000.0; + void main() { - vec4 fragColor = gs_color; + // vec4 fragColor = vec4(gs_texcoord.x, gs_texcoord.x , gs_texcoord.x, 1)*gs_color; + vec4 fragColor = texture(texture1, gs_texcoord)*gs_color; float depth = pscDepth(gs_position); ABufferStruct_t frag = createGeometryFragment(fragColor, gs_position, depth); diff --git a/shaders/fieldline_gs.glsl b/shaders/fieldline_gs.glsl index 6338dda9b9..968fba25dd 100644 --- a/shaders/fieldline_gs.glsl +++ b/shaders/fieldline_gs.glsl @@ -1,90 +1,133 @@ +/***************************************************************************************** + * * + * 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__ uniform mat4 modelViewProjection; uniform mat4 modelTransform; - -layout(lines) in; -layout(line_strip, max_vertices = 2) out; +uniform vec3 cameraViewDir; in vec4 vs_color[]; -in vec4 vs_position[]; out vec4 gs_color; out vec4 gs_position; +out vec3 gs_normal; +out vec2 gs_texcoord; #include "PowerScaling/powerScaling_vs.hglsl" -void main() { - gs_color = vs_color[0]; - for(int i = 0; i < 2; i++) { - // gs_position = gl_in[i].gl_Position; - // gl_Position = gl_in[i].gl_Position; +layout(lines_adjacency) in; +layout(triangle_strip, max_vertices = 4) out; - // calculate psc position - vec4 tmp = gl_in[i].gl_Position; - vec4 position = pscTransform(tmp, modelTransform); - gs_position = tmp; +vec4 prismoid[4]; +vec2 texcoords[4]; +float EARTH_RADIUS = 6371000.0; - // project the position to view space - position = modelViewProjection * position; - gl_Position = z_normalization(position); - EmitVertex(); - } - EndPrimitive(); +// Calculate the correct powerscaled position and depth for the ABuffer +void ABufferEmitVertex(vec4 pos) { + // calculate psc position + vec4 tmp = pos; + vec4 position = pscTransform(tmp, modelTransform); + gs_position = tmp; + + // project the position to view space + position = modelViewProjection*position; + gl_Position = position; + EmitVertex(); } -// uniform mat4 ModelviewProjection; -// layout(lines_adjacency) in; -// layout(location = 0) in vec3 vPosition[4]; // Four inputs since we're using GL_LINE_STRIP_ADJACENCY -// // layout(location = 2) in vec3 vNormal[4]; // Orientation vectors are necessary for consistent alignment -// layout(triangle_strip, max_vertices = 24) out; +void emitFace(int a, int b, int c, int d) { + gs_texcoord = texcoords[a]; + ABufferEmitVertex(prismoid[a]); + gs_texcoord = texcoords[b]; + ABufferEmitVertex(prismoid[b]); + gs_texcoord = texcoords[c]; + ABufferEmitVertex(prismoid[c]); + gs_texcoord = texcoords[d]; + ABufferEmitVertex(prismoid[d]); + EndPrimitive(); +} -// out vec4 in_color; +// Original code from http://prideout.net/blog/?p=61 +void main() { + gs_color = vs_color[0]; + vec3 p0, p1, p2, p3; + p0 = gl_in[0].gl_Position.xyz; p1 = gl_in[1].gl_Position.xyz; + p2 = gl_in[2].gl_Position.xyz; p3 = gl_in[3].gl_Position.xyz; + vec3 n0 = normalize(p1-p0); + vec3 n1 = normalize(p2-p1); + vec3 n2 = normalize(p3-p2); + vec3 u = normalize(n0+n1); + vec3 v = normalize(n1+n2); -// vec4 prismoid[8]; // Scratch space for the eight corners of the prismoid + // Declare scratch variables for basis vectors: + float width = 0.15*EARTH_RADIUS; + vec3 normals[2]; + normals[0] = normalize(cross(cameraViewDir,u)); + normals[1] = normalize(cross(cameraViewDir,v)); -// void emit(int a, int b, int c, int d) { -// gl_Position = prismoid[a]; EmitVertex(); -// gl_Position = prismoid[b]; EmitVertex(); -// gl_Position = prismoid[c]; EmitVertex(); -// gl_Position = prismoid[d]; EmitVertex(); -// EndPrimitive(); -// } + texcoords[0] = vec2(1,1); + texcoords[1] = vec2(1,0); + texcoords[2] = vec2(0,0); + texcoords[3] = vec2(0,1); -// void main() { -// // Compute orientation vectors for the two connecting faces: -// vec3 vNormal = vec3(0, 0, 1); + prismoid[0] = vec4(p1 + normals[0]*width, 0); + prismoid[1] = vec4(p1 - normals[0]*width, 0); + prismoid[2] = vec4(p2 - normals[1]*width, 0); + prismoid[3] = vec4(p2 + normals[1]*width, 0); -// vec3 p0, p1, p2, p3; -// p0 = vPosition[0]; p1 = vPosition[1]; -// p2 = vPosition[2]; p3 = vPosition[3]; -// vec3 n0 = normalize(p1-p0); -// vec3 n1 = normalize(p2-p1); -// vec3 n2 = normalize(p3-p2); -// vec3 u = normalize(n0+n1); -// vec3 v = normalize(n1+n2); + gs_normal = n1; + gs_texcoord = texcoords[0]; + ABufferEmitVertex(prismoid[0]); -// // Declare scratch variables for basis vectors: -// vec3 i,j,k; float r = 0.1; + gs_texcoord = texcoords[1]; + ABufferEmitVertex(prismoid[1]); -// // Compute face 1 of 2: -// // j = u; i = vNormal[1]; k = cross(i, j); i *= r; k *= r; -// j = u; i = vNormal; k = cross(i, j); i *= r; k *= r; -// prismoid[0] = ModelviewProjection * vec4(p1 + i + k, 1); -// prismoid[1] = ModelviewProjection * vec4(p1 + i - k, 1); -// prismoid[2] = ModelviewProjection * vec4(p1 - i - k, 1); -// prismoid[3] = ModelviewProjection * vec4(p1 - i + k, 1); + gs_normal = n2; + gs_texcoord = texcoords[3]; + ABufferEmitVertex(prismoid[3]); -// // Compute face 2 of 2: -// // j = v; i = vNormal[2]; k = cross(i, j); i *= r; k *= r; -// j = v; i = vNormal; k = cross(i, j); i *= r; k *= r; -// prismoid[4] = ModelviewProjection * vec4(p2 + i + k, 1); -// prismoid[5] = ModelviewProjection * vec4(p2 + i - k, 1); -// prismoid[6] = ModelviewProjection * vec4(p2 - i - k, 1); -// prismoid[7] = ModelviewProjection * vec4(p2 - i + k, 1); + gs_texcoord = texcoords[2]; + ABufferEmitVertex(prismoid[2]); + EndPrimitive(); -// // Emit the six faces of the prismoid: -// emit(0,1,3,2); emit(5,4,6,7); -// emit(4,5,0,1); emit(3,2,7,6); -// emit(0,3,4,7); emit(2,1,6,5); -// } + // vec3 i,j,k; float r = 0.05*EARTH_RADIUS; + // j = u; i = normal; k = cross(i, j); i *= r; k *= r; + + // // Compute face 1 of 2: + // prismoid[0] = vec4(p1 + i + k, 0); + // prismoid[1] = vec4(p1 + i - k, 0); + // prismoid[2] = vec4(p1 - i - k, 0); + // prismoid[3] = vec4(p1 - i + k, 0); + + // // Compute face 2 of 2: + // prismoid[4] = vec4(p2 + i + k, 0); + // prismoid[5] = vec4(p2 + i - k, 0); + // prismoid[6] = vec4(p2 - i - k, 0); + // prismoid[7] = vec4(p2 - i + k, 0); + + // // Emit the six faces of the prismoid: + // emitFace(0,1,3,2); emitFace(5,4,6,7); + // emitFace(4,5,0,1); emitFace(3,2,7,6); + // emitFace(0,3,4,7); emitFace(2,1,6,5); +} \ No newline at end of file diff --git a/shaders/fieldline_vs.glsl b/shaders/fieldline_vs.glsl index 97b3455db6..d08dc19d08 100644 --- a/shaders/fieldline_vs.glsl +++ b/shaders/fieldline_vs.glsl @@ -31,21 +31,10 @@ layout(location = 0) in vec3 in_position; layout(location = 1) in vec4 in_color; out vec4 vs_color; -// out vec4 vs_position; #include "PowerScaling/powerScaling_vs.hglsl" void main() { vs_color = in_color; - - // // calculate psc position - // vec4 tmp = vec4(in_position, 0); - // vec4 position = pscTransform(tmp, modelTransform); - // // vs_position = tmp; - - // // project the position to view space - // position = modelViewProjection * position; - // gl_Position = z_normalization(position); - gl_Position = vec4(in_position, 0); } \ No newline at end of file diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index 49256d0163..db3662e007 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -29,6 +29,10 @@ #include +#include +#include +#include + namespace { const std::string _loggerCat = "RenderableFieldlines"; @@ -43,6 +47,7 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _fieldlineVAO(0) , _shader(nullptr) + , _texture(nullptr) { std::string name; bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); @@ -149,17 +154,13 @@ bool RenderableFieldlines::initialize() { glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(LinePoint), (void*)(sizeof(glm::vec3))); glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer - glBindVertexArray(0); //unbind array - - glPointSize(5); // size of seedpoints - //glEnable(GL_LINE_SMOOTH); - //glEnable(GL_POLYGON_SMOOTH); - //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - //glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + glBindVertexArray(0); //unbind array OsEng.ref().configurationManager().getValue("FieldlineProgram", _shader); assert(_shader); + loadTexture("C:/openspace/openspace-data/test.png"); + return true; } @@ -170,20 +171,29 @@ bool RenderableFieldlines::deinitialize() { void RenderableFieldlines::render(const RenderData& data) { if (!_shader) return; - + _shader->activate(); _shader->setUniform("modelViewProjection", data.camera.viewProjectionMatrix()); _shader->setUniform("modelTransform", glm::mat4(1.0)); + _shader->setUniform("cameraViewDir", data.camera.viewDirection()); setPscUniforms(_shader, &data.camera, data.position); + ghoul::opengl::TextureUnit unit; + unit.activate(); + _texture->bind(); + _shader->setUniform("texture1", unit); + // ------ DRAW FIELDLINES ----------------- + glEnable(GL_POLYGON_SMOOTH); + glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glBindVertexArray(_fieldlineVAO); - glMultiDrawArrays(GL_LINE_STRIP, &_lineStart[0], &_lineCount[0], _lineStart.size()); + glMultiDrawArrays(GL_LINE_STRIP_ADJACENCY, &_lineStart[0], &_lineCount[0], _lineStart.size()); -// // ------ DRAW SEEDPOINTS ----------------- -// glBindVertexArray(_seedpointVAO); -// glMultiDrawArrays(GL_POINTS, &_lineStart[0], &_lineCount[0], _seedPoints.size()); + //// ------ DRAW SEEDPOINTS ----------------- + //glBindVertexArray(_seedpointVAO); + //glMultiDrawArrays(GL_LINE_STRIP_ADJACENCY, &_lineStart[0], &_lineCount[0], _seedPoints.size()); + glDisable(GL_POLYGON_SMOOTH); glBindVertexArray(0); _shader->deactivate(); } @@ -268,4 +278,22 @@ std::vector > RenderableFieldlines::getFieldlinesData(std return fieldlinesData; } +// TEST +void RenderableFieldlines::loadTexture(std::string path) { + if (path != "") { + ghoul::opengl::Texture* texture = ghoul::opengl::loadTexture(path); + if (texture) { + LDEBUG("Loaded texture from '" << path << "'"); + texture->uploadTexture(); + + // Textures of planets looks much smoother with AnisotropicMipMap rather than linear + texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + + if (_texture) + delete _texture; + _texture = texture; + } + } +} + } // namespace openspace diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 8fba5b4147..f8abc9c3b7 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -402,6 +402,7 @@ KameleonWrapper::Fieldlines KameleonWrapper::getClassifiedFieldLines( fLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::FORWARD, forwardEnd); bLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::BACK, backEnd); + bLine.erase(bLine.begin()); bLine.insert(bLine.begin(), fLine.rbegin(), fLine.rend()); // classify @@ -442,7 +443,8 @@ KameleonWrapper::Fieldlines KameleonWrapper::getFieldLines( fLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::FORWARD, forwardEnd); bLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::BACK, backEnd); - bLine.insert(bLine.begin(), fLine.rbegin(), fLine.rend()); + bLine.erase(bLine.begin()); + bLine.insert(bLine.begin(), fLine.rbegin(), fLine.rend()); // write colors std::vector line; From fdca1c0b3b1e734e6b52cfb490fbcf4703ca5f4b Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 25 Nov 2014 19:15:33 +0100 Subject: [PATCH 04/19] Deinitialize scenegraph nodes when scenegraph is deinitialized --- src/scenegraph/scenegraph.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 9f5f6f2e40..a44801be12 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -303,7 +303,10 @@ void SceneGraph::scheduleLoadSceneFile(const std::string& sceneDescriptionFilePa } void SceneGraph::clearSceneGraph() { - // deallocate the scene graph. Recursive deallocation will occur + for (auto node : _nodes) + node->deinitialize(); + + // deallocate the scene graph. Recursive deallocation will occur delete _root; _root = nullptr; From b4f6070642a04081ee3c8d72cb8280d10da1c80d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 25 Nov 2014 19:15:59 +0100 Subject: [PATCH 05/19] Started cleanup of RenderableStars class --- ext/ghoul | 2 +- .../rendering/stars/renderablestars.h | 37 +- include/openspace/util/constants.h | 9 +- openspace-data | 2 +- src/rendering/stars/renderablestars.cpp | 445 ++++++++++-------- 5 files changed, 288 insertions(+), 207 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index d06a196c28..1a05da7f5c 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit d06a196c2895ab8f548c3e520690eb921f3437d4 +Subproject commit 1a05da7f5c345bf69894bacadf1783df9b081be8 diff --git a/include/openspace/rendering/stars/renderablestars.h b/include/openspace/rendering/stars/renderablestars.h index fa52926f29..445b9b219c 100644 --- a/include/openspace/rendering/stars/renderablestars.h +++ b/include/openspace/rendering/stars/renderablestars.h @@ -33,10 +33,9 @@ #include #include +namespace openspace { -namespace openspace{ - -class RenderableStars : public Renderable{ +class RenderableStars : public Renderable { public: RenderableStars(const ghoul::Dictionary& dictionary); ~RenderableStars(); @@ -47,12 +46,34 @@ public: void render(const RenderData& data) override; void update(const UpdateData& data) override; -protected: +private: + class DataSource { + public: + const std::vector& data() const; + + virtual bool loadData() = 0; + + protected: + std::vector _data; + }; + + class SpeckDataSource : public DataSource { + public: + SpeckDataSource(const ghoul::Dictionary& dictionary); + + bool loadData() override; + + private: + bool readSpeckFile(); + bool loadCachedFile(const std::string& file); + bool saveCachedFile(const std::string& file) const; + + std::string _file; + }; + + void loadTexture(); -private: - std::ifstream& skipToLine(std::ifstream& file, unsigned int num); - bool readSpeckFile(const std::string& path); void generateBufferObjects(const void* data); properties::StringProperty _colorTexturePath; @@ -64,6 +85,8 @@ private: std::string _speckPath; + DataSource* _source; + //GLint vertsToDraw; GLuint _vboID; diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index 18bcb36255..57d0a55d9d 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -88,8 +88,13 @@ namespace modelgeometry { } // namespace modelgeometry namespace renderablestars { - const std::string keySpeckFile = "SpeckFile"; - const std::string keyPathModule = "ModulePath"; + const std::string keyDataSource = "DataSource"; + const std::string keyTexture = "Texture"; + + namespace datasource { + const std::string keyType = "Type"; + const std::string keyFile = "File"; + } // namespace datasource } // namespace renderablestars namespace renderablevolumegl { diff --git a/openspace-data b/openspace-data index bdf9fefa78..3dc211027b 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit bdf9fefa784d3c764c1e217dd438a400f51a72f3 +Subproject commit 3dc211027b3668e0cfd37bf1f6c7c0dec09a62e8 diff --git a/src/rendering/stars/renderablestars.cpp b/src/rendering/stars/renderablestars.cpp index 8ad791b18e..8473a40117 100644 --- a/src/rendering/stars/renderablestars.cpp +++ b/src/rendering/stars/renderablestars.cpp @@ -22,66 +22,66 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -//standard includes -#include -#include -#include -#include -#include -#include - -// openspace includes #include -#include -#include +#include +#include + +#include +#include #include #include -#include -#include -#include -#define _USE_MATH_DEFINES -#include - -#define GLSPRITES -//#define GLPOINTS +#include namespace { const std::string _loggerCat = "RenderableStars"; } namespace openspace { + RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _colorTexturePath("colorTexture", "Color Texture") , _haloProgram(nullptr) , _pointProgram(nullptr) , _texture(nullptr) + , _source(nullptr) { - std::string path; - dictionary.getValue(constants::renderablestars::keyPathModule, path); - std::string texturePath = ""; - if (dictionary.hasKey("Textures.Color")) { - dictionary.getValue("Textures.Color", texturePath); - _colorTexturePath = path + "/" + texturePath; + if (dictionary.hasKey(constants::renderablestars::keyTexture)) { + dictionary.getValue(constants::renderablestars::keyTexture, texturePath); + _colorTexturePath = absPath(texturePath); } - dictionary.getValue(constants::renderablestars::keySpeckFile, path); - _speckPath = FileSys.absolutePath(path); + ghoul::TemplateFactory sourceFactory; + sourceFactory.registerClass("Speck"); + + ghoul::Dictionary sourceDictionary; + bool success = dictionary.getValue(constants::renderablestars::keyDataSource, + sourceDictionary); + if (!success) { + LERROR("RenderableStars did not have key '" << + constants::renderablestars::keyDataSource << "'"); + return; + } + std::string type = ""; + success = sourceDictionary.getValue(constants::renderablestars::datasource::keyType, type); + if (!success) { + LERROR("DataSource did not have key '" << constants::renderablestars::datasource::keyType << "'"); + return; + } + + _source = sourceFactory.create(type, sourceDictionary); addProperty(_colorTexturePath); _colorTexturePath.onChange(std::bind(&RenderableStars::loadTexture, this)); } -RenderableStars::~RenderableStars(){ - glDeleteBuffers(1, &_vboID); - glDeleteVertexArrays(1, &_vaoID); - deinitialize(); +RenderableStars::~RenderableStars() { } -std::ifstream& RenderableStars::skipToLine(std::ifstream& file, unsigned int num){ +std::ifstream& skipToLine(std::ifstream& file, unsigned int num){ file.seekg(std::ios::beg); for (size_t i = 0; i < num - 1; ++i){ file.ignore(std::numeric_limits::max(), '\n'); @@ -89,139 +89,6 @@ std::ifstream& RenderableStars::skipToLine(std::ifstream& file, unsigned int num return file; } - -//#define ROTATESTARS - -bool RenderableStars::readSpeckFile(const std::string& path){ - - bool readCache = false; - - std::ifstream file; - std::string str, starDescription, datastr; - std::vector strvec; - std::vector starcluster; - std::vector floatingPointData; - - int count = 0; - const std::string absPath = FileSys.absolutePath(path); - std::string::size_type last - = absPath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator); - if (last == std::string::npos) return false; - std::string cacheName = absPath.substr(last + 1, absPath.size() - absPath.rfind('.') - 1); - std::string basePath = absPath.substr(0, last); - cacheName = basePath + "\\" + cacheName + ".bin"; - - //if (!FileSys.fileExists(cacheName)){ - if (!readCache){ // dumb boolean for now. - std::ofstream cache; - cache.open(cacheName, std::ios::binary); - - file.open(absPath); - if (!file.is_open()){ - LERROR("Failed to open spec file for : '" << path << "'"); - return false; - } - // count metadata lines to skip. - do{ - getline(file, str); - count++; - } while (str[0] != ' '); - // set seek pointer to first line with actual data - skipToLine(file, count); - count = 0; - - do{ - getline(file, str); - if (file.eof()) break; - // split the line on pound symbol. we only want data. - std::size_t mid = str.find('#'); - if (mid != std::string::npos){ - datastr = str.substr(0, mid); - std::size_t end = str.find('\n'); - if (end == std::string::npos) - starDescription = str.substr(mid, end); - } - // split data string on whitespace -> push to to vector - std::istringstream ss(datastr); - std::copy(std::istream_iterator(ss), - std::istream_iterator(), - std::back_inserter >(strvec)); - ss.clear(); - // conv. string vector to doubles - floatingPointData.reserve(strvec.size()); - transform(strvec.begin(), strvec.end(), back_inserter(floatingPointData), - [](std::string const& val) {return std::stod(val); }); - // store data concerning apparent luminocity, brigthness etc. - // convert to powerscaled coordinate - psc powerscaled = PowerScaledCoordinate::CreatePowerScaledCoordinate(floatingPointData[0], - floatingPointData[1], - floatingPointData[2]); - // Convert parsecs -> meter - // Could convert floatingPointData instead ?? - // (possible as 3.4 × 10^38 is max rep nr of float) - PowerScaledScalar parsecsToMetersFactor = glm::vec2(0.308567758, 17); - powerscaled[0] *= parsecsToMetersFactor[0]; - powerscaled[1] *= parsecsToMetersFactor[0]; - powerscaled[2] *= parsecsToMetersFactor[0]; - powerscaled[3] += parsecsToMetersFactor[1]; - -#ifdef ROTATESTARS - glm::mat4 transform = glm::mat4(1); - - glm::dmat3 stateMatrix; - double initTime = 0; - openspace::SpiceManager::ref().getPositionTransformMatrixGLM("GALACTIC", "IAU_EARTH", 0, stateMatrix); - - for (int i = 0; i < 3; i++){ - for (int j = 0; j < 3; j++){ - transform[i][j] = stateMatrix[i][j]; - } - } - - glm::vec4 tmp(powerscaled[0], powerscaled[1], powerscaled[2], powerscaled[3] ); - tmp = transform*tmp; - - powerscaled[0] = tmp[0]; - powerscaled[1] = tmp[1]; - powerscaled[2] = tmp[2]; - powerscaled[3] = tmp[3]; -#endif - // We use std::vector to store data - // needs no preallocation and has tightly packed arr. - for (int i = 0; i < 4; i++){ - starcluster.push_back(powerscaled[i]); - cache << ' ' << powerscaled[i]; - } - // will need more elegant solution here. - starcluster.push_back(floatingPointData[3]); - starcluster.push_back(floatingPointData[4]); - starcluster.push_back(floatingPointData[5]); - - strvec.clear(); - floatingPointData.clear(); - count++; - } while (file.good()); - }else{ - LINFO("Found cached data, loading"); - file.open(cacheName, std::ios::binary); - while (file.good()){ - if (file.eof()) break; - count++; - float cachedValue; - file >> cachedValue; - starcluster.push_back(cachedValue); - } - } - v_stride = 7; // stride in VBO, set manually for now. - v_size = static_cast(starcluster.size()); // size of VBO - v_total = v_size / v_stride; // total number of vertecies - - // create vao and interleaved vbo from vectors internal array - generateBufferObjects(&starcluster[0]); - - return true; -} - void RenderableStars::generateBufferObjects(const void* data){ // generate and buffer data glGenVertexArrays(1, &_vaoID); @@ -262,9 +129,21 @@ bool RenderableStars::initialize(){ if (_pointProgram == nullptr) completeSuccess &= OsEng.ref().configurationManager().getValue("PointProgram", _pointProgram); - // Run read star-datafile routine. - if (!readSpeckFile(_speckPath)) - LERROR("Failed to read speck file for path : '" << _speckPath << "'"); + completeSuccess &= _source->loadData(); + + const std::vector& data = _source->data(); + + v_stride = 7; // stride in VBO, set manually for now. + v_size = static_cast(data.size()); // size of VBO + v_total = v_size / v_stride; // total number of vertecies + + // create vao and interleaved vbo from vectors internal array + generateBufferObjects(&data[0]); + + + //// Run read star-datafile routine. + //if (!readSpeckFile(_speckPath)) + // LERROR("Failed to read speck file for path : '" << _speckPath << "'"); loadTexture(); completeSuccess &= (_texture != nullptr); @@ -273,6 +152,9 @@ bool RenderableStars::initialize(){ } bool RenderableStars::deinitialize(){ + glDeleteBuffers(1, &_vboID); + glDeleteVertexArrays(1, &_vaoID); + delete _texture; _texture = nullptr; return true; @@ -303,7 +185,6 @@ void RenderableStars::render(const RenderData& data){ glEnable(GL_BLEND); glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE); -#ifdef GLSPRITES glm::mat4 modelMatrix = data.camera.modelMatrix(); glm::mat4 viewMatrix = data.camera.viewMatrix(); glm::mat4 projectionMatrix = data.camera.projectionMatrix(); @@ -328,34 +209,33 @@ void RenderableStars::render(const RenderData& data){ glBindVertexArray(_vaoID); glDrawArrays(GL_POINTS, 0, v_total); glBindVertexArray(0); -#endif _haloProgram->deactivate(); -#ifdef GLPOINTS - -// ---------------------- RENDER POINTS ----------------------------- - _pointProgram->activate(); - - _pointProgram->setUniform("ViewProjection", data.camera.viewProjectionMatrix); - _pointProgram->setUniform("ModelTransform", transform); - _pointProgram->setUniform("campos", campos.vec4()); - _pointProgram->setUniform("objpos", currentPosition.vec4()); - _pointProgram->setUniform("camrot", camrot); - //_pointProgram->setUniform("scaling", scaling.vec2()); - - glEnable(GL_PROGRAM_POINT_SIZE_EXT); // Allows shader to determine pointsize. - - //glEnable(GL_POINT_SMOOTH); // decrepated in core profile, workaround in frag. - glBindVertexArray(_vaoID); - glDrawArrays(GL_POINTS, 0, v_total*7); - glBindVertexArray(0); - - glDisable(GL_BLEND); - - _pointProgram->deactivate(); - glEnable(GL_DEPTH_TEST); - -#endif +//#ifdef GLPOINTS +// +//// ---------------------- RENDER POINTS ----------------------------- +// _pointProgram->activate(); +// +// _pointProgram->setUniform("ViewProjection", data.camera.viewProjectionMatrix); +// _pointProgram->setUniform("ModelTransform", transform); +// _pointProgram->setUniform("campos", campos.vec4()); +// _pointProgram->setUniform("objpos", currentPosition.vec4()); +// _pointProgram->setUniform("camrot", camrot); +// //_pointProgram->setUniform("scaling", scaling.vec2()); +// +// glEnable(GL_PROGRAM_POINT_SIZE_EXT); // Allows shader to determine pointsize. +// +// //glEnable(GL_POINT_SMOOTH); // decrepated in core profile, workaround in frag. +// glBindVertexArray(_vaoID); +// glDrawArrays(GL_POINTS, 0, v_total*7); +// glBindVertexArray(0); +// +// glDisable(GL_BLEND); +// +// _pointProgram->deactivate(); +// glEnable(GL_DEPTH_TEST); +// +//#endif glDisable(GL_BLEND); } @@ -376,5 +256,178 @@ void RenderableStars::update(const UpdateData& data) } - + +const std::vector& RenderableStars::DataSource::data() const { + return _data; +} + +RenderableStars::SpeckDataSource::SpeckDataSource(const ghoul::Dictionary& dictionary) + : DataSource() + , _file("") +{ + bool success = dictionary.getValue(constants::renderablestars::datasource::keyFile, _file); + if (!success) { + LERROR("SpeckDataSource did not contain key '" << + constants::renderablestars::datasource::keyFile << "'"); + return; + } + _file = absPath(_file); +} + +bool RenderableStars::SpeckDataSource::loadData() { + std::string cachedFile = ""; + FileSys.cacheManager()->getCachedFile(_file, cachedFile, true); + + bool hasCachedFile = FileSys.fileExists(cachedFile); + if (hasCachedFile) { + LINFO("Cached file '" << cachedFile << "' used for Speck file '" << _file << "'"); + + 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 { + LINFO("Cache for Speck file '" << _file << "' not found"); + } + LINFO("Loading Speck file '" << _file << "'"); + + bool success = readSpeckFile(); + if (!success) + return false; + + LINFO("Saving cache"); + success = saveCachedFile(cachedFile); + + return success; +} + +bool RenderableStars::SpeckDataSource::readSpeckFile() { + std::ifstream file(_file); + if (!file.good()) { + LERROR("Failed to open Speck file '" << _file << "'"); + return false; + } + + int nValues = 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::ifstream::streampos position = file.tellg(); + std::getline(file, line); + + if (line[0] == '#') + 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; + } + + 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 >> nValues; + nValues += 1; // We want the number, but the index is 0 based + } + } + + nValues += 3; // X Y Z are not counted in the Speck file indices + + do { + std::vector values(nValues); + + std::getline(file, line); + std::stringstream str(line); + + for (int i = 0; i < nValues; ++i) + str >> values[i]; + + // Extract the position (in parsecs) + psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate( + values[0], + values[1], + values[2] + ); + + // Convert parsecs -> meter + PowerScaledScalar parsecsToMetersFactor = PowerScaledScalar(0.308567758f, 17.f); + position[0] *= parsecsToMetersFactor[0]; + position[1] *= parsecsToMetersFactor[0]; + position[2] *= parsecsToMetersFactor[0]; + position[3] += parsecsToMetersFactor[1]; + + // Push the position into the data array + _data.push_back(position[0]); + _data.push_back(position[1]); + _data.push_back(position[2]); + _data.push_back(position[3]); + + // Push the other values into the array + _data.push_back(values[3]); // colorb_v + _data.push_back(values[4]); // luminance + _data.push_back(values[5]); // absolute magnitude + } while (!file.eof()); + + return true; +} + +bool RenderableStars::SpeckDataSource::loadCachedFile(const std::string& file) { + std::ifstream fileStream(file, std::ifstream::binary); + if (fileStream.good()) { + int32_t nValues = 0; + fileStream.read(reinterpret_cast(&nValues), sizeof(int32_t)); + + _data.resize(nValues); + fileStream.read(reinterpret_cast(&_data[0]), nValues * sizeof(_data[0])); + + bool success = fileStream.good(); + return success; + } + else { + LERROR("Error opening file '" << file << "' for loading cache file"); + return false; + } +} + +bool RenderableStars::SpeckDataSource::saveCachedFile(const std::string& file) const { + std::ofstream fileStream(file, std::ofstream::binary); + if (fileStream.good()) { + int32_t nValues = static_cast(_data.size()); + if (nValues == 0) { + LERROR("Error writing cache: No values were loaded"); + return false; + } + fileStream.write(reinterpret_cast(&nValues), sizeof(int32_t)); + + size_t nBytes = nValues * sizeof(_data[0]); + fileStream.write(reinterpret_cast(&_data[0]), nBytes); + + bool success = fileStream.good(); + return success; + } + else { + LERROR("Error opening file '" << file << "' for save cache file"); + return false; + } +} + } \ No newline at end of file From fc1dcfabc830f12cdafb06ce02f514583b788bb5 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 26 Nov 2014 16:36:02 +0100 Subject: [PATCH 06/19] Some more changes to the RenderableStars class --- ext/ghoul | 2 +- .../rendering/stars/renderablestars.h | 43 +++++++----- include/openspace/util/constants.h | 7 +- openspace-data | 2 +- src/rendering/stars/renderablestars.cpp | 66 ++++++++----------- 5 files changed, 55 insertions(+), 65 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 1a05da7f5c..48bd2ef9a3 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 1a05da7f5c345bf69894bacadf1783df9b081be8 +Subproject commit 48bd2ef9a32498be7dd5c7261561f6257342d6ec diff --git a/include/openspace/rendering/stars/renderablestars.h b/include/openspace/rendering/stars/renderablestars.h index 445b9b219c..b4c7ff5093 100644 --- a/include/openspace/rendering/stars/renderablestars.h +++ b/include/openspace/rendering/stars/renderablestars.h @@ -47,33 +47,40 @@ public: void update(const UpdateData& data) override; private: - class DataSource { - public: - const std::vector& data() const; + //class DataSource { + //public: + // const std::vector& data() const; - virtual bool loadData() = 0; + // virtual bool loadData() = 0; - protected: - std::vector _data; - }; + //protected: + // std::vector _data; + //}; - class SpeckDataSource : public DataSource { - public: - SpeckDataSource(const ghoul::Dictionary& dictionary); + //class SpeckDataSource : public DataSource { + //public: + // SpeckDataSource(const ghoul::Dictionary& dictionary); - bool loadData() override; + // bool loadData() override; - private: - bool readSpeckFile(); - bool loadCachedFile(const std::string& file); - bool saveCachedFile(const std::string& file) const; + //private: + // bool readSpeckFile(); + // bool loadCachedFile(const std::string& file); + // bool saveCachedFile(const std::string& file) const; - std::string _file; - }; + // std::string _file; + //}; void loadTexture(); + const std::vector& data() const; + + bool loadData(); + bool readSpeckFile(); + bool loadCachedFile(const std::string& file); + bool saveCachedFile(const std::string& file) const; + void generateBufferObjects(const void* data); properties::StringProperty _colorTexturePath; @@ -85,7 +92,7 @@ private: std::string _speckPath; - DataSource* _source; + std::vector _data; //GLint vertsToDraw; diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index 57d0a55d9d..92c1ce7ee3 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -88,13 +88,8 @@ namespace modelgeometry { } // namespace modelgeometry namespace renderablestars { - const std::string keyDataSource = "DataSource"; + const std::string keyFile = "File"; const std::string keyTexture = "Texture"; - - namespace datasource { - const std::string keyType = "Type"; - const std::string keyFile = "File"; - } // namespace datasource } // namespace renderablestars namespace renderablevolumegl { diff --git a/openspace-data b/openspace-data index 3dc211027b..65ac894014 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 3dc211027b3668e0cfd37bf1f6c7c0dec09a62e8 +Subproject commit 65ac8940144d28dc7d2669cad40ce0abe0ab62fb diff --git a/src/rendering/stars/renderablestars.cpp b/src/rendering/stars/renderablestars.cpp index 8473a40117..7a9b0d318a 100644 --- a/src/rendering/stars/renderablestars.cpp +++ b/src/rendering/stars/renderablestars.cpp @@ -46,7 +46,6 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) , _haloProgram(nullptr) , _pointProgram(nullptr) , _texture(nullptr) - , _source(nullptr) { std::string texturePath = ""; if (dictionary.hasKey(constants::renderablestars::keyTexture)) { @@ -54,25 +53,13 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary) _colorTexturePath = absPath(texturePath); } - ghoul::TemplateFactory sourceFactory; - sourceFactory.registerClass("Speck"); - - ghoul::Dictionary sourceDictionary; - bool success = dictionary.getValue(constants::renderablestars::keyDataSource, - sourceDictionary); + bool success = dictionary.getValue(constants::renderablestars::keyFile, _speckPath); if (!success) { - LERROR("RenderableStars did not have key '" << - constants::renderablestars::keyDataSource << "'"); + LERROR("SpeckDataSource did not contain key '" << + constants::renderablestars::keyFile << "'"); return; } - std::string type = ""; - success = sourceDictionary.getValue(constants::renderablestars::datasource::keyType, type); - if (!success) { - LERROR("DataSource did not have key '" << constants::renderablestars::datasource::keyType << "'"); - return; - } - - _source = sourceFactory.create(type, sourceDictionary); + _speckPath = absPath(_speckPath); addProperty(_colorTexturePath); _colorTexturePath.onChange(std::bind(&RenderableStars::loadTexture, this)); @@ -118,7 +105,7 @@ void RenderableStars::generateBufferObjects(const void* data){ glBindVertexArray(0); } -bool RenderableStars::initialize(){ +bool RenderableStars::initialize() { bool completeSuccess = true; // 1. StarProgram - Generates quads with png image of halo @@ -129,9 +116,8 @@ bool RenderableStars::initialize(){ if (_pointProgram == nullptr) completeSuccess &= OsEng.ref().configurationManager().getValue("PointProgram", _pointProgram); - completeSuccess &= _source->loadData(); - - const std::vector& data = _source->data(); + completeSuccess &= loadData(); + const std::vector& data = this->data(); v_stride = 7; // stride in VBO, set manually for now. v_size = static_cast(data.size()); // size of VBO @@ -256,25 +242,26 @@ void RenderableStars::update(const UpdateData& data) } - -const std::vector& RenderableStars::DataSource::data() const { +const std::vector& RenderableStars::data() const { return _data; } -RenderableStars::SpeckDataSource::SpeckDataSource(const ghoul::Dictionary& dictionary) - : DataSource() - , _file("") -{ - bool success = dictionary.getValue(constants::renderablestars::datasource::keyFile, _file); - if (!success) { - LERROR("SpeckDataSource did not contain key '" << - constants::renderablestars::datasource::keyFile << "'"); - return; - } - _file = absPath(_file); -} -bool RenderableStars::SpeckDataSource::loadData() { +//RenderableStars::SpeckDataSource(const ghoul::Dictionary& dictionary) +// : DataSource() +// , _file("") +//{ +// bool success = dictionary.getValue(constants::renderablestars::datasource::keyFile, _file); +// if (!success) { +// LERROR("SpeckDataSource did not contain key '" << +// constants::renderablestars::datasource::keyFile << "'"); +// return; +// } +// _file = absPath(_file); +//} + +bool RenderableStars::loadData() { + std::string _file = _speckPath; std::string cachedFile = ""; FileSys.cacheManager()->getCachedFile(_file, cachedFile, true); @@ -305,7 +292,8 @@ bool RenderableStars::SpeckDataSource::loadData() { return success; } -bool RenderableStars::SpeckDataSource::readSpeckFile() { +bool RenderableStars::readSpeckFile() { + std::string _file = _speckPath; std::ifstream file(_file); if (!file.good()) { LERROR("Failed to open Speck file '" << _file << "'"); @@ -390,7 +378,7 @@ bool RenderableStars::SpeckDataSource::readSpeckFile() { return true; } -bool RenderableStars::SpeckDataSource::loadCachedFile(const std::string& file) { +bool RenderableStars::loadCachedFile(const std::string& file) { std::ifstream fileStream(file, std::ifstream::binary); if (fileStream.good()) { int32_t nValues = 0; @@ -408,7 +396,7 @@ bool RenderableStars::SpeckDataSource::loadCachedFile(const std::string& file) { } } -bool RenderableStars::SpeckDataSource::saveCachedFile(const std::string& file) const { +bool RenderableStars::saveCachedFile(const std::string& file) const { std::ofstream fileStream(file, std::ofstream::binary); if (fileStream.good()) { int32_t nValues = static_cast(_data.size()); From b9868987a283c17570a250a8dd1118d67e1c0d9c Mon Sep 17 00:00:00 2001 From: michal Date: Wed, 26 Nov 2014 12:12:03 -0500 Subject: [PATCH 07/19] intermediate commit --- ext/spice | 2 +- include/openspace/tests/test_spicemanager.inl | 8 ++++---- src/util/spicemanager.cpp | 13 ++++++++----- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ext/spice b/ext/spice index 38f7fe9fe4..e679c330e7 160000 --- a/ext/spice +++ b/ext/spice @@ -1 +1 @@ -Subproject commit 38f7fe9fe4aad217be7ab68a8d39de2140a3e22c +Subproject commit e679c330e719c7bff6f636d078410c455a33c201 diff --git a/include/openspace/tests/test_spicemanager.inl b/include/openspace/tests/test_spicemanager.inl index bfefd4bd58..98750107d1 100644 --- a/include/openspace/tests/test_spicemanager.inl +++ b/include/openspace/tests/test_spicemanager.inl @@ -47,7 +47,7 @@ protected: #define SRCLEN 128 const int nrMetaKernels = 9; -int which, handle, count = 0; +SpiceInt which, handle, count = 0; char file[FILLEN], filtyp[TYPLEN], source[SRCLEN]; double abs_error = 0.00001; @@ -353,8 +353,8 @@ TEST_F(SpiceManagerTest, getPositionTransformMatrix){ TEST_F(SpiceManagerTest, getFieldOfView){ loadMetaKernel(); - int n; - int cassini_ID; + SpiceInt n; + SpiceInt cassini_ID; double et; glm::dvec3 boresight; double bounds_ref[5][3]; @@ -395,7 +395,7 @@ TEST_F(SpiceManagerTest, planetocentricToRectangular){ double lat = -35.0; //initial values double lon = 100.0; double rectangular_ref[3]; - int naifId; + SpiceInt naifId; SpiceBoolean foundSpice; bodn2c_c("EARTH", &naifId, &foundSpice); diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index d83ce3100c..ed1a9682e0 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -165,13 +165,15 @@ bool SpiceManager::hasValue(const std::string& body, const std::string& item) co } bool SpiceManager::getNaifId(const std::string& body, int& id) const { + + SpiceInt s_id = id; if (body.empty()) { LERROR("No body was provided"); return false; } else { SpiceBoolean success; - bods2c_c(body.c_str(), &id, &success); + bods2c_c(body.c_str(), &s_id, &success); if (success == SPICEFALSE) LERROR("Could not find NAIF ID of body '" + body + "'"); return (success == SPICETRUE); @@ -190,8 +192,9 @@ bool getValueInternal(const std::string& body, const std::string& value, int S, return false; } - int n; - bodvrd_c(body.c_str(), value.c_str(), S, &n, v); + SpiceInt n; + SpiceInt _s = S; + bodvrd_c(body.c_str(), value.c_str(), _s, &n, v); bool hasError = SpiceManager::checkForError("Error getting value '" + value + "' for body '" + body + "'"); @@ -232,7 +235,7 @@ bool SpiceManager::getValue(const std::string& body, const std::string& value, return false; } - int n; + SpiceInt n; bodvrd_c(body.c_str(), value.c_str(), static_cast(v.size()), &n, &v[0]); bool hasError = checkForError("Error getting value '" + value + "' for body '" + @@ -433,7 +436,7 @@ bool SpiceManager::getFieldOfView(int instrument, static char fovShapeBuffer[bufferSize]; static char frameNameBuffer[bufferSize]; - int nrReturned; + SpiceInt nrReturned; double boundsArr[maxBoundsSize][3]; getfov_c(instrument, // instrument id From 0fc0ba929bd6753bee95dae02878626539fb5c7a Mon Sep 17 00:00:00 2001 From: michal Date: Wed, 26 Nov 2014 13:02:20 -0500 Subject: [PATCH 08/19] updating some spicemanger stuff --- openspace-data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openspace-data b/openspace-data index 65ac894014..d23a7bdc6c 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 65ac8940144d28dc7d2669cad40ce0abe0ab62fb +Subproject commit d23a7bdc6c00afe57dd60a5707698b33d957a100 From e9d3993ad6905abbf99c85aaf7d966d9a10186e7 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 27 Nov 2014 02:26:13 +0100 Subject: [PATCH 09/19] Fix virtual-ness in TemplateProperty Add OptionProperty --- include/openspace/properties/optionproperty.h | 97 +++++++++++++++++++ .../openspace/properties/templateproperty.h | 2 +- src/properties/optionproperty.cpp | 73 ++++++++++++++ 3 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 include/openspace/properties/optionproperty.h create mode 100644 src/properties/optionproperty.cpp diff --git a/include/openspace/properties/optionproperty.h b/include/openspace/properties/optionproperty.h new file mode 100644 index 0000000000..ae7f36125e --- /dev/null +++ b/include/openspace/properties/optionproperty.h @@ -0,0 +1,97 @@ +/***************************************************************************************** +* * +* 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 __OPTIONPROPERTY_H__ +#define __OPTIONPROPERTY_H__ + +#include + +#include + +namespace openspace { +namespace properties { + +/** + * The OptionProperty is a property that provides a number of predefined (using the + * addOption method) options consisting of a description and a + * value. The available options can be queried using the options method. + * Only values representing valid options can be used to set this property, or an error + * will be logged + */ +class OptionProperty : public IntProperty { +public: + /** + * The struct storing a single option consisting of an integer value and + * a string description. + */ + struct Option { + int value; + std::string description; + }; + + /** + * The constructor delegating the identifier and the guiName + * to its super class. + * \param identifier A unique identifier for this property + * \param guiName The GUI name that should be used to represent this property + */ + OptionProperty(std::string identifier, std::string guiName); + + /** + * Returns the name of the class for reflection purposes. + * \return The name of this class for reflection purposes + */ + std::string className() const override; + using IntProperty::operator=; + + /** + * Adds the passed option to the list of available options. The value of + * the option must not have been registered previously, or a warning will + * be logged. + * \param option The option that will be added to the list of available options + */ + void addOption(Option option); + + /** + * Returns the list of available options. + * /return The list of available options + */ + const std::vector