mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-03 09:20:26 -05:00
Add initial (non working) verison of new renderable tube
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* 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 <modules/base/rendering/renderabletube.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/rendering/helper.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/opengl/openglstatecache.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <optional>
|
||||
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "RenderableTube";
|
||||
constexpr int8_t DataFileVersion = 0;
|
||||
constexpr std::array<const char*, 2> UniformNames = {
|
||||
"modelViewProjectionTransform", "vs_color"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo LineWidthInfo = {
|
||||
"LineWidth",
|
||||
"Line Width",
|
||||
"This value specifies the line width",
|
||||
// @VISIBILITY(2.0)
|
||||
openspace::properties::Property::Visibility::User
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo LineColorInfo = {
|
||||
"Color",
|
||||
"Color",
|
||||
"This value determines the RGB color for the line",
|
||||
// @VISIBILITY(1.2)
|
||||
openspace::properties::Property::Visibility::NoviceUser
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(RenderableTube)]] Parameters {
|
||||
// The input file with data for the tube
|
||||
std::string file;
|
||||
|
||||
// [[codegen::verbatim(LineWidthInfo.description)]]
|
||||
std::optional<float> lineWidth;
|
||||
|
||||
// [[codegen::verbatim(LineColorInfo.description)]]
|
||||
std::optional<glm::vec3> color [[codegen::color()]];
|
||||
};
|
||||
#include "renderabletube_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableTube::Documentation() {
|
||||
return codegen::doc<Parameters>("base_renderable_tube");
|
||||
}
|
||||
|
||||
RenderableTube::RenderableTube(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _lineWidth(LineWidthInfo, 1.f, 1.f, 20.f)
|
||||
, _lineColor(LineColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_dataFile = p.file;
|
||||
|
||||
_lineWidth = p.lineWidth.value_or(_lineWidth);
|
||||
addProperty(_lineWidth);
|
||||
|
||||
_lineColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
_lineColor = p.color.value_or(_lineColor);
|
||||
addProperty(_lineColor);
|
||||
|
||||
addProperty(Fadeable::_opacity);
|
||||
}
|
||||
|
||||
bool RenderableTube::isReady() const {
|
||||
return _shader != nullptr;
|
||||
}
|
||||
|
||||
void RenderableTube::initialize() {
|
||||
updateTubeData();
|
||||
}
|
||||
|
||||
void RenderableTube::initializeGL() {
|
||||
_shader = global::renderEngine->buildRenderProgram(
|
||||
"PrismProgram",
|
||||
absPath("${MODULE_BASE}/shaders/prism_vs.glsl"),
|
||||
absPath("${MODULE_BASE}/shaders/prism_fs.glsl")
|
||||
);
|
||||
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
|
||||
|
||||
glGenVertexArrays(1, &_vaoId);
|
||||
glGenBuffers(1, &_vboId);
|
||||
glGenBuffers(1, &_iboId);
|
||||
|
||||
glBindVertexArray(_vaoId);
|
||||
|
||||
updateBufferData();
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void RenderableTube::deinitializeGL() {
|
||||
global::renderEngine->removeRenderProgram(_shader.get());
|
||||
_shader = nullptr;
|
||||
|
||||
glDeleteVertexArrays(1, &_vaoId);
|
||||
_vaoId = 0;
|
||||
|
||||
glDeleteBuffers(1, &_vboId);
|
||||
_vboId = 0;
|
||||
|
||||
glDeleteBuffers(1, &_iboId);
|
||||
_iboId = 0;
|
||||
}
|
||||
|
||||
void RenderableTube::readDataFile() {
|
||||
std::filesystem::path file = absPath(_dataFile);
|
||||
if (!std::filesystem::is_regular_file(file)) {
|
||||
LWARNING(fmt::format("The data file '{}' could not be found", file));
|
||||
return;
|
||||
}
|
||||
|
||||
// Open file
|
||||
std::ifstream fileStream(file);
|
||||
if (!fileStream.good()) {
|
||||
LERROR(fmt::format("Failed to open data file '{}'", file));
|
||||
return;
|
||||
}
|
||||
|
||||
// Read 1 item
|
||||
|
||||
|
||||
// Loop over all items until stream is not good
|
||||
|
||||
fileStream.close();
|
||||
}
|
||||
|
||||
RenderableTube::TimePolygon RenderableTube::readDataLine(std::ifstream& file) {
|
||||
RenderableTube::TimePolygon timePolygon;
|
||||
int nPoints = 0;
|
||||
std::string date, time;
|
||||
|
||||
file >> date >> time >> nPoints;
|
||||
|
||||
if (!file) {
|
||||
return std::move(RenderableTube::TimePolygon());
|
||||
}
|
||||
|
||||
// Convert to J2000 seconds
|
||||
std::string timeString = fmt::format("{} {}", date, time);
|
||||
timePolygon.timestamp = Time::convertTime(timeString);
|
||||
|
||||
for (int i = 0; i < nPoints; ++i) {
|
||||
RenderableTube::Coordinate coord;
|
||||
file >> coord.x >> coord.y >> coord.z;
|
||||
|
||||
if (file) {
|
||||
timePolygon.points.push_back(coord);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(timePolygon);
|
||||
}
|
||||
|
||||
void RenderableTube::updateTubeData() {
|
||||
/*_vertexArray.clear();
|
||||
_indexArray.clear();
|
||||
|
||||
using namespace rendering::helper;
|
||||
|
||||
// Get unit circle vertices on the XY-plane
|
||||
std::vector<VertexXYZ> unitVertices = createRingXYZ(_nShapeSegments.value(), 1.f);
|
||||
std::vector<VertexXYZ> unitVerticesLines = createRingXYZ(_nLines.value(), 1.f);
|
||||
|
||||
// Put base vertices into array
|
||||
for (int j = 0; j < _nShapeSegments; ++j) {
|
||||
float ux = unitVertices[j].xyz[0];
|
||||
float uy = unitVertices[j].xyz[1];
|
||||
|
||||
_vertexArray.push_back(ux * _baseRadius); // x
|
||||
_vertexArray.push_back(uy * _baseRadius); // y
|
||||
_vertexArray.push_back(0.f); // z
|
||||
}
|
||||
|
||||
// Put top shape vertices into array
|
||||
for (int j = 0; j < _nShapeSegments; ++j) {
|
||||
float ux = unitVertices[j].xyz[0];
|
||||
float uy = unitVertices[j].xyz[1];
|
||||
|
||||
_vertexArray.push_back(ux * _radius); // x
|
||||
_vertexArray.push_back(uy * _radius); // y
|
||||
_vertexArray.push_back(_length); // z
|
||||
}
|
||||
|
||||
// Put the vertices for the connecting lines into array
|
||||
if (_nLines == 1) {
|
||||
// In the case of just one line then connect the center points instead
|
||||
// Center for base shape
|
||||
_vertexArray.push_back(0.f);
|
||||
_vertexArray.push_back(0.f);
|
||||
_vertexArray.push_back(0.f);
|
||||
|
||||
// Center for top shape
|
||||
_vertexArray.push_back(0.f);
|
||||
_vertexArray.push_back(0.f);
|
||||
_vertexArray.push_back(_length);
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < _nLines; ++j) {
|
||||
float ux = unitVerticesLines[j].xyz[0];
|
||||
float uy = unitVerticesLines[j].xyz[1];
|
||||
|
||||
// Base
|
||||
_vertexArray.push_back(ux * _baseRadius); // x
|
||||
_vertexArray.push_back(uy * _baseRadius); // y
|
||||
_vertexArray.push_back(0.f); // z
|
||||
|
||||
// Top
|
||||
_vertexArray.push_back(ux * _radius); // x
|
||||
_vertexArray.push_back(uy * _radius); // y
|
||||
_vertexArray.push_back(_length); // z
|
||||
}
|
||||
}
|
||||
|
||||
// Indices for Base shape
|
||||
ghoul_assert(
|
||||
_nShapeSegments.value() <= std::numeric_limits<uint8_t>::max(),
|
||||
"Too many shape segments"
|
||||
);
|
||||
for (uint8_t i = 0; i < _nShapeSegments; ++i) {
|
||||
_indexArray.push_back(i);
|
||||
}
|
||||
|
||||
// Reset
|
||||
_indexArray.push_back(255);
|
||||
|
||||
// Indices for Top shape
|
||||
for (int i = _nShapeSegments; i < 2 * _nShapeSegments; ++i) {
|
||||
_indexArray.push_back(static_cast<uint8_t>(i));
|
||||
}
|
||||
|
||||
// Indices for connecting lines
|
||||
for (int i = 0, k = 0; i < _nLines; ++i, k += 2) {
|
||||
// Reset
|
||||
_indexArray.push_back(255);
|
||||
|
||||
_indexArray.push_back(static_cast<uint8_t>(2 * _nShapeSegments + k));
|
||||
_indexArray.push_back(static_cast<uint8_t>(2 * _nShapeSegments + k + 1));
|
||||
}*/
|
||||
}
|
||||
|
||||
void RenderableTube::updateBufferData() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vboId);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
_vertexArray.size() * sizeof(float),
|
||||
_vertexArray.data(),
|
||||
GL_STREAM_DRAW
|
||||
);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iboId);
|
||||
glBufferData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
_indexArray.size() * sizeof(uint8_t),
|
||||
_indexArray.data(),
|
||||
GL_STREAM_DRAW
|
||||
);
|
||||
}
|
||||
|
||||
void RenderableTube::render(const RenderData& data, RendererTasks&) {
|
||||
_shader->activate();
|
||||
|
||||
// Model transform and view transform needs to be in double precision
|
||||
const glm::dmat4 modelViewProjectionTransform =
|
||||
calcModelViewProjectionTransform(data);
|
||||
|
||||
// Uniforms
|
||||
_shader->setUniform(
|
||||
_uniformCache.modelViewProjection,
|
||||
glm::mat4(modelViewProjectionTransform)
|
||||
);
|
||||
_shader->setUniform(_uniformCache.color, glm::vec4(_lineColor.value(), opacity()));
|
||||
|
||||
// Render
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
glPrimitiveRestartIndex(255);
|
||||
glLineWidth(_lineWidth);
|
||||
glBindVertexArray(_vaoId);
|
||||
|
||||
glDrawElements(
|
||||
GL_LINE_LOOP,
|
||||
static_cast<GLsizei>(_indexArray.size()),
|
||||
GL_UNSIGNED_BYTE,
|
||||
nullptr
|
||||
);
|
||||
|
||||
glBindVertexArray(0);
|
||||
global::renderEngine->openglStateCache().resetLineState();
|
||||
glDisable(GL_PRIMITIVE_RESTART);
|
||||
|
||||
_shader->deactivate();
|
||||
}
|
||||
|
||||
void RenderableTube::update(const UpdateData& data) {
|
||||
/*if (_shader->isDirty()) {
|
||||
_shader->rebuildFromFile();
|
||||
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
|
||||
}
|
||||
if (_prismIsDirty) {
|
||||
updateVertexData();
|
||||
updateBufferData();
|
||||
setBoundingSphere(_length * glm::compMax(data.modelTransform.scale));
|
||||
_prismIsDirty = false;
|
||||
}*/
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,96 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_BASE___RENDERABLETUBE___H__
|
||||
#define __OPENSPACE_MODULE_BASE___RENDERABLETUBE___H__
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <openspace/properties/vector/vec3property.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <ghoul/opengl/uniformcache.h>
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace {
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
class RenderableTube : public Renderable {
|
||||
public:
|
||||
RenderableTube(const ghoul::Dictionary& dictionary);
|
||||
|
||||
void initialize() override;
|
||||
void initializeGL() override;
|
||||
void deinitializeGL() override;
|
||||
|
||||
bool isReady() const override;
|
||||
|
||||
void render(const RenderData& data, RendererTasks& rendererTask) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
struct Coordinate {
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
};
|
||||
|
||||
struct TimePolygon {
|
||||
double timestamp;
|
||||
std::vector<Coordinate> points;
|
||||
};
|
||||
|
||||
void readDataFile();
|
||||
TimePolygon readDataLine(std::ifstream& file);
|
||||
|
||||
void updateTubeData();
|
||||
void updateBufferData();
|
||||
|
||||
// Properties
|
||||
properties::FloatProperty _lineWidth;
|
||||
properties::Vec3Property _lineColor;
|
||||
|
||||
UniformCache(modelViewProjection, color) _uniformCache;
|
||||
|
||||
std::filesystem::path _dataFile;
|
||||
std::vector<TimePolygon> _data;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
|
||||
GLuint _vaoId = 0;
|
||||
GLuint _vboId = 0;
|
||||
GLuint _iboId = 0;
|
||||
std::vector<float> _vertexArray;
|
||||
std::vector<uint8_t> _indexArray;
|
||||
|
||||
bool _prismIsDirty = false;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_BASE___RENDERABLETUBE___H__
|
||||
Reference in New Issue
Block a user