From 2dab48b85082ea960465e13f07b80a81eb4302f4 Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Wed, 21 May 2014 15:11:13 -0400 Subject: [PATCH 001/113] Updated kameleonwrapper to be able to load several variables into a RGB texture. Added support for 'Variables' tag in .mod scenegraph files which takes 3 variables as an array --- include/openspace/util/kameleonwrapper.h | 2 + src/rendering/renderablevolume.cpp | 154 ++++++++++------- src/rendering/renderablevolumeexpert.cpp | 7 +- src/util/kameleonwrapper.cpp | 205 +++++++++++++++-------- 4 files changed, 235 insertions(+), 133 deletions(-) diff --git a/include/openspace/util/kameleonwrapper.h b/include/openspace/util/kameleonwrapper.h index 3ba0afbbb0..a92483b094 100644 --- a/include/openspace/util/kameleonwrapper.h +++ b/include/openspace/util/kameleonwrapper.h @@ -46,8 +46,10 @@ public: KameleonWrapper(const std::string& filename, Model model); ~KameleonWrapper(); float* getUniformSampledValues(const std::string& var, glm::size3_t outDimensions); + float* getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions); private: + void getGridVariables(std::string& x, std::string& y, std::string& z); ccmc::Model* _model; Model _type; ccmc::Interpolator* _interpolator; diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index c96b8ca7ae..81e58e5180 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -102,63 +102,103 @@ std::string RenderableVolume::findPath(const std::string& path) { } ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary) { - if( ! FileSys.fileExists(filepath)) { - LWARNING("Could not load volume, could not find '" << filepath << "'"); - return nullptr; - } - - if(hasExtension(filepath, "raw")) { - ghoul::RawVolumeReader::ReadHints hints = readHints(hintsDictionary); - ghoul::RawVolumeReader rawReader(hints); - return rawReader.read(filepath); - } else if(hasExtension(filepath, "cdf")) { - - std::string modelString; - if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) { - KameleonWrapper::Model model; - if (modelString == "BATSRUS") { - model = KameleonWrapper::Model::BATSRUS; - } else if (modelString == "ENLIL") { - model = KameleonWrapper::Model::ENLIL; - } else { - LWARNING("Hints does not specify a valid 'Model'"); - return nullptr; - } - - std::string variableString; - if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) { - glm::size3_t dimensions(1,1,1); - double tempValue; - if (hintsDictionary.hasKey("Dimensions.1") && hintsDictionary.getValue("Dimensions.1", tempValue)) { - int intVal = static_cast(tempValue); - if(intVal > 0) - dimensions[0] = intVal; - } - if (hintsDictionary.hasKey("Dimensions.2") && hintsDictionary.getValue("Dimensions.2", tempValue)) { - int intVal = static_cast(tempValue); - if(intVal > 0) - dimensions[1] = intVal; - } - if (hintsDictionary.hasKey("Dimensions.3") && hintsDictionary.getValue("Dimensions.3", tempValue)) { - int intVal = static_cast(tempValue); - if(intVal > 0) - dimensions[2] = intVal; - } - - KameleonWrapper kw(filepath, model); - float* data = kw.getUniformSampledValues(variableString, dimensions); - return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); - } else { - LWARNING("Hints does not specify a 'Variable'"); - } - - - } - LWARNING("Hints does not specify a 'Model'"); - } else { - LWARNING("No valid file extension."); - } - return nullptr; + if( ! FileSys.fileExists(filepath)) { + LWARNING("Could not load volume, could not find '" << filepath << "'"); + return nullptr; + } + + if(hasExtension(filepath, "raw")) { + ghoul::RawVolumeReader::ReadHints hints = readHints(hintsDictionary); + ghoul::RawVolumeReader rawReader(hints); + return rawReader.read(filepath); + } else if(hasExtension(filepath, "cdf")) { + + std::string modelString; + if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) { + KameleonWrapper::Model model; + if (modelString == "BATSRUS") { + model = KameleonWrapper::Model::BATSRUS; + } else if (modelString == "ENLIL") { + model = KameleonWrapper::Model::ENLIL; + } else { + LWARNING("Hints does not specify a valid 'Model'"); + return nullptr; + } + + glm::size3_t dimensions(1,1,1); + double tempValue; + if (hintsDictionary.hasKey("Dimensions.1") && hintsDictionary.getValue("Dimensions.1", tempValue)) { + int intVal = static_cast(tempValue); + if(intVal > 0) + dimensions[0] = intVal; + } + if (hintsDictionary.hasKey("Dimensions.2") && hintsDictionary.getValue("Dimensions.2", tempValue)) { + int intVal = static_cast(tempValue); + if(intVal > 0) + dimensions[1] = intVal; + } + if (hintsDictionary.hasKey("Dimensions.3") && hintsDictionary.getValue("Dimensions.3", tempValue)) { + int intVal = static_cast(tempValue); + if(intVal > 0) + dimensions[2] = intVal; + } + + KameleonWrapper kw(filepath, model); + + std::string variableString; + if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) { + float* data = kw.getUniformSampledValues(variableString, dimensions); + return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); + + } else if (hintsDictionary.hasKey("Variables")) { + std::string xVariable, yVariable, zVariable; + bool xVar, yVar, zVar; + xVar = hintsDictionary.getValue("Variables.1", xVariable); + yVar = hintsDictionary.getValue("Variables.2", yVariable); + zVar = hintsDictionary.getValue("Variables.3", zVariable); + + if (!xVar || !yVar || !zVar) { + LERROR("Error reading variables! Must be 3 and must exist in CDF data"); + } else { + float* data = kw.getUniformSampledVectorValues(xVariable, yVariable, zVariable, dimensions); + return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT); + } + + } else { + LWARNING("Hints does not specify a 'Variable' or 'Variables'"); + } + + + + + // float* data = kw.getUniformSampledVectorValues(variableString, dimensions); + // return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT); + + // float* data = kw.getUniformSampledValues(variableString, dimensions); + // new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); + +// ghoul::opengl::Texture* texture; +// float* data; + + // if (hintsDictionary.hasKey("VectorData") && hintsDictionary.getValue("VectorData", variableString)) { + // if (variableString == "1") { // Vector data + // LDEBUG("VectorData"); + // data = kw.getUniformSampledVectorValues(variableString, dimensions); + // texture = new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGB, GL_RGB8, GL_FLOAT); + // } else { // Scalar data + // LDEBUG("ScalarData"); + // data = kw.getUniformSampledValues(variableString, dimensions); + // texture = new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); + // } + // } + + + } + LWARNING("Hints does not specify a 'Model'"); + } else { + LWARNING("No valid file extension."); + } + return nullptr; } ghoul::RawVolumeReader::ReadHints RenderableVolume::readHints(const ghoul::Dictionary& dictionary) { diff --git a/src/rendering/renderablevolumeexpert.cpp b/src/rendering/renderablevolumeexpert.cpp index c3f268ae4a..e6a15c7136 100644 --- a/src/rendering/renderablevolumeexpert.cpp +++ b/src/rendering/renderablevolumeexpert.cpp @@ -248,14 +248,17 @@ bool RenderableVolumeExpert::initialize() { for (int i = 0; i < _volumePaths.size(); ++i) { ghoul::opengl::Texture* volume = loadVolume(_volumePaths.at(i), _volumeHints.at(i)); - if(volume) { + if(volume != nullptr) { + LDEBUG("All is well"); volume->uploadTexture(); LDEBUG("Creating CL texture from GL texture with path '" << _volumePaths.at(i) << "'"); cl_mem volumeTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *volume); - + _volumes.push_back(volume); _clVolumes.push_back(volumeTexture); + } else { + LDEBUG("nullptr, derp"); } } diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 66db1fb2d9..212761663b 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -42,19 +42,19 @@ KameleonWrapper::KameleonWrapper(const std::string& filename, Model model): _typ switch (_type) { case Model::BATSRUS: _model = new ccmc::BATSRUS(); - if(!_model) LERROR("BATSRUS:Failed to create model instance"); + if(!_model) LERROR("BATSRUS:Failed to create BATSRUS model instance"); if (_model->open(filename) != ccmc::FileReader::OK) LERROR("BATSRUS:Failed to open "+filename); _interpolator = _model->createNewInterpolator(); - if (!_interpolator) LERROR("BATSRUS:Failed to create interpolator"); + if (!_interpolator) LERROR("BATSRUS:Failed to create BATSRUS interpolator"); break; case Model::ENLIL: _model = new ccmc::ENLIL(); - if(!_model) LERROR("Failed to create model instance"); + if(!_model) LERROR("Failed to create ENLIL model instance"); if (_model->open(filename) != ccmc::FileReader::OK) LERROR("Failed to open "+filename); _interpolator = _model->createNewInterpolator(); - if (!_interpolator) LERROR("Failed to create interpolator"); + if (!_interpolator) LERROR("Failed to create ENLIL interpolator"); break; default: LERROR("No valid model type provided!"); @@ -70,54 +70,14 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz assert(_model && _interpolator); assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0); assert(_type == Model::ENLIL || _type == Model::BATSRUS); - LINFO("Loading CDF data"); + LINFO("Loading variable " << var << " from CDF data with a uniform sampling"); int size = outDimensions.x*outDimensions.y*outDimensions.z; float* data = new float[size]; - - // get the grid system string - std::string gridSystem = _model->getGlobalAttribute("grid_system_1").getAttributeString(); - - // remove leading and trailing brackets - gridSystem = gridSystem.substr(1,gridSystem.length()-2); - - // remove all whitespaces - gridSystem.erase(remove_if(gridSystem.begin(), gridSystem.end(), isspace), gridSystem.end()); - - // replace all comma signs with whitespaces - std::replace( gridSystem.begin(), gridSystem.end(), ',', ' '); - - // tokenize - std::istringstream iss(gridSystem); - std::vector tokens{std::istream_iterator{iss},std::istream_iterator{}}; - - // validate - if (tokens.size() != 3) { - LERROR("Something went wrong"); - delete[] data; - return 0; - } - std::string v_x = tokens.at(0), v_y = tokens.at(1), v_z = tokens.at(2); - /* - for(auto t: tokens) - LDEBUG("t: " << t); - */ - /* - LERROR("getVariableAttributeNames"); - std::vector attributeNames = _model->getVariableAttributeNames(); - for(auto name : attributeNames) - LDEBUG(name); - */ - //_model->getVa - - //auto fan = std::find(attributeNames.begin(), attributeNames.end(), ""); - - - //KameleonWrapper (Debug) grid_system_1 - //KameleonWrapper (Debug) grid_1_type - - LDEBUG("Using coordinate system: " << v_x << ", " << v_y << ", " << v_z); + std::string v_x, v_y, v_z; + getGridVariables(v_x, v_y, v_z); + LDEBUG("Using coordinate system variables: " << v_x << ", " << v_y << ", " << v_z); float xMin = _model->getVariableAttribute(v_x, "actual_min").getAttributeFloat(); float xMax = _model->getVariableAttribute(v_x, "actual_max").getAttributeFloat(); @@ -132,7 +92,6 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz float stepY = (yMax-yMin)/(static_cast(outDimensions.y)); float stepZ = (zMax-zMin)/(static_cast(outDimensions.z)); - LDEBUG(v_x << "Min: " << xMin); LDEBUG(v_x << "Max: " << xMax); LDEBUG(v_y << "Min: " << yMin); @@ -174,10 +133,6 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz // scale to [0,1] data[index] = (value-varMin)/(varMax-varMin); } else if (_type == Model::ENLIL) { - //LDEBUG("data: " << theval); - - // Calculate array index - //unsigned int index = r + theta*xDim_ + phi*xDim_*yDim_; // Put r in the [0..sqrt(3)] range float rNorm = sqrt(3.0)*(float)x/(float)(outDimensions.x-1); @@ -191,15 +146,12 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz // Go to physical coordinates before sampling float rPh = xMin + rNorm*(xMax-xMin); float thetaPh = thetaNorm; - //phi range needs to be mapped to the slightly different - // model range to avoid gaps in the data - // Subtract a small term to avoid rounding errors when comparing - // to phiMax. + // phi range needs to be mapped to the slightly different model + // range to avoid gaps in the data Subtract a small term to + // avoid rounding errors when comparing to phiMax. float phiPh = zMin + phiNorm/(2.0*M_PI)*(zMax-zMin-0.000001); - // Hardcoded variables (rho or rho - rho_back) - // TODO Don't hardcode, make more flexible - float varValue = 0.f;//, rho_back = 0.f, diff = 0.f; + float varValue = 0.f; // See if sample point is inside domain if (rPh < xMin || rPh > xMax || thetaPh < yMin || thetaPh > yMax || phiPh < zMin || phiPh > zMax) { @@ -218,22 +170,9 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz phiPh = phiPh*180.f/M_PI; // Sample varValue = _interpolator->interpolate(var, rPh, thetaPh, phiPh); - //rho_back = _interpolator->interpolate("rho-back",rPh,thetaPh,phiPh); - - // Calculate difference (or just rho) - //diff = rho; - //diff = rho - rho_back; - - // Clamp to 0 - //if (diff < 0.f) diff = 0.f; } - //if(var < 0.0f) var = 0.0f; - //data[index] = var; + data[index] = (varValue-varMin)/(varMax-varMin); - //LDEBUG("varValue:" << varValue); - //LDEBUG("data[index]:" << data[index]); - //data[index] = var; - //data[index] = diff; } } } @@ -244,5 +183,123 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz return data; } +float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions) { + assert(_model && _interpolator); + assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0); + assert(_type == Model::ENLIL || _type == Model::BATSRUS); + LINFO("Loading variables " << xVar << " " << yVar << " " << zVar << " from CDF data with a uniform sampling"); + + int size = 4*outDimensions.x*outDimensions.y*outDimensions.z; + float* data = new float[size]; + + std::string v_x, v_y, v_z; + getGridVariables(v_x, v_y, v_z); + LDEBUG("Using coordinate system variables: " << v_x << ", " << v_y << ", " << v_z); + + float xMin = _model->getVariableAttribute(v_x, "actual_min").getAttributeFloat(); + float xMax = _model->getVariableAttribute(v_x, "actual_max").getAttributeFloat(); + float yMin = _model->getVariableAttribute(v_y, "actual_min").getAttributeFloat(); + float yMax = _model->getVariableAttribute(v_y, "actual_max").getAttributeFloat(); + float zMin = _model->getVariableAttribute(v_z, "actual_min").getAttributeFloat(); + float zMax = _model->getVariableAttribute(v_z, "actual_max").getAttributeFloat(); + float varXMin = _model->getVariableAttribute(xVar, "actual_min").getAttributeFloat(); + float varXMax = _model->getVariableAttribute(xVar, "actual_max").getAttributeFloat(); + float varYMin = _model->getVariableAttribute(yVar, "actual_min").getAttributeFloat(); + float varYMax = _model->getVariableAttribute(yVar, "actual_max").getAttributeFloat(); + float varZMin = _model->getVariableAttribute(zVar, "actual_min").getAttributeFloat(); + float varZMax = _model->getVariableAttribute(zVar, "actual_max").getAttributeFloat(); + + float stepX = (xMax-xMin)/(static_cast(outDimensions.x)); + float stepY = (yMax-yMin)/(static_cast(outDimensions.y)); + float stepZ = (zMax-zMin)/(static_cast(outDimensions.z)); + + LDEBUG(v_x << "Min: " << xMin); + LDEBUG(v_x << "Max: " << xMax); + LDEBUG(v_y << "Min: " << yMin); + LDEBUG(v_y << "Max: " << yMax); + LDEBUG(v_z << "Min: " << zMin); + LDEBUG(v_z << "Max: " << zMax); + LDEBUG(xVar << "Min: " << varXMin); + LDEBUG(xVar << "Max: " << varXMax); + LDEBUG(yVar << "Min: " << varYMin); + LDEBUG(yVar << "Max: " << varYMax); + LDEBUG(zVar << "Min: " << varZMin); + LDEBUG(zVar << "Max: " << varZMax); + + int barWidth = 70; + int lastiProgress = -1; + for (int x = 0; x < outDimensions.x; ++x) { + float progress = static_cast(x) / static_cast(outDimensions.x-1); + int iprogress = static_cast(progress*100.0f); + if (iprogress != lastiProgress) { + + int pos = barWidth * progress; + int eqWidth = pos+1; + int spWidth = barWidth - pos + 2; + std::cout << "[" << std::setfill('=') << std::setw(eqWidth) + << ">" << std::setfill(' ') << std::setw(spWidth) + << "] " << iprogress << " % \r" << std::flush; + } + lastiProgress = iprogress; + + for (int y = 0; y < outDimensions.y; ++y) { + for (int z = 0; z < outDimensions.z; ++z) { + + int index = 4*x + 4*y*outDimensions.x + 4*z*outDimensions.x*outDimensions.y; + + if(_type == Model::BATSRUS) { + float xPos = xMin + stepX*x; + float yPos = yMin + stepY*y; + float zPos = zMin + stepZ*z; + + // get interpolated data value for (xPos, yPos, zPos) + float xValue = _interpolator->interpolate(xVar, xPos, yPos, zPos); + float yValue = _interpolator->interpolate(yVar, xPos, yPos, zPos); + float zValue = _interpolator->interpolate(zVar, xPos, yPos, zPos); + + // scale to [0,1] + data[index] = (xValue-varXMin)/(varXMax-varXMin); + data[index + 1] = (yValue-varYMin)/(varYMax-varYMin); + data[index + 2] = (zValue-varZMin)/(varZMax-varZMin); + data[index + 3] = 1.0; + } else { + LERROR("Only BATSRUS supported for getUniformSampledVectorValues"); + } + } + } + } + std::cout << std::endl; + LINFO("Done!"); + + return data; +} + +void KameleonWrapper::getGridVariables(std::string& x, std::string& y, std::string& z) { + // get the grid system string + std::string gridSystem = _model->getGlobalAttribute("grid_system_1").getAttributeString(); + + // remove leading and trailing brackets + gridSystem = gridSystem.substr(1,gridSystem.length()-2); + + // remove all whitespaces + gridSystem.erase(remove_if(gridSystem.begin(), gridSystem.end(), isspace), gridSystem.end()); + + // replace all comma signs with whitespaces + std::replace( gridSystem.begin(), gridSystem.end(), ',', ' '); + + // tokenize + std::istringstream iss(gridSystem); + std::vector tokens{std::istream_iterator{iss},std::istream_iterator{}}; + + // validate + if (tokens.size() != 3) { + LERROR("Something went wrong"); + } + + x = tokens.at(0); + y = tokens.at(1); + z = tokens.at(2); +} + } // namespace openspace From 29b4cffd7882eb3066cb0e743c52f7f1d815d39a Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Wed, 21 May 2014 16:24:47 -0400 Subject: [PATCH 002/113] Code cleaup --- include/openspace/util/kameleonwrapper.h | 4 ++ src/rendering/renderablevolume.cpp | 25 --------- src/util/kameleonwrapper.cpp | 65 ++++++++++-------------- 3 files changed, 31 insertions(+), 63 deletions(-) diff --git a/include/openspace/util/kameleonwrapper.h b/include/openspace/util/kameleonwrapper.h index a92483b094..9c7f55c9bd 100644 --- a/include/openspace/util/kameleonwrapper.h +++ b/include/openspace/util/kameleonwrapper.h @@ -50,9 +50,13 @@ public: private: void getGridVariables(std::string& x, std::string& y, std::string& z); + void progressBar(int current, int end); + ccmc::Model* _model; Model _type; ccmc::Interpolator* _interpolator; + + int _lastiProgress; // for progressbar }; } // namespace openspace diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index 81e58e5180..c01b9bb3bd 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -168,31 +168,6 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath LWARNING("Hints does not specify a 'Variable' or 'Variables'"); } - - - - // float* data = kw.getUniformSampledVectorValues(variableString, dimensions); - // return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT); - - // float* data = kw.getUniformSampledValues(variableString, dimensions); - // new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); - -// ghoul::opengl::Texture* texture; -// float* data; - - // if (hintsDictionary.hasKey("VectorData") && hintsDictionary.getValue("VectorData", variableString)) { - // if (variableString == "1") { // Vector data - // LDEBUG("VectorData"); - // data = kw.getUniformSampledVectorValues(variableString, dimensions); - // texture = new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGB, GL_RGB8, GL_FLOAT); - // } else { // Scalar data - // LDEBUG("ScalarData"); - // data = kw.getUniformSampledValues(variableString, dimensions); - // texture = new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); - // } - // } - - } LWARNING("Hints does not specify a 'Model'"); } else { diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 212761663b..2e4378fa2a 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -59,6 +59,7 @@ KameleonWrapper::KameleonWrapper(const std::string& filename, Model model): _typ default: LERROR("No valid model type provided!"); } + _lastiProgress = -1; // for progressbar } KameleonWrapper::~KameleonWrapper() { @@ -101,21 +102,8 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz LDEBUG(var << "Min: " << varMin); LDEBUG(var << "Max: " << varMax); - int barWidth = 70; - int lastiProgress = -1; for (int x = 0; x < outDimensions.x; ++x) { - float progress = static_cast(x) / static_cast(outDimensions.x-1); - int iprogress = static_cast(progress*100.0f); - if (iprogress != lastiProgress) { - - int pos = barWidth * progress; - int eqWidth = pos+1; - int spWidth = barWidth - pos + 2; - std::cout << "[" << std::setfill('=') << std::setw(eqWidth) - << ">" << std::setfill(' ') << std::setw(spWidth) - << "] " << iprogress << " % \r" << std::flush; - } - lastiProgress = iprogress; + progressBar(x, outDimensions.x); for (int y = 0; y < outDimensions.y; ++y) { for (int z = 0; z < outDimensions.z; ++z) { @@ -189,7 +177,8 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c assert(_type == Model::ENLIL || _type == Model::BATSRUS); LINFO("Loading variables " << xVar << " " << yVar << " " << zVar << " from CDF data with a uniform sampling"); - int size = 4*outDimensions.x*outDimensions.y*outDimensions.z; + int channels = 4; + int size = channels*outDimensions.x*outDimensions.y*outDimensions.z; float* data = new float[size]; std::string v_x, v_y, v_z; @@ -226,26 +215,13 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c LDEBUG(zVar << "Min: " << varZMin); LDEBUG(zVar << "Max: " << varZMax); - int barWidth = 70; - int lastiProgress = -1; for (int x = 0; x < outDimensions.x; ++x) { - float progress = static_cast(x) / static_cast(outDimensions.x-1); - int iprogress = static_cast(progress*100.0f); - if (iprogress != lastiProgress) { - - int pos = barWidth * progress; - int eqWidth = pos+1; - int spWidth = barWidth - pos + 2; - std::cout << "[" << std::setfill('=') << std::setw(eqWidth) - << ">" << std::setfill(' ') << std::setw(spWidth) - << "] " << iprogress << " % \r" << std::flush; - } - lastiProgress = iprogress; + progressBar(x, outDimensions.x); for (int y = 0; y < outDimensions.y; ++y) { for (int z = 0; z < outDimensions.z; ++z) { - int index = 4*x + 4*y*outDimensions.x + 4*z*outDimensions.x*outDimensions.y; + int index = x*channels + y*channels*outDimensions.x + z*channels*outDimensions.x*outDimensions.y; if(_type == Model::BATSRUS) { float xPos = xMin + stepX*x; @@ -258,12 +234,12 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c float zValue = _interpolator->interpolate(zVar, xPos, yPos, zPos); // scale to [0,1] - data[index] = (xValue-varXMin)/(varXMax-varXMin); - data[index + 1] = (yValue-varYMin)/(varYMax-varYMin); - data[index + 2] = (zValue-varZMin)/(varZMax-varZMin); - data[index + 3] = 1.0; + data[index] = (xValue-varXMin)/(varXMax-varXMin); // R + data[index + 1] = (yValue-varYMin)/(varYMax-varYMin); // G + data[index + 2] = (zValue-varZMin)/(varZMax-varZMin); // B + data[index + 3] = 1.0; // GL_RGB refuses to work. Workaround by doing a GL_RGBA with hardcoded alpha } else { - LERROR("Only BATSRUS supported for getUniformSampledVectorValues"); + LERROR("Only BATSRUS supported for getUniformSampledVectorValues (for now)"); } } } @@ -292,14 +268,27 @@ void KameleonWrapper::getGridVariables(std::string& x, std::string& y, std::stri std::vector tokens{std::istream_iterator{iss},std::istream_iterator{}}; // validate - if (tokens.size() != 3) { - LERROR("Something went wrong"); - } + if (tokens.size() != 3) LERROR("Something went wrong"); x = tokens.at(0); y = tokens.at(1); z = tokens.at(2); } +void KameleonWrapper::progressBar(int current, int end) { + float progress = static_cast(current) / static_cast(end-1); + int iprogress = static_cast(progress*100.0f); + int barWidth = 70; + if (iprogress != _lastiProgress) { + int pos = barWidth * progress; + int eqWidth = pos+1; + int spWidth = barWidth - pos + 2; + std::cout << "[" << std::setfill('=') << std::setw(eqWidth) + << ">" << std::setfill(' ') << std::setw(spWidth) + << "] " << iprogress << " % \r" << std::flush; + } + _lastiProgress = iprogress; +} + } // namespace openspace From 48f1b6aa5ceb146bc189085167a4a96ce60c7e82 Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Fri, 23 May 2014 16:20:11 -0400 Subject: [PATCH 003/113] Added basic fieldline implementation in kameleonwrapper --- include/openspace/util/kameleonwrapper.h | 6 ++- src/rendering/renderablevolume.cpp | 19 ++++++- src/rendering/renderablevolumeexpert.cpp | 5 +- src/util/kameleonwrapper.cpp | 68 +++++++++++++++++++++++- 4 files changed, 91 insertions(+), 7 deletions(-) diff --git a/include/openspace/util/kameleonwrapper.h b/include/openspace/util/kameleonwrapper.h index 9c7f55c9bd..e52172b214 100644 --- a/include/openspace/util/kameleonwrapper.h +++ b/include/openspace/util/kameleonwrapper.h @@ -46,7 +46,11 @@ public: KameleonWrapper(const std::string& filename, Model model); ~KameleonWrapper(); float* getUniformSampledValues(const std::string& var, glm::size3_t outDimensions); - float* getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions); + float* getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar, + const std::string& zVar, glm::size3_t outDimensions); + + float* getFieldLines(const std::string& xVar, const std::string& yVar, + const std::string& zVar, glm::size3_t outDimensions, std::vector seedPoints); private: void getGridVariables(std::string& x, std::string& y, std::string& z); diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index c01b9bb3bd..6645357612 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -160,8 +160,23 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath if (!xVar || !yVar || !zVar) { LERROR("Error reading variables! Must be 3 and must exist in CDF data"); } else { - float* data = kw.getUniformSampledVectorValues(xVariable, yVariable, zVariable, dimensions); - return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT); + + // Seed 'em all + std::vector seedPoints; + for (int z = -20; z <= 20; z+=20) { + for (int y = -20; y <= 20; y+=20) + seedPoints.push_back(glm::vec3(-10.0, (float)y, (float)z)); + } + + float* fieldlinesData = kw.getFieldLines(xVariable, yVariable, zVariable, dimensions, seedPoints); + float* rhoData = kw.getUniformSampledValues("rho", dimensions); + + // Combine fieldlines with rhoData, clamp to [0,1] + float* data = new float[dimensions.x*dimensions.y*dimensions.z]; + for (int i = 0; i < dimensions.x*dimensions.y*dimensions.z; ++i) + data[i] = std::min(fieldlinesData[i]+rhoData[i], 1.0f); + + return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); } } else { diff --git a/src/rendering/renderablevolumeexpert.cpp b/src/rendering/renderablevolumeexpert.cpp index e6a15c7136..1785c58857 100644 --- a/src/rendering/renderablevolumeexpert.cpp +++ b/src/rendering/renderablevolumeexpert.cpp @@ -248,8 +248,7 @@ bool RenderableVolumeExpert::initialize() { for (int i = 0; i < _volumePaths.size(); ++i) { ghoul::opengl::Texture* volume = loadVolume(_volumePaths.at(i), _volumeHints.at(i)); - if(volume != nullptr) { - LDEBUG("All is well"); + if(volume) { volume->uploadTexture(); LDEBUG("Creating CL texture from GL texture with path '" << _volumePaths.at(i) << "'"); @@ -258,7 +257,7 @@ bool RenderableVolumeExpert::initialize() { _volumes.push_back(volume); _clVolumes.push_back(volumeTexture); } else { - LDEBUG("nullptr, derp"); + LERROR("Invalid volume"); } } diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 2e4378fa2a..60d2ea6aa4 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -31,7 +31,8 @@ #include #define _USE_MATH_DEFINES #include - +#include +#include #include namespace openspace { @@ -181,6 +182,10 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c int size = channels*outDimensions.x*outDimensions.y*outDimensions.z; float* data = new float[size]; +// memset(data, 0.0, sizeof(data)); + + + std::string v_x, v_y, v_z; getGridVariables(v_x, v_y, v_z); LDEBUG("Using coordinate system variables: " << v_x << ", " << v_y << ", " << v_z); @@ -275,6 +280,67 @@ void KameleonWrapper::getGridVariables(std::string& x, std::string& y, std::stri z = tokens.at(2); } +float* KameleonWrapper::getFieldLines(const std::string& xVar, + const std::string& yVar, const std::string& zVar, + glm::size3_t outDimensions, std::vector seedPoints) { + assert(_model && _interpolator); + assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0); + assert(_type == Model::ENLIL || _type == Model::BATSRUS); + LINFO("Creating " << seedPoints.size() << " fieldlines from variables " << xVar << " " << yVar << " " << zVar); + + std::string v_x, v_y, v_z; + getGridVariables(v_x, v_y, v_z); + LDEBUG("Using coordinate system variables: " << v_x << ", " << v_y << ", " << v_z); + + float xMin = _model->getVariableAttribute(v_x, "actual_min").getAttributeFloat(); + float xMax = _model->getVariableAttribute(v_x, "actual_max").getAttributeFloat(); + float yMin = _model->getVariableAttribute(v_y, "actual_min").getAttributeFloat(); + float yMax = _model->getVariableAttribute(v_y, "actual_max").getAttributeFloat(); + float zMin = _model->getVariableAttribute(v_z, "actual_min").getAttributeFloat(); + float zMax = _model->getVariableAttribute(v_z, "actual_max").getAttributeFloat(); + + float stepSize = 0.001; + float stepX = stepSize*(xMax-xMin)/(static_cast(outDimensions.x)); + float stepY = stepSize*(yMax-yMin)/(static_cast(outDimensions.y)); + float stepZ = stepSize*(zMax-zMin)/(static_cast(outDimensions.z)); + + int size = outDimensions.x*outDimensions.y*outDimensions.z; + float* data = new float[size]; + glm::vec3 dir, pos; + + int highNumber = 100000; + + for (int i = 0; i < seedPoints.size(); ++i) { + progressBar(i, seedPoints.size()); + pos = seedPoints.at(i); + int avoidInfLoopPlz = 0; + while (pos.x < xMax && pos.x > xMin && + pos.y < yMax && pos.y > yMin && + pos.z < zMax && pos.z > zMin) { + + // Save position + int vPosX = std::floor(outDimensions.x*(pos.x-xMin)/(xMax-xMin)); + int vPosY = std::floor(outDimensions.y*(pos.y-yMin)/(yMax-yMin)); + int vPosZ = std::floor(outDimensions.z*(pos.z-zMin)/(zMax-zMin)); + int index = vPosX + vPosY*outDimensions.x + vPosZ*outDimensions.x*outDimensions.y; + data[index] = 1.0; + + // Calculate the next position + dir.x = _interpolator->interpolate(xVar, pos.x, pos.y, pos.z); + dir.y = _interpolator->interpolate(yVar, pos.x, pos.y, pos.z); + dir.z = _interpolator->interpolate(zVar, pos.x, pos.y, pos.z); + pos = glm::vec3(stepX*dir.x+pos.x, stepY*dir.y+pos.y, stepZ*dir.z+pos.z); + ++avoidInfLoopPlz; + + if (avoidInfLoopPlz > highNumber) { + LDEBUG("Inf loop averted"); + break; + } + } + } + return data; +} + void KameleonWrapper::progressBar(int current, int end) { float progress = static_cast(current) / static_cast(end-1); int iprogress = static_cast(progress*100.0f); From 4269282718953ceaffaa708b789b6e15374e80b8 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Tue, 27 May 2014 16:28:46 -0400 Subject: [PATCH 004/113] Intermediate ABuffer work --- .../openspace/abuffer/abufferSingleLinked.h | 56 +++++++++++++++++ include/openspace/abuffer/abuffer_i.h | 45 +++++++++++++ src/CMakeLists.txt | 6 ++ src/abuffer/abufferSingleLinked.cpp | 63 +++++++++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 include/openspace/abuffer/abufferSingleLinked.h create mode 100644 include/openspace/abuffer/abuffer_i.h create mode 100644 src/abuffer/abufferSingleLinked.cpp diff --git a/include/openspace/abuffer/abufferSingleLinked.h b/include/openspace/abuffer/abufferSingleLinked.h new file mode 100644 index 0000000000..93edd06924 --- /dev/null +++ b/include/openspace/abuffer/abufferSingleLinked.h @@ -0,0 +1,56 @@ +/***************************************************************************************** + * * + * 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 __ABUFFERSINGLELINKED_H__ +#define __ABUFFERSINGLELINKED_H__ + +#include + + +namespace openspace { + +class ABufferSingleLinked: public ABuffer_I { +public: + + ABufferSingleLinked(); + virtual ~ABufferSingleLinked(); + virtual bool initialize(); + + virtual void clear(); + virtual void preRender(); + virtual void postRender(); + +private: + + + unsigned int width, height, totalPixels, maxFragments; + + ghoul::opengl::Texture* data; + ghoul::opengl::Texture* anchorPointer; + ghoul::opengl::Texture* anchorPointerInitializer; + +}; // ABuffer_I +} // openspace + +#endif // __ABUFFERSINGLELINKED_H__ \ No newline at end of file diff --git a/include/openspace/abuffer/abuffer_i.h b/include/openspace/abuffer/abuffer_i.h new file mode 100644 index 0000000000..9e1644edb0 --- /dev/null +++ b/include/openspace/abuffer/abuffer_i.h @@ -0,0 +1,45 @@ +/***************************************************************************************** + * * + * 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 __ABUFFER_I_H__ +#define __ABUFFER_I_H__ + +#include +#include + +namespace openspace { + +class ABuffer_I { +public: + virtual ~ABuffer_I() {}; + virtual bool initialize() = 0; + + virtual void clear() = 0; + virtual void preRender() = 0; + virtual void postRender() = 0; + +}; // ABuffer_I +} // openspace + +#endif // __ABUFFER_I_H__ \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 310b700bc5..42fe1ebbac 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,6 +34,12 @@ file(GLOB CONFIGURATION_HEADER ${HEADER_ROOT_DIR}/openspace/configuration/*.h) set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${CONFIGURATION_HEADER}) source_group(Configuration FILES ${CONFIGURATION_SOURCE} ${CONFIGURATION_HEADER}) +file(GLOB ABUFFER_SOURCE ${SOURCE_ROOT_DIR}/abuffer/*.cpp) +set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${ABUFFER_SOURCE}) +file(GLOB ABUFFER_HEADER ${HEADER_ROOT_DIR}/openspace/abuffer/*.h) +set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${ABUFFER_HEADER}) +source_group(ABuffer FILES ${ABUFFER_SOURCE} ${ABUFFER_HEADER}) + file(GLOB ENGINE_SOURCE ${SOURCE_ROOT_DIR}/engine/*.cpp) set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${ENGINE_SOURCE}) file(GLOB ENGINE_HEADER ${HEADER_ROOT_DIR}/openspace/engine/*.h) diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp new file mode 100644 index 0000000000..14645678ce --- /dev/null +++ b/src/abuffer/abufferSingleLinked.cpp @@ -0,0 +1,63 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include + +#define MAX_LAYERS 10 + +namespace openspace { + +ABufferSingleLinked::ABufferSingleLinked() { + int x1, xSize, y1, ySize; + sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); + width = xSize; + height = ySize; + totalPixels = width * height; + maxFragments = totalPixels * MAX_LAYERS; +} + +ABufferSingleLinked::~ABufferSingleLinked() { + +} + +bool ABufferSingleLinked::initialize() { + data = new ghoul::opengl::Texture(glm::size3_t(width, height, 1), ghoul::opengl::Texture::Format::RED, GL_RED, GL_R32UI); + return true; +} + +void ABufferSingleLinked::clear() { + +} + +void ABufferSingleLinked::preRender() { + +} + +void ABufferSingleLinked::postRender() { + +} + +} // openspace \ No newline at end of file From 4379d27cbc106ec75ab31b49492c88d0cf022c5d Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Thu, 29 May 2014 12:25:04 -0400 Subject: [PATCH 005/113] Single Linked ABuffer implementation --- .../openspace/abuffer/abufferSingleLinked.h | 13 +- include/openspace/engine/openspaceengine.h | 2 +- include/openspace/rendering/renderengine.h | 4 + shaders/ABuffer/abufferResolveFragment.glsl | 77 +++++++++++ shaders/ABuffer/abufferResolveVertex.glsl | 9 ++ shaders/pscstandard_fs.glsl | 26 +++- shaders/pscstandard_vs.glsl | 2 +- src/abuffer/abufferSingleLinked.cpp | 120 +++++++++++++++++- src/rendering/renderengine.cpp | 13 +- 9 files changed, 251 insertions(+), 15 deletions(-) create mode 100644 shaders/ABuffer/abufferResolveFragment.glsl create mode 100644 shaders/ABuffer/abufferResolveVertex.glsl diff --git a/include/openspace/abuffer/abufferSingleLinked.h b/include/openspace/abuffer/abufferSingleLinked.h index 93edd06924..4ff20b2070 100644 --- a/include/openspace/abuffer/abufferSingleLinked.h +++ b/include/openspace/abuffer/abufferSingleLinked.h @@ -27,6 +27,7 @@ #include +#include namespace openspace { @@ -46,9 +47,15 @@ private: unsigned int width, height, totalPixels, maxFragments; - ghoul::opengl::Texture* data; - ghoul::opengl::Texture* anchorPointer; - ghoul::opengl::Texture* anchorPointerInitializer; + GLuint *data; + GLuint anchorPointerTexture; + GLuint anchorPointerTextureInitializer; + GLuint atomicCounterBuffer; + GLuint fragmentBuffer; + GLuint fragmentTexture; + GLuint _screenQuad; + + ghoul::opengl::ProgramObject* resolveShader; }; // ABuffer_I } // openspace diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index a1b414f606..66fdd720f3 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -34,7 +34,7 @@ #include #include -#define FLARE_ONLY +//#define FLARE_ONLY #include diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index da2c74d712..52c32db385 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -30,6 +30,8 @@ #include #include +#include + namespace openspace { class Camera; @@ -58,6 +60,8 @@ public: private: Camera* _mainCamera; SceneGraph* _sceneGraph; + + ABuffer_I* _abuffer; }; } // namespace openspace diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl new file mode 100644 index 0000000000..d0b46b2968 --- /dev/null +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -0,0 +1,77 @@ +#version 430 + +// texture bindings +layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; +layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; + +// atomic buffer bindings +layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; + +// uniforms +uniform int SCREEN_WIDTH; +uniform int SCREEN_HEIGHT; + +in vec2 texCoord; +out vec4 color; + +#define MAX_FRAGMENTS 16 +uvec4 fragments[MAX_FRAGMENTS]; + +int build_local_fragments_list() { + uint current; + int frag_count = 0; + + current = imageLoad(anchorPointerTexture, ivec2(gl_FragCoord.xy)).x; + + while(current != 0 && frag_count < MAX_FRAGMENTS) { + uvec4 item = imageLoad(fragmentTexture, int(current)); + current = item.x; + + fragments[frag_count] = item; + + frag_count++; + } + + return frag_count; +} + +void sort_fragments_list(uint frag_count) { + uint i,j; + uvec4 tmp; + + // INSERTION SORT + for(i = 1; i < frag_count; ++i) { + tmp = fragments[i]; + for(j = i; j > 0 && tmp.z > fragments[j-1].z; --j) { + fragments[j] = fragments[j-1]; + } + fragments[j] = tmp; + } +} + +vec4 blend(vec4 current_color, vec4 new_color) { + return mix(current_color, new_color, new_color.a); +} + +vec4 calculate_final_color(uint frag_count) { + + vec4 final_color = vec4(0); + for(uint i = 0; i < frag_count; i++) { + uvec4 item = fragments[i]; + vec4 frag_color = unpackUnorm4x8(item.y); + final_color = blend(final_color, frag_color); + } + + return final_color; + +} + + +void main() { + color = vec4(texCoord,0.0,1.0); + int frag_count = build_local_fragments_list(); + sort_fragments_list(frag_count); + color = calculate_final_color(frag_count); + + //color = vec4(float(frag_count) / 5.0, 0.0, 0.0, 1.0); +} \ No newline at end of file diff --git a/shaders/ABuffer/abufferResolveVertex.glsl b/shaders/ABuffer/abufferResolveVertex.glsl new file mode 100644 index 0000000000..ded6af8a7a --- /dev/null +++ b/shaders/ABuffer/abufferResolveVertex.glsl @@ -0,0 +1,9 @@ +#version 430 + +in vec4 position; +out vec2 texCoord; + +void main() { + gl_Position = position; + texCoord = 0.5 + position.xy / 2.0; +} diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index 6a3faef107..eb95f757ba 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -7,7 +7,11 @@ The above copyright notice and this permission notice shall be included in all c 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 400 core +#version 430 + +layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; +layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; +layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; uniform mat4 ViewProjection; uniform mat4 ModelTransform; @@ -15,12 +19,8 @@ uniform vec4 campos; uniform vec4 objpos; uniform float time; uniform sampler2D texture1; -uniform sampler2D texture2; -uniform sampler2D texture3; -uniform float TessLevel; -uniform bool Wireframe; -uniform bool Lightsource; -uniform bool UseTexture; + +vec3 light_position = vec3(40.0, 20.0, 100.0); in vec2 vs_st; //in vec3 vs_stp; @@ -97,6 +97,8 @@ void main() // do I need to be discarded? // discard; } + + // set the depth @@ -112,4 +114,14 @@ void main() //diffuse = vec4(depth*5,0.0, 0.0, 1.0); //diffuse = vec4(vs_position.w,0.0, 0.0, 1.0); //diffuse = vec4(1.0,0.0,0.0,1.0); + uint index = atomicCounterIncrement(atomicCounterBuffer); + uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); + uvec4 item; + item.x = old_head; + item.y = packUnorm4x8(diffuse); + item.z = floatBitsToUint(gl_FragCoord.z / gl_FragCoord.w); + item.w = 0; + imageStore(fragmentTexture, int(index), item); + + discard; } \ No newline at end of file diff --git a/shaders/pscstandard_vs.glsl b/shaders/pscstandard_vs.glsl index 0c588a7ccd..5a612667a2 100644 --- a/shaders/pscstandard_vs.glsl +++ b/shaders/pscstandard_vs.glsl @@ -19,7 +19,7 @@ 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 400 core +#version 430 uniform mat4 ViewProjection; uniform mat4 ModelTransform; diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp index 14645678ce..3d3c7cf7d4 100644 --- a/src/abuffer/abufferSingleLinked.cpp +++ b/src/abuffer/abufferSingleLinked.cpp @@ -24,9 +24,16 @@ #include +#include +#include #include #define MAX_LAYERS 10 +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +namespace { + std::string _loggerCat = "ABufferSingleLinked"; +} namespace openspace { @@ -37,27 +44,136 @@ ABufferSingleLinked::ABufferSingleLinked() { height = ySize; totalPixels = width * height; maxFragments = totalPixels * MAX_LAYERS; + data = 0; + anchorPointerTexture = 0; + anchorPointerTextureInitializer = 0; + atomicCounterBuffer = 0; + fragmentBuffer = 0; + fragmentTexture = 0; } ABufferSingleLinked::~ABufferSingleLinked() { + if(data != 0) + delete data; + glDeleteTextures(1,&anchorPointerTexture); + glDeleteTextures(1,&fragmentTexture); + glDeleteBuffers(1,&anchorPointerTextureInitializer); + glDeleteBuffers(1,&atomicCounterBuffer); + glDeleteBuffers(1,&anchorPointerTextureInitializer); } bool ABufferSingleLinked::initialize() { - data = new ghoul::opengl::Texture(glm::size3_t(width, height, 1), ghoul::opengl::Texture::Format::RED, GL_RED, GL_R32UI); + // ============================ + // BUFFERS + // ============================ + glGenTextures(1, &anchorPointerTexture); + glBindTexture(GL_TEXTURE_2D, anchorPointerTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + + glGenBuffers(1, &anchorPointerTextureInitializer); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, anchorPointerTextureInitializer); + glBufferData(GL_PIXEL_UNPACK_BUFFER, totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW); + + data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); + memset(data, 0x00, totalPixels * sizeof(GLuint)); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + glGenBuffers(1, &atomicCounterBuffer); + glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer); + glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY); + + glGenBuffers(1, &fragmentBuffer); + glBindBuffer(GL_TEXTURE_BUFFER, fragmentBuffer); + glBufferData(GL_TEXTURE_BUFFER, MAX_LAYERS*totalPixels*sizeof(GLfloat)*4, NULL, GL_DYNAMIC_COPY); + + glGenTextures(1, &fragmentTexture); + glBindTexture(GL_TEXTURE_BUFFER, fragmentTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, fragmentBuffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + + glBindImageTexture(1, fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); + + // ============================ + // SHADERS + // ============================ + resolveShader = nullptr; + using ghoul::opengl::ShaderObject; + using ghoul::opengl::ProgramObject; + ShaderObject* vs + = new ShaderObject(ShaderObject::ShaderType::ShaderTypeVertex, + absPath("${SHADERS}/ABuffer/abufferResolveVertex.glsl"), "Vertex"); + ShaderObject* fs + = new ShaderObject(ShaderObject::ShaderType::ShaderTypeFragment, + absPath("${SHADERS}/ABuffer/abufferResolveFragment.glsl"), "Fragment"); + + resolveShader = new ProgramObject; + resolveShader->attachObject(vs); + resolveShader->attachObject(fs); + + if (!resolveShader->compileShaderObjects()) { + LERROR("Could not compile shader"); + return false; + } + if (!resolveShader->linkProgramObject()){ + LERROR("Could not link shader"); + return false; + } + + // ============================ + // GEOMETRY (quad) + // ============================ + const GLfloat size = 1.0f; + const GLfloat vertex_data[] = { // square of two triangles (sigh) + // x y z w s t + -size, -size, 0.0f, 1.0f, + size, size, 0.0f, 1.0f, + -size, size, 0.0f, 1.0f, + -size, -size, 0.0f, 1.0f, + size, -size, 0.0f, 1.0f, + size, size, 0.0f, 1.0f, + }; + GLuint vertexPositionBuffer; + glGenVertexArrays(1, &_screenQuad); // generate array + glBindVertexArray(_screenQuad); // bind array + glGenBuffers(1, &vertexPositionBuffer); // generate buffer + glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(0); + return true; } void ABufferSingleLinked::clear() { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, anchorPointerTextureInitializer); + glBindTexture(GL_TEXTURE_2D, anchorPointerTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + static const GLuint zero = 1; + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer); + glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(zero), &zero); + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0); } void ABufferSingleLinked::preRender() { + // Bind head-pointer image for read-write + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer); + glBindImageTexture(0, anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); + glBindImageTexture(1, fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); } void ABufferSingleLinked::postRender() { - + resolveShader->activate(); + //resolveShader->setUniform("SCREEN_WIDTH", width); + //resolveShader->setUniform("SCREEN_HEIGHT", height); + glBindVertexArray(_screenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + resolveShader->deactivate(); } } // openspace \ No newline at end of file diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 86691afd84..5d9380a1d2 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -34,6 +34,8 @@ #include +#include + namespace { const std::string _loggerCat = "RenderEngine"; } @@ -42,6 +44,7 @@ namespace openspace { RenderEngine::RenderEngine() : _mainCamera(nullptr) , _sceneGraph(nullptr) + , _abuffer(nullptr) { } @@ -61,6 +64,8 @@ bool RenderEngine::initialize() //if (sgct::Engine::instance()->isMaster()) OsEng.interactionHandler().setCamera(_mainCamera); + _abuffer = new ABufferSingleLinked(); + return true; } @@ -132,6 +137,8 @@ bool RenderEngine::initializeGL() _mainCamera->setMaxFov(maxFov); } + _abuffer->initialize(); + // successful init return true; } @@ -163,8 +170,11 @@ void RenderEngine::render() sgct::Engine::instance()->getActiveModelViewProjectionMatrix() * view); // render the scene starting from the root node + _abuffer->clear(); + _abuffer->preRender(); _sceneGraph->render(_mainCamera); - + _abuffer->postRender(); +/* // Print some useful information on the master viewport if (sgct::Engine::instance()->isMaster()) { // Apple usually has retina screens @@ -200,6 +210,7 @@ void RenderEngine::render() sgct_text::FontManager::instance()->getFont("SGCTFont", FONT_SIZE), FONT_SIZE, FONT_SIZE * 2, "Scaling: (%.10f, %.2f)", scaling[0], scaling[1]); } + */ } SceneGraph* RenderEngine::sceneGraph() From 281104805cbd8738a0b67c7952de7a08e46631e4 Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Thu, 29 May 2014 16:04:27 -0400 Subject: [PATCH 006/113] Is now a bi-directional fieldline tracer using Runge-Kutta 4th order instead of a forward-only tracer using Euler --- include/openspace/util/kameleonwrapper.h | 15 +- src/rendering/renderablevolume.cpp | 23 ++- src/util/kameleonwrapper.cpp | 240 ++++++++++++----------- 3 files changed, 152 insertions(+), 126 deletions(-) diff --git a/include/openspace/util/kameleonwrapper.h b/include/openspace/util/kameleonwrapper.h index e52172b214..513448b03d 100644 --- a/include/openspace/util/kameleonwrapper.h +++ b/include/openspace/util/kameleonwrapper.h @@ -43,6 +43,11 @@ public: BATSRUS // Magnetosphere }; + enum TraceDirection { + FORWARD = 1, + BACK = -1 + }; + KameleonWrapper(const std::string& filename, Model model); ~KameleonWrapper(); float* getUniformSampledValues(const std::string& var, glm::size3_t outDimensions); @@ -53,6 +58,9 @@ public: const std::string& zVar, glm::size3_t outDimensions, std::vector seedPoints); private: + void traceCartesianFieldlines(const std::string& xVar, const std::string& yVar, + const std::string& zVar, glm::size3_t outDimensions, + std::vector seedPoints, TraceDirection direction, float* data); void getGridVariables(std::string& x, std::string& y, std::string& z); void progressBar(int current, int end); @@ -60,7 +68,12 @@ private: Model _type; ccmc::Interpolator* _interpolator; - int _lastiProgress; // for progressbar + // Model parameters + float _xMin, _xMax, _yMin, _yMax, _zMin, _zMax; + std::string _xCoordVar, _yCoordVar, _zCoordVar; + + // For progressbar + int _lastiProgress; }; } // namespace openspace diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index 6645357612..ba4581cf23 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -163,20 +163,23 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath // Seed 'em all std::vector seedPoints; - for (int z = -20; z <= 20; z+=20) { - for (int y = -20; y <= 20; y+=20) - seedPoints.push_back(glm::vec3(-10.0, (float)y, (float)z)); + for (int z = -5; z <= 5; z+=5) { + for (int y = -5; y <= 5; y+=5) + seedPoints.push_back(glm::vec3(5.0, (float)y, (float)z)); } float* fieldlinesData = kw.getFieldLines(xVariable, yVariable, zVariable, dimensions, seedPoints); - float* rhoData = kw.getUniformSampledValues("rho", dimensions); +// float* rhoData = kw.getUniformSampledValues("rho", dimensions); +// +// // Combine fieldlines with rhoData, clamp to [0,1] +// float* data = new float[dimensions.x*dimensions.y*dimensions.z]; +// for (int i = 0; i < dimensions.x*dimensions.y*dimensions.z; ++i) +// data[i] = std::min(fieldlinesData[i]+rhoData[i], 1.0f); +// +// delete fieldlinesData; +// delete rhoData; - // Combine fieldlines with rhoData, clamp to [0,1] - float* data = new float[dimensions.x*dimensions.y*dimensions.z]; - for (int i = 0; i < dimensions.x*dimensions.y*dimensions.z; ++i) - data[i] = std::min(fieldlinesData[i]+rhoData[i], 1.0f); - - return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); + return new ghoul::opengl::Texture(fieldlinesData, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); } } else { diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 60d2ea6aa4..e360301a4b 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -60,7 +60,25 @@ KameleonWrapper::KameleonWrapper(const std::string& filename, Model model): _typ default: LERROR("No valid model type provided!"); } - _lastiProgress = -1; // for progressbar + + getGridVariables(_xCoordVar, _yCoordVar, _zCoordVar); + LDEBUG("Using coordinate system variables: " << _xCoordVar << ", " << _yCoordVar << ", " << _zCoordVar); + + _xMin = _model->getVariableAttribute(_xCoordVar, "actual_min").getAttributeFloat(); + _xMax = _model->getVariableAttribute(_xCoordVar, "actual_max").getAttributeFloat(); + _yMin = _model->getVariableAttribute(_yCoordVar, "actual_min").getAttributeFloat(); + _yMax = _model->getVariableAttribute(_yCoordVar, "actual_max").getAttributeFloat(); + _zMin = _model->getVariableAttribute(_zCoordVar, "actual_min").getAttributeFloat(); + _zMax = _model->getVariableAttribute(_zCoordVar, "actual_max").getAttributeFloat(); + + LDEBUG(_xCoordVar << "Min: " << _xMin); + LDEBUG(_xCoordVar << "Max: " << _xMax); + LDEBUG(_yCoordVar << "Min: " << _yMin); + LDEBUG(_yCoordVar << "Max: " << _yMax); + LDEBUG(_zCoordVar << "Min: " << _zMin); + LDEBUG(_zCoordVar << "Max: " << _zMax); + + _lastiProgress = -1; // For progressbar } KameleonWrapper::~KameleonWrapper() { @@ -77,29 +95,13 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz int size = outDimensions.x*outDimensions.y*outDimensions.z; float* data = new float[size]; - std::string v_x, v_y, v_z; - getGridVariables(v_x, v_y, v_z); - LDEBUG("Using coordinate system variables: " << v_x << ", " << v_y << ", " << v_z); - - float xMin = _model->getVariableAttribute(v_x, "actual_min").getAttributeFloat(); - float xMax = _model->getVariableAttribute(v_x, "actual_max").getAttributeFloat(); - float yMin = _model->getVariableAttribute(v_y, "actual_min").getAttributeFloat(); - float yMax = _model->getVariableAttribute(v_y, "actual_max").getAttributeFloat(); - float zMin = _model->getVariableAttribute(v_z, "actual_min").getAttributeFloat(); - float zMax = _model->getVariableAttribute(v_z, "actual_max").getAttributeFloat(); float varMin = _model->getVariableAttribute(var, "actual_min").getAttributeFloat(); float varMax = _model->getVariableAttribute(var, "actual_max").getAttributeFloat(); - float stepX = (xMax-xMin)/(static_cast(outDimensions.x)); - float stepY = (yMax-yMin)/(static_cast(outDimensions.y)); - float stepZ = (zMax-zMin)/(static_cast(outDimensions.z)); + float stepX = (_xMax-_xMin)/(static_cast(outDimensions.x)); + float stepY = (_yMax-_yMin)/(static_cast(outDimensions.y)); + float stepZ = (_zMax-_zMin)/(static_cast(outDimensions.z)); - LDEBUG(v_x << "Min: " << xMin); - LDEBUG(v_x << "Max: " << xMax); - LDEBUG(v_y << "Min: " << yMin); - LDEBUG(v_y << "Max: " << yMax); - LDEBUG(v_z << "Min: " << zMin); - LDEBUG(v_z << "Max: " << zMax); LDEBUG(var << "Min: " << varMin); LDEBUG(var << "Max: " << varMax); @@ -112,9 +114,9 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz int index = x + y*outDimensions.x + z*outDimensions.x*outDimensions.y; if(_type == Model::BATSRUS) { - float xPos = xMin + stepX*x; - float yPos = yMin + stepY*y; - float zPos = zMin + stepZ*z; + float xPos = _xMin + stepX*x; + float yPos = _yMin + stepY*y; + float zPos = _zMin + stepZ*z; // get interpolated data value for (xPos, yPos, zPos) float value = _interpolator->interpolate(var, xPos, yPos, zPos); @@ -133,18 +135,18 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz float phiNorm = 2.0*M_PI*(float)z/(float)(outDimensions.z-1); // Go to physical coordinates before sampling - float rPh = xMin + rNorm*(xMax-xMin); + float rPh = _xMin + rNorm*(_xMax-_xMin); float thetaPh = thetaNorm; // phi range needs to be mapped to the slightly different model // range to avoid gaps in the data Subtract a small term to // avoid rounding errors when comparing to phiMax. - float phiPh = zMin + phiNorm/(2.0*M_PI)*(zMax-zMin-0.000001); + float phiPh = _zMin + phiNorm/(2.0*M_PI)*(_zMax-_zMin-0.000001); float varValue = 0.f; // See if sample point is inside domain - if (rPh < xMin || rPh > xMax || thetaPh < yMin || - thetaPh > yMax || phiPh < zMin || phiPh > zMax) { - if (phiPh > zMax) { + if (rPh < _xMin || rPh > _xMax || thetaPh < _yMin || + thetaPh > _yMax || phiPh < _zMin || phiPh > _zMax) { + if (phiPh > _zMax) { std::cout << "Warning: There might be a gap in the data\n"; } // Leave values at zero if outside domain @@ -182,20 +184,6 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c int size = channels*outDimensions.x*outDimensions.y*outDimensions.z; float* data = new float[size]; -// memset(data, 0.0, sizeof(data)); - - - - std::string v_x, v_y, v_z; - getGridVariables(v_x, v_y, v_z); - LDEBUG("Using coordinate system variables: " << v_x << ", " << v_y << ", " << v_z); - - float xMin = _model->getVariableAttribute(v_x, "actual_min").getAttributeFloat(); - float xMax = _model->getVariableAttribute(v_x, "actual_max").getAttributeFloat(); - float yMin = _model->getVariableAttribute(v_y, "actual_min").getAttributeFloat(); - float yMax = _model->getVariableAttribute(v_y, "actual_max").getAttributeFloat(); - float zMin = _model->getVariableAttribute(v_z, "actual_min").getAttributeFloat(); - float zMax = _model->getVariableAttribute(v_z, "actual_max").getAttributeFloat(); float varXMin = _model->getVariableAttribute(xVar, "actual_min").getAttributeFloat(); float varXMax = _model->getVariableAttribute(xVar, "actual_max").getAttributeFloat(); float varYMin = _model->getVariableAttribute(yVar, "actual_min").getAttributeFloat(); @@ -203,16 +191,10 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c float varZMin = _model->getVariableAttribute(zVar, "actual_min").getAttributeFloat(); float varZMax = _model->getVariableAttribute(zVar, "actual_max").getAttributeFloat(); - float stepX = (xMax-xMin)/(static_cast(outDimensions.x)); - float stepY = (yMax-yMin)/(static_cast(outDimensions.y)); - float stepZ = (zMax-zMin)/(static_cast(outDimensions.z)); + float stepX = (_xMax-_xMin)/(static_cast(outDimensions.x)); + float stepY = (_yMax-_yMin)/(static_cast(outDimensions.y)); + float stepZ = (_zMax-_zMin)/(static_cast(outDimensions.z)); - LDEBUG(v_x << "Min: " << xMin); - LDEBUG(v_x << "Max: " << xMax); - LDEBUG(v_y << "Min: " << yMin); - LDEBUG(v_y << "Max: " << yMax); - LDEBUG(v_z << "Min: " << zMin); - LDEBUG(v_z << "Max: " << zMax); LDEBUG(xVar << "Min: " << varXMin); LDEBUG(xVar << "Max: " << varXMax); LDEBUG(yVar << "Min: " << varYMin); @@ -229,9 +211,9 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c int index = x*channels + y*channels*outDimensions.x + z*channels*outDimensions.x*outDimensions.y; if(_type == Model::BATSRUS) { - float xPos = xMin + stepX*x; - float yPos = yMin + stepY*y; - float zPos = zMin + stepZ*z; + float xPos = _xMin + stepX*x; + float yPos = _yMin + stepY*y; + float zPos = _zMin + stepZ*z; // get interpolated data value for (xPos, yPos, zPos) float xValue = _interpolator->interpolate(xVar, xPos, yPos, zPos); @@ -255,6 +237,95 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c return data; } +float* KameleonWrapper::getFieldLines(const std::string& xVar, + const std::string& yVar, const std::string& zVar, + glm::size3_t outDimensions, std::vector seedPoints) { + assert(_model && _interpolator); + assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0); + assert(_type == Model::ENLIL || _type == Model::BATSRUS); + LINFO("Creating " << seedPoints.size() << " fieldlines from variables " << xVar << " " << yVar << " " << zVar); + + int size = outDimensions.x*outDimensions.y*outDimensions.z; + float* data = new float[size]; + + if (_type == Model::BATSRUS) { + // Bi-directional tracing of fieldlines + traceCartesianFieldlines(xVar, yVar, zVar, outDimensions, seedPoints, TraceDirection::FORWARD, data); + traceCartesianFieldlines(xVar, yVar, zVar, outDimensions, seedPoints, TraceDirection::BACK, data); + } else { + LERROR("Fieldlines are only supported for BATSRUS model"); + } + + return data; +} + +void KameleonWrapper::traceCartesianFieldlines(const std::string& xVar, + const std::string& yVar, const std::string& zVar, + glm::size3_t outDimensions, std::vector seedPoints, + TraceDirection direction, float* data) { + + int highNumber = 100000; + glm::vec3 pos, k1, k2, k3, k4; + + float stepSize = 2.0; + float stepX = stepSize*(_xMax-_xMin)/(static_cast(outDimensions.x)); + float stepY = stepSize*(_yMax-_yMin)/(static_cast(outDimensions.y)); + float stepZ = stepSize*(_zMax-_zMin)/(static_cast(outDimensions.z)); + + for (int i = 0; i < seedPoints.size(); ++i) { + progressBar(i, seedPoints.size()); + pos = seedPoints.at(i); + int avoidInfLoopPlz = 0; + while (pos.x < _xMax && pos.x > _xMin && + pos.y < _yMax && pos.y > _yMin && + pos.z < _zMax && pos.z > _zMin) { + + // Save position + int vPosX = std::floor(outDimensions.x*(pos.x-_xMin)/(_xMax-_xMin)); + int vPosY = std::floor(outDimensions.y*(pos.y-_yMin)/(_yMax-_yMin)); + int vPosZ = std::floor(outDimensions.z*(pos.z-_zMin)/(_zMax-_zMin)); + int index = vPosX + vPosY*outDimensions.x + vPosZ*outDimensions.x*outDimensions.y; + data[index] = 1.0; + + // Calculate the next position + // Euler +// dir.x = _interpolator->interpolate(xVar, pos.x, pos.y, pos.z); +// dir.y = _interpolator->interpolate(yVar, pos.x, pos.y, pos.z); +// dir.z = _interpolator->interpolate(zVar, pos.x, pos.y, pos.z); +// dir = (float)direction*glm::normalize(dir); +// pos = glm::vec3(stepX*dir.x+pos.x, stepY*dir.y+pos.y, stepZ*dir.z+pos.z); + + // Runge-Kutta 4th order + k1.x = _interpolator->interpolate(xVar, pos.x, pos.y, pos.z); + k1.y = _interpolator->interpolate(yVar, pos.x, pos.y, pos.z); + k1.z = _interpolator->interpolate(zVar, pos.x, pos.y, pos.z); + k1 = (float)direction*glm::normalize(k1); + k2.x = _interpolator->interpolate(xVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); + k2.y = _interpolator->interpolate(yVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); + k2.z = _interpolator->interpolate(zVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); + k2 = (float)direction*glm::normalize(k2); + k3.x = _interpolator->interpolate(xVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); + k3.y = _interpolator->interpolate(yVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); + k3.z = _interpolator->interpolate(zVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); + k3 = (float)direction*glm::normalize(k3); + k4.x = _interpolator->interpolate(xVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); + k4.y = _interpolator->interpolate(yVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); + k4.z = _interpolator->interpolate(zVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); + k4 = (float)direction*glm::normalize(k4); + pos.x = pos.x + (stepX/6.0)*(k1.x + 2.0*k2.x + 2.0*k3.x + k4.x); + pos.y = pos.y + (stepY/6.0)*(k1.y + 2.0*k2.y + 2.0*k3.y + k4.y); + pos.z = pos.z + (stepZ/6.0)*(k1.z + 2.0*k2.z + 2.0*k3.z + k4.z); + + ++avoidInfLoopPlz; + + if (avoidInfLoopPlz > highNumber) { + LDEBUG("Inf loop averted"); + break; + } + } + } +} + void KameleonWrapper::getGridVariables(std::string& x, std::string& y, std::string& z) { // get the grid system string std::string gridSystem = _model->getGlobalAttribute("grid_system_1").getAttributeString(); @@ -280,67 +351,6 @@ void KameleonWrapper::getGridVariables(std::string& x, std::string& y, std::stri z = tokens.at(2); } -float* KameleonWrapper::getFieldLines(const std::string& xVar, - const std::string& yVar, const std::string& zVar, - glm::size3_t outDimensions, std::vector seedPoints) { - assert(_model && _interpolator); - assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0); - assert(_type == Model::ENLIL || _type == Model::BATSRUS); - LINFO("Creating " << seedPoints.size() << " fieldlines from variables " << xVar << " " << yVar << " " << zVar); - - std::string v_x, v_y, v_z; - getGridVariables(v_x, v_y, v_z); - LDEBUG("Using coordinate system variables: " << v_x << ", " << v_y << ", " << v_z); - - float xMin = _model->getVariableAttribute(v_x, "actual_min").getAttributeFloat(); - float xMax = _model->getVariableAttribute(v_x, "actual_max").getAttributeFloat(); - float yMin = _model->getVariableAttribute(v_y, "actual_min").getAttributeFloat(); - float yMax = _model->getVariableAttribute(v_y, "actual_max").getAttributeFloat(); - float zMin = _model->getVariableAttribute(v_z, "actual_min").getAttributeFloat(); - float zMax = _model->getVariableAttribute(v_z, "actual_max").getAttributeFloat(); - - float stepSize = 0.001; - float stepX = stepSize*(xMax-xMin)/(static_cast(outDimensions.x)); - float stepY = stepSize*(yMax-yMin)/(static_cast(outDimensions.y)); - float stepZ = stepSize*(zMax-zMin)/(static_cast(outDimensions.z)); - - int size = outDimensions.x*outDimensions.y*outDimensions.z; - float* data = new float[size]; - glm::vec3 dir, pos; - - int highNumber = 100000; - - for (int i = 0; i < seedPoints.size(); ++i) { - progressBar(i, seedPoints.size()); - pos = seedPoints.at(i); - int avoidInfLoopPlz = 0; - while (pos.x < xMax && pos.x > xMin && - pos.y < yMax && pos.y > yMin && - pos.z < zMax && pos.z > zMin) { - - // Save position - int vPosX = std::floor(outDimensions.x*(pos.x-xMin)/(xMax-xMin)); - int vPosY = std::floor(outDimensions.y*(pos.y-yMin)/(yMax-yMin)); - int vPosZ = std::floor(outDimensions.z*(pos.z-zMin)/(zMax-zMin)); - int index = vPosX + vPosY*outDimensions.x + vPosZ*outDimensions.x*outDimensions.y; - data[index] = 1.0; - - // Calculate the next position - dir.x = _interpolator->interpolate(xVar, pos.x, pos.y, pos.z); - dir.y = _interpolator->interpolate(yVar, pos.x, pos.y, pos.z); - dir.z = _interpolator->interpolate(zVar, pos.x, pos.y, pos.z); - pos = glm::vec3(stepX*dir.x+pos.x, stepY*dir.y+pos.y, stepZ*dir.z+pos.z); - ++avoidInfLoopPlz; - - if (avoidInfLoopPlz > highNumber) { - LDEBUG("Inf loop averted"); - break; - } - } - } - return data; -} - void KameleonWrapper::progressBar(int current, int end) { float progress = static_cast(current) / static_cast(end-1); int iprogress = static_cast(progress*100.0f); From d2ccf6cdfb3ada755e9a63a569dba1e310290d8a Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Mon, 2 Jun 2014 13:35:17 -0400 Subject: [PATCH 007/113] Intermediate ABuffer with ABufferStruct_t --- shaders/ABuffer/abufferAddToBuffer.hglsl | 9 ++ shaders/ABuffer/abufferResolveFragment.glsl | 38 ++------- shaders/ABuffer/abufferSort.hglsl | 32 ++++++++ shaders/ABuffer/abufferStruct.hglsl | 91 +++++++++++++++++++++ shaders/pscstandard_fs.glsl | 16 +++- src/rendering/renderengine.cpp | 6 +- 6 files changed, 155 insertions(+), 37 deletions(-) create mode 100644 shaders/ABuffer/abufferAddToBuffer.hglsl create mode 100644 shaders/ABuffer/abufferSort.hglsl create mode 100644 shaders/ABuffer/abufferStruct.hglsl diff --git a/shaders/ABuffer/abufferAddToBuffer.hglsl b/shaders/ABuffer/abufferAddToBuffer.hglsl new file mode 100644 index 0000000000..c2421ba3f3 --- /dev/null +++ b/shaders/ABuffer/abufferAddToBuffer.hglsl @@ -0,0 +1,9 @@ + + +void addToBuffer(ABufferStruct_t frag) { + + uint index = atomicCounterIncrement(atomicCounterBuffer); + uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); + _next_(frag,old_head); + imageStore(fragmentTexture, int(index), _uvec4_(frag)); +} \ No newline at end of file diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index d0b46b2968..a849b99b18 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -13,41 +13,13 @@ uniform int SCREEN_HEIGHT; in vec2 texCoord; out vec4 color; +#include "abufferStruct.hglsl" #define MAX_FRAGMENTS 16 -uvec4 fragments[MAX_FRAGMENTS]; +ABufferStruct_t fragments[MAX_FRAGMENTS]; -int build_local_fragments_list() { - uint current; - int frag_count = 0; +#include "abufferSort.hglsl" - current = imageLoad(anchorPointerTexture, ivec2(gl_FragCoord.xy)).x; - - while(current != 0 && frag_count < MAX_FRAGMENTS) { - uvec4 item = imageLoad(fragmentTexture, int(current)); - current = item.x; - - fragments[frag_count] = item; - - frag_count++; - } - - return frag_count; -} - -void sort_fragments_list(uint frag_count) { - uint i,j; - uvec4 tmp; - - // INSERTION SORT - for(i = 1; i < frag_count; ++i) { - tmp = fragments[i]; - for(j = i; j > 0 && tmp.z > fragments[j-1].z; --j) { - fragments[j] = fragments[j-1]; - } - fragments[j] = tmp; - } -} vec4 blend(vec4 current_color, vec4 new_color) { return mix(current_color, new_color, new_color.a); @@ -57,8 +29,8 @@ vec4 calculate_final_color(uint frag_count) { vec4 final_color = vec4(0); for(uint i = 0; i < frag_count; i++) { - uvec4 item = fragments[i]; - vec4 frag_color = unpackUnorm4x8(item.y); + ABufferStruct_t item = fragments[i]; + vec4 frag_color = _col_(item); final_color = blend(final_color, frag_color); } diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl new file mode 100644 index 0000000000..df61c45353 --- /dev/null +++ b/shaders/ABuffer/abufferSort.hglsl @@ -0,0 +1,32 @@ + +int build_local_fragments_list() { + uint current; + int frag_count = 0; + + current = imageLoad(anchorPointerTexture, ivec2(gl_FragCoord.xy)).x; + + while(current != 0 && frag_count < MAX_FRAGMENTS) { + ABufferStruct_t item = _ABufferStruct_t_(imageLoad(fragmentTexture, int(current))); + current = _next_(item); + + fragments[frag_count] = item; + + frag_count++; + } + + return frag_count; +} + +void sort_fragments_list(uint frag_count) { + uint i,j; + ABufferStruct_t tmp; + + // INSERTION SORT + for(i = 1; i < frag_count; ++i) { + tmp = fragments[i]; + for(j = i; j > 0 && _z_(tmp) > _z_(fragments[j-1]); --j) { + fragments[j] = fragments[j-1]; + } + fragments[j] = tmp; + } +} diff --git a/shaders/ABuffer/abufferStruct.hglsl b/shaders/ABuffer/abufferStruct.hglsl new file mode 100644 index 0000000000..5e343e5176 --- /dev/null +++ b/shaders/ABuffer/abufferStruct.hglsl @@ -0,0 +1,91 @@ +#ifndef ABUFFERSTRUCT_H_HGLSL +#define ABUFFERSTRUCT_H_HGLSL + + +//======================================================= +// ABufferStruct_t declaration +//======================================================= +struct ABufferStruct_t { + uint z; // the depth value + uint id; // bits 0-28 next, bits 29-32 type + uint color; // packed rgba + uint type; // packed position +}; + +//======================================================= +// Bitwise operations +//======================================================= +const uint mask_1 = 1; +const uint mask_8 = 255; +const uint mask_16 = 65535; +const uint mask_24 = 16777215; +const uint mask_29 = 536870911; +const uint mask_30 = 1073741823; +const uint mask_31 = 2147483647; +const uint mask_32 = 4294967295; +const uint mask_id = mask_16; +const uint shift_id = 0; +const uint mask_type = mask_24 - mask_16; +const uint shift_type = 16; +void bitinsert_u(inout uint pack, uint val, uint mask, uint shift) { + pack &= ~mask; + pack |= (val << shift) & mask; +} +uint bitextract_u(in uint pack, uint mask, uint shift) { + return (pack >> shift) & (mask >> shift); +} +void bitinsert_i(inout int pack, int val, uint mask, uint shift) { + pack &= int( ~mask ); + pack |= int( (uint(val) << shift) & mask ); +} +int bitextract_i(in int pack, uint mask, uint shift) { + return int( (uint(pack) >> shift) & (mask >> shift) ); +} + + +//======================================================= +// Access functions +//======================================================= +float _z_(ABufferStruct_t frag) { + return uintBitsToFloat(frag.z); +} +void _z_(inout ABufferStruct_t frag, float z) { + frag.z = floatBitsToUint(z); +} + +uint _next_(ABufferStruct_t frag) { + return frag.id; +} +void _next_(inout ABufferStruct_t frag, uint id) { + frag.id = id; +} + +vec4 _col_(ABufferStruct_t frag) { + return unpackUnorm4x8(frag.color); +} +void _col_(inout ABufferStruct_t frag, vec4 color) { + frag.color = packUnorm4x8(color); +} + +uint _type_(ABufferStruct_t frag) { + return frag.type; +} +void _type_(inout ABufferStruct_t frag, uint type) { + frag.type = type;; +} + +/* +_id_ +_type_ +uint _type_(ABufferStruct_t frag) { + return frag +} +*/ + +ABufferStruct_t _ABufferStruct_t_(uvec4 frag) { + return ABufferStruct_t(frag.x, frag.y, frag.z, frag.w); +}; +uvec4 _uvec4_(ABufferStruct_t frag) { + return uvec4(frag.z, frag.id, frag.color, frag.type); +}; +#endif \ No newline at end of file diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index eb95f757ba..c35b40e5f4 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -31,6 +31,10 @@ out vec4 diffuse; const float k = 10.0; +#include "ABuffer/abufferStruct.hglsl" +#include "ABuffer/abufferAddToBuffer.hglsl" + + vec4 psc_normlization(vec4 invec) { float xymax = max(invec.x,invec.y); @@ -106,7 +110,7 @@ void main() //gl_FragDepth = 0.5; // color - diffuse = texture(texture1, vs_st); + diffuse = texture(texture1, vs_st); //diffuse = vec4(vs_position.z,0.0, 0.0, 1.0); // diffuse = vec4(vs_position.xyz * pow(10, vs_position.w), 1.0); //diffuse = vec4(vs_st, 0.0, 1.0); @@ -114,6 +118,14 @@ void main() //diffuse = vec4(depth*5,0.0, 0.0, 1.0); //diffuse = vec4(vs_position.w,0.0, 0.0, 1.0); //diffuse = vec4(1.0,0.0,0.0,1.0); + + ABufferStruct_t frag; + _col_(frag, diffuse); + _z_(frag, depth); + _type_(frag, 0); + addToBuffer(frag); + + /* uint index = atomicCounterIncrement(atomicCounterBuffer); uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); uvec4 item; @@ -122,6 +134,6 @@ void main() item.z = floatBitsToUint(gl_FragCoord.z / gl_FragCoord.w); item.w = 0; imageStore(fragmentTexture, int(index), item); - +*/ discard; } \ No newline at end of file diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 5d9380a1d2..da40fe000f 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -157,8 +157,10 @@ void RenderEngine::postSynchronizationPreDraw() void RenderEngine::render() { // SGCT resets certain settings - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); + //glEnable(GL_DEPTH_TEST); + //glEnable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); // setup the camera for the current frame const glm::vec3 eyePosition From 67778209d214ed6b58dcd0096dcd8c3dfe575720 Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Mon, 2 Jun 2014 14:22:45 -0400 Subject: [PATCH 008/113] Fieldline work. Fixed VolumeRenderableGL --- .../openspace/rendering/renderablevolumegl.h | 25 +--- openspace-data | 2 +- src/rendering/renderablevolumeexpert.cpp | 2 +- src/rendering/renderablevolumegl.cpp | 128 ++++++------------ 4 files changed, 47 insertions(+), 110 deletions(-) diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index 6cca3f458f..b6b261ebe7 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -27,6 +27,7 @@ // open space includes #include +#include // ghoul includes #include @@ -35,24 +36,16 @@ #include #include -#define SGCT_WINDOWS_INCLUDE -#include - #ifdef __APPLE__ #include #else #include #endif -namespace sgct_utils { - class SGCTBox; -} - namespace openspace { class RenderableVolumeGL: public RenderableVolume { public: - // constructors & destructor RenderableVolumeGL(const ghoul::Dictionary& dictionary); ~RenderableVolumeGL(); @@ -64,18 +57,15 @@ public: virtual void update(); private: - - + ghoul::Dictionary _hintsDictionary; std::string _filename; - ghoul::RawVolumeReader::ReadHints _hints; float _stepSize; - ghoul::opengl::FramebufferObject* _fbo; - ghoul::opengl::Texture* _backTexture; - ghoul::opengl::Texture* _frontTexture; ghoul::opengl::Texture* _volume; - ghoul::opengl::ProgramObject *_fboProgram, *_twopassProgram; - sgct_utils::SGCTBox* _boundingBox; + ghoul::opengl::ProgramObject* _twopassProgram; GLuint _screenQuad; + + VolumeRaycasterBox* _colorBoxRenderer; + glm::vec3 _boxScaling; std::mutex* _shaderMutex; @@ -84,9 +74,8 @@ private: bool _programUpdateOnSave; void safeShaderCompilation(); - }; } // namespace openspace -#endif \ No newline at end of file +#endif diff --git a/openspace-data b/openspace-data index 42865a2858..4af0a41ba1 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 42865a28580b0195ef7b82b175df8ef9f73f46bc +Subproject commit 4af0a41ba1d5dd1afade5d95495485b7de58c072 diff --git a/src/rendering/renderablevolumeexpert.cpp b/src/rendering/renderablevolumeexpert.cpp index 1785c58857..d1d33c9e51 100644 --- a/src/rendering/renderablevolumeexpert.cpp +++ b/src/rendering/renderablevolumeexpert.cpp @@ -210,7 +210,7 @@ RenderableVolumeExpert::RenderableVolumeExpert(const ghoul::Dictionary& dictiona } } - setBoundingSphere(PowerScaledScalar::CreatePSS(_boxScaling.length())); + setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling))); } RenderableVolumeExpert::~RenderableVolumeExpert() { diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index 0d1ae60475..52739394b1 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -24,15 +24,13 @@ // open space includes #include - #include +#include #include #include #include -#include - #include namespace { @@ -42,8 +40,7 @@ namespace { namespace openspace { RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): - RenderableVolume(dictionary), - _backTexture(nullptr), _frontTexture(nullptr), _screenQuad(0), + RenderableVolume(dictionary), _screenQuad(0), _boxScaling(1.0, 1.0, 1.0), _programUpdateOnSave(false) { _shaderMutex = new std::mutex; @@ -54,13 +51,11 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): _filename = findPath(_filename); } } - + LDEBUG("filename: " << _filename); - ghoul::Dictionary hintsDictionary; if(dictionary.hasKey("Hints")) - dictionary.getValue("Hints", hintsDictionary); - _hints = readHints(hintsDictionary); + dictionary.getValue("Hints", _hintsDictionary); std::string vshaderpath = ""; std::string fshaderpath = ""; @@ -87,35 +82,43 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): _twopassProgram->attachObject(vertexShader); _twopassProgram->attachObject(fragmentShader); } - - } if(dictionary.hasKey("UpdateOnSave")) { dictionary.getValue("UpdateOnSave", _programUpdateOnSave); } + double tempValue; + if(dictionary.hasKey("BoxScaling.1") && dictionary.getValue("BoxScaling.1", tempValue)) { + if(tempValue > 0.0) + _boxScaling[0] = tempValue; + } + if(dictionary.hasKey("BoxScaling.2") && dictionary.getValue("BoxScaling.2", tempValue)) { + if(tempValue > 0.0) + _boxScaling[1] = tempValue; + } + if(dictionary.hasKey("BoxScaling.3") && dictionary.getValue("BoxScaling.3", tempValue)) { + if(tempValue > 0.0) + _boxScaling[2] = tempValue; + } + + _colorBoxRenderer = new VolumeRaycasterBox(); + setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling))); } RenderableVolumeGL::~RenderableVolumeGL() { deinitialize(); - if(_fbo) - delete _fbo; - if(_backTexture) - delete _backTexture; - if(_frontTexture) - delete _frontTexture; if(_volume) delete _volume; - if(_boundingBox) - delete _boundingBox; + if(_colorBoxRenderer) + delete _colorBoxRenderer; } bool RenderableVolumeGL::initialize() { assert(_filename != ""); // ------ VOLUME READING ---------------- - ghoul::RawVolumeReader rawReader(_hints); - _volume = rawReader.read(_filename); + _volume = loadVolume(_filename, _hintsDictionary); + _volume->uploadTexture(); // ------ SETUP GEOMETRY ---------------- const GLfloat size = 1.0f; @@ -149,12 +152,9 @@ bool RenderableVolumeGL::initialize() { glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer glBindVertexArray(0); //unbind array - _boundingBox = new sgct_utils::SGCTBox(1.0f, sgct_utils::SGCTBox::Regular); + _colorBoxRenderer->initialize(); // ------ SETUP SHADERS ----------------- - // TODO error control or better design pattern - OsEng.ref().configurationManager().getValue("RaycastProgram", _fboProgram); - auto privateCallback = [this](const ghoul::filesystem::File& file) { safeShaderCompilation(); }; @@ -168,76 +168,27 @@ bool RenderableVolumeGL::initialize() { _twopassProgram->setUniform("texBack", 0); _twopassProgram->setUniform("texFront", 1); _twopassProgram->setUniform("texVolume", 2); - //OsEng.ref().configurationManager().getValue("TwoPassProgram", _twopassProgram); - - // ------ SETUP FBO --------------------- - _fbo = new ghoul::opengl::FramebufferObject(); - _fbo->activate(); - - int x = sgct::Engine::instance()->getActiveXResolution(); - int y = sgct::Engine::instance()->getActiveYResolution(); - _backTexture = new ghoul::opengl::Texture(glm::size3_t(x,y,1)); - _frontTexture = new ghoul::opengl::Texture(glm::size3_t(x,y,1)); - _backTexture->uploadTexture(); - _frontTexture->uploadTexture(); - _fbo->attachTexture(_backTexture, GL_COLOR_ATTACHMENT0); - _fbo->attachTexture(_frontTexture, GL_COLOR_ATTACHMENT1); - - _fbo->deactivate(); - return true; } bool RenderableVolumeGL::deinitialize() { - - return true; } void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { - - float speed = 50.0f; - float time = sgct::Engine::getTime(); - glm::mat4 transform = camera->viewProjectionMatrix(); - - double factor = pow(10.0,thisPosition[3]); - transform = glm::translate(transform, glm::vec3(thisPosition[0]*factor, thisPosition[1]*factor, thisPosition[2]*factor)); - transform = glm::rotate(transform, time*speed, glm::vec3(0.0f, 1.0f, 0.0f)); - - _stepSize = 0.01f; + + glm::mat4 transform = camera->viewProjectionMatrix(); + glm::mat4 camTransform = camera->viewRotationMatrix(); + psc relative = thisPosition-camera->position(); + + transform = transform*camTransform; + transform = glm::translate(transform, relative.vec3()); + transform = glm::scale(transform, _boxScaling); + + _colorBoxRenderer->render(transform); - // ------ DRAW TO FBO ------------------- - GLuint sgctFBO = ghoul::opengl::FramebufferObject::getActiveObject(); // Save SGCTs main FBO - _fbo->activate(); - _fboProgram->activate(); - _fboProgram->setUniform("modelViewProjection", transform); - - // Draw backface - glDrawBuffer(GL_COLOR_ATTACHMENT0); - glClearColor(0.2f, 0.2f, 0.2f, 0); - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - _boundingBox->draw(); - glDisable(GL_CULL_FACE); - - // Draw frontface - glDrawBuffer(GL_COLOR_ATTACHMENT1); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(0.2f, 0.2f, 0.2f, 0); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - _boundingBox->draw(); - glDisable(GL_CULL_FACE); - - _fboProgram->deactivate(); - _fbo->deactivate(); - - // ------ DRAW TO SCREEN ---------------- - glBindFramebuffer(GL_FRAMEBUFFER, sgctFBO); // Re-bind SGCTs main FBO - // Draw screenquad glClearColor(0.2f, 0.2f, 0.2f, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -248,9 +199,9 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { // Set textures glActiveTexture(GL_TEXTURE0); - _backTexture->bind(); + _colorBoxRenderer->backFace()->bind(); glActiveTexture(GL_TEXTURE1); - _frontTexture->bind(); + _colorBoxRenderer->frontFace()->bind(); glActiveTexture(GL_TEXTURE2); _volume->bind(); @@ -260,7 +211,6 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { _twopassProgram->deactivate(); _shaderMutex->unlock(); - } void RenderableVolumeGL::update() { @@ -277,7 +227,5 @@ void RenderableVolumeGL::safeShaderCompilation() { _twopassProgram->setUniform("texVolume", 2); _shaderMutex->unlock(); } - - -} // namespace openspace \ No newline at end of file +} // namespace openspace From 2c3f6396ec0c39437574da0d7c304771cb7fb8c8 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Mon, 2 Jun 2014 14:51:56 -0400 Subject: [PATCH 009/113] Intermedieate ABuffer, cleaning up shader loading --- shaders/ABuffer/abufferStruct.hglsl | 11 +- shaders/pscvolume_fs.glsl | 139 ++++++++++++++++++++++++ shaders/pscvolume_vs.glsl | 115 ++++++++++++++++++++ src/scenegraph/scenegraph.cpp | 157 ++++++++++++++++------------ 4 files changed, 346 insertions(+), 76 deletions(-) create mode 100644 shaders/pscvolume_fs.glsl create mode 100644 shaders/pscvolume_vs.glsl diff --git a/shaders/ABuffer/abufferStruct.hglsl b/shaders/ABuffer/abufferStruct.hglsl index 5e343e5176..83f212b7fe 100644 --- a/shaders/ABuffer/abufferStruct.hglsl +++ b/shaders/ABuffer/abufferStruct.hglsl @@ -9,7 +9,7 @@ struct ABufferStruct_t { uint z; // the depth value uint id; // bits 0-28 next, bits 29-32 type uint color; // packed rgba - uint type; // packed position + uint type; // packed position }; //======================================================= @@ -42,7 +42,6 @@ int bitextract_i(in int pack, uint mask, uint shift) { return int( (uint(pack) >> shift) & (mask >> shift) ); } - //======================================================= // Access functions //======================================================= @@ -74,14 +73,6 @@ void _type_(inout ABufferStruct_t frag, uint type) { frag.type = type;; } -/* -_id_ -_type_ -uint _type_(ABufferStruct_t frag) { - return frag -} -*/ - ABufferStruct_t _ABufferStruct_t_(uvec4 frag) { return ABufferStruct_t(frag.x, frag.y, frag.z, frag.w); }; diff --git a/shaders/pscvolume_fs.glsl b/shaders/pscvolume_fs.glsl new file mode 100644 index 0000000000..c35b40e5f4 --- /dev/null +++ b/shaders/pscvolume_fs.glsl @@ -0,0 +1,139 @@ +/** +Copyright (C) 2012-2014 Jonas Strandstedt + +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 430 + +layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; +layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; +layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; + +uniform mat4 ViewProjection; +uniform mat4 ModelTransform; +uniform vec4 campos; +uniform vec4 objpos; +uniform float time; +uniform sampler2D texture1; + +vec3 light_position = vec3(40.0, 20.0, 100.0); + +in vec2 vs_st; +//in vec3 vs_stp; +in vec4 vs_normal; +in vec4 vs_position; + +out vec4 diffuse; + +const float k = 10.0; + +#include "ABuffer/abufferStruct.hglsl" +#include "ABuffer/abufferAddToBuffer.hglsl" + + +vec4 psc_normlization(vec4 invec) { + + float xymax = max(invec.x,invec.y); + + if(invec.z > 0.0f || invec.z < 0.0f) { + return invec / abs(invec.z); + } else if (xymax != 0.0f) { + return invec / xymax; + } else { + return invec / -.0; + } +} + +void main() +{ + + // Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD! + float s_far = 27.0; //= gl_DepthRange.far; // 40 + float s_farcutoff = 12.0; + float s_nearcutoff = 7.0; + float s_near = 0.0f;// gl_DepthRange.near; // 0.1 + float depth; + + // the value can be normalized to 1 + + vec4 p = vs_position; + if(vs_position.w <= 0.5) { + //depth = abs(vs_position.z * pow(10, vs_position.w)) / pow(k,s_far); + depth = (vs_position.w+log(abs(vs_position.z)))/pow(k, vs_position.w); + } else if(vs_position.w < 3.0) { + depth = vs_position.w+log(abs(vs_position.z))/pow(k, vs_position.w); + } else { + depth = vs_position.w+log(abs(vs_position.z)); + } + + + // DEBUG + float depth_orig = depth; + float x = 0.0f; + float cutoffs = 0.0; + float orig_z = vs_position.z; + + // calculate a normalized depth [0.0 1.0] + if((depth > s_near && depth <= s_nearcutoff) || (depth > s_farcutoff && depth < s_far)) { + + // completely linear interpolation [s_near .. depth .. s_far] + depth = (depth - s_near) / (s_far - s_near); + + } else if(depth > s_nearcutoff && depth < s_farcutoff) { + + // DEBUG + cutoffs = 1.0; + + // interpolate [10^s_nearcutoff .. 10^depth .. 10^s_farcutoff] + // calculate between 0..1 where the depth is + x = (pow(10,depth) - pow(10, s_nearcutoff)) / (pow(10,s_farcutoff) - pow(10, s_nearcutoff)); + + // remap the depth to the 0..1 depth buffer + depth = s_nearcutoff + x * (s_farcutoff - s_nearcutoff); + depth = (depth - s_near) / (s_far - s_near); + + } else { + // where am I? + // do I need to be discarded? + // discard; + } + + + + + // set the depth + gl_FragDepth = depth; + //gl_FragDepth = 0.5; + + // color + diffuse = texture(texture1, vs_st); + //diffuse = vec4(vs_position.z,0.0, 0.0, 1.0); + // diffuse = vec4(vs_position.xyz * pow(10, vs_position.w), 1.0); + //diffuse = vec4(vs_st, 0.0, 1.0); + //diffuse = vec4(1.0,1.0, 0.0, 1.0); + //diffuse = vec4(depth*5,0.0, 0.0, 1.0); + //diffuse = vec4(vs_position.w,0.0, 0.0, 1.0); + //diffuse = vec4(1.0,0.0,0.0,1.0); + + ABufferStruct_t frag; + _col_(frag, diffuse); + _z_(frag, depth); + _type_(frag, 0); + addToBuffer(frag); + + /* + uint index = atomicCounterIncrement(atomicCounterBuffer); + uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); + uvec4 item; + item.x = old_head; + item.y = packUnorm4x8(diffuse); + item.z = floatBitsToUint(gl_FragCoord.z / gl_FragCoord.w); + item.w = 0; + imageStore(fragmentTexture, int(index), item); +*/ + discard; +} \ No newline at end of file diff --git a/shaders/pscvolume_vs.glsl b/shaders/pscvolume_vs.glsl new file mode 100644 index 0000000000..5a612667a2 --- /dev/null +++ b/shaders/pscvolume_vs.glsl @@ -0,0 +1,115 @@ +/** +Copyright (C) 2012-2014 Jonas Strandstedt + +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 430 + +uniform mat4 ViewProjection; +uniform mat4 ModelTransform; +uniform vec4 campos; +uniform mat4 camrot; +uniform vec2 scaling; +uniform vec4 objpos; +uniform float time; +uniform sampler2D texture1; +uniform sampler2D texture2; +uniform sampler2D texture3; +uniform float TessLevel; +uniform bool Wireframe; +uniform bool Lightsource; +uniform bool UseTexture; + +layout(location = 0) in vec4 in_position; +//in vec3 in_position; +layout(location = 1) in vec2 in_st; +layout(location = 2) in vec3 in_normal; + +out vec2 vs_st; +out vec3 vs_stp; +out vec4 vs_normal; +out vec4 vs_position; + +const float k = 10.0; +const float dgr_to_rad = 0.0174532925; + +vec4 psc_addition(vec4 v1, vec4 v2) { + float ds = v2.w - v1.w; + if(ds >= 0) { + float p = pow(k,-ds); + return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w); + } else { + float p = pow(k,ds); + return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w); + } +} + +vec4 psc_to_meter(vec4 v1, vec2 v2) { + float factor = v2.x * pow(k,v2.y + v1.w); + return vec4(v1.xyz * factor, 1.0); +} + +vec4 psc_scaling(vec4 v1, vec2 v2) { + float ds = v2.y - v1.w; + if(ds >= 0) { + return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y); + } else { + return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w); + } +} + +void main() +{ + // set variables + vs_st = in_st; + //vs_stp = in_position.xyz; + vs_normal = normalize(ModelTransform * vec4(in_normal,0)); + + // fetch model and view translation + //vec4 vertex_translate = ModelTransform[3]; + + // rotate and scale vertex with model transform and add the translation + vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz; + //vec4 lvp = ModelTransform * in_position; + + // PSC addition; local vertex position and the object power scaled world position + vs_position = psc_addition(vec4(local_vertex_pos,in_position.w),objpos); + //vs_position = psc_addition(lvp,objpos); + + // PSC addition; rotated and viewscaled vertex and the cmaeras negative position + vs_position = psc_addition(vs_position,vec4(-campos.xyz,campos.w)); + + // rotate the camera + local_vertex_pos = mat3(camrot) * vs_position.xyz; + vs_position = vec4(local_vertex_pos, vs_position.w); + //vs_position = camrot* vs_position; + + // rescales the scene to fit inside the view frustum + // is set from the main program, but these are decent values + // scaling = vec2(1.0, -8.0); + + // project using the rescaled coordinates, + //vec4 vs_position_rescaled = psc_scaling(vs_position, scaling); + vec4 vs_position_rescaled = psc_to_meter(vs_position, scaling); + //vs_position = vs_position_rescaled; + + + // project the position to view space + gl_Position = ViewProjection * vs_position_rescaled; +} \ No newline at end of file diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 17a55e4158..e0ab7ba128 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -51,18 +51,18 @@ const std::string _loggerCat = "SceneGraph"; const std::string _rootNodeName = "Root"; const std::string _moduleExtension = ".mod"; +void printTree(openspace::SceneGraphNode* node, std::string pre = "") +{ + LDEBUGC("Tree", pre << node->nodeName()); + const std::vector& children = node->children(); + for (openspace::SceneGraphNode* child : children) + printTree(child, pre + " "); +} + } namespace openspace { -void printTree(SceneGraphNode* node, std::string pre = "") -{ - LDEBUGC("Tree", pre << node->nodeName()); - const std::vector& children = node->children(); - for (SceneGraphNode* child : children) - printTree(child, pre + " "); -} - SceneGraph::SceneGraph() : _focus("Root") , _position("Root") @@ -82,69 +82,94 @@ bool SceneGraph::initialize() using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; - ProgramObject* po = nullptr; - if (OsEng.ref().configurationManager().hasKey("pscShader") - && OsEng.ref().configurationManager().getValue("pscShader", po)) { - LWARNING("pscShader already in ConfigurationManager, deleting."); - delete po; - po = nullptr; + // pscstandard + { + std::string programObjectName = "pscstandard"; + ProgramObject* po = new ProgramObject(programObjectName); + ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, + absPath("${SHADERS}/pscstandard_vs.glsl"), + programObjectName + "Vertex"); + ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, + absPath("${SHADERS}/pscstandard_fs.glsl"), + programObjectName + "Fragment"); + po->attachObject(vs); + po->attachObject(fs); + if ( ! po->compileShaderObjects()) return false; + if ( ! po->linkProgramObject()) return false; + OsEng.ref().configurationManager().setValue("pscShader", po); } - ShaderObject* powerscale_vs - = new ShaderObject(ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/pscstandard_vs.glsl"), "PS Vertex"); - ShaderObject* powerscale_fs - = new ShaderObject(ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/pscstandard_fs.glsl"), "PS Fragment"); + // pscVolume + { + std::string programObjectName = "pscVolume"; + ProgramObject* po = new ProgramObject(programObjectName); + ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, + absPath("${SHADERS}/pscvolume_vs.glsl"), + programObjectName + "Vertex"); + ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, + absPath("${SHADERS}/pscvolume_fs.glsl"), + programObjectName + "Fragment"); + po->attachObject(vs); + po->attachObject(fs); + if ( ! po->compileShaderObjects()) return false; + if ( ! po->linkProgramObject()) return false; + OsEng.ref().configurationManager().setValue("pscVolume", po); + } - po = new ProgramObject; - po->attachObject(powerscale_vs); - po->attachObject(powerscale_fs); + // RaycastProgram + { + std::string programObjectName = "RaycastProgram"; + ProgramObject* po = new ProgramObject(programObjectName); + ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, + absPath("${SHADERS}/exitpoints.vert"), + programObjectName + "Vertex"); + ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, + absPath("${SHADERS}/exitpoints.frag"), + programObjectName + "Fragment"); + po->attachObject(vs); + po->attachObject(fs); + if ( ! po->compileShaderObjects()) return false; + if ( ! po->linkProgramObject()) return false; + OsEng.ref().configurationManager().setValue("RaycastProgram", po); + } - if (!po->compileShaderObjects()) - return false; - if (!po->linkProgramObject()) - return false; + // TwoPassProgram + { + std::string programObjectName = "TwoPassProgram"; + ProgramObject* po = new ProgramObject(programObjectName); + ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, + absPath("${SHADERS}/twopassraycaster.vert"), + programObjectName + "Vertex"); + ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, + absPath("${SHADERS}/twopassraycaster.frag"), + programObjectName + "Fragment"); + po->attachObject(vs); + po->attachObject(fs); + if ( ! po->compileShaderObjects()) return false; + if ( ! po->linkProgramObject()) return false; + po->setUniform("texBack", 0); + po->setUniform("texFront", 1); + po->setUniform("texVolume", 2); + OsEng.ref().configurationManager().setValue("TwoPassProgram", po); + } - OsEng.ref().configurationManager().setValue("pscShader", po); - - ProgramObject* _fboProgram = new ProgramObject("RaycastProgram"); - ShaderObject* vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex, - absPath("${SHADERS}/exitpoints.vert")); - ShaderObject* fragmentShader = new ShaderObject( - ShaderObject::ShaderTypeFragment, absPath("${SHADERS}/exitpoints.frag")); - _fboProgram->attachObject(vertexShader); - _fboProgram->attachObject(fragmentShader); - _fboProgram->compileShaderObjects(); - _fboProgram->linkProgramObject(); - - ProgramObject* _twopassProgram = new ProgramObject("TwoPassProgram"); - vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex, - absPath("${SHADERS}/twopassraycaster.vert")); - fragmentShader = new ShaderObject(ShaderObject::ShaderTypeFragment, - absPath("${SHADERS}/twopassraycaster.frag")); - _twopassProgram->attachObject(vertexShader); - _twopassProgram->attachObject(fragmentShader); - _twopassProgram->compileShaderObjects(); - _twopassProgram->linkProgramObject(); - _twopassProgram->setUniform("texBack", 0); - _twopassProgram->setUniform("texFront", 1); - _twopassProgram->setUniform("texVolume", 2); - - ProgramObject* quad = new ProgramObject("Quad"); - ShaderObject* quadv = new ShaderObject(ShaderObject::ShaderTypeVertex, - absPath("${SHADERS}/quadVert.glsl")); - ShaderObject* quadf = new ShaderObject(ShaderObject::ShaderTypeFragment, - absPath("${SHADERS}/quadFrag.glsl")); - quad->attachObject(quadv); - quad->attachObject(quadf); - quad->compileShaderObjects(); - quad->linkProgramObject(); - quad->setUniform("quadTex", 0); - - OsEng.ref().configurationManager().setValue("RaycastProgram", _fboProgram); - OsEng.ref().configurationManager().setValue("TwoPassProgram", _twopassProgram); - OsEng.ref().configurationManager().setValue("Quad", quad); + // Quad + { + std::string programObjectName = "Quad"; + ProgramObject* po = new ProgramObject(programObjectName); + ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, + absPath("${SHADERS}/quadVert.glsl"), + programObjectName + "Vertex"); + ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, + absPath("${SHADERS}/quadFrag.glsl"), + programObjectName + "Fragment"); + po->attachObject(vs); + po->attachObject(fs); + if ( ! po->compileShaderObjects()) return false; + if ( ! po->linkProgramObject()) return false; + po->setUniform("quadTex", 0); + OsEng.ref().configurationManager().setValue("Quad", po); + } // Initialize all nodes for (auto node : _nodes) { From b18e8ab713aeb0da46f3c9b0f4fa633097392fa1 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Mon, 2 Jun 2014 15:15:36 -0400 Subject: [PATCH 010/113] Pointing to new ghoul changes --- ext/ghoul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ghoul b/ext/ghoul index 6448e0542c..1f478d7956 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 6448e0542ce84a8dcadd025b16c8a28f30b2cc90 +Subproject commit 1f478d79565c3c7b4343ab5ca1cd3cb30c491173 From 0a539caf41b67b6dba5a583217ef6c9995810adc Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Mon, 2 Jun 2014 15:52:15 -0400 Subject: [PATCH 011/113] Cleanup and removal of pscVolume shaders --- shaders/ABuffer/abufferAddToBuffer.hglsl | 3 + shaders/exitpoints.frag | 13 ++- shaders/exitpoints.vert | 2 +- shaders/pscstandard_fs.glsl | 4 - shaders/pscvolume_fs.glsl | 139 ----------------------- shaders/pscvolume_vs.glsl | 115 ------------------- src/scenegraph/scenegraph.cpp | 17 --- 7 files changed, 16 insertions(+), 277 deletions(-) delete mode 100644 shaders/pscvolume_fs.glsl delete mode 100644 shaders/pscvolume_vs.glsl diff --git a/shaders/ABuffer/abufferAddToBuffer.hglsl b/shaders/ABuffer/abufferAddToBuffer.hglsl index c2421ba3f3..2127bf8715 100644 --- a/shaders/ABuffer/abufferAddToBuffer.hglsl +++ b/shaders/ABuffer/abufferAddToBuffer.hglsl @@ -1,4 +1,7 @@ +layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; +layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; +layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; void addToBuffer(ABufferStruct_t frag) { diff --git a/shaders/exitpoints.frag b/shaders/exitpoints.frag index 1ea86ecb38..47280749fa 100644 --- a/shaders/exitpoints.frag +++ b/shaders/exitpoints.frag @@ -1,8 +1,19 @@ -#version 400 core +#version 430 core in vec3 vPosition; out vec4 fragColor; + +#include "ABuffer/abufferStruct.hglsl" +#include "ABuffer/abufferAddToBuffer.hglsl" void main() { fragColor = vec4(vPosition+0.5, 1.0); + + ABufferStruct_t frag; + _col_(frag, fragColor); + _z_(frag, gl_FragDepth); + _type_(frag, 0); + addToBuffer(frag); + + discard; } \ No newline at end of file diff --git a/shaders/exitpoints.vert b/shaders/exitpoints.vert index 0668ef5618..cc0dd3624d 100644 --- a/shaders/exitpoints.vert +++ b/shaders/exitpoints.vert @@ -1,4 +1,4 @@ -#version 400 core +#version 430 core layout(location = 2) in vec3 vertPosition; uniform mat4 modelViewProjection; diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index c35b40e5f4..1d68f801fc 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -9,10 +9,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ #version 430 -layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; -layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; -layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; - uniform mat4 ViewProjection; uniform mat4 ModelTransform; uniform vec4 campos; diff --git a/shaders/pscvolume_fs.glsl b/shaders/pscvolume_fs.glsl deleted file mode 100644 index c35b40e5f4..0000000000 --- a/shaders/pscvolume_fs.glsl +++ /dev/null @@ -1,139 +0,0 @@ -/** -Copyright (C) 2012-2014 Jonas Strandstedt - -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 430 - -layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; -layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; -layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; - -uniform mat4 ViewProjection; -uniform mat4 ModelTransform; -uniform vec4 campos; -uniform vec4 objpos; -uniform float time; -uniform sampler2D texture1; - -vec3 light_position = vec3(40.0, 20.0, 100.0); - -in vec2 vs_st; -//in vec3 vs_stp; -in vec4 vs_normal; -in vec4 vs_position; - -out vec4 diffuse; - -const float k = 10.0; - -#include "ABuffer/abufferStruct.hglsl" -#include "ABuffer/abufferAddToBuffer.hglsl" - - -vec4 psc_normlization(vec4 invec) { - - float xymax = max(invec.x,invec.y); - - if(invec.z > 0.0f || invec.z < 0.0f) { - return invec / abs(invec.z); - } else if (xymax != 0.0f) { - return invec / xymax; - } else { - return invec / -.0; - } -} - -void main() -{ - - // Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD! - float s_far = 27.0; //= gl_DepthRange.far; // 40 - float s_farcutoff = 12.0; - float s_nearcutoff = 7.0; - float s_near = 0.0f;// gl_DepthRange.near; // 0.1 - float depth; - - // the value can be normalized to 1 - - vec4 p = vs_position; - if(vs_position.w <= 0.5) { - //depth = abs(vs_position.z * pow(10, vs_position.w)) / pow(k,s_far); - depth = (vs_position.w+log(abs(vs_position.z)))/pow(k, vs_position.w); - } else if(vs_position.w < 3.0) { - depth = vs_position.w+log(abs(vs_position.z))/pow(k, vs_position.w); - } else { - depth = vs_position.w+log(abs(vs_position.z)); - } - - - // DEBUG - float depth_orig = depth; - float x = 0.0f; - float cutoffs = 0.0; - float orig_z = vs_position.z; - - // calculate a normalized depth [0.0 1.0] - if((depth > s_near && depth <= s_nearcutoff) || (depth > s_farcutoff && depth < s_far)) { - - // completely linear interpolation [s_near .. depth .. s_far] - depth = (depth - s_near) / (s_far - s_near); - - } else if(depth > s_nearcutoff && depth < s_farcutoff) { - - // DEBUG - cutoffs = 1.0; - - // interpolate [10^s_nearcutoff .. 10^depth .. 10^s_farcutoff] - // calculate between 0..1 where the depth is - x = (pow(10,depth) - pow(10, s_nearcutoff)) / (pow(10,s_farcutoff) - pow(10, s_nearcutoff)); - - // remap the depth to the 0..1 depth buffer - depth = s_nearcutoff + x * (s_farcutoff - s_nearcutoff); - depth = (depth - s_near) / (s_far - s_near); - - } else { - // where am I? - // do I need to be discarded? - // discard; - } - - - - - // set the depth - gl_FragDepth = depth; - //gl_FragDepth = 0.5; - - // color - diffuse = texture(texture1, vs_st); - //diffuse = vec4(vs_position.z,0.0, 0.0, 1.0); - // diffuse = vec4(vs_position.xyz * pow(10, vs_position.w), 1.0); - //diffuse = vec4(vs_st, 0.0, 1.0); - //diffuse = vec4(1.0,1.0, 0.0, 1.0); - //diffuse = vec4(depth*5,0.0, 0.0, 1.0); - //diffuse = vec4(vs_position.w,0.0, 0.0, 1.0); - //diffuse = vec4(1.0,0.0,0.0,1.0); - - ABufferStruct_t frag; - _col_(frag, diffuse); - _z_(frag, depth); - _type_(frag, 0); - addToBuffer(frag); - - /* - uint index = atomicCounterIncrement(atomicCounterBuffer); - uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); - uvec4 item; - item.x = old_head; - item.y = packUnorm4x8(diffuse); - item.z = floatBitsToUint(gl_FragCoord.z / gl_FragCoord.w); - item.w = 0; - imageStore(fragmentTexture, int(index), item); -*/ - discard; -} \ No newline at end of file diff --git a/shaders/pscvolume_vs.glsl b/shaders/pscvolume_vs.glsl deleted file mode 100644 index 5a612667a2..0000000000 --- a/shaders/pscvolume_vs.glsl +++ /dev/null @@ -1,115 +0,0 @@ -/** -Copyright (C) 2012-2014 Jonas Strandstedt - -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 430 - -uniform mat4 ViewProjection; -uniform mat4 ModelTransform; -uniform vec4 campos; -uniform mat4 camrot; -uniform vec2 scaling; -uniform vec4 objpos; -uniform float time; -uniform sampler2D texture1; -uniform sampler2D texture2; -uniform sampler2D texture3; -uniform float TessLevel; -uniform bool Wireframe; -uniform bool Lightsource; -uniform bool UseTexture; - -layout(location = 0) in vec4 in_position; -//in vec3 in_position; -layout(location = 1) in vec2 in_st; -layout(location = 2) in vec3 in_normal; - -out vec2 vs_st; -out vec3 vs_stp; -out vec4 vs_normal; -out vec4 vs_position; - -const float k = 10.0; -const float dgr_to_rad = 0.0174532925; - -vec4 psc_addition(vec4 v1, vec4 v2) { - float ds = v2.w - v1.w; - if(ds >= 0) { - float p = pow(k,-ds); - return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w); - } else { - float p = pow(k,ds); - return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w); - } -} - -vec4 psc_to_meter(vec4 v1, vec2 v2) { - float factor = v2.x * pow(k,v2.y + v1.w); - return vec4(v1.xyz * factor, 1.0); -} - -vec4 psc_scaling(vec4 v1, vec2 v2) { - float ds = v2.y - v1.w; - if(ds >= 0) { - return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y); - } else { - return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w); - } -} - -void main() -{ - // set variables - vs_st = in_st; - //vs_stp = in_position.xyz; - vs_normal = normalize(ModelTransform * vec4(in_normal,0)); - - // fetch model and view translation - //vec4 vertex_translate = ModelTransform[3]; - - // rotate and scale vertex with model transform and add the translation - vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz; - //vec4 lvp = ModelTransform * in_position; - - // PSC addition; local vertex position and the object power scaled world position - vs_position = psc_addition(vec4(local_vertex_pos,in_position.w),objpos); - //vs_position = psc_addition(lvp,objpos); - - // PSC addition; rotated and viewscaled vertex and the cmaeras negative position - vs_position = psc_addition(vs_position,vec4(-campos.xyz,campos.w)); - - // rotate the camera - local_vertex_pos = mat3(camrot) * vs_position.xyz; - vs_position = vec4(local_vertex_pos, vs_position.w); - //vs_position = camrot* vs_position; - - // rescales the scene to fit inside the view frustum - // is set from the main program, but these are decent values - // scaling = vec2(1.0, -8.0); - - // project using the rescaled coordinates, - //vec4 vs_position_rescaled = psc_scaling(vs_position, scaling); - vec4 vs_position_rescaled = psc_to_meter(vs_position, scaling); - //vs_position = vs_position_rescaled; - - - // project the position to view space - gl_Position = ViewProjection * vs_position_rescaled; -} \ No newline at end of file diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index e0ab7ba128..75434d2a54 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -99,23 +99,6 @@ bool SceneGraph::initialize() OsEng.ref().configurationManager().setValue("pscShader", po); } - // pscVolume - { - std::string programObjectName = "pscVolume"; - ProgramObject* po = new ProgramObject(programObjectName); - ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/pscvolume_vs.glsl"), - programObjectName + "Vertex"); - ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/pscvolume_fs.glsl"), - programObjectName + "Fragment"); - po->attachObject(vs); - po->attachObject(fs); - if ( ! po->compileShaderObjects()) return false; - if ( ! po->linkProgramObject()) return false; - OsEng.ref().configurationManager().setValue("pscVolume", po); - } - // RaycastProgram { std::string programObjectName = "RaycastProgram"; From 08a8e2f3bb5568c647626b087415485930ecd1a7 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Tue, 3 Jun 2014 16:50:47 -0400 Subject: [PATCH 012/113] Intermediate ABuffer commit --- .../openspace/rendering/renderablevolumegl.h | 25 +--- include/openspace/scenegraph/scenegraphnode.h | 1 + shaders/ABuffer/abufferResolveFragment.glsl | 58 ++++++-- shaders/ABuffer/abufferSort.hglsl | 9 +- shaders/ABuffer/abufferStruct.hglsl | 39 ++++- shaders/exitpoints.frag | 6 +- shaders/pscstandard_fs.glsl | 2 +- shaders/pscstandard_vs.glsl | 2 +- src/rendering/renderablevolumegl.cpp | 133 ++++++------------ src/scenegraph/scenegraphnode.cpp | 20 ++- 10 files changed, 155 insertions(+), 140 deletions(-) diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index 6cca3f458f..b6b261ebe7 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -27,6 +27,7 @@ // open space includes #include +#include // ghoul includes #include @@ -35,24 +36,16 @@ #include #include -#define SGCT_WINDOWS_INCLUDE -#include - #ifdef __APPLE__ #include #else #include #endif -namespace sgct_utils { - class SGCTBox; -} - namespace openspace { class RenderableVolumeGL: public RenderableVolume { public: - // constructors & destructor RenderableVolumeGL(const ghoul::Dictionary& dictionary); ~RenderableVolumeGL(); @@ -64,18 +57,15 @@ public: virtual void update(); private: - - + ghoul::Dictionary _hintsDictionary; std::string _filename; - ghoul::RawVolumeReader::ReadHints _hints; float _stepSize; - ghoul::opengl::FramebufferObject* _fbo; - ghoul::opengl::Texture* _backTexture; - ghoul::opengl::Texture* _frontTexture; ghoul::opengl::Texture* _volume; - ghoul::opengl::ProgramObject *_fboProgram, *_twopassProgram; - sgct_utils::SGCTBox* _boundingBox; + ghoul::opengl::ProgramObject* _twopassProgram; GLuint _screenQuad; + + VolumeRaycasterBox* _colorBoxRenderer; + glm::vec3 _boxScaling; std::mutex* _shaderMutex; @@ -84,9 +74,8 @@ private: bool _programUpdateOnSave; void safeShaderCompilation(); - }; } // namespace openspace -#endif \ No newline at end of file +#endif diff --git a/include/openspace/scenegraph/scenegraphnode.h b/include/openspace/scenegraph/scenegraphnode.h index 2269d7d7cf..9a8b847d97 100644 --- a/include/openspace/scenegraph/scenegraphnode.h +++ b/include/openspace/scenegraph/scenegraphnode.h @@ -70,6 +70,7 @@ public: // bounding sphere PowerScaledScalar calculateBoundingSphere(); + PowerScaledScalar boundingSphere() const; SceneGraphNode* get(const std::string& name); diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index a849b99b18..3a8619d474 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -1,37 +1,64 @@ #version 430 -// texture bindings -layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; -layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; - -// atomic buffer bindings -layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; - // uniforms -uniform int SCREEN_WIDTH; -uniform int SCREEN_HEIGHT; in vec2 texCoord; out vec4 color; -#include "abufferStruct.hglsl" +// settings +#define ALPHA_LIMIT 0.51 #define MAX_FRAGMENTS 16 +#define MAX_VOLUMES 4 + +#include "abufferStruct.hglsl" ABufferStruct_t fragments[MAX_FRAGMENTS]; +vec3 volume_direction[MAX_VOLUMES]; +vec3 volume_position[MAX_VOLUMES]; + #include "abufferSort.hglsl" -vec4 blend(vec4 current_color, vec4 new_color) { - return mix(current_color, new_color, new_color.a); +vec4 blend(vec4 src, vec4 dst) { + vec4 o; + o.a = src.a + dst.a * (1.0f - src.a); + o.rgb = (src.rgb*src.a + dst.rgb*dst.a* (1.0f - src.a)); + return o; + //return mix(src, dst, dst.a*(1.0f - src.a)); +} + +vec3 direction(vec4 v1, vec4 v2) { + const float k = 10.0; + float ds = v2.w - v1.w; + if(ds >= 0) { + float p = pow(k,-ds); + return vec4(v1.x*p - v2.x, v1.y*p - v2.y, v1.z*p - v2.z, v2.w).xyz; + } else { + float p = pow(k,ds); + return vec4(v1.x - v2.x*p, v1.y - v2.y*p, v1.z - v2.z*p, v1.w).xyz; + } } vec4 calculate_final_color(uint frag_count) { + int currentVolumeBitmask = 0; vec4 final_color = vec4(0); - for(uint i = 0; i < frag_count; i++) { + for(uint i = 0; i < frag_count && final_color.a < ALPHA_LIMIT; i++) { ABufferStruct_t item = fragments[i]; vec4 frag_color = _col_(item); - final_color = blend(final_color, frag_color); + vec4 position = _pos_(item); + uint type = _type_(item); + + + if(currentVolumeBitmask != 0) { + currentVolumeBitmask = currentVolumeBitmask ^ (1 << type); + } + /* + if(_type_(item) == 1) +*/ + final_color = blend(final_color, frag_color); + //final_color = blend(frag_color, final_color); + } return final_color; @@ -43,6 +70,9 @@ void main() { color = vec4(texCoord,0.0,1.0); int frag_count = build_local_fragments_list(); sort_fragments_list(frag_count); + + + color = calculate_final_color(frag_count); //color = vec4(float(frag_count) / 5.0, 0.0, 0.0, 1.0); diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index df61c45353..4cdc8bf481 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -1,4 +1,11 @@ +// texture bindings +layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; +layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; + +// atomic buffer bindings +layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; + int build_local_fragments_list() { uint current; int frag_count = 0; @@ -24,7 +31,7 @@ void sort_fragments_list(uint frag_count) { // INSERTION SORT for(i = 1; i < frag_count; ++i) { tmp = fragments[i]; - for(j = i; j > 0 && _z_(tmp) > _z_(fragments[j-1]); --j) { + for(j = i; j > 0 && _z_(tmp) < _z_(fragments[j-1]); --j) { fragments[j] = fragments[j-1]; } fragments[j] = tmp; diff --git a/shaders/ABuffer/abufferStruct.hglsl b/shaders/ABuffer/abufferStruct.hglsl index 83f212b7fe..f220fbb02f 100644 --- a/shaders/ABuffer/abufferStruct.hglsl +++ b/shaders/ABuffer/abufferStruct.hglsl @@ -9,7 +9,7 @@ struct ABufferStruct_t { uint z; // the depth value uint id; // bits 0-28 next, bits 29-32 type uint color; // packed rgba - uint type; // packed position + uint position; // packed position }; //======================================================= @@ -27,6 +27,22 @@ const uint mask_id = mask_16; const uint shift_id = 0; const uint mask_type = mask_24 - mask_16; const uint shift_type = 16; +/* +const uint mask_zid_z = mask_24; +const uint shift_zid_z = 0; +const uint mask_zid_id = mask_29 - mask_24; +const uint shift_zid_id = 24; +const uint mask_zid_type = mask_31 - mask_29; +const uint shift_zid_type = 29; +const uint mask_zid_xxx = mask_32 - mask_31; +const uint shift_zid_xxx = 31; +*/ + +const uint mask_id_next = mask_29; +const uint shift_id_next = 0; +const uint mask_id_type = mask_32 - mask_29; +const uint shift_id_type = 29; + void bitinsert_u(inout uint pack, uint val, uint mask, uint shift) { pack &= ~mask; pack |= (val << shift) & mask; @@ -53,10 +69,19 @@ void _z_(inout ABufferStruct_t frag, float z) { } uint _next_(ABufferStruct_t frag) { - return frag.id; + return bitextract_u(frag.id, mask_id_next, shift_id_next); + //return frag.id; } void _next_(inout ABufferStruct_t frag, uint id) { - frag.id = id; + bitinsert_u(frag.id, id, mask_id_next, shift_id_next); + //frag.id = id; +} + +vec4 _pos_(ABufferStruct_t frag) { + return unpackUnorm4x8(frag.position); +} +void _pos_(inout ABufferStruct_t frag, vec4 position) { + frag.position = packUnorm4x8(position); } vec4 _col_(ABufferStruct_t frag) { @@ -67,16 +92,18 @@ void _col_(inout ABufferStruct_t frag, vec4 color) { } uint _type_(ABufferStruct_t frag) { - return frag.type; + return bitextract_u(frag.id, mask_id_type, shift_id_type); + //return frag.type; } void _type_(inout ABufferStruct_t frag, uint type) { - frag.type = type;; + bitinsert_u(frag.id, type, mask_id_type, shift_id_type); + //frag.type = type; } ABufferStruct_t _ABufferStruct_t_(uvec4 frag) { return ABufferStruct_t(frag.x, frag.y, frag.z, frag.w); }; uvec4 _uvec4_(ABufferStruct_t frag) { - return uvec4(frag.z, frag.id, frag.color, frag.type); + return uvec4(frag.z, frag.id, frag.color, frag.position); }; #endif \ No newline at end of file diff --git a/shaders/exitpoints.frag b/shaders/exitpoints.frag index 47280749fa..72041462b2 100644 --- a/shaders/exitpoints.frag +++ b/shaders/exitpoints.frag @@ -7,13 +7,13 @@ out vec4 fragColor; #include "ABuffer/abufferAddToBuffer.hglsl" void main() { - fragColor = vec4(vPosition+0.5, 1.0); + fragColor = vec4(vPosition+0.5, 0.3); ABufferStruct_t frag; _col_(frag, fragColor); _z_(frag, gl_FragDepth); - _type_(frag, 0); + _type_(frag, 1); addToBuffer(frag); - discard; + //discard; } \ No newline at end of file diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index 1d68f801fc..b5304ad234 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -117,7 +117,7 @@ void main() ABufferStruct_t frag; _col_(frag, diffuse); - _z_(frag, depth); + _z_(frag, gl_FragDepth); _type_(frag, 0); addToBuffer(frag); diff --git a/shaders/pscstandard_vs.glsl b/shaders/pscstandard_vs.glsl index 5a612667a2..be3ead04f7 100644 --- a/shaders/pscstandard_vs.glsl +++ b/shaders/pscstandard_vs.glsl @@ -107,7 +107,7 @@ void main() // project using the rescaled coordinates, //vec4 vs_position_rescaled = psc_scaling(vs_position, scaling); vec4 vs_position_rescaled = psc_to_meter(vs_position, scaling); - //vs_position = vs_position_rescaled; + vs_position = vs_position_rescaled; // project the position to view space diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index 0d1ae60475..9e3bdcbf43 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -24,15 +24,13 @@ // open space includes #include - #include +#include #include #include #include -#include - #include namespace { @@ -42,8 +40,7 @@ namespace { namespace openspace { RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): - RenderableVolume(dictionary), - _backTexture(nullptr), _frontTexture(nullptr), _screenQuad(0), + RenderableVolume(dictionary), _screenQuad(0), _boxScaling(1.0, 1.0, 1.0), _programUpdateOnSave(false) { _shaderMutex = new std::mutex; @@ -54,13 +51,11 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): _filename = findPath(_filename); } } - + LDEBUG("filename: " << _filename); - ghoul::Dictionary hintsDictionary; if(dictionary.hasKey("Hints")) - dictionary.getValue("Hints", hintsDictionary); - _hints = readHints(hintsDictionary); + dictionary.getValue("Hints", _hintsDictionary); std::string vshaderpath = ""; std::string fshaderpath = ""; @@ -87,35 +82,43 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): _twopassProgram->attachObject(vertexShader); _twopassProgram->attachObject(fragmentShader); } - - } if(dictionary.hasKey("UpdateOnSave")) { dictionary.getValue("UpdateOnSave", _programUpdateOnSave); } + double tempValue; + if(dictionary.hasKey("BoxScaling.1") && dictionary.getValue("BoxScaling.1", tempValue)) { + if(tempValue > 0.0) + _boxScaling[0] = tempValue; + } + if(dictionary.hasKey("BoxScaling.2") && dictionary.getValue("BoxScaling.2", tempValue)) { + if(tempValue > 0.0) + _boxScaling[1] = tempValue; + } + if(dictionary.hasKey("BoxScaling.3") && dictionary.getValue("BoxScaling.3", tempValue)) { + if(tempValue > 0.0) + _boxScaling[2] = tempValue; + } + + _colorBoxRenderer = new VolumeRaycasterBox(); + setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling))); } RenderableVolumeGL::~RenderableVolumeGL() { deinitialize(); - if(_fbo) - delete _fbo; - if(_backTexture) - delete _backTexture; - if(_frontTexture) - delete _frontTexture; if(_volume) delete _volume; - if(_boundingBox) - delete _boundingBox; + if(_colorBoxRenderer) + delete _colorBoxRenderer; } bool RenderableVolumeGL::initialize() { assert(_filename != ""); // ------ VOLUME READING ---------------- - ghoul::RawVolumeReader rawReader(_hints); - _volume = rawReader.read(_filename); + _volume = loadVolume(_filename, _hintsDictionary); + _volume->uploadTexture(); // ------ SETUP GEOMETRY ---------------- const GLfloat size = 1.0f; @@ -149,12 +152,9 @@ bool RenderableVolumeGL::initialize() { glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer glBindVertexArray(0); //unbind array - _boundingBox = new sgct_utils::SGCTBox(1.0f, sgct_utils::SGCTBox::Regular); + _colorBoxRenderer->initialize(); // ------ SETUP SHADERS ----------------- - // TODO error control or better design pattern - OsEng.ref().configurationManager().getValue("RaycastProgram", _fboProgram); - auto privateCallback = [this](const ghoul::filesystem::File& file) { safeShaderCompilation(); }; @@ -168,76 +168,27 @@ bool RenderableVolumeGL::initialize() { _twopassProgram->setUniform("texBack", 0); _twopassProgram->setUniform("texFront", 1); _twopassProgram->setUniform("texVolume", 2); - //OsEng.ref().configurationManager().getValue("TwoPassProgram", _twopassProgram); - - // ------ SETUP FBO --------------------- - _fbo = new ghoul::opengl::FramebufferObject(); - _fbo->activate(); - - int x = sgct::Engine::instance()->getActiveXResolution(); - int y = sgct::Engine::instance()->getActiveYResolution(); - _backTexture = new ghoul::opengl::Texture(glm::size3_t(x,y,1)); - _frontTexture = new ghoul::opengl::Texture(glm::size3_t(x,y,1)); - _backTexture->uploadTexture(); - _frontTexture->uploadTexture(); - _fbo->attachTexture(_backTexture, GL_COLOR_ATTACHMENT0); - _fbo->attachTexture(_frontTexture, GL_COLOR_ATTACHMENT1); - - _fbo->deactivate(); - return true; } bool RenderableVolumeGL::deinitialize() { - - return true; } void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { - - float speed = 50.0f; - float time = sgct::Engine::getTime(); - glm::mat4 transform = camera->viewProjectionMatrix(); - - double factor = pow(10.0,thisPosition[3]); - transform = glm::translate(transform, glm::vec3(thisPosition[0]*factor, thisPosition[1]*factor, thisPosition[2]*factor)); - transform = glm::rotate(transform, time*speed, glm::vec3(0.0f, 1.0f, 0.0f)); - - _stepSize = 0.01f; - - // ------ DRAW TO FBO ------------------- - GLuint sgctFBO = ghoul::opengl::FramebufferObject::getActiveObject(); // Save SGCTs main FBO - _fbo->activate(); - _fboProgram->activate(); - _fboProgram->setUniform("modelViewProjection", transform); - - // Draw backface - glDrawBuffer(GL_COLOR_ATTACHMENT0); - glClearColor(0.2f, 0.2f, 0.2f, 0); - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - _boundingBox->draw(); - glDisable(GL_CULL_FACE); - - // Draw frontface - glDrawBuffer(GL_COLOR_ATTACHMENT1); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(0.2f, 0.2f, 0.2f, 0); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - _boundingBox->draw(); - glDisable(GL_CULL_FACE); - - _fboProgram->deactivate(); - _fbo->deactivate(); - - // ------ DRAW TO SCREEN ---------------- - glBindFramebuffer(GL_FRAMEBUFFER, sgctFBO); // Re-bind SGCTs main FBO - + + glm::mat4 transform = camera->viewProjectionMatrix(); + glm::mat4 camTransform = camera->viewRotationMatrix(); + psc relative = thisPosition-camera->position(); + + transform = transform*camTransform; + transform = glm::translate(transform, relative.vec3()); + transform = glm::scale(transform, _boxScaling); + + _colorBoxRenderer->render(transform); + /* // Draw screenquad glClearColor(0.2f, 0.2f, 0.2f, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -248,9 +199,9 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { // Set textures glActiveTexture(GL_TEXTURE0); - _backTexture->bind(); + _colorBoxRenderer->backFace()->bind(); glActiveTexture(GL_TEXTURE1); - _frontTexture->bind(); + _colorBoxRenderer->frontFace()->bind(); glActiveTexture(GL_TEXTURE2); _volume->bind(); @@ -260,7 +211,7 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { _twopassProgram->deactivate(); _shaderMutex->unlock(); - + */ } void RenderableVolumeGL::update() { @@ -268,6 +219,7 @@ void RenderableVolumeGL::update() { } void RenderableVolumeGL::safeShaderCompilation() { + /* _shaderMutex->lock(); _twopassProgram->rebuildFromFile(); _twopassProgram->compileShaderObjects(); @@ -276,8 +228,7 @@ void RenderableVolumeGL::safeShaderCompilation() { _twopassProgram->setUniform("texFront", 1); _twopassProgram->setUniform("texVolume", 2); _shaderMutex->unlock(); + */ } - - -} // namespace openspace \ No newline at end of file +} // namespace openspace diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index b0b3e752df..b0e5f25616 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -181,6 +181,7 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) if (!sphereInsideFrustum(thisPosition, _boundingSphere, camera)) { // the node is completely outside of the camera view, stop evaluating this // node + //LFATAL(_nodeName << " is outside of frustum"); return; } } @@ -198,7 +199,7 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) // evaluate all the children, tail-recursive function(?) for (auto& child : _children) { - child->evaluate(camera, psc()); + child->evaluate(camera, thisPosition); } } @@ -290,13 +291,22 @@ PowerScaledScalar SceneGraphNode::calculateBoundingSphere() } } _boundingSphere += maxChild; - } else { // leaf + } - // if has a renderable, use that boundingsphere - if (_renderable) - _boundingSphere += _renderable->getBoundingSphere(); + // if has a renderable, use that boundingsphere + if (_renderable ) { + PowerScaledScalar renderableBS = _renderable->getBoundingSphere(); + if(renderableBS > _boundingSphere) + _boundingSphere = renderableBS; } + + LWARNING(_nodeName << ": " << _boundingSphere); + + return _boundingSphere; +} + +PowerScaledScalar SceneGraphNode::boundingSphere() const{ return _boundingSphere; } From 3373ffd10d784b38a63c64e42a9b6687b1b8ec6f Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Thu, 5 Jun 2014 10:12:42 -0400 Subject: [PATCH 013/113] Added renderablefieldlines class which renders fieldlines as geometry --- .../rendering/renderablefieldlines.h | 74 ++++++++ include/openspace/util/kameleonwrapper.h | 15 +- openspace-data | 2 +- src/rendering/renderablefieldlines.cpp | 170 ++++++++++++++++++ src/rendering/renderablevolume.cpp | 3 +- src/rendering/renderablevolumegl.cpp | 3 - src/util/factorymanager.cpp | 4 +- src/util/kameleonwrapper.cpp | 144 ++++++++------- 8 files changed, 344 insertions(+), 71 deletions(-) create mode 100644 include/openspace/rendering/renderablefieldlines.h create mode 100644 src/rendering/renderablefieldlines.cpp diff --git a/include/openspace/rendering/renderablefieldlines.h b/include/openspace/rendering/renderablefieldlines.h new file mode 100644 index 0000000000..a1546b52b6 --- /dev/null +++ b/include/openspace/rendering/renderablefieldlines.h @@ -0,0 +1,74 @@ +/***************************************************************************************** + * * + * 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 RENDERABLEFIELDLINES_H_ +#define RENDERABLEFIELDLINES_H_ + +// open space includes +#include + +// ghoul includes +#include +#include + +#ifdef __APPLE__ + #include +#else + #include +#endif + +namespace openspace { + +class RenderableFieldlines : public RenderableVolume { +public: + RenderableFieldlines(const ghoul::Dictionary& dictionary); + ~RenderableFieldlines(); + + bool initialize(); + bool deinitialize(); + + virtual void render(const Camera *camera, const psc& thisPosition); + virtual void update(); + +private: + ghoul::Dictionary _hintsDictionary; + std::string _filename; + + ghoul::opengl::ProgramObject* _fieldlinesProgram; + GLuint _VAO; + + std::mutex* _shaderMutex; + + ghoul::filesystem::File* _vertexSourceFile; + ghoul::filesystem::File* _fragmentSourceFile; + bool _programUpdateOnSave; + + void safeShaderCompilation(); + + std::vector _lineStart; + std::vector _lineCount; +}; + +} // namespace openspace +#endif // RENDERABLEFIELDLINES_H_ diff --git a/include/openspace/util/kameleonwrapper.h b/include/openspace/util/kameleonwrapper.h index 513448b03d..55bb1dbbca 100644 --- a/include/openspace/util/kameleonwrapper.h +++ b/include/openspace/util/kameleonwrapper.h @@ -25,7 +25,7 @@ #ifndef KAMELEONWRAPPER_H_ #define KAMELEONWRAPPER_H_ -#include +//#include #include namespace ccmc { @@ -54,13 +54,18 @@ public: float* getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions); - float* getFieldLines(const std::string& xVar, const std::string& yVar, + float* getVolumeFieldLines(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions, std::vector seedPoints); + std::vector > getFieldLines(const std::string& xVar, + const std::string& yVar, const std::string& zVar, + std::vector seedPoints); + private: - void traceCartesianFieldlines(const std::string& xVar, const std::string& yVar, - const std::string& zVar, glm::size3_t outDimensions, - std::vector seedPoints, TraceDirection direction, float* data); + std::vector traceCartesianFieldline(const std::string& xVar, + const std::string& yVar, const std::string& zVar, + glm::vec3 seedPoint, TraceDirection direction); + void getGridVariables(std::string& x, std::string& y, std::string& z); void progressBar(int current, int end); diff --git a/openspace-data b/openspace-data index 4af0a41ba1..8c9a21935d 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 4af0a41ba1d5dd1afade5d95495485b7de58c072 +Subproject commit 8c9a21935d4e1295857997664b0b7b297cce8dda diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp new file mode 100644 index 0000000000..203b07f740 --- /dev/null +++ b/src/rendering/renderablefieldlines.cpp @@ -0,0 +1,170 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include +#include +#include + +namespace { + std::string _loggerCat = "RenderableFieldlines"; +} + +namespace openspace { + +RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) : + RenderableVolume(dictionary), _VAO(0), _programUpdateOnSave(false) { + _shaderMutex = new std::mutex; + + _filename = ""; + if(dictionary.hasKey("Volume")) { + if(dictionary.getValue("Volume", _filename)) { + _filename = findPath(_filename); + } + } + + LDEBUG("filename: " << _filename); + + if(dictionary.hasKey("Hints")) + dictionary.getValue("Hints", _hintsDictionary); + + std::string vshaderpath = ""; + std::string fshaderpath = ""; + + if (dictionary.hasKey("Shaders")) { + ghoul::Dictionary shaderDictionary; + if(dictionary.getValue("Shaders", shaderDictionary)) { + if (shaderDictionary.hasKey("VertexShader")) { + shaderDictionary.getValue("VertexShader", vshaderpath); + } + if (shaderDictionary.hasKey("FragmentShader")) { + shaderDictionary.getValue("FragmentShader", fshaderpath); + } + + vshaderpath = findPath(vshaderpath); + fshaderpath = findPath(fshaderpath); + + _vertexSourceFile = new ghoul::filesystem::File(vshaderpath, false); + _fragmentSourceFile = new ghoul::filesystem::File(fshaderpath, false); + + _fieldlinesProgram = new ghoul::opengl::ProgramObject("FieldlinesProgram"); + ghoul::opengl::ShaderObject* vertexShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeVertex,vshaderpath); + ghoul::opengl::ShaderObject* fragmentShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeFragment,fshaderpath); + _fieldlinesProgram->attachObject(vertexShader); + _fieldlinesProgram->attachObject(fragmentShader); + } + } + + if(dictionary.hasKey("UpdateOnSave")) { + dictionary.getValue("UpdateOnSave", _programUpdateOnSave); + } + + setBoundingSphere(PowerScaledScalar::CreatePSS(5)); +} + +RenderableFieldlines::~RenderableFieldlines() { + +} + +bool RenderableFieldlines::initialize() { + assert(_filename != ""); + KameleonWrapper kameleon(_filename, KameleonWrapper::Model::BATSRUS); + std::vector seedPoints; + + for (int x = -3; x <= 3; x+=3) { + for (int y = -3; y <= 3; y+=3) { + for (int z = -3; z <= 3; z+=3) { + seedPoints.push_back(glm::vec3((float)x, (float)y, (float)z)); + } + } + } + + std::vector > fieldlines = kameleon.getFieldLines("bx", "by", "bz", seedPoints); + std::vector vertexData; + LDEBUG("Fieldlines.size() = " << fieldlines.size()); + + int prevEnd = 0; + + for (int i = 0; i < fieldlines.size(); i++) { + _lineStart.push_back(prevEnd); + _lineCount.push_back(fieldlines[i].size()); + prevEnd = prevEnd + fieldlines[i].size(); + + vertexData.insert( vertexData.end(), fieldlines[i].begin(), fieldlines[i].end()); + } + + GLuint vertexPositionBuffer; + glGenVertexArrays(1, &_VAO); // generate array + glBindVertexArray(_VAO); // bind array + glGenBuffers(1, &vertexPositionBuffer); // generate buffer + glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer + glBufferData(GL_ARRAY_BUFFER, vertexData.size()*sizeof(glm::vec3), &vertexData.front(), GL_STATIC_DRAW); + + // Vertex positions + GLuint vertexLocation = 0; + glEnableVertexAttribArray(vertexLocation); + glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), reinterpret_cast(0)); + + glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer + glBindVertexArray(0); //unbind array + + _fieldlinesProgram->compileShaderObjects(); + _fieldlinesProgram->linkProgramObject(); + + return true; +} + +bool RenderableFieldlines::deinitialize() { + return true; +} + +void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) { + glm::mat4 transform = camera->viewProjectionMatrix(); + glm::mat4 camTransform = camera->viewRotationMatrix(); + psc relative = thisPosition-camera->position(); + + transform = transform*camTransform; + transform = glm::translate(transform, relative.vec3()); + transform = glm::scale(transform, glm::vec3(0.1)); + + _shaderMutex->lock(); + _fieldlinesProgram->activate(); + _fieldlinesProgram->setUniform("modelViewProjection", transform); + + + glBindVertexArray(_VAO); + glMultiDrawArrays(GL_LINE_STRIP, &_lineStart[0], &_lineCount[0], _lineStart.size()); + glBindVertexArray(0); + + _fieldlinesProgram->deactivate(); + _shaderMutex->unlock(); +} + +void RenderableFieldlines::update() { +} + +void RenderableFieldlines::safeShaderCompilation() { +} + +} // namespace openspace diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index ba4581cf23..a16305b408 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -163,12 +163,13 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath // Seed 'em all std::vector seedPoints; +// seedPoints.push_back(glm::vec3(5.0, 0.0, 0.0)); for (int z = -5; z <= 5; z+=5) { for (int y = -5; y <= 5; y+=5) seedPoints.push_back(glm::vec3(5.0, (float)y, (float)z)); } - float* fieldlinesData = kw.getFieldLines(xVariable, yVariable, zVariable, dimensions, seedPoints); + float* fieldlinesData = kw.getVolumeFieldLines(xVariable, yVariable, zVariable, dimensions, seedPoints); // float* rhoData = kw.getUniformSampledValues("rho", dimensions); // // // Combine fieldlines with rhoData, clamp to [0,1] diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index 52739394b1..1816da5be7 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -190,9 +190,6 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { _colorBoxRenderer->render(transform); // Draw screenquad - glClearColor(0.2f, 0.2f, 0.2f, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - _shaderMutex->lock(); _twopassProgram->activate(); _twopassProgram->setUniform("stepSize", _stepSize); diff --git a/src/util/factorymanager.cpp b/src/util/factorymanager.cpp index 46561078dc..4a6e71ff59 100644 --- a/src/util/factorymanager.cpp +++ b/src/util/factorymanager.cpp @@ -27,6 +27,7 @@ #include // renderables +#include #include #include #include @@ -62,6 +63,7 @@ void FactoryManager::initialize() _manager->factory()->registerClass( "RenderableVolumeExpert"); _manager->factory()->registerClass("RenderableFlare"); + _manager->factory()->registerClass("RenderableFieldlines"); // Add Ephimerides _manager->addFactory(new ghoul::TemplateFactory); @@ -102,4 +104,4 @@ void FactoryManager::addFactory(ghoul::TemplateFactoryBase* factory) { } -} // namespace openspace \ No newline at end of file +} // namespace openspace diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index e360301a4b..b34bee3aeb 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -237,7 +237,7 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c return data; } -float* KameleonWrapper::getFieldLines(const std::string& xVar, +float* KameleonWrapper::getVolumeFieldLines(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions, std::vector seedPoints) { assert(_model && _interpolator); @@ -247,11 +247,28 @@ float* KameleonWrapper::getFieldLines(const std::string& xVar, int size = outDimensions.x*outDimensions.y*outDimensions.z; float* data = new float[size]; + std::vector line; if (_type == Model::BATSRUS) { - // Bi-directional tracing of fieldlines - traceCartesianFieldlines(xVar, yVar, zVar, outDimensions, seedPoints, TraceDirection::FORWARD, data); - traceCartesianFieldlines(xVar, yVar, zVar, outDimensions, seedPoints, TraceDirection::BACK, data); + for (glm::vec3 seedPoint : seedPoints) { + line = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::FORWARD); + for (glm::vec3 point : line) { + int vPosX = std::floor(outDimensions.x*(point.x-_xMin)/(_xMax-_xMin)); + int vPosY = std::floor(outDimensions.y*(point.y-_yMin)/(_yMax-_yMin)); + int vPosZ = std::floor(outDimensions.z*(point.z-_zMin)/(_zMax-_zMin)); + int index = vPosX + vPosY*outDimensions.x + vPosZ*outDimensions.x*outDimensions.y; + data[index] = 1.0; + } + + line = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::BACK); + for (glm::vec3 point : line) { + int vPosX = std::floor(outDimensions.x*(point.x-_xMin)/(_xMax-_xMin)); + int vPosY = std::floor(outDimensions.y*(point.y-_yMin)/(_yMax-_yMin)); + int vPosZ = std::floor(outDimensions.z*(point.z-_zMin)/(_zMax-_zMin)); + int index = vPosX + vPosY*outDimensions.x + vPosZ*outDimensions.x*outDimensions.y; + data[index] = 1.0; + } + } } else { LERROR("Fieldlines are only supported for BATSRUS model"); } @@ -259,71 +276,79 @@ float* KameleonWrapper::getFieldLines(const std::string& xVar, return data; } -void KameleonWrapper::traceCartesianFieldlines(const std::string& xVar, - const std::string& yVar, const std::string& zVar, - glm::size3_t outDimensions, std::vector seedPoints, - TraceDirection direction, float* data) { +std::vector > KameleonWrapper::getFieldLines( + const std::string& xVar, const std::string& yVar, + const std::string& zVar, std::vector seedPoints) { + assert(_model && _interpolator); + assert(_type == Model::ENLIL || _type == Model::BATSRUS); + LINFO("Creating " << seedPoints.size() << " fieldlines from variables " << xVar << " " << yVar << " " << zVar); + + std::vector fLine, bLine; + std::vector > fieldLines; + + if (_type == Model::BATSRUS) { + for (glm::vec3 seedPoint : seedPoints) { + fLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::FORWARD); + bLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::BACK); + bLine.insert(bLine.begin(), fLine.rbegin(), fLine.rend()); + fieldLines.push_back(bLine); + } + } else { + LERROR("Fieldlines are only supported for BATSRUS model"); + } + + return fieldLines; +} + +std::vector KameleonWrapper::traceCartesianFieldline( + const std::string& xVar, const std::string& yVar, + const std::string& zVar, glm::vec3 seedPoint, TraceDirection direction) { - int highNumber = 100000; glm::vec3 pos, k1, k2, k3, k4; + std::vector line; - float stepSize = 2.0; - float stepX = stepSize*(_xMax-_xMin)/(static_cast(outDimensions.x)); - float stepY = stepSize*(_yMax-_yMin)/(static_cast(outDimensions.y)); - float stepZ = stepSize*(_zMax-_zMin)/(static_cast(outDimensions.z)); + float stepX = 0.5, stepY = 0.5, stepZ = 0.5; - for (int i = 0; i < seedPoints.size(); ++i) { - progressBar(i, seedPoints.size()); - pos = seedPoints.at(i); - int avoidInfLoopPlz = 0; - while (pos.x < _xMax && pos.x > _xMin && - pos.y < _yMax && pos.y > _yMin && - pos.z < _zMax && pos.z > _zMin) { + int numSteps = 0; + int maxSteps = 1000; + pos = seedPoint; - // Save position - int vPosX = std::floor(outDimensions.x*(pos.x-_xMin)/(_xMax-_xMin)); - int vPosY = std::floor(outDimensions.y*(pos.y-_yMin)/(_yMax-_yMin)); - int vPosZ = std::floor(outDimensions.z*(pos.z-_zMin)/(_zMax-_zMin)); - int index = vPosX + vPosY*outDimensions.x + vPosZ*outDimensions.x*outDimensions.y; - data[index] = 1.0; + // While we are inside the models boundries and not inside earth + while ((pos.x < _xMax && pos.x > _xMin && pos.y < _yMax && pos.y > _yMin && + pos.z < _zMax && pos.z > _zMin) && !(pos.x < 1.0 && pos.x > -1.0 && + pos.y < 1.0 && pos.y > -1.0 && pos.z < 1.0 && pos.z > -1.0)) { - // Calculate the next position - // Euler -// dir.x = _interpolator->interpolate(xVar, pos.x, pos.y, pos.z); -// dir.y = _interpolator->interpolate(yVar, pos.x, pos.y, pos.z); -// dir.z = _interpolator->interpolate(zVar, pos.x, pos.y, pos.z); -// dir = (float)direction*glm::normalize(dir); -// pos = glm::vec3(stepX*dir.x+pos.x, stepY*dir.y+pos.y, stepZ*dir.z+pos.z); + // Save position + line.push_back(pos); - // Runge-Kutta 4th order - k1.x = _interpolator->interpolate(xVar, pos.x, pos.y, pos.z); - k1.y = _interpolator->interpolate(yVar, pos.x, pos.y, pos.z); - k1.z = _interpolator->interpolate(zVar, pos.x, pos.y, pos.z); - k1 = (float)direction*glm::normalize(k1); - k2.x = _interpolator->interpolate(xVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); - k2.y = _interpolator->interpolate(yVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); - k2.z = _interpolator->interpolate(zVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); - k2 = (float)direction*glm::normalize(k2); - k3.x = _interpolator->interpolate(xVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); - k3.y = _interpolator->interpolate(yVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); - k3.z = _interpolator->interpolate(zVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); - k3 = (float)direction*glm::normalize(k3); - k4.x = _interpolator->interpolate(xVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); - k4.y = _interpolator->interpolate(yVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); - k4.z = _interpolator->interpolate(zVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); - k4 = (float)direction*glm::normalize(k4); - pos.x = pos.x + (stepX/6.0)*(k1.x + 2.0*k2.x + 2.0*k3.x + k4.x); - pos.y = pos.y + (stepY/6.0)*(k1.y + 2.0*k2.y + 2.0*k3.y + k4.y); - pos.z = pos.z + (stepZ/6.0)*(k1.z + 2.0*k2.z + 2.0*k3.z + k4.z); + // Calculate new position with Runge-Kutta 4th order + k1.x = _interpolator->interpolate(xVar, pos.x, pos.y, pos.z); + k1.y = _interpolator->interpolate(yVar, pos.x, pos.y, pos.z); + k1.z = _interpolator->interpolate(zVar, pos.x, pos.y, pos.z); + k1 = (float)direction*glm::normalize(k1); + k2.x = _interpolator->interpolate(xVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); + k2.y = _interpolator->interpolate(yVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); + k2.z = _interpolator->interpolate(zVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); + k2 = (float)direction*glm::normalize(k2); + k3.x = _interpolator->interpolate(xVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); + k3.y = _interpolator->interpolate(yVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); + k3.z = _interpolator->interpolate(zVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); + k3 = (float)direction*glm::normalize(k3); + k4.x = _interpolator->interpolate(xVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); + k4.y = _interpolator->interpolate(yVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); + k4.z = _interpolator->interpolate(zVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); + k4 = (float)direction*glm::normalize(k4); + pos.x = pos.x + (stepX/6.0)*(k1.x + 2.0*k2.x + 2.0*k3.x + k4.x); + pos.y = pos.y + (stepY/6.0)*(k1.y + 2.0*k2.y + 2.0*k3.y + k4.y); + pos.z = pos.z + (stepZ/6.0)*(k1.z + 2.0*k2.z + 2.0*k3.z + k4.z); - ++avoidInfLoopPlz; - - if (avoidInfLoopPlz > highNumber) { - LDEBUG("Inf loop averted"); - break; - } + ++numSteps; + if (numSteps > maxSteps) { + LDEBUG("Max number of steps taken"); + break; } } + return line; } void KameleonWrapper::getGridVariables(std::string& x, std::string& y, std::string& z) { @@ -367,4 +392,3 @@ void KameleonWrapper::progressBar(int current, int end) { } } // namespace openspace - From f4dad8dc1c3b2740d77d892e49c9c56b050e8fca Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Thu, 5 Jun 2014 13:18:22 -0400 Subject: [PATCH 014/113] Intermediate ABuffer - Raycasting works - TODO: Mix raycasting with fragment list - TODO: Fix PowerScaling --- .../openspace/rendering/volumeraycasterbox.h | 4 +- shaders/ABuffer/abufferResolveFragment.glsl | 109 ++++++++++++++---- shaders/ABuffer/abufferSort.hglsl | 40 +++++++ shaders/exitpoints.frag | 2 + shaders/exitpoints.vert | 5 +- shaders/pscstandard_fs.glsl | 5 +- src/abuffer/abufferSingleLinked.cpp | 7 ++ src/rendering/renderablevolumegl.cpp | 10 +- src/rendering/volumeraycasterbox.cpp | 8 +- 9 files changed, 153 insertions(+), 37 deletions(-) diff --git a/include/openspace/rendering/volumeraycasterbox.h b/include/openspace/rendering/volumeraycasterbox.h index 5792b0e0c3..8597a1c265 100644 --- a/include/openspace/rendering/volumeraycasterbox.h +++ b/include/openspace/rendering/volumeraycasterbox.h @@ -45,7 +45,7 @@ public: VolumeRaycasterBox(); ~VolumeRaycasterBox(); bool initialize(); - void render(const glm::mat4& MVP); + void render(const glm::mat4& MVP,const glm::mat4& transform = glm::mat4(1.0)); ghoul::opengl::Texture* backFace(); ghoul::opengl::Texture* frontFace(); @@ -56,7 +56,7 @@ private: ghoul::opengl::Texture *_backTexture, *_frontTexture; ghoul::opengl::ProgramObject *_boxProgram; sgct_utils::SGCTBox* _boundingBox; - GLint _MVPLocation; + GLint _MVPLocation, _modelTransformLocation; glm::size2_t _dimensions; }; diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index 3a8619d474..3bd50f984e 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -1,19 +1,20 @@ #version 430 // uniforms +uniform sampler3D volume; in vec2 texCoord; out vec4 color; // settings -#define ALPHA_LIMIT 0.51 +#define ALPHA_LIMIT 1.0 #define MAX_FRAGMENTS 16 #define MAX_VOLUMES 4 #include "abufferStruct.hglsl" ABufferStruct_t fragments[MAX_FRAGMENTS]; - vec3 volume_direction[MAX_VOLUMES]; +float volume_length[MAX_VOLUMES]; vec3 volume_position[MAX_VOLUMES]; #include "abufferSort.hglsl" @@ -26,41 +27,101 @@ vec4 blend(vec4 src, vec4 dst) { return o; //return mix(src, dst, dst.a*(1.0f - src.a)); } - -vec3 direction(vec4 v1, vec4 v2) { - const float k = 10.0; - float ds = v2.w - v1.w; - if(ds >= 0) { - float p = pow(k,-ds); - return vec4(v1.x*p - v2.x, v1.y*p - v2.y, v1.z*p - v2.z, v2.w).xyz; - } else { - float p = pow(k,ds); - return vec4(v1.x - v2.x*p, v1.y - v2.y*p, v1.z - v2.z*p, v1.w).xyz; - } +/* +void blend(inout vec4 dst, in vec4 src, in float stepSize) { + src.a = 1.0 - pow(1.0 - src.a, stepSize ); + dst.rgb = dst.rgb + (1.0 - dst.a) * src.a * src.rgb; + dst.a = dst.a + (1.0 -dst.a) * src.a; } +//Color geometry +void blendGeometry(inout vec4 color, ABufferStruct_t frag) { + //vec4 c; + //c.rg = unpackHalf2x16(frag.rg); + //c.ba = unpackHalf2x16(frag.ba); + vec4 c = _col_(frag); + c.a = clamp(c.a, 0.0,1.0); + blend(color, c, 0.01); + return; +} +*/ + vec4 calculate_final_color(uint frag_count) { int currentVolumeBitmask = 0; vec4 final_color = vec4(0); - for(uint i = 0; i < frag_count && final_color.a < ALPHA_LIMIT; i++) { - ABufferStruct_t item = fragments[i]; - vec4 frag_color = _col_(item); - vec4 position = _pos_(item); - uint type = _type_(item); + + // if(frag_count == 1 && _type_(fragments[0]) == 0) { + // blendGeometry(final_color, fragments[0]); + // return final_color; + // } + + int frag_count_1 = int(frag_count); + for(int i = 0; i < frag_count_1 && final_color.a < ALPHA_LIMIT; i++) { + + //int maxFrags = int(frag_count)-1; + //for(int i = 0; i < frag_count; i++) { + ABufferStruct_t startFrag = fragments[i]; + //ABufferStruct_t endFrag = fragments[i+1]; + //vec4 frag_color = _col_(startFrag); + //vec4 position = _pos_(startFrag); + int type = int(_type_(startFrag)); - if(currentVolumeBitmask != 0) { + if(type != 0) { currentVolumeBitmask = currentVolumeBitmask ^ (1 << type); + if(currentVolumeBitmask != 0) { + float p = 0.0f; + const float stepSize = 0.01; + float l = volume_length[type-1]; + vec3 direction = volume_direction[type-1]; + vec3 position; + vec4 tmp, color = vec4(0); + while(p < l) { + position = volume_position[type-1] + direction*p; + tmp = texture(volume, position); + color = max(color, tmp); + p+= stepSize; + } + vec4 volume_color = vec4(color.r,color.r,color.r,color.r*2.0); + final_color = blend(final_color, volume_color); + } + /* + const vec3 direction = volume_direction[type-1]; + const float l = pscLength(_pos_(fragments[i+1]), _pos_(fragments[i])); + const float stepSize = 0.01; + const float iterationsStop = l / volume_length[type-1]; + //const int iterations = 100; + float p = 0.0f; + int maxit = 500; + int it = 0; + while(p < iterationsStop && it < maxit) { + vec4 sample_color = vec4(0.1, 0.0, 0.0, 0.1); + blend(final_color, sample_color, stepSize); + + p+=stepSize; + ++it; + } + */ + } else { + final_color = blend(final_color, _col_(startFrag)); + //blendGeometry(final_color, startFrag); } - /* - if(_type_(item) == 1) -*/ - final_color = blend(final_color, frag_color); - //final_color = blend(frag_color, final_color); + + + //blendGeometry(final_color, startFrag); + //if(i == maxFrags -1 && _type_(endFrag) == 0) + // blendGeometry(final_color, endFrag); + + // final_color = blend(final_color, frag_color); + //if(i == frag_count_1 && _type_(endFrag) == 0) + // final_color = blend(final_color, _col_(endFrag)); } + //int id =2; + //if(id < frag_count)final_color = blend(final_color, _col_(fragments[id])); + return final_color; } diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index 4cdc8bf481..4ec61e9cb8 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -24,6 +24,20 @@ int build_local_fragments_list() { return frag_count; } +float pscLength(vec4 v1, vec4 v2) { + const float k = 10.0; + float ds = v2.w - v1.w; + vec4 vector; + if(ds >= 0) { + float p = pow(k,-ds); + vector = vec4(v1.x*p - v2.x, v1.y*p - v2.y, v1.z*p - v2.z, v2.w); + } else { + float p = pow(k,ds); + vector = vec4(v1.x - v2.x*p, v1.y - v2.y*p, v1.z - v2.z*p, v1.w); + } + return length(vector.xyz)*pow(k,vector.w); +} + void sort_fragments_list(uint frag_count) { uint i,j; ABufferStruct_t tmp; @@ -36,4 +50,30 @@ void sort_fragments_list(uint frag_count) { } fragments[j] = tmp; } + + int ii, jj; + for(ii = 0; ii < MAX_VOLUMES; ++ii) { + bool start = true; + vec3 startColor; + vec4 startPosition; + for(jj = 0; jj < frag_count; ++jj) { + int type = int(_type_(fragments[jj])) -1; + if(type== ii) { + if(start) { + startColor = _col_(fragments[jj]).rgb; + startPosition = _pos_(fragments[jj]); + start = false; + } else { + vec3 dir = _col_(fragments[jj]).rgb - startColor; + volume_direction[ii] = normalize(dir); + volume_position[ii] = startColor; + volume_length[ii] = length(dir); + //volume_length[ii] = pscLength(_pos_(fragments[jj]), startPosition); + break; + } + } + } + } + //volume_direction[0] = vec3(1.0,0.0,0.0); + //volume_direction[0] = _col_(fragments[0]).rgb; } diff --git a/shaders/exitpoints.frag b/shaders/exitpoints.frag index 72041462b2..606bfeff10 100644 --- a/shaders/exitpoints.frag +++ b/shaders/exitpoints.frag @@ -1,6 +1,7 @@ #version 430 core in vec3 vPosition; +in vec3 worldPosition; out vec4 fragColor; #include "ABuffer/abufferStruct.hglsl" @@ -13,6 +14,7 @@ void main() { _col_(frag, fragColor); _z_(frag, gl_FragDepth); _type_(frag, 1); + _pos_(frag, vec4(worldPosition,0)); addToBuffer(frag); //discard; diff --git a/shaders/exitpoints.vert b/shaders/exitpoints.vert index cc0dd3624d..15e86a76df 100644 --- a/shaders/exitpoints.vert +++ b/shaders/exitpoints.vert @@ -2,10 +2,13 @@ layout(location = 2) in vec3 vertPosition; uniform mat4 modelViewProjection; +uniform mat4 modelTransform; out vec3 vPosition; +out vec3 worldPosition; void main() { - gl_Position = modelViewProjection * vec4(vertPosition, 1.0); vPosition = vertPosition; + worldPosition = (modelTransform *vec4(vPosition, 1.0)).xyz; + gl_Position = modelViewProjection *vec4(worldPosition, 1.0); } \ No newline at end of file diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index b5304ad234..85dc406b22 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -9,10 +9,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ #version 430 -uniform mat4 ViewProjection; -uniform mat4 ModelTransform; -uniform vec4 campos; -uniform vec4 objpos; uniform float time; uniform sampler2D texture1; @@ -119,6 +115,7 @@ void main() _col_(frag, diffuse); _z_(frag, gl_FragDepth); _type_(frag, 0); + _pos_(frag, vs_position); addToBuffer(frag); /* diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp index 3d3c7cf7d4..727a023015 100644 --- a/src/abuffer/abufferSingleLinked.cpp +++ b/src/abuffer/abufferSingleLinked.cpp @@ -23,6 +23,7 @@ ****************************************************************************************/ #include +#include #include #include @@ -168,7 +169,13 @@ void ABufferSingleLinked::preRender() { } void ABufferSingleLinked::postRender() { + + ghoul::opengl::Texture* volume; + OsEng.configurationManager().getValue("firstVolume", volume); resolveShader->activate(); + glActiveTexture(GL_TEXTURE0); + volume->bind(); + resolveShader->setUniform("volume", 0); //resolveShader->setUniform("SCREEN_WIDTH", width); //resolveShader->setUniform("SCREEN_HEIGHT", height); glBindVertexArray(_screenQuad); diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index 9e3bdcbf43..051180a773 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -33,6 +33,8 @@ #include +#include + namespace { std::string _loggerCat = "RenderableVolumeGL"; } @@ -119,6 +121,8 @@ bool RenderableVolumeGL::initialize() { // ------ VOLUME READING ---------------- _volume = loadVolume(_filename, _hintsDictionary); _volume->uploadTexture(); + OsEng.configurationManager().setValue("firstVolume", _volume); + //glBindImageTexture(2, *_volume, 0, GL_FALSE, 0, GL_READ_ONLY, _volume->type()); // ------ SETUP GEOMETRY ---------------- const GLfloat size = 1.0f; @@ -179,15 +183,15 @@ bool RenderableVolumeGL::deinitialize() { void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { _stepSize = 0.01f; - glm::mat4 transform = camera->viewProjectionMatrix(); + glm::mat4 transform ; glm::mat4 camTransform = camera->viewRotationMatrix(); psc relative = thisPosition-camera->position(); - transform = transform*camTransform; + transform = camTransform; transform = glm::translate(transform, relative.vec3()); transform = glm::scale(transform, _boxScaling); - _colorBoxRenderer->render(transform); + _colorBoxRenderer->render(camera->viewProjectionMatrix(), transform); /* // Draw screenquad glClearColor(0.2f, 0.2f, 0.2f, 0); diff --git a/src/rendering/volumeraycasterbox.cpp b/src/rendering/volumeraycasterbox.cpp index 3e27e0d95d..ad51b1eabd 100644 --- a/src/rendering/volumeraycasterbox.cpp +++ b/src/rendering/volumeraycasterbox.cpp @@ -61,7 +61,8 @@ bool VolumeRaycasterBox::initialize() { // ------ SETUP SHADER ----------------- OsEng.configurationManager().getValue("RaycastProgram", _boxProgram); - _MVPLocation = _boxProgram->uniformLocation("modelViewProjection"); + _MVPLocation = _boxProgram->uniformLocation("modelViewProjection"); + _modelTransformLocation = _boxProgram->uniformLocation("modelTransform"); // ------ SETUP FBO --------------------- _fbo = new FramebufferObject(); @@ -89,11 +90,12 @@ bool VolumeRaycasterBox::initialize() { return true; } -void VolumeRaycasterBox::render(const glm::mat4& MVP) { +void VolumeRaycasterBox::render(const glm::mat4& MVP,const glm::mat4& transform) { GLuint activeFBO = FramebufferObject::getActiveObject(); // Save SGCTs main FBO _fbo->activate(); _boxProgram->activate(); - _boxProgram->setUniform(_MVPLocation, MVP); + _boxProgram->setUniform(_MVPLocation, MVP); + _boxProgram->setUniform(_modelTransformLocation, transform); sgct_core::Frustum::FrustumMode mode = sgct::Engine::instance()-> getActiveWindowPtr()-> From 4a08f10d66c346e7e1a9a41c91d936aaa786133a Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Thu, 5 Jun 2014 13:26:10 -0400 Subject: [PATCH 015/113] You can now specify seedpoints in the mod-file for fieldlines --- include/openspace/rendering/renderable.h | 3 +- .../rendering/renderablefieldlines.h | 13 +-- .../openspace/rendering/renderablevolume.h | 8 +- openspace-data | 2 +- src/rendering/renderable.cpp | 25 +++++- src/rendering/renderablefieldlines.cpp | 89 ++++++++++++++----- src/rendering/renderablevolume.cpp | 32 +------ 7 files changed, 107 insertions(+), 65 deletions(-) diff --git a/include/openspace/rendering/renderable.h b/include/openspace/rendering/renderable.h index 2ff4bda48a..a1959f72aa 100644 --- a/include/openspace/rendering/renderable.h +++ b/include/openspace/rendering/renderable.h @@ -52,9 +52,10 @@ public: virtual void update(); protected: - // Renderable(); + std::string findPath(const std::string& path); private: PowerScaledScalar boundingSphere_; + std::string _relativePath; }; } // namespace openspace diff --git a/include/openspace/rendering/renderablefieldlines.h b/include/openspace/rendering/renderablefieldlines.h index a1546b52b6..ade8173be8 100644 --- a/include/openspace/rendering/renderablefieldlines.h +++ b/include/openspace/rendering/renderablefieldlines.h @@ -26,7 +26,7 @@ #define RENDERABLEFIELDLINES_H_ // open space includes -#include +#include // ghoul includes #include @@ -40,7 +40,7 @@ namespace openspace { -class RenderableFieldlines : public RenderableVolume { +class RenderableFieldlines : public Renderable { public: RenderableFieldlines(const ghoul::Dictionary& dictionary); ~RenderableFieldlines(); @@ -54,6 +54,7 @@ public: private: ghoul::Dictionary _hintsDictionary; std::string _filename; + std::vector _seedPoints; ghoul::opengl::ProgramObject* _fieldlinesProgram; GLuint _VAO; @@ -62,12 +63,14 @@ private: ghoul::filesystem::File* _vertexSourceFile; ghoul::filesystem::File* _fragmentSourceFile; - bool _programUpdateOnSave; - - void safeShaderCompilation(); std::vector _lineStart; std::vector _lineCount; + + bool _programUpdateOnSave; + void safeShaderCompilation(); + + }; } // namespace openspace diff --git a/include/openspace/rendering/renderablevolume.h b/include/openspace/rendering/renderablevolume.h index 00bc8c680b..870b8ee672 100644 --- a/include/openspace/rendering/renderablevolume.h +++ b/include/openspace/rendering/renderablevolume.h @@ -29,7 +29,6 @@ #include // ghoul includes -#include #include #include @@ -37,23 +36,18 @@ namespace openspace { class RenderableVolume: public Renderable { public: - // constructors & destructor RenderableVolume(const ghoul::Dictionary& dictionary); ~RenderableVolume(); protected: - std::string findPath(const std::string& path); ghoul::opengl::Texture* loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary); ghoul::RawVolumeReader::ReadHints readHints(const ghoul::Dictionary& dictionary); ghoul::opengl::Texture* loadTransferFunction(const std::string& filepath); private: - - // relative path - std::string _relativePath; }; } // namespace openspace -#endif \ No newline at end of file +#endif diff --git a/openspace-data b/openspace-data index 8c9a21935d..3b9a6e638b 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 8c9a21935d4e1295857997664b0b7b297cce8dda +Subproject commit 3b9a6e638b3018d099f04d8abcac994cb505a542 diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 9a432b02d7..40a9c193a3 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -27,6 +27,8 @@ #include #include +#include + namespace { const std::string _loggerCat = "Renderable"; } @@ -63,6 +65,13 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary) std::string name; dictionary.getValue(constants::scenegraphnode::keyName, name); setName(name); + + // get path if available + _relativePath = ""; + if(dictionary.hasKey(constants::scenegraph::keyPathModule)) { + dictionary.getValue(constants::scenegraph::keyPathModule, _relativePath); + _relativePath += "/"; + } } Renderable::~Renderable() @@ -83,4 +92,18 @@ void Renderable::update() { } -} // namespace openspace \ No newline at end of file +std::string Renderable::findPath(const std::string& path) { + std::string tmp = absPath(path); + if(FileSys.fileExists(tmp)) + return tmp; + + tmp = absPath(_relativePath + path); + if(FileSys.fileExists(tmp)) + return tmp; + + LERROR("Could not find file '" << path << "'"); + + return ""; +} + +} // namespace openspace diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index 203b07f740..b19740d54d 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -34,21 +34,47 @@ namespace { namespace openspace { RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) : - RenderableVolume(dictionary), _VAO(0), _programUpdateOnSave(false) { + Renderable(dictionary), _VAO(0), _programUpdateOnSave(false) { _shaderMutex = new std::mutex; - _filename = ""; - if(dictionary.hasKey("Volume")) { - if(dictionary.getValue("Volume", _filename)) { - _filename = findPath(_filename); + if(dictionary.hasKey("Fieldlines")) { + ghoul::Dictionary fieldlines; + if(dictionary.getValue("Fieldlines", fieldlines)) { + for(auto key: fieldlines.keys()) { + ghoul::Dictionary fieldline; + if(fieldlines.getValue(key, fieldline)) { + if (fieldline.hasKey("File")) { + std::string file = ""; + if (fieldline.getValue("File", file)) { + file = findPath(file); + if (file != "") { + + // parse hints + ghoul::Dictionary hintsDictionary; + if(fieldline.hasKey("Hints")) + fieldline.getValue("Hints", hintsDictionary); + + // TODO Vectors of filenames and dictionaries + _filename = file; + _hintsDictionary = hintsDictionary; + + ghoul::Dictionary seedpointsDictionary; + if (fieldline.hasKey("Seedpoints") && fieldline.getValue("Seedpoints", seedpointsDictionary)) { + glm::vec3 tmpVal; + for (int i = 0; i < seedpointsDictionary.keys().size(); ++i) { + fieldline.getValue("Seedpoints."+std::to_string(i+1), tmpVal); + _seedPoints.push_back(tmpVal); + } + } + } else + LERROR("File not found!"); + } + } + } + } } } - LDEBUG("filename: " << _filename); - - if(dictionary.hasKey("Hints")) - dictionary.getValue("Hints", _hintsDictionary); - std::string vshaderpath = ""; std::string fshaderpath = ""; @@ -89,31 +115,36 @@ RenderableFieldlines::~RenderableFieldlines() { bool RenderableFieldlines::initialize() { assert(_filename != ""); + +// std::vector seedPoints; +// for (int x = -6; x <= 6; x+=3) { +// for (int y = -6; y <= 6; y+=3) { +// for (int z = -6; z <= 6; z+=3) { +// seedPoints.push_back(glm::vec3((float)x, (float)y, (float)z)); +// } +// } +// } + KameleonWrapper kameleon(_filename, KameleonWrapper::Model::BATSRUS); - std::vector seedPoints; + std::vector > fieldlines = kameleon.getFieldLines("bx", "by", "bz", _seedPoints); - for (int x = -3; x <= 3; x+=3) { - for (int y = -3; y <= 3; y+=3) { - for (int z = -3; z <= 3; z+=3) { - seedPoints.push_back(glm::vec3((float)x, (float)y, (float)z)); - } - } - } - - std::vector > fieldlines = kameleon.getFieldLines("bx", "by", "bz", seedPoints); std::vector vertexData; - LDEBUG("Fieldlines.size() = " << fieldlines.size()); - int prevEnd = 0; + int vertexSum = 0; + for (int i = 0; i < fieldlines.size(); i++) { _lineStart.push_back(prevEnd); _lineCount.push_back(fieldlines[i].size()); prevEnd = prevEnd + fieldlines[i].size(); + vertexSum += fieldlines[i].size(); vertexData.insert( vertexData.end(), fieldlines[i].begin(), fieldlines[i].end()); } + LDEBUG("Vertex size: " << vertexSum); + LDEBUG("Line average : " << (float)vertexSum/(float)fieldlines.size()); + GLuint vertexPositionBuffer; glGenVertexArrays(1, &_VAO); // generate array glBindVertexArray(_VAO); // bind array @@ -129,6 +160,15 @@ bool RenderableFieldlines::initialize() { glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer glBindVertexArray(0); //unbind array + // ------ SETUP SHADERS ----------------- + auto privateCallback = [this](const ghoul::filesystem::File& file) { + safeShaderCompilation(); + }; + if(_programUpdateOnSave) { + _vertexSourceFile->setCallback(privateCallback); + _fragmentSourceFile->setCallback(privateCallback); + } + _fieldlinesProgram->compileShaderObjects(); _fieldlinesProgram->linkProgramObject(); @@ -165,6 +205,11 @@ void RenderableFieldlines::update() { } void RenderableFieldlines::safeShaderCompilation() { + _shaderMutex->lock(); + _fieldlinesProgram->rebuildFromFile(); + _fieldlinesProgram->compileShaderObjects(); + _fieldlinesProgram->linkProgramObject(); + _shaderMutex->unlock(); } } // namespace openspace diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index a16305b408..c5ee3d6b16 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -24,15 +24,13 @@ // open space includes #include - -#include -#include - #include #include #include -#include +// ghoul includes +#include +#include #include #include @@ -73,34 +71,12 @@ namespace { namespace openspace { -RenderableVolume::RenderableVolume(const ghoul::Dictionary& dictionary) - : Renderable(dictionary) -{ - // get path if available - _relativePath = ""; - if(dictionary.hasKey(constants::scenegraph::keyPathModule)) { - dictionary.getValue(constants::scenegraph::keyPathModule, _relativePath); - _relativePath += "/"; - } +RenderableVolume::RenderableVolume(const ghoul::Dictionary& dictionary) : Renderable(dictionary) { } RenderableVolume::~RenderableVolume() { } -std::string RenderableVolume::findPath(const std::string& path) { - std::string tmp = absPath(path); - if(FileSys.fileExists(tmp)) - return tmp; - - tmp = absPath(_relativePath + path); - if(FileSys.fileExists(tmp)) - return tmp; - - LERROR("Could not find file '" << path << "'"); - - return ""; -} - ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary) { if( ! FileSys.fileExists(filepath)) { LWARNING("Could not load volume, could not find '" << filepath << "'"); From f3f9a5aa1595e33979a61a6e6b054865b2c6fc1b Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Thu, 5 Jun 2014 16:45:24 -0400 Subject: [PATCH 016/113] Renderablefieldliens now properly read hints from .mod file --- src/rendering/renderablefieldlines.cpp | 53 ++++++++++++++++++++------ 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index b19740d54d..ba8d78f4dc 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -115,6 +115,8 @@ RenderableFieldlines::~RenderableFieldlines() { bool RenderableFieldlines::initialize() { assert(_filename != ""); + assert(_hintsDictionary.size() != 0); + assert(_seedPoints.size() != 0); // std::vector seedPoints; // for (int x = -6; x <= 6; x+=3) { @@ -125,26 +127,53 @@ bool RenderableFieldlines::initialize() { // } // } - KameleonWrapper kameleon(_filename, KameleonWrapper::Model::BATSRUS); - std::vector > fieldlines = kameleon.getFieldLines("bx", "by", "bz", _seedPoints); + std::string modelString; + std::vector > fieldlinesData; + + if (_hintsDictionary.hasKey("Model") && _hintsDictionary.getValue("Model", modelString)) { + KameleonWrapper::Model model; + if (modelString == "BATSRUS") { + model = KameleonWrapper::Model::BATSRUS; + } else if (modelString == "ENLIL") { + LWARNING("ENLIL model not supported for fieldlines"); + return false; + } else { + LWARNING("Hints does not specify a valid 'Model'"); + return false; + } + + std::string xVariable, yVariable, zVariable; + if (_hintsDictionary.hasKey("Variables")) { + bool xVar, yVar, zVar; + xVar = _hintsDictionary.getValue("Variables.1", xVariable); + yVar = _hintsDictionary.getValue("Variables.2", yVariable); + zVar = _hintsDictionary.getValue("Variables.3", zVariable); + + if (xVar || yVar || zVar) { + KameleonWrapper kw(_filename, model); + fieldlinesData = kw.getFieldLines(xVariable, yVariable, zVariable, _seedPoints); + + } else { + LWARNING("Error reading variables! Must be 3 and must exist in CDF data"); + return false; + } + } else { + LWARNING("Hints does not specify valid 'Variables'"); + return false; + } + } std::vector vertexData; int prevEnd = 0; - int vertexSum = 0; - - for (int i = 0; i < fieldlines.size(); i++) { + for (int i = 0; i < fieldlinesData.size(); i++) { _lineStart.push_back(prevEnd); - _lineCount.push_back(fieldlines[i].size()); - prevEnd = prevEnd + fieldlines[i].size(); - vertexSum += fieldlines[i].size(); + _lineCount.push_back(fieldlinesData[i].size()); + prevEnd = prevEnd + fieldlinesData[i].size(); - vertexData.insert( vertexData.end(), fieldlines[i].begin(), fieldlines[i].end()); + vertexData.insert( vertexData.end(), fieldlinesData[i].begin(), fieldlinesData[i].end()); } - LDEBUG("Vertex size: " << vertexSum); - LDEBUG("Line average : " << (float)vertexSum/(float)fieldlines.size()); - GLuint vertexPositionBuffer; glGenVertexArrays(1, &_VAO); // generate array glBindVertexArray(_VAO); // bind array From 08f2498e8a7fe6b074988e57c6c034eafd7833b6 Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Fri, 6 Jun 2014 12:18:45 -0400 Subject: [PATCH 017/113] Fieldlines are now created with seedpoints from mod-file. Stepsize can be specified in mod-file aswell --- include/openspace/util/kameleonwrapper.h | 9 ++-- openspace-data | 2 +- src/rendering/renderablefieldlines.cpp | 36 +++++++++------- src/rendering/renderablevolume.cpp | 23 +--------- src/util/kameleonwrapper.cpp | 53 ++++-------------------- 5 files changed, 35 insertions(+), 88 deletions(-) diff --git a/include/openspace/util/kameleonwrapper.h b/include/openspace/util/kameleonwrapper.h index 55bb1dbbca..81023772e8 100644 --- a/include/openspace/util/kameleonwrapper.h +++ b/include/openspace/util/kameleonwrapper.h @@ -54,17 +54,14 @@ public: float* getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions); - float* getVolumeFieldLines(const std::string& xVar, const std::string& yVar, - const std::string& zVar, glm::size3_t outDimensions, std::vector seedPoints); - std::vector > getFieldLines(const std::string& xVar, const std::string& yVar, const std::string& zVar, - std::vector seedPoints); + std::vector seedPoints, float stepSize); private: std::vector traceCartesianFieldline(const std::string& xVar, - const std::string& yVar, const std::string& zVar, - glm::vec3 seedPoint, TraceDirection direction); + const std::string& yVar, const std::string& zVar, glm::vec3 seedPoint, + float stepSize, TraceDirection direction); void getGridVariables(std::string& x, std::string& y, std::string& z); void progressBar(int current, int end); diff --git a/openspace-data b/openspace-data index 3b9a6e638b..a0e8d47b2d 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 3b9a6e638b3018d099f04d8abcac994cb505a542 +Subproject commit a0e8d47b2dafa584c2313fe7199ce29030c5e4ae diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index ba8d78f4dc..919d04c68d 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -118,20 +118,22 @@ bool RenderableFieldlines::initialize() { assert(_hintsDictionary.size() != 0); assert(_seedPoints.size() != 0); -// std::vector seedPoints; -// for (int x = -6; x <= 6; x+=3) { -// for (int y = -6; y <= 6; y+=3) { -// for (int z = -6; z <= 6; z+=3) { -// seedPoints.push_back(glm::vec3((float)x, (float)y, (float)z)); -// } -// } -// } + std::vector seedPoints; + for (int x = -6; x <= 6; x+=3) { + for (int y = -6; y <= 6; y+=3) { + for (int z = -6; z <= 6; z+=3) { + seedPoints.push_back(glm::vec3((float)x, (float)y, (float)z)); + } + } + } std::string modelString; std::vector > fieldlinesData; + float stepSize; + std::string xVariable, yVariable, zVariable; + KameleonWrapper::Model model; if (_hintsDictionary.hasKey("Model") && _hintsDictionary.getValue("Model", modelString)) { - KameleonWrapper::Model model; if (modelString == "BATSRUS") { model = KameleonWrapper::Model::BATSRUS; } else if (modelString == "ENLIL") { @@ -142,18 +144,13 @@ bool RenderableFieldlines::initialize() { return false; } - std::string xVariable, yVariable, zVariable; if (_hintsDictionary.hasKey("Variables")) { bool xVar, yVar, zVar; xVar = _hintsDictionary.getValue("Variables.1", xVariable); yVar = _hintsDictionary.getValue("Variables.2", yVariable); zVar = _hintsDictionary.getValue("Variables.3", zVariable); - if (xVar || yVar || zVar) { - KameleonWrapper kw(_filename, model); - fieldlinesData = kw.getFieldLines(xVariable, yVariable, zVariable, _seedPoints); - - } else { + if (!xVar || !yVar || !zVar) { LWARNING("Error reading variables! Must be 3 and must exist in CDF data"); return false; } @@ -161,8 +158,16 @@ bool RenderableFieldlines::initialize() { LWARNING("Hints does not specify valid 'Variables'"); return false; } + + if (!_hintsDictionary.hasKey("Stepsize") || !_hintsDictionary.getValue("Stepsize", stepSize)) { + LDEBUG("No stepsize set for fieldlines. Setting to default value (0.5)"); + stepSize = 0.5; + } } + KameleonWrapper kw(_filename, model); + fieldlinesData = kw.getFieldLines(xVariable, yVariable, zVariable, _seedPoints, stepSize); + std::vector vertexData; int prevEnd = 0; @@ -215,6 +220,7 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) transform = transform*camTransform; transform = glm::translate(transform, relative.vec3()); + transform = glm::rotate(transform, 90.0f, glm::vec3(1.0, 0.0, 0.0)); transform = glm::scale(transform, glm::vec3(0.1)); _shaderMutex->lock(); diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index c5ee3d6b16..0897e291d7 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -136,27 +136,8 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath if (!xVar || !yVar || !zVar) { LERROR("Error reading variables! Must be 3 and must exist in CDF data"); } else { - - // Seed 'em all - std::vector seedPoints; -// seedPoints.push_back(glm::vec3(5.0, 0.0, 0.0)); - for (int z = -5; z <= 5; z+=5) { - for (int y = -5; y <= 5; y+=5) - seedPoints.push_back(glm::vec3(5.0, (float)y, (float)z)); - } - - float* fieldlinesData = kw.getVolumeFieldLines(xVariable, yVariable, zVariable, dimensions, seedPoints); -// float* rhoData = kw.getUniformSampledValues("rho", dimensions); -// -// // Combine fieldlines with rhoData, clamp to [0,1] -// float* data = new float[dimensions.x*dimensions.y*dimensions.z]; -// for (int i = 0; i < dimensions.x*dimensions.y*dimensions.z; ++i) -// data[i] = std::min(fieldlinesData[i]+rhoData[i], 1.0f); -// -// delete fieldlinesData; -// delete rhoData; - - return new ghoul::opengl::Texture(fieldlinesData, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); + float* data = kw.getUniformSampledVectorValues(xVariable, yVariable, zVariable, dimensions); + return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT); } } else { diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index b34bee3aeb..0a4a1f5b21 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -237,48 +237,10 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c return data; } -float* KameleonWrapper::getVolumeFieldLines(const std::string& xVar, - const std::string& yVar, const std::string& zVar, - glm::size3_t outDimensions, std::vector seedPoints) { - assert(_model && _interpolator); - assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0); - assert(_type == Model::ENLIL || _type == Model::BATSRUS); - LINFO("Creating " << seedPoints.size() << " fieldlines from variables " << xVar << " " << yVar << " " << zVar); - - int size = outDimensions.x*outDimensions.y*outDimensions.z; - float* data = new float[size]; - std::vector line; - - if (_type == Model::BATSRUS) { - for (glm::vec3 seedPoint : seedPoints) { - line = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::FORWARD); - for (glm::vec3 point : line) { - int vPosX = std::floor(outDimensions.x*(point.x-_xMin)/(_xMax-_xMin)); - int vPosY = std::floor(outDimensions.y*(point.y-_yMin)/(_yMax-_yMin)); - int vPosZ = std::floor(outDimensions.z*(point.z-_zMin)/(_zMax-_zMin)); - int index = vPosX + vPosY*outDimensions.x + vPosZ*outDimensions.x*outDimensions.y; - data[index] = 1.0; - } - - line = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::BACK); - for (glm::vec3 point : line) { - int vPosX = std::floor(outDimensions.x*(point.x-_xMin)/(_xMax-_xMin)); - int vPosY = std::floor(outDimensions.y*(point.y-_yMin)/(_yMax-_yMin)); - int vPosZ = std::floor(outDimensions.z*(point.z-_zMin)/(_zMax-_zMin)); - int index = vPosX + vPosY*outDimensions.x + vPosZ*outDimensions.x*outDimensions.y; - data[index] = 1.0; - } - } - } else { - LERROR("Fieldlines are only supported for BATSRUS model"); - } - - return data; -} - std::vector > KameleonWrapper::getFieldLines( const std::string& xVar, const std::string& yVar, - const std::string& zVar, std::vector seedPoints) { + const std::string& zVar, std::vector seedPoints, + float stepSize ) { assert(_model && _interpolator); assert(_type == Model::ENLIL || _type == Model::BATSRUS); LINFO("Creating " << seedPoints.size() << " fieldlines from variables " << xVar << " " << yVar << " " << zVar); @@ -288,8 +250,8 @@ std::vector > KameleonWrapper::getFieldLines( if (_type == Model::BATSRUS) { for (glm::vec3 seedPoint : seedPoints) { - fLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::FORWARD); - bLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::BACK); + fLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::FORWARD); + bLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::BACK); bLine.insert(bLine.begin(), fLine.rbegin(), fLine.rend()); fieldLines.push_back(bLine); } @@ -302,15 +264,16 @@ std::vector > KameleonWrapper::getFieldLines( std::vector KameleonWrapper::traceCartesianFieldline( const std::string& xVar, const std::string& yVar, - const std::string& zVar, glm::vec3 seedPoint, TraceDirection direction) { + const std::string& zVar, glm::vec3 seedPoint, + float stepSize, TraceDirection direction) { glm::vec3 pos, k1, k2, k3, k4; std::vector line; - float stepX = 0.5, stepY = 0.5, stepZ = 0.5; + float stepX = stepSize, stepY = stepSize, stepZ = stepSize; // Should I do different stepsizes? int numSteps = 0; - int maxSteps = 1000; + int maxSteps = 5000; pos = seedPoint; // While we are inside the models boundries and not inside earth From d5e6063670937ff7a56a3e4153a541977c6911f4 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Tue, 10 Jun 2014 11:40:49 -0400 Subject: [PATCH 018/113] Bugfixes - Added support for volume caching - Fixed bug when moving camera in the direction or the origin causing position lock - Fixed camera being to only being affected on SGCT_PRESS and SGCT_REPEAT --- config/sgct/single.xml | 3 +- .../openspace/rendering/renderablevolumegl.h | 2 + shaders/ABuffer/abufferResolveFragment.glsl | 115 ++++++----- shaders/ABuffer/abufferSort.hglsl | 2 + shaders/exitpoints.frag | 2 +- src/abuffer/abufferSingleLinked.cpp | 19 +- src/interaction/interactionhandler.cpp | 133 ++++++------- src/rendering/renderablefieldlines.cpp | 2 +- src/rendering/renderablevolume.cpp | 178 +++++++++++------- src/rendering/renderablevolumegl.cpp | 16 ++ 10 files changed, 285 insertions(+), 187 deletions(-) diff --git a/config/sgct/single.xml b/config/sgct/single.xml index 63abb4989c..87e59f7b28 100644 --- a/config/sgct/single.xml +++ b/config/sgct/single.xml @@ -6,7 +6,8 @@ - + + diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index b6b261ebe7..4aaed2a6c0 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -59,8 +59,10 @@ public: private: ghoul::Dictionary _hintsDictionary; std::string _filename; + std::string _transferFunctionPath; float _stepSize; ghoul::opengl::Texture* _volume; + ghoul::opengl::Texture* _transferFunction; ghoul::opengl::ProgramObject* _twopassProgram; GLuint _screenQuad; diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index af95d73951..c3fe4d24f0 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -2,12 +2,14 @@ // uniforms uniform sampler3D volume; +uniform sampler1D transferFunction; in vec2 texCoord; out vec4 color; // settings -#define ALPHA_LIMIT 1.0 +#define ALPHA_LIMIT 0.98 +#define LOOP_LIMIT 200 #define MAX_FRAGMENTS 16 #define MAX_VOLUMES 4 @@ -15,6 +17,7 @@ out vec4 color; ABufferStruct_t fragments[MAX_FRAGMENTS]; vec3 volume_direction[MAX_VOLUMES]; float volume_length[MAX_VOLUMES]; +vec2 volume_zlength[MAX_VOLUMES]; vec3 volume_position[MAX_VOLUMES]; #include "abufferSort.hglsl" @@ -27,13 +30,13 @@ vec4 blend(vec4 src, vec4 dst) { return o; //return mix(src, dst, dst.a*(1.0f - src.a)); } -/* -void blend(inout vec4 dst, in vec4 src, in float stepSize) { + +void blendStep(inout vec4 dst, in vec4 src, in float stepSize) { src.a = 1.0 - pow(1.0 - src.a, stepSize ); dst.rgb = dst.rgb + (1.0 - dst.a) * src.a * src.rgb; dst.a = dst.a + (1.0 -dst.a) * src.a; } - +/* //Color geometry void blendGeometry(inout vec4 color, ABufferStruct_t frag) { //vec4 c; @@ -51,75 +54,83 @@ vec4 calculate_final_color(uint frag_count) { int currentVolumeBitmask = 0; vec4 final_color = vec4(0); - // if(frag_count == 1 && _type_(fragments[0]) == 0) { - // blendGeometry(final_color, fragments[0]); - // return final_color; - // } + if(frag_count == 1 && _type_(fragments[0]) == 0) { + final_color = blend(final_color, _col_(fragments[0])); + return final_color; + } - int frag_count_1 = int(frag_count); + int frag_count_1 = int(frag_count)-1; for(int i = 0; i < frag_count_1 && final_color.a < ALPHA_LIMIT; i++) { //int maxFrags = int(frag_count)-1; //for(int i = 0; i < frag_count; i++) { ABufferStruct_t startFrag = fragments[i]; - //ABufferStruct_t endFrag = fragments[i+1]; + ABufferStruct_t endFrag = fragments[i+1]; //vec4 frag_color = _col_(startFrag); //vec4 position = _pos_(startFrag); int type = int(_type_(startFrag)); - - - if(type != 0) { - currentVolumeBitmask = currentVolumeBitmask ^ (1 << type); - if(currentVolumeBitmask != 0) { - float p = 0.0f; - const float stepSize = 0.01; - float l = volume_length[type-1]; - vec3 direction = volume_direction[type-1]; - vec3 position; - vec4 tmp, color = vec4(0); - while(p < l) { - position = volume_position[type-1] + direction*p; - tmp = texture(volume, position); - color = max(color, tmp); - p+= stepSize; - } - vec4 volume_color = vec4(color.r,color.r,color.r,color.r*2.0); - final_color = blend(final_color, volume_color); - } - /* - const vec3 direction = volume_direction[type-1]; - const float l = pscLength(_pos_(fragments[i+1]), _pos_(fragments[i])); - const float stepSize = 0.01; - const float iterationsStop = l / volume_length[type-1]; - //const int iterations = 100; - float p = 0.0f; - int maxit = 500; - int it = 0; - while(p < iterationsStop && it < maxit) { - vec4 sample_color = vec4(0.1, 0.0, 0.0, 0.1); - blend(final_color, sample_color, stepSize); - - p+=stepSize; - ++it; - } - */ - } else { + currentVolumeBitmask = currentVolumeBitmask ^ (type); + + if(type == 0) final_color = blend(final_color, _col_(startFrag)); - //blendGeometry(final_color, startFrag); + + if(bool(currentVolumeBitmask)) { + int volID = type -1; + float p = 0.0f; + + const float stepSize = 0.01; + //const float l = volume_length[volID]; + const float S1 = volume_zlength[volID].x; + const float S2 = volume_zlength[volID].y; + const float L = S1 - S2; + const float l = (_z_(startFrag) - S1) / L - (_z_(endFrag) - S1) / L; + const vec3 direction = volume_direction[volID]; + int iterations = 0; + vec3 position; + + // MIP + // vec4 tmp, color = vec4(0); + // while(p < l && iterations < LOOP_LIMIT) { + // tmp = texture(volume, volume_position[volID]); + // color = max(color, tmp); + // p+= stepSize; + // volume_position[volID] += direction*stepSize; + // ++iterations; + // } + // vec4 volume_color = vec4(color.r,color.r,color.r,color.r*2.0); + // if(volume_color.a < 0.1) volume_color = vec4(0.0,0.0,0.0,0.0); + // final_color = blend(final_color, volume_color); + + + // TransferFunction + vec4 color = vec4(0); + float intensity; + while(p < l && iterations < LOOP_LIMIT) { + intensity = length(texture(volume, volume_position[volID])); + color = texture(transferFunction, intensity); + blendStep(final_color, color, stepSize); + //final_color = blend(final_color, color*stepSize); + p+= stepSize; + volume_position[volID] += direction*stepSize; + ++iterations; + } + } + + //blendGeometry(final_color, startFrag); //if(i == maxFrags -1 && _type_(endFrag) == 0) // blendGeometry(final_color, endFrag); // final_color = blend(final_color, frag_color); - //if(i == frag_count_1 && _type_(endFrag) == 0) - // final_color = blend(final_color, _col_(endFrag)); + if(i == frag_count_1 -1 && _type_(endFrag) == 0) + final_color = blend(final_color, _col_(endFrag)); } // final_color = vec4(0); - // int id =0; + // int id =3; // if(id < frag_count)final_color = blend(final_color, _col_(fragments[id])); return final_color; diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index 4ec61e9cb8..71e8534100 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -62,12 +62,14 @@ void sort_fragments_list(uint frag_count) { if(start) { startColor = _col_(fragments[jj]).rgb; startPosition = _pos_(fragments[jj]); + volume_zlength[ii].x = _z_(fragments[jj]); start = false; } else { vec3 dir = _col_(fragments[jj]).rgb - startColor; volume_direction[ii] = normalize(dir); volume_position[ii] = startColor; volume_length[ii] = length(dir); + volume_zlength[ii].y = _z_(fragments[jj]); //volume_length[ii] = pscLength(_pos_(fragments[jj]), startPosition); break; } diff --git a/shaders/exitpoints.frag b/shaders/exitpoints.frag index 606bfeff10..fee208094a 100644 --- a/shaders/exitpoints.frag +++ b/shaders/exitpoints.frag @@ -12,7 +12,7 @@ void main() { ABufferStruct_t frag; _col_(frag, fragColor); - _z_(frag, gl_FragDepth); + _z_(frag, gl_FragCoord.z); _type_(frag, 1); _pos_(frag, vec4(worldPosition,0)); addToBuffer(frag); diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp index 727a023015..b28948c5d4 100644 --- a/src/abuffer/abufferSingleLinked.cpp +++ b/src/abuffer/abufferSingleLinked.cpp @@ -121,6 +121,8 @@ bool ABufferSingleLinked::initialize() { LERROR("Could not link shader"); return false; } + resolveShader->setUniform("volume", 0); + resolveShader->setUniform("transferFunction", 1); // ============================ // GEOMETRY (quad) @@ -170,12 +172,21 @@ void ABufferSingleLinked::preRender() { void ABufferSingleLinked::postRender() { - ghoul::opengl::Texture* volume; + ghoul::opengl::Texture* volume = nullptr; + ghoul::opengl::Texture* tf = nullptr; OsEng.configurationManager().getValue("firstVolume", volume); + OsEng.configurationManager().getValue("firstTransferFunction", tf); resolveShader->activate(); - glActiveTexture(GL_TEXTURE0); - volume->bind(); - resolveShader->setUniform("volume", 0); + + if(volume) { + glActiveTexture(GL_TEXTURE0); + volume->bind(); + } + + if(tf) { + glActiveTexture(GL_TEXTURE1); + tf->bind(); + } //resolveShader->setUniform("SCREEN_WIDTH", width); //resolveShader->setUniform("SCREEN_HEIGHT", height); glBindVertexArray(_screenQuad); diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index b9a18a634e..fc7cb4ba9c 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -173,19 +173,21 @@ void InteractionHandler::distance(const PowerScaledScalar &distance) { lockControls(); psc relative = camera_->position(); - psc origin; - if(node_) { - origin = node_->getWorldPosition(); - } + const psc origin = (node_) ? node_->getWorldPosition() : psc(); psc relative_origin_coordinate = relative - origin; - glm::vec3 dir(relative_origin_coordinate.direction()); - dir = dir * distance[0]; - relative_origin_coordinate = dir; + const glm::vec3 dir(relative_origin_coordinate.direction()); + glm:: vec3 newdir = dir * distance[0]; + relative_origin_coordinate = newdir; relative_origin_coordinate[3] = distance[1]; relative = relative + relative_origin_coordinate; - camera_->setPosition(relative); + relative_origin_coordinate = relative - origin; + newdir = relative_origin_coordinate.direction(); + + // update only if on the same side of the origin + if(glm::angle(newdir, dir) < 90.0f) + camera_->setPosition(relative); unlockControls(); } @@ -303,62 +305,65 @@ void InteractionHandler::keyboardCallback(int key, int action) { // TODO package in script const double speed = 2.75; const double dt = getDt(); - if (key == 'S') { - glm::vec3 euler(speed * dt, 0.0, 0.0); - glm::quat rot = glm::quat(euler); - orbit(rot); - } - if (key == 'W') { - glm::vec3 euler(-speed * dt, 0.0, 0.0); - glm::quat rot = glm::quat(euler); - orbit(rot); - } - if (key == 'A') { - glm::vec3 euler(0.0, -speed * dt, 0.0); - glm::quat rot = glm::quat(euler); - orbit(rot); - } - if (key == 'D') { - glm::vec3 euler(0.0, speed * dt, 0.0); - glm::quat rot = glm::quat(euler); - orbit(rot); - } - if (key == 262) { - glm::vec3 euler(0.0, speed * dt, 0.0); - glm::quat rot = glm::quat(euler); - rotate(rot); - } - if (key == 263) { - glm::vec3 euler(0.0, -speed * dt, 0.0); - glm::quat rot = glm::quat(euler); - rotate(rot); - } - if (key == 264) { - glm::vec3 euler(speed * dt, 0.0, 0.0); - glm::quat rot = glm::quat(euler); - rotate(rot); - } - if (key == 265) { - glm::vec3 euler(-speed * dt, 0.0, 0.0); - glm::quat rot = glm::quat(euler); - rotate(rot); - } - if (key == 'R') { - PowerScaledScalar dist(-speed * dt, 0.0); - distance(dist); - } - if (key == 'F') { - PowerScaledScalar dist(speed * dt, 0.0); - distance(dist); - } - if (key == 'T') { - PowerScaledScalar dist(-speed * 100.0 * dt, 0.0); - distance(dist); - } - if (key == 'G') { - PowerScaledScalar dist(speed * 100.0 * dt, 0.0); - distance(dist); - } + + if(action == SGCT_PRESS || action == SGCT_REPEAT) { + if (key == 'S') { + glm::vec3 euler(speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + orbit(rot); + } + if (key == 'W') { + glm::vec3 euler(-speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + orbit(rot); + } + if (key == 'A') { + glm::vec3 euler(0.0, -speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + orbit(rot); + } + if (key == 'D') { + glm::vec3 euler(0.0, speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + orbit(rot); + } + if (key == 262) { + glm::vec3 euler(0.0, speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + rotate(rot); + } + if (key == 263) { + glm::vec3 euler(0.0, -speed * dt, 0.0); + glm::quat rot = glm::quat(euler); + rotate(rot); + } + if (key == 264) { + glm::vec3 euler(speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + rotate(rot); + } + if (key == 265) { + glm::vec3 euler(-speed * dt, 0.0, 0.0); + glm::quat rot = glm::quat(euler); + rotate(rot); + } + if (key == 'R') { + PowerScaledScalar dist(-speed * dt, 0.0); + distance(dist); + } + if (key == 'F') { + PowerScaledScalar dist(speed * dt, 0.0); + distance(dist); + } + if (key == 'T') { + PowerScaledScalar dist(-speed * 100.0 * dt, 0.0); + distance(dist); + } + if (key == 'G') { + PowerScaledScalar dist(speed * 100.0 * dt, 0.0); + distance(dist); + } + } /* if (key == '1') { SceneGraphNode* node = getSceneGraphNode("sun"); diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index b19740d54d..866a76df1d 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -186,7 +186,7 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) transform = transform*camTransform; transform = glm::translate(transform, relative.vec3()); - transform = glm::scale(transform, glm::vec3(0.1)); + transform = glm::scale(transform, glm::vec3(0.036*0.5*0.5)); _shaderMutex->lock(); _fieldlinesProgram->activate(); diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index c5ee3d6b16..dd741cc8b1 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -89,63 +89,115 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath return rawReader.read(filepath); } else if(hasExtension(filepath, "cdf")) { - std::string modelString; - if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) { - KameleonWrapper::Model model; - if (modelString == "BATSRUS") { - model = KameleonWrapper::Model::BATSRUS; - } else if (modelString == "ENLIL") { - model = KameleonWrapper::Model::ENLIL; + glm::size3_t dimensions(1,1,1); + double tempValue; + if (hintsDictionary.hasKey("Dimensions.1") && hintsDictionary.getValue("Dimensions.1", tempValue)) { + int intVal = static_cast(tempValue); + if(intVal > 0) + dimensions[0] = intVal; + } + if (hintsDictionary.hasKey("Dimensions.2") && hintsDictionary.getValue("Dimensions.2", tempValue)) { + int intVal = static_cast(tempValue); + if(intVal > 0) + dimensions[1] = intVal; + } + if (hintsDictionary.hasKey("Dimensions.3") && hintsDictionary.getValue("Dimensions.3", tempValue)) { + int intVal = static_cast(tempValue); + if(intVal > 0) + dimensions[2] = intVal; + } + + std::string modelString = ""; + if (hintsDictionary.hasKey("Model")) + hintsDictionary.getValue("Model", modelString); + + if(modelString == "") { + LWARNING("Model not specified."); + return nullptr; + } + + std::string variableCacheString = ""; + if (hintsDictionary.hasKey("Variable")) { + hintsDictionary.getValue("Variable", variableCacheString); + } else if(hintsDictionary.hasKey("Variables")) { + std::string xVariable, yVariable, zVariable; + bool xVar, yVar, zVar; + xVar = hintsDictionary.getValue("Variables.1", xVariable); + yVar = hintsDictionary.getValue("Variables.2", yVariable); + zVar = hintsDictionary.getValue("Variables.3", zVariable); + if (xVar && yVar && zVar) { + variableCacheString = xVariable + "." + yVariable + "." + zVariable; + } + } + + bool cache = false; + hintsDictionary.hasKey("Cache"); + if (hintsDictionary.hasKey("Cache")) + hintsDictionary.getValue("Cache", cache); + + std::stringstream ss; + ss << "." << dimensions[0] << "x" << dimensions[1] << "x" << dimensions[2] << "." << modelString << "." << variableCacheString << ".cache"; + std::string cachepath = filepath + ss.str(); + if( cache && FileSys.fileExists(cachepath)) { + + FILE* file = fopen (cachepath.c_str(), "rb"); + + int length = dimensions[0] *dimensions[1] *dimensions[2]; + float* data = new float[length]; + + for(int i = 0; i< length; i++){ + float f; + fread(&f, sizeof(float), 1, file); + data[i] = f; + } + + fclose(file); + return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, ghoul::opengl::Texture::FilterMode::Linear, ghoul::opengl::Texture::WrappingMode::ClampToBorder); + } + + KameleonWrapper::Model model; + if (modelString == "BATSRUS") { + model = KameleonWrapper::Model::BATSRUS; + } else if (modelString == "ENLIL") { + model = KameleonWrapper::Model::ENLIL; + } else { + LWARNING("Hints does not specify a valid 'Model'"); + return nullptr; + } + + KameleonWrapper kw(filepath, model); + + std::string variableString; + if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) { + float* data = kw.getUniformSampledValues(variableString, dimensions); + if(cache) { + FILE* file = fopen (cachepath.c_str(), "wb"); + int length = dimensions[0] *dimensions[1] *dimensions[2]; + fwrite(data, sizeof(float), length, file); + fclose(file); + } + return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, ghoul::opengl::Texture::FilterMode::Linear, ghoul::opengl::Texture::WrappingMode::ClampToBorder); + + } else if (hintsDictionary.hasKey("Variables")) { + std::string xVariable, yVariable, zVariable; + bool xVar, yVar, zVar; + xVar = hintsDictionary.getValue("Variables.1", xVariable); + yVar = hintsDictionary.getValue("Variables.2", yVariable); + zVar = hintsDictionary.getValue("Variables.3", zVariable); + + if (!xVar || !yVar || !zVar) { + LERROR("Error reading variables! Must be 3 and must exist in CDF data"); } else { - LWARNING("Hints does not specify a valid 'Model'"); - return nullptr; - } - glm::size3_t dimensions(1,1,1); - double tempValue; - if (hintsDictionary.hasKey("Dimensions.1") && hintsDictionary.getValue("Dimensions.1", tempValue)) { - int intVal = static_cast(tempValue); - if(intVal > 0) - dimensions[0] = intVal; - } - if (hintsDictionary.hasKey("Dimensions.2") && hintsDictionary.getValue("Dimensions.2", tempValue)) { - int intVal = static_cast(tempValue); - if(intVal > 0) - dimensions[1] = intVal; - } - if (hintsDictionary.hasKey("Dimensions.3") && hintsDictionary.getValue("Dimensions.3", tempValue)) { - int intVal = static_cast(tempValue); - if(intVal > 0) - dimensions[2] = intVal; - } - - KameleonWrapper kw(filepath, model); - - std::string variableString; - if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) { - float* data = kw.getUniformSampledValues(variableString, dimensions); - return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); - - } else if (hintsDictionary.hasKey("Variables")) { - std::string xVariable, yVariable, zVariable; - bool xVar, yVar, zVar; - xVar = hintsDictionary.getValue("Variables.1", xVariable); - yVar = hintsDictionary.getValue("Variables.2", yVariable); - zVar = hintsDictionary.getValue("Variables.3", zVariable); - - if (!xVar || !yVar || !zVar) { - LERROR("Error reading variables! Must be 3 and must exist in CDF data"); - } else { - - // Seed 'em all - std::vector seedPoints; + // Seed 'em all + std::vector seedPoints; // seedPoints.push_back(glm::vec3(5.0, 0.0, 0.0)); - for (int z = -5; z <= 5; z+=5) { - for (int y = -5; y <= 5; y+=5) - seedPoints.push_back(glm::vec3(5.0, (float)y, (float)z)); - } + for (int z = -5; z <= 5; z+=5) { + for (int y = -5; y <= 5; y+=5) + seedPoints.push_back(glm::vec3(5.0, (float)y, (float)z)); + } - float* fieldlinesData = kw.getVolumeFieldLines(xVariable, yVariable, zVariable, dimensions, seedPoints); + float* fieldlinesData = kw.getVolumeFieldLines(xVariable, yVariable, zVariable, dimensions, seedPoints); // float* rhoData = kw.getUniformSampledValues("rho", dimensions); // // // Combine fieldlines with rhoData, clamp to [0,1] @@ -156,15 +208,12 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath // delete fieldlinesData; // delete rhoData; - return new ghoul::opengl::Texture(fieldlinesData, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); - } - - } else { - LWARNING("Hints does not specify a 'Variable' or 'Variables'"); + return new ghoul::opengl::Texture(fieldlinesData, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); } + } else { + LWARNING("Hints does not specify a 'Variable' or 'Variables'"); } - LWARNING("Hints does not specify a 'Model'"); } else { LWARNING("No valid file extension."); } @@ -371,13 +420,14 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string //LDEBUG("["<< position <<"] " << value); } -// LDEBUG(weight << ", (" << -// transferFunction[4*i+0] << ", " << -// transferFunction[4*i+1] << ", " << -// transferFunction[4*i+2] << ", " << -// transferFunction[4*i+3] << ")"); + LDEBUG(weight << ", (" << + transferFunction[4*i+0] << ", " << + transferFunction[4*i+1] << ", " << + transferFunction[4*i+2] << ", " << + transferFunction[4*i+3] << ")"); } + return new ghoul::opengl::Texture(transferFunction, glm::size3_t(width,1,1),ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT);; diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index d002dbea9f..cb52808d40 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -85,6 +85,18 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): _twopassProgram->attachObject(fragmentShader); } } + + _transferFunction = nullptr; + if (dictionary.hasKey("TransferFunction")) { + std::string transferFunctionPath = ""; + if(dictionary.getValue("TransferFunction", transferFunctionPath)) { + _transferFunctionPath = findPath(transferFunctionPath); + } + } + if( _transferFunctionPath == "") { + LERROR("No transferFunction!"); + } + if(dictionary.hasKey("UpdateOnSave")) { dictionary.getValue("UpdateOnSave", _programUpdateOnSave); @@ -121,7 +133,10 @@ bool RenderableVolumeGL::initialize() { // ------ VOLUME READING ---------------- _volume = loadVolume(_filename, _hintsDictionary); _volume->uploadTexture(); + _transferFunction = loadTransferFunction(_transferFunctionPath); + _transferFunction->uploadTexture(); OsEng.configurationManager().setValue("firstVolume", _volume); + OsEng.configurationManager().setValue("firstTransferFunction", _transferFunction); //glBindImageTexture(2, *_volume, 0, GL_FALSE, 0, GL_READ_ONLY, _volume->type()); // ------ SETUP GEOMETRY ---------------- @@ -189,6 +204,7 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { transform = camTransform; transform = glm::translate(transform, relative.vec3()); + transform = glm::translate(transform, glm::vec3(-1.1,0.0,0.0)); transform = glm::scale(transform, _boxScaling); _colorBoxRenderer->render(camera->viewProjectionMatrix(), transform); From 6f40de5f376cb485ba22c05f0f085fb8a19b6517 Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Tue, 10 Jun 2014 16:59:47 -0400 Subject: [PATCH 019/113] Added classification of fieldlines (closed, open from north, open from south, solar wind) and coloring after classification --- .../rendering/renderablefieldlines.h | 8 +-- include/openspace/util/kameleonwrapper.h | 9 ++- openspace-data | 2 +- src/rendering/renderablefieldlines.cpp | 68 +++++++++++++++---- src/util/kameleonwrapper.cpp | 53 +++++++++++++-- 5 files changed, 115 insertions(+), 25 deletions(-) diff --git a/include/openspace/rendering/renderablefieldlines.h b/include/openspace/rendering/renderablefieldlines.h index ade8173be8..87461bf924 100644 --- a/include/openspace/rendering/renderablefieldlines.h +++ b/include/openspace/rendering/renderablefieldlines.h @@ -56,16 +56,16 @@ private: std::string _filename; std::vector _seedPoints; - ghoul::opengl::ProgramObject* _fieldlinesProgram; - GLuint _VAO; + ghoul::opengl::ProgramObject *_fieldlinesProgram, *_seedpointsProgram; + GLuint _VAO, _seedpointVAO; std::mutex* _shaderMutex; ghoul::filesystem::File* _vertexSourceFile; ghoul::filesystem::File* _fragmentSourceFile; - std::vector _lineStart; - std::vector _lineCount; + std::vector _lineStart, _seedpointStart; + std::vector _lineCount, _seedpointCount; bool _programUpdateOnSave; void safeShaderCompilation(); diff --git a/include/openspace/util/kameleonwrapper.h b/include/openspace/util/kameleonwrapper.h index 81023772e8..4141bdec52 100644 --- a/include/openspace/util/kameleonwrapper.h +++ b/include/openspace/util/kameleonwrapper.h @@ -48,6 +48,12 @@ public: BACK = -1 }; + enum FieldlineEnd { + NORTH, + SOUTH, + OUT + }; + KameleonWrapper(const std::string& filename, Model model); ~KameleonWrapper(); float* getUniformSampledValues(const std::string& var, glm::size3_t outDimensions); @@ -61,10 +67,11 @@ public: private: std::vector traceCartesianFieldline(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::vec3 seedPoint, - float stepSize, TraceDirection direction); + float stepSize, TraceDirection direction, FieldlineEnd& end); void getGridVariables(std::string& x, std::string& y, std::string& z); void progressBar(int current, int end); + glm::vec3 classifyFieldline(FieldlineEnd fEnd, FieldlineEnd bEnd); ccmc::Model* _model; Model _type; diff --git a/openspace-data b/openspace-data index a0e8d47b2d..4d83eac48d 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit a0e8d47b2dafa584c2313fe7199ce29030c5e4ae +Subproject commit 4d83eac48d185247c293ecdcda1dfc392b8fcd52 diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index 919d04c68d..a2f355ce8f 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -102,6 +102,14 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) } } + _seedpointsProgram = new ghoul::opengl::ProgramObject("SeedpointsProgram"); + ghoul::opengl::ShaderObject* seedpointVertexShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeVertex, + "/home/hhellteg/openspace/openspace-data/scene/fieldlines/seedPoints.vert"); + ghoul::opengl::ShaderObject* seedpointFragmentShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeFragment, + "/home/hhellteg/openspace/openspace-data/scene/fieldlines/seedPoints.frag"); + _seedpointsProgram->attachObject(seedpointVertexShader); + _seedpointsProgram->attachObject(seedpointFragmentShader); + if(dictionary.hasKey("UpdateOnSave")) { dictionary.getValue("UpdateOnSave", _programUpdateOnSave); } @@ -118,15 +126,6 @@ bool RenderableFieldlines::initialize() { assert(_hintsDictionary.size() != 0); assert(_seedPoints.size() != 0); - std::vector seedPoints; - for (int x = -6; x <= 6; x+=3) { - for (int y = -6; y <= 6; y+=3) { - for (int z = -6; z <= 6; z+=3) { - seedPoints.push_back(glm::vec3((float)x, (float)y, (float)z)); - } - } - } - std::string modelString; std::vector > fieldlinesData; float stepSize; @@ -173,12 +172,16 @@ bool RenderableFieldlines::initialize() { for (int i = 0; i < fieldlinesData.size(); i++) { _lineStart.push_back(prevEnd); - _lineCount.push_back(fieldlinesData[i].size()); - prevEnd = prevEnd + fieldlinesData[i].size(); + _lineCount.push_back(fieldlinesData[i].size()/2.0); + prevEnd = prevEnd + fieldlinesData[i].size()/2.0; + + _seedpointStart.push_back(i); + _seedpointCount.push_back(1); vertexData.insert( vertexData.end(), fieldlinesData[i].begin(), fieldlinesData[i].end()); } + // ------ FIELDLINES ----------------- GLuint vertexPositionBuffer; glGenVertexArrays(1, &_VAO); // generate array glBindVertexArray(_VAO); // bind array @@ -189,11 +192,32 @@ bool RenderableFieldlines::initialize() { // Vertex positions GLuint vertexLocation = 0; glEnableVertexAttribArray(vertexLocation); - glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), reinterpret_cast(0)); + glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 2*sizeof(glm::vec3), reinterpret_cast(0)); + + // Texture coordinates + GLuint texcoordLocation = 1; + glEnableVertexAttribArray(texcoordLocation); + glVertexAttribPointer(texcoordLocation, 3, GL_FLOAT, GL_FALSE, 2*sizeof(glm::vec3), (void*)(sizeof(glm::vec3))); glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer glBindVertexArray(0); //unbind array +// // ------ SEEDPOINTS ----------------- +// GLuint seedpointPositionBuffer; +// glGenVertexArrays(1, &_seedpointVAO); // generate array +// glBindVertexArray(_seedpointVAO); // bind array +// glGenBuffers(1, &seedpointPositionBuffer); // generate buffer +// glBindBuffer(GL_ARRAY_BUFFER, seedpointPositionBuffer); // bind buffer +// glBufferData(GL_ARRAY_BUFFER, _seedPoints.size()*sizeof(glm::vec3), &_seedPoints.front(), GL_STATIC_DRAW); +// +// // Vertex positions +// GLuint seedpointLocation = 0; +// glEnableVertexAttribArray(seedpointLocation); +// glVertexAttribPointer(seedpointLocation, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), reinterpret_cast(0)); +// +// glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer +// glBindVertexArray(0); //unbind array + // ------ SETUP SHADERS ----------------- auto privateCallback = [this](const ghoul::filesystem::File& file) { safeShaderCompilation(); @@ -206,6 +230,9 @@ bool RenderableFieldlines::initialize() { _fieldlinesProgram->compileShaderObjects(); _fieldlinesProgram->linkProgramObject(); + _seedpointsProgram->compileShaderObjects(); + _seedpointsProgram->linkProgramObject(); + return true; } @@ -220,20 +247,33 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) transform = transform*camTransform; transform = glm::translate(transform, relative.vec3()); - transform = glm::rotate(transform, 90.0f, glm::vec3(1.0, 0.0, 0.0)); + transform = glm::rotate(transform, -90.0f, glm::vec3(1.0, 0.0, 0.0)); transform = glm::scale(transform, glm::vec3(0.1)); + // ------ FIELDLINES ----------------- _shaderMutex->lock(); _fieldlinesProgram->activate(); _fieldlinesProgram->setUniform("modelViewProjection", transform); - glBindVertexArray(_VAO); glMultiDrawArrays(GL_LINE_STRIP, &_lineStart[0], &_lineCount[0], _lineStart.size()); glBindVertexArray(0); _fieldlinesProgram->deactivate(); _shaderMutex->unlock(); + +// // ------ SEEDPOINTS ----------------- +// _shaderMutex->lock(); +// _seedpointsProgram->activate(); +// _seedpointsProgram->setUniform("modelViewProjection", transform); +// +// glBindVertexArray(_seedpointVAO); +// glPointSize(3); +// glMultiDrawArrays(GL_POINTS, &_seedpointStart[0], &_seedpointCount[0], _seedPoints.size()); +// glBindVertexArray(0); +// +// _seedpointsProgram->deactivate(); +// _shaderMutex->unlock(); } void RenderableFieldlines::update() { diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 0a4a1f5b21..985c4328bb 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -34,6 +34,7 @@ #include #include #include +#include namespace openspace { @@ -247,13 +248,26 @@ std::vector > KameleonWrapper::getFieldLines( std::vector fLine, bLine; std::vector > fieldLines; + glm::vec3 color; + FieldlineEnd forwardEnd, backEnd; if (_type == Model::BATSRUS) { for (glm::vec3 seedPoint : seedPoints) { - fLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::FORWARD); - bLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::BACK); + 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()); - fieldLines.push_back(bLine); + + // classify + color = classifyFieldline(forwardEnd, backEnd); + + // write colors + std::vector line; + for (glm::vec3 position : bLine) { + line.push_back(position); + line.push_back(color); + } + + fieldLines.push_back(line); } } else { LERROR("Fieldlines are only supported for BATSRUS model"); @@ -265,9 +279,9 @@ std::vector > KameleonWrapper::getFieldLines( std::vector KameleonWrapper::traceCartesianFieldline( const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::vec3 seedPoint, - float stepSize, TraceDirection direction) { + float stepSize, TraceDirection direction, FieldlineEnd& end) { - glm::vec3 pos, k1, k2, k3, k4; + glm::vec3 color, pos, k1, k2, k3, k4; std::vector line; float stepX = stepSize, stepY = stepSize, stepZ = stepSize; // Should I do different stepsizes? @@ -311,6 +325,14 @@ std::vector KameleonWrapper::traceCartesianFieldline( break; } } + + if (pos.z > 0.0 && pos.x < 1.0 && pos.x > -1.0 && pos.y < 1.0 && pos.y > -1.0) + end = FieldlineEnd::NORTH; + else if (pos.z < 0.0 && pos.x < 1.0 && pos.x > -1.0 && pos.y < 1.0 && pos.y > -1.0) + end = FieldlineEnd::SOUTH; + else + end = FieldlineEnd::OUT; + return line; } @@ -354,4 +376,25 @@ void KameleonWrapper::progressBar(int current, int end) { _lastiProgress = iprogress; } +glm::vec3 KameleonWrapper::classifyFieldline(FieldlineEnd fEnd, FieldlineEnd bEnd) { + glm::vec3 color; + if ( (fEnd == FieldlineEnd::NORTH || fEnd == FieldlineEnd::SOUTH) + && (bEnd == FieldlineEnd::NORTH || bEnd == FieldlineEnd::SOUTH)) { + // closed + color = glm::vec3(1.0, 0.0, 0.0); + } else if ((fEnd == FieldlineEnd::OUT && bEnd == FieldlineEnd::NORTH) + || (bEnd == FieldlineEnd::OUT && fEnd == FieldlineEnd::NORTH)) { + // north + color = glm::vec3(1.0, 1.0, 0.0); + } else if ((fEnd == FieldlineEnd::OUT && bEnd == FieldlineEnd::SOUTH) + || (bEnd == FieldlineEnd::OUT && fEnd == FieldlineEnd::SOUTH)) { + // south + color = glm::vec3(0.0, 1.0, 0.0); + } else if (fEnd == FieldlineEnd::OUT && bEnd == FieldlineEnd::OUT) { + // solar wind + color = glm::vec3(0.0, 0.0, 1.0); + } + return color; +} + } // namespace openspace From 56c5c259fbc4c28ebdf0415761c9685f780a1359 Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Mon, 16 Jun 2014 11:39:10 -0400 Subject: [PATCH 020/113] Added support for multiple fieldlines in a single module. Stepsize is now adaptive based on the local grid size in the model --- .../rendering/renderablefieldlines.h | 8 +- openspace-data | 2 +- src/rendering/renderablefieldlines.cpp | 190 +++++++++--------- src/util/kameleonwrapper.cpp | 57 +++--- 4 files changed, 132 insertions(+), 125 deletions(-) diff --git a/include/openspace/rendering/renderablefieldlines.h b/include/openspace/rendering/renderablefieldlines.h index 87461bf924..e26c7c2b54 100644 --- a/include/openspace/rendering/renderablefieldlines.h +++ b/include/openspace/rendering/renderablefieldlines.h @@ -52,8 +52,10 @@ public: virtual void update(); private: - ghoul::Dictionary _hintsDictionary; - std::string _filename; + std::vector > getFieldlinesData(std::string filename, ghoul::Dictionary hintsDictionary); + + std::vector _hintsDictionaries; + std::vector _filenames; std::vector _seedPoints; ghoul::opengl::ProgramObject *_fieldlinesProgram, *_seedpointsProgram; @@ -69,8 +71,6 @@ private: bool _programUpdateOnSave; void safeShaderCompilation(); - - }; } // namespace openspace diff --git a/openspace-data b/openspace-data index 4d83eac48d..afbca6e2a5 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 4d83eac48d185247c293ecdcda1dfc392b8fcd52 +Subproject commit afbca6e2a5375a5899aed4855e45d26991c0d450 diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index a2f355ce8f..64dab8daaa 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -49,23 +49,15 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) file = findPath(file); if (file != "") { - // parse hints + // read hints into dictionary ghoul::Dictionary hintsDictionary; if(fieldline.hasKey("Hints")) fieldline.getValue("Hints", hintsDictionary); // TODO Vectors of filenames and dictionaries - _filename = file; - _hintsDictionary = hintsDictionary; + _filenames.push_back(file); + _hintsDictionaries.push_back(hintsDictionary); - ghoul::Dictionary seedpointsDictionary; - if (fieldline.hasKey("Seedpoints") && fieldline.getValue("Seedpoints", seedpointsDictionary)) { - glm::vec3 tmpVal; - for (int i = 0; i < seedpointsDictionary.keys().size(); ++i) { - fieldline.getValue("Seedpoints."+std::to_string(i+1), tmpVal); - _seedPoints.push_back(tmpVal); - } - } } else LERROR("File not found!"); } @@ -122,65 +114,30 @@ RenderableFieldlines::~RenderableFieldlines() { } bool RenderableFieldlines::initialize() { - assert(_filename != ""); - assert(_hintsDictionary.size() != 0); - assert(_seedPoints.size() != 0); + assert(_filenames.size() != 0); + assert(_hintsDictionaries.size() != 0); - std::string modelString; - std::vector > fieldlinesData; - float stepSize; - std::string xVariable, yVariable, zVariable; - KameleonWrapper::Model model; - - if (_hintsDictionary.hasKey("Model") && _hintsDictionary.getValue("Model", modelString)) { - if (modelString == "BATSRUS") { - model = KameleonWrapper::Model::BATSRUS; - } else if (modelString == "ENLIL") { - LWARNING("ENLIL model not supported for fieldlines"); - return false; - } else { - LWARNING("Hints does not specify a valid 'Model'"); - return false; - } - - if (_hintsDictionary.hasKey("Variables")) { - bool xVar, yVar, zVar; - xVar = _hintsDictionary.getValue("Variables.1", xVariable); - yVar = _hintsDictionary.getValue("Variables.2", yVariable); - zVar = _hintsDictionary.getValue("Variables.3", zVariable); - - if (!xVar || !yVar || !zVar) { - LWARNING("Error reading variables! Must be 3 and must exist in CDF data"); - return false; - } - } else { - LWARNING("Hints does not specify valid 'Variables'"); - return false; - } - - if (!_hintsDictionary.hasKey("Stepsize") || !_hintsDictionary.getValue("Stepsize", stepSize)) { - LDEBUG("No stepsize set for fieldlines. Setting to default value (0.5)"); - stepSize = 0.5; - } - } - - KameleonWrapper kw(_filename, model); - fieldlinesData = kw.getFieldLines(xVariable, yVariable, zVariable, _seedPoints, stepSize); - - std::vector vertexData; int prevEnd = 0; + std::vector vertexData; + std::vector > fieldlinesData; - for (int i = 0; i < fieldlinesData.size(); i++) { - _lineStart.push_back(prevEnd); - _lineCount.push_back(fieldlinesData[i].size()/2.0); - prevEnd = prevEnd + fieldlinesData[i].size()/2.0; + for (int i = 0; i < _filenames.size(); ++i) { + fieldlinesData = getFieldlinesData(_filenames[i], _hintsDictionaries[i]); - _seedpointStart.push_back(i); - _seedpointCount.push_back(1); + for (int j = 0; j < fieldlinesData.size(); j++) { + _lineStart.push_back(prevEnd); + _lineCount.push_back(fieldlinesData[j].size()/2.0); + prevEnd = prevEnd + fieldlinesData[j].size()/2.0; - vertexData.insert( vertexData.end(), fieldlinesData[i].begin(), fieldlinesData[i].end()); + _seedpointStart.push_back(j); + _seedpointCount.push_back(1); + + vertexData.insert( vertexData.end(), fieldlinesData[j].begin(), fieldlinesData[j].end()); + } } + LDEBUG("Vertex orginal : " << vertexData.size()/2.0); + // ------ FIELDLINES ----------------- GLuint vertexPositionBuffer; glGenVertexArrays(1, &_VAO); // generate array @@ -203,20 +160,20 @@ bool RenderableFieldlines::initialize() { glBindVertexArray(0); //unbind array // // ------ SEEDPOINTS ----------------- -// GLuint seedpointPositionBuffer; -// glGenVertexArrays(1, &_seedpointVAO); // generate array -// glBindVertexArray(_seedpointVAO); // bind array -// glGenBuffers(1, &seedpointPositionBuffer); // generate buffer -// glBindBuffer(GL_ARRAY_BUFFER, seedpointPositionBuffer); // bind buffer -// glBufferData(GL_ARRAY_BUFFER, _seedPoints.size()*sizeof(glm::vec3), &_seedPoints.front(), GL_STATIC_DRAW); -// -// // Vertex positions -// GLuint seedpointLocation = 0; -// glEnableVertexAttribArray(seedpointLocation); -// glVertexAttribPointer(seedpointLocation, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), reinterpret_cast(0)); -// -// glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer -// glBindVertexArray(0); //unbind array + GLuint seedpointPositionBuffer; + glGenVertexArrays(1, &_seedpointVAO); // generate array + glBindVertexArray(_seedpointVAO); // bind array + glGenBuffers(1, &seedpointPositionBuffer); // generate buffer + glBindBuffer(GL_ARRAY_BUFFER, seedpointPositionBuffer); // bind buffer + glBufferData(GL_ARRAY_BUFFER, _seedPoints.size()*sizeof(glm::vec3), &_seedPoints.front(), GL_STATIC_DRAW); + + // Vertex positions + GLuint seedpointLocation = 0; + glEnableVertexAttribArray(seedpointLocation); + glVertexAttribPointer(seedpointLocation, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), reinterpret_cast(0)); + + glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer + glBindVertexArray(0); //unbind array // ------ SETUP SHADERS ----------------- auto privateCallback = [this](const ghoul::filesystem::File& file) { @@ -247,8 +204,8 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) transform = transform*camTransform; transform = glm::translate(transform, relative.vec3()); - transform = glm::rotate(transform, -90.0f, glm::vec3(1.0, 0.0, 0.0)); - transform = glm::scale(transform, glm::vec3(0.1)); + transform = glm::rotate(transform, -90.0f, glm::vec3(1.0, 0.0, 0.0)); // Model has positive Z as up + transform = glm::scale(transform, glm::vec3(0.1)); // Scale to avoid depth buffer problems // ------ FIELDLINES ----------------- _shaderMutex->lock(); @@ -262,18 +219,18 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) _fieldlinesProgram->deactivate(); _shaderMutex->unlock(); -// // ------ SEEDPOINTS ----------------- -// _shaderMutex->lock(); -// _seedpointsProgram->activate(); -// _seedpointsProgram->setUniform("modelViewProjection", transform); -// -// glBindVertexArray(_seedpointVAO); -// glPointSize(3); -// glMultiDrawArrays(GL_POINTS, &_seedpointStart[0], &_seedpointCount[0], _seedPoints.size()); -// glBindVertexArray(0); -// -// _seedpointsProgram->deactivate(); -// _shaderMutex->unlock(); + // ------ SEEDPOINTS ----------------- + _shaderMutex->lock(); + _seedpointsProgram->activate(); + _seedpointsProgram->setUniform("modelViewProjection", transform); + + glBindVertexArray(_seedpointVAO); + glPointSize(5); + glMultiDrawArrays(GL_POINTS, &_lineStart[0], &_lineCount[0], _seedPoints.size()); + glBindVertexArray(0); + + _seedpointsProgram->deactivate(); + _shaderMutex->unlock(); } void RenderableFieldlines::update() { @@ -287,4 +244,55 @@ void RenderableFieldlines::safeShaderCompilation() { _shaderMutex->unlock(); } +std::vector > RenderableFieldlines::getFieldlinesData(std::string filename, ghoul::Dictionary hintsDictionary) { + std::string modelString; + float stepSize = 0.5; // default if no stepsize is specified in hints + std::string xVariable, yVariable, zVariable; + KameleonWrapper::Model model; + std::vector > fieldlinesData; + + if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) { + if (modelString == "BATSRUS") { + model = KameleonWrapper::Model::BATSRUS; + } else if (modelString == "ENLIL") { + LWARNING("ENLIL model not supported for fieldlines"); + return fieldlinesData; + } else { + LWARNING("Hints does not specify a valid 'Model'"); + return fieldlinesData; + } + + if (hintsDictionary.hasKey("Variables")) { + bool xVar, yVar, zVar; + xVar = hintsDictionary.getValue("Variables.1", xVariable); + yVar = hintsDictionary.getValue("Variables.2", yVariable); + zVar = hintsDictionary.getValue("Variables.3", zVariable); + + if (!xVar || !yVar || !zVar) { + LWARNING("Error reading variables! Must be 3 and must exist in CDF data"); + return fieldlinesData; + } + } else { + LWARNING("Hints does not specify valid 'Variables'"); + return fieldlinesData; + } + + if (!hintsDictionary.hasKey("Stepsize") || !hintsDictionary.getValue("Stepsize", stepSize)) { + LDEBUG("No stepsize set for fieldlines. Setting to default value (" << stepSize << ")"); + } + ghoul::Dictionary seedpointsDictionary; + if (hintsDictionary.hasKey("Seedpoints") && hintsDictionary.getValue("Seedpoints", seedpointsDictionary)) { + glm::vec3 seedPos; + for (auto index : seedpointsDictionary.keys()) { + hintsDictionary.getValue("Seedpoints."+index, seedPos); + _seedPoints.push_back(seedPos); + } + } + } + + KameleonWrapper kw(filename, model); + fieldlinesData = kw.getFieldLines(xVariable, yVariable, zVariable, _seedPoints, stepSize); + return fieldlinesData; +} + } // namespace openspace diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 985c4328bb..314074c0a0 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -63,8 +63,6 @@ KameleonWrapper::KameleonWrapper(const std::string& filename, Model model): _typ } getGridVariables(_xCoordVar, _yCoordVar, _zCoordVar); - LDEBUG("Using coordinate system variables: " << _xCoordVar << ", " << _yCoordVar << ", " << _zCoordVar); - _xMin = _model->getVariableAttribute(_xCoordVar, "actual_min").getAttributeFloat(); _xMax = _model->getVariableAttribute(_xCoordVar, "actual_max").getAttributeFloat(); _yMin = _model->getVariableAttribute(_yCoordVar, "actual_min").getAttributeFloat(); @@ -72,13 +70,6 @@ KameleonWrapper::KameleonWrapper(const std::string& filename, Model model): _typ _zMin = _model->getVariableAttribute(_zCoordVar, "actual_min").getAttributeFloat(); _zMax = _model->getVariableAttribute(_zCoordVar, "actual_max").getAttributeFloat(); - LDEBUG(_xCoordVar << "Min: " << _xMin); - LDEBUG(_xCoordVar << "Max: " << _xMax); - LDEBUG(_yCoordVar << "Min: " << _yMin); - LDEBUG(_yCoordVar << "Max: " << _yMax); - LDEBUG(_zCoordVar << "Min: " << _zMin); - LDEBUG(_zCoordVar << "Max: " << _zMax); - _lastiProgress = -1; // For progressbar } @@ -255,6 +246,7 @@ std::vector > KameleonWrapper::getFieldLines( for (glm::vec3 seedPoint : seedPoints) { 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()); // classify @@ -283,37 +275,43 @@ std::vector KameleonWrapper::traceCartesianFieldline( glm::vec3 color, pos, k1, k2, k3, k4; std::vector line; - - float stepX = stepSize, stepY = stepSize, stepZ = stepSize; // Should I do different stepsizes? - + float stepX, stepY, stepZ; int numSteps = 0; int maxSteps = 5000; pos = seedPoint; + _model->loadVariable(xVar); + _model->loadVariable(yVar); + _model->loadVariable(zVar); + + long int xID = _model->getVariableID(xVar); + long int yID = _model->getVariableID(yVar); + long int zID = _model->getVariableID(zVar); + // While we are inside the models boundries and not inside earth while ((pos.x < _xMax && pos.x > _xMin && pos.y < _yMax && pos.y > _yMin && - pos.z < _zMax && pos.z > _zMin) && !(pos.x < 1.0 && pos.x > -1.0 && - pos.y < 1.0 && pos.y > -1.0 && pos.z < 1.0 && pos.z > -1.0)) { + pos.z < _zMax && pos.z > _zMin) && !(pos.x*pos.x + pos.y*pos.y + pos.z*pos.z < 1.0)) { // Save position line.push_back(pos); // Calculate new position with Runge-Kutta 4th order - k1.x = _interpolator->interpolate(xVar, pos.x, pos.y, pos.z); - k1.y = _interpolator->interpolate(yVar, pos.x, pos.y, pos.z); - k1.z = _interpolator->interpolate(zVar, pos.x, pos.y, pos.z); + k1.x = _interpolator->interpolate(xID, pos.x, pos.y, pos.z, stepX, stepY, stepZ); + k1.y = _interpolator->interpolate(yID, pos.x, pos.y, pos.z); + k1.z = _interpolator->interpolate(zID, pos.x, pos.y, pos.z); k1 = (float)direction*glm::normalize(k1); - k2.x = _interpolator->interpolate(xVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); - k2.y = _interpolator->interpolate(yVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); - k2.z = _interpolator->interpolate(zVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); +// stepX*=stepSize, stepY*=stepSize, stepZ*=stepSize; + k2.x = _interpolator->interpolate(xID, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); + k2.y = _interpolator->interpolate(yID, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); + k2.z = _interpolator->interpolate(zID, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); k2 = (float)direction*glm::normalize(k2); - k3.x = _interpolator->interpolate(xVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); - k3.y = _interpolator->interpolate(yVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); - k3.z = _interpolator->interpolate(zVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); + k3.x = _interpolator->interpolate(xID, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); + k3.y = _interpolator->interpolate(yID, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); + k3.z = _interpolator->interpolate(zID, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z); k3 = (float)direction*glm::normalize(k3); - k4.x = _interpolator->interpolate(xVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); - k4.y = _interpolator->interpolate(yVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); - k4.z = _interpolator->interpolate(zVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); + k4.x = _interpolator->interpolate(xID, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); + k4.y = _interpolator->interpolate(yID, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); + k4.z = _interpolator->interpolate(zID, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z); k4 = (float)direction*glm::normalize(k4); pos.x = pos.x + (stepX/6.0)*(k1.x + 2.0*k2.x + 2.0*k3.x + k4.x); pos.y = pos.y + (stepY/6.0)*(k1.y + 2.0*k2.y + 2.0*k3.y + k4.y); @@ -321,14 +319,15 @@ std::vector KameleonWrapper::traceCartesianFieldline( ++numSteps; if (numSteps > maxSteps) { - LDEBUG("Max number of steps taken"); + LDEBUG("Max number of steps taken (" << maxSteps <<")"); break; } } + line.push_back(pos); - if (pos.z > 0.0 && pos.x < 1.0 && pos.x > -1.0 && pos.y < 1.0 && pos.y > -1.0) + if (pos.z > 0.0 && (pos.x*pos.x + pos.y*pos.y + pos.z*pos.z < 1.0)) end = FieldlineEnd::NORTH; - else if (pos.z < 0.0 && pos.x < 1.0 && pos.x > -1.0 && pos.y < 1.0 && pos.y > -1.0) + else if (pos.z < 0.0 && (pos.x*pos.x + pos.y*pos.y + pos.z*pos.z < 1.0)) end = FieldlineEnd::SOUTH; else end = FieldlineEnd::OUT; From 6419f34b5a0b7f66d1ef11053053f420c3bc68d0 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Wed, 18 Jun 2014 10:34:40 -0400 Subject: [PATCH 021/113] ABuffer working with small issues - Pointing to bugfixed Ghoul - Pointing to Ghoul with Linux file callback - Fixed interaction distance control bug when moving to close - Distance control with mouse wheel added - Kameleonwrapper normalization based on histogram - ABuffer seems to work with small issues --- .gitignore | 3 + ext/ghoul | 2 +- .../openspace/abuffer/abufferSingleLinked.h | 10 +- include/openspace/abuffer/abuffer_i.h | 1 + .../openspace/rendering/renderablevolumegl.h | 15 +- openspace-data | 2 +- shaders/ABuffer/abufferResolveFragment.glsl | 95 ++++++++-- shaders/ABuffer/abufferSort.hglsl | 7 +- src/abuffer/abufferSingleLinked.cpp | 177 ++++++++++++++---- src/engine/openspaceengine.cpp | 4 +- src/interaction/interactionhandler.cpp | 25 ++- src/main.cpp | 4 +- src/rendering/renderablevolume.cpp | 54 ++++-- src/rendering/renderablevolumegl.cpp | 140 +++----------- src/rendering/renderengine.cpp | 1 + src/util/kameleonwrapper.cpp | 75 ++++++-- 16 files changed, 377 insertions(+), 238 deletions(-) diff --git a/.gitignore b/.gitignore index dc6c035a1a..b86c3ed18d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ ext/SGCT .DS_Store *.swp +# generated glsl files +*.gglsl + # CMake stuff CMakeCache.txt CMakeFiles diff --git a/ext/ghoul b/ext/ghoul index 1f478d7956..a616a2ce84 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 1f478d79565c3c7b4343ab5ca1cd3cb30c491173 +Subproject commit a616a2ce84ec0fd9d6573ef6690707ef4a841669 diff --git a/include/openspace/abuffer/abufferSingleLinked.h b/include/openspace/abuffer/abufferSingleLinked.h index 4ff20b2070..5e946af48a 100644 --- a/include/openspace/abuffer/abufferSingleLinked.h +++ b/include/openspace/abuffer/abufferSingleLinked.h @@ -28,6 +28,7 @@ #include #include +#include namespace openspace { @@ -41,6 +42,7 @@ public: virtual void clear(); virtual void preRender(); virtual void postRender(); + virtual void resolve(); private: @@ -55,7 +57,13 @@ private: GLuint fragmentTexture; GLuint _screenQuad; - ghoul::opengl::ProgramObject* resolveShader; + ghoul::opengl::ProgramObject* _resolveShader; + ghoul::filesystem::File* _fragmentShaderFile; + std::string _fragmentShaderPath; + bool _updateShader; + + void generateShaderSource(); + bool updateShader(); }; // ABuffer_I } // openspace diff --git a/include/openspace/abuffer/abuffer_i.h b/include/openspace/abuffer/abuffer_i.h index 9e1644edb0..8ee04eedb7 100644 --- a/include/openspace/abuffer/abuffer_i.h +++ b/include/openspace/abuffer/abuffer_i.h @@ -38,6 +38,7 @@ public: virtual void clear() = 0; virtual void preRender() = 0; virtual void postRender() = 0; + virtual void resolve() = 0; }; // ABuffer_I } // openspace diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index 4aaed2a6c0..eb39fe3065 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -58,24 +58,19 @@ public: private: ghoul::Dictionary _hintsDictionary; + std::string _filename; std::string _transferFunctionPath; - float _stepSize; + + ghoul::filesystem::File* _transferFunctionFile; + ghoul::opengl::Texture* _volume; ghoul::opengl::Texture* _transferFunction; - ghoul::opengl::ProgramObject* _twopassProgram; - GLuint _screenQuad; VolumeRaycasterBox* _colorBoxRenderer; glm::vec3 _boxScaling; - std::mutex* _shaderMutex; - - ghoul::filesystem::File* _vertexSourceFile; - ghoul::filesystem::File* _fragmentSourceFile; - bool _programUpdateOnSave; - - void safeShaderCompilation(); + bool _updateTransferfunction; }; } // namespace openspace diff --git a/openspace-data b/openspace-data index 840edd3a81..835261f477 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 840edd3a81db2957825abe9e49a524d490b7332f +Subproject commit 835261f4775ac7a7e5fcd000b1e254d4c947e389 diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index c3fe4d24f0..84c7720f25 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -1,17 +1,28 @@ #version 430 -// uniforms -uniform sampler3D volume; -uniform sampler1D transferFunction; +uniform int SCREEN_WIDTH; +uniform int SCREEN_HEIGHT; +uniform float ALPHA_LIMIT = 0.95; in vec2 texCoord; out vec4 color; // settings -#define ALPHA_LIMIT 0.98 -#define LOOP_LIMIT 200 +#define LOOP_LIMIT 800 #define MAX_FRAGMENTS 16 -#define MAX_VOLUMES 4 +#define SHOWFUNC + +// GENERATED CONTENT +#pragma openspace insert HEADERS +// END GENERATED CONTENT + + +const float stepSize = 0.01; +const float samplingRate = 1.0; +float volumeStepSize[] = { + stepSize +}; + #include "abufferStruct.hglsl" ABufferStruct_t fragments[MAX_FRAGMENTS]; @@ -49,8 +60,22 @@ void blendGeometry(inout vec4 color, ABufferStruct_t frag) { } */ +float globz(float z) { + return z; + // return log(2.0*z-1.0); + // return exp(2.0*z-1.0); + // const float zNear = 0.1f; + // const float zFar = 1.0f; + // //float z_b = texture2D(depthBuffTex, vTexCoord).x; + // float z_b = z; + // float z_n = 2.0 * z_b - 1.0; + // float z_e = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); + // return z_e; + //return (2.0 * z - near - far) / (far - near); +} + vec4 calculate_final_color(uint frag_count) { - + // volumeStepSize[volID] = 0.01; int currentVolumeBitmask = 0; vec4 final_color = vec4(0); @@ -72,19 +97,23 @@ vec4 calculate_final_color(uint frag_count) { currentVolumeBitmask = currentVolumeBitmask ^ (type); if(type == 0) + //blendStep(final_color, _col_(startFrag), stepSize); final_color = blend(final_color, _col_(startFrag)); if(bool(currentVolumeBitmask)) { int volID = type -1; float p = 0.0f; - const float stepSize = 0.01; //const float l = volume_length[volID]; const float S1 = volume_zlength[volID].x; const float S2 = volume_zlength[volID].y; const float L = S1 - S2; - const float l = (_z_(startFrag) - S1) / L - (_z_(endFrag) - S1) / L; - const vec3 direction = volume_direction[volID]; + const float z1 = globz(_z_(startFrag)); + const float z2 = globz(_z_(endFrag)); + // const float z1 = _z_(startFrag); + // const float z2 = _z_(endFrag); + const float l = ((z1 - S1) / L - (z2 - S1) / L) * volume_length[volID]; + int max_iterations = int(l / volumeStepSize[volID]); int iterations = 0; vec3 position; @@ -104,15 +133,18 @@ vec4 calculate_final_color(uint frag_count) { // TransferFunction vec4 color = vec4(0); - float intensity; - while(p < l && iterations < LOOP_LIMIT) { - intensity = length(texture(volume, volume_position[volID])); - color = texture(transferFunction, intensity); - blendStep(final_color, color, stepSize); + for(int k = 0; k < max_iterations && k < LOOP_LIMIT; ++k) { + //while(p < l && iterations < LOOP_LIMIT) { + +// GENERATED CONTENT +#pragma openspace insert SAMPLERCALLS +// END GENERATED CONTENT + //final_color = blend(final_color, color*stepSize); - p+= stepSize; - volume_position[volID] += direction*stepSize; - ++iterations; + + volume_position[volID] += volume_direction[volID]*volumeStepSize[volID]; + //p+= stepSize; + //++iterations; } } @@ -125,7 +157,8 @@ vec4 calculate_final_color(uint frag_count) { // blendGeometry(final_color, endFrag); // final_color = blend(final_color, frag_color); - if(i == frag_count_1 -1 && _type_(endFrag) == 0) + if(i == frag_count_1 -1 && _type_(endFrag) == 0) + // if(i == frag_count_1 -1) final_color = blend(final_color, _col_(endFrag)); } @@ -133,6 +166,20 @@ vec4 calculate_final_color(uint frag_count) { // int id =3; // if(id < frag_count)final_color = blend(final_color, _col_(fragments[id])); + // if(frag_count > 0) + // final_color = _col_(fragments[0]); +#ifdef SHOWFUNC + float showfunc_size = 20.0; + if(gl_FragCoord.y > float(SCREEN_HEIGHT) - showfunc_size) { + float normalizedIntensity = gl_FragCoord.x / float(SCREEN_WIDTH) ; + vec4 tfc = texture(transferFunction, normalizedIntensity); + final_color = tfc; + } else if(ceil(gl_FragCoord.y) == float(SCREEN_HEIGHT) - showfunc_size) { + const float intensity = 0.4; + final_color = vec4(intensity,intensity,intensity,1.0); + } +#endif + return final_color; } @@ -148,4 +195,12 @@ void main() { color = calculate_final_color(frag_count); //color = vec4(float(frag_count) / 5.0, 0.0, 0.0, 1.0); -} \ No newline at end of file +} + +// GENERATED CONTENT +#pragma openspace insert SAMPLERS +// END GENERATED CONTENT + + + + diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index 71e8534100..c8becb8b00 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -56,8 +56,8 @@ void sort_fragments_list(uint frag_count) { bool start = true; vec3 startColor; vec4 startPosition; - for(jj = 0; jj < frag_count; ++jj) { - int type = int(_type_(fragments[jj])) -1; + for(jj = ii; jj < frag_count; ++jj) { + int type = int(_type_(fragments[jj])) - 1; if(type== ii) { if(start) { startColor = _col_(fragments[jj]).rgb; @@ -66,10 +66,11 @@ void sort_fragments_list(uint frag_count) { start = false; } else { vec3 dir = _col_(fragments[jj]).rgb - startColor; - volume_direction[ii] = normalize(dir); volume_position[ii] = startColor; volume_length[ii] = length(dir); + volume_direction[ii] = normalize(dir); volume_zlength[ii].y = _z_(fragments[jj]); + volumeStepSize[ii] = 1.0/(length(volume_direction[ii]*volume_dim[ii])); //volume_length[ii] = pscLength(_pos_(fragments[jj]), startPosition); break; } diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp index b28948c5d4..8b64a1ae6f 100644 --- a/src/abuffer/abufferSingleLinked.cpp +++ b/src/abuffer/abufferSingleLinked.cpp @@ -29,11 +29,43 @@ #include #include +#include +#include + #define MAX_LAYERS 10 #define BUFFER_OFFSET(i) ((char *)NULL + (i)) namespace { std::string _loggerCat = "ABufferSingleLinked"; + +const std::string openspaceHeaders = R"( +#define MAX_VOLUMES 1 +// VOLUME1 +uniform sampler3D volume; +uniform sampler1D transferFunction; +void sampleVolume1(inout vec4 finalColor, vec3 position); + + +const vec3 volume_dim[] = { + vec3(300.0,100.0,100.0) +}; +)"; + +const std::string openspaceSamplerCalls = R"( +if((currentVolumeBitmask & (1 << 0)) == 1) + sampleVolume1(final_color,volume_position[volID]); +)"; + +const std::string openspaceSamplers = R"( +void sampleVolume1(inout vec4 finalColor, vec3 position) { + float intensity = texture(volume, position).x; + //intensity *=25.0; + //intensity = clamp(intensity*100.0, 0.0, 1.0); + vec4 color = texture(transferFunction, intensity); + blendStep(finalColor, color, stepSize); +} +)"; + } namespace openspace { @@ -51,12 +83,27 @@ ABufferSingleLinked::ABufferSingleLinked() { atomicCounterBuffer = 0; fragmentBuffer = 0; fragmentTexture = 0; + + const std::string fragmentShaderSourcePath = absPath("${SHADERS}/ABuffer/abufferResolveFragment.glsl"); + _fragmentShaderFile = new ghoul::filesystem::File(fragmentShaderSourcePath, true); + _updateShader = false; + _fragmentShaderPath = fragmentShaderSourcePath + ".ABuffer.gglsl"; + + generateShaderSource(); + + } ABufferSingleLinked::~ABufferSingleLinked() { if(data != 0) delete data; + if(_fragmentShaderFile) + delete _fragmentShaderFile; + + if(_resolveShader) + delete _resolveShader; + glDeleteTextures(1,&anchorPointerTexture); glDeleteTextures(1,&fragmentTexture); glDeleteBuffers(1,&anchorPointerTextureInitializer); @@ -99,30 +146,13 @@ bool ABufferSingleLinked::initialize() { // ============================ // SHADERS // ============================ - resolveShader = nullptr; - using ghoul::opengl::ShaderObject; - using ghoul::opengl::ProgramObject; - ShaderObject* vs - = new ShaderObject(ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/ABuffer/abufferResolveVertex.glsl"), "Vertex"); - ShaderObject* fs - = new ShaderObject(ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/ABuffer/abufferResolveFragment.glsl"), "Fragment"); + auto shaderCallback = [this](const ghoul::filesystem::File& file) { + _updateShader = true; + }; + _fragmentShaderFile->setCallback(shaderCallback); - resolveShader = new ProgramObject; - resolveShader->attachObject(vs); - resolveShader->attachObject(fs); - - if (!resolveShader->compileShaderObjects()) { - LERROR("Could not compile shader"); - return false; - } - if (!resolveShader->linkProgramObject()){ - LERROR("Could not link shader"); - return false; - } - resolveShader->setUniform("volume", 0); - resolveShader->setUniform("transferFunction", 1); + _resolveShader = nullptr; + updateShader(); // ============================ // GEOMETRY (quad) @@ -172,26 +202,95 @@ void ABufferSingleLinked::preRender() { void ABufferSingleLinked::postRender() { - ghoul::opengl::Texture* volume = nullptr; - ghoul::opengl::Texture* tf = nullptr; - OsEng.configurationManager().getValue("firstVolume", volume); - OsEng.configurationManager().getValue("firstTransferFunction", tf); - resolveShader->activate(); + if(_updateShader) { + _updateShader = false; + generateShaderSource(); + updateShader(); - if(volume) { - glActiveTexture(GL_TEXTURE0); - volume->bind(); } +} - if(tf) { - glActiveTexture(GL_TEXTURE1); - tf->bind(); +void ABufferSingleLinked::resolve() { + + if(_resolveShader) { + ghoul::opengl::Texture* volume = nullptr; + ghoul::opengl::Texture* tf = nullptr; + OsEng.configurationManager().getValue("firstVolume", volume); + OsEng.configurationManager().getValue("firstTransferFunction", tf); + _resolveShader->activate(); + + if(volume) { + glActiveTexture(GL_TEXTURE0); + volume->bind(); + } + + if(tf) { + glActiveTexture(GL_TEXTURE1); + tf->bind(); + } + //LDEBUG("SCREEN_WIDTH" << width); + glBindVertexArray(_screenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + _resolveShader->deactivate(); } - //resolveShader->setUniform("SCREEN_WIDTH", width); - //resolveShader->setUniform("SCREEN_HEIGHT", height); - glBindVertexArray(_screenQuad); - glDrawArrays(GL_TRIANGLES, 0, 6); - resolveShader->deactivate(); + +} + +bool ABufferSingleLinked::updateShader() { + + using ghoul::opengl::ShaderObject; + using ghoul::opengl::ProgramObject; + ShaderObject* vs + = new ShaderObject(ShaderObject::ShaderType::ShaderTypeVertex, + absPath("${SHADERS}/ABuffer/abufferResolveVertex.glsl"), "Vertex"); + ShaderObject* fs + = new ShaderObject(ShaderObject::ShaderType::ShaderTypeFragment,_fragmentShaderPath, "Fragment"); + + ghoul::opengl::ProgramObject* resolveShader = new ProgramObject; + resolveShader->attachObject(vs); + resolveShader->attachObject(fs); + + if (!resolveShader->compileShaderObjects()) { + LERROR("Could not compile shader"); + return false; + } + if (!resolveShader->linkProgramObject()){ + LERROR("Could not link shader"); + return false; + } + resolveShader->setUniform("volume", 0); + resolveShader->setUniform("transferFunction", 1); + resolveShader->setUniform("SCREEN_WIDTH", static_cast(width)); + resolveShader->setUniform("SCREEN_HEIGHT", static_cast(height)); + + if(_resolveShader) + delete _resolveShader; + + _resolveShader = resolveShader; + LDEBUG("Successfully updated shader!"); + return true; +} + +void ABufferSingleLinked::generateShaderSource() { + std::string line, source = ""; + std::ifstream fragmentShaderFile(_fragmentShaderFile->path()); + if(fragmentShaderFile.is_open()) { + while(std::getline(fragmentShaderFile, line)) { + if(line == "#pragma openspace insert HEADERS") { + line = openspaceHeaders; + } else if(line == "#pragma openspace insert SAMPLERCALLS") { + line = openspaceSamplerCalls; + } else if(line == "#pragma openspace insert SAMPLERS") { + line = openspaceSamplers; + } + source += line + "\n"; + } + } + fragmentShaderFile.close(); + + std::ofstream fragmentShaderOut(_fragmentShaderPath); + fragmentShaderOut << source; + fragmentShaderOut.close(); } } // openspace \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 55e29ad495..ca1e7bbbab 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -124,9 +124,9 @@ bool OpenSpaceEngine::registerBasePathFromConfigurationFile(const std::string& f bool OpenSpaceEngine::findConfiguration(std::string& filename) { - if (!filename.empty()) + if (!filename.empty()) { return FileSys.fileExists(filename); - else { + } else { std::string currentDirectory = FileSys.absolutePath(FileSys.currentDirectory()); size_t occurrences = std::count(currentDirectory.begin(), currentDirectory.end(), ghoul::filesystem::FileSystem::PathSeparator); diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index fc7cb4ba9c..020ba82d3f 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -307,22 +307,22 @@ void InteractionHandler::keyboardCallback(int key, int action) { const double dt = getDt(); if(action == SGCT_PRESS || action == SGCT_REPEAT) { - if (key == 'S') { + if (key == SGCT_KEY_S) { glm::vec3 euler(speed * dt, 0.0, 0.0); glm::quat rot = glm::quat(euler); orbit(rot); } - if (key == 'W') { + if (key == SGCT_KEY_W) { glm::vec3 euler(-speed * dt, 0.0, 0.0); glm::quat rot = glm::quat(euler); orbit(rot); } - if (key == 'A') { + if (key == SGCT_KEY_A) { glm::vec3 euler(0.0, -speed * dt, 0.0); glm::quat rot = glm::quat(euler); orbit(rot); } - if (key == 'D') { + if (key == SGCT_KEY_D) { glm::vec3 euler(0.0, speed * dt, 0.0); glm::quat rot = glm::quat(euler); orbit(rot); @@ -347,19 +347,19 @@ void InteractionHandler::keyboardCallback(int key, int action) { glm::quat rot = glm::quat(euler); rotate(rot); } - if (key == 'R') { + if (key == SGCT_KEY_R) { PowerScaledScalar dist(-speed * dt, 0.0); distance(dist); } - if (key == 'F') { + if (key == SGCT_KEY_F) { PowerScaledScalar dist(speed * dt, 0.0); distance(dist); } - if (key == 'T') { + if (key == SGCT_KEY_T) { PowerScaledScalar dist(-speed * 100.0 * dt, 0.0); distance(dist); } - if (key == 'G') { + if (key == SGCT_KEY_G) { PowerScaledScalar dist(speed * 100.0 * dt, 0.0); distance(dist); } @@ -417,6 +417,15 @@ void InteractionHandler::mouseScrollWheelCallback(int pos) { //if(mouseControl_ != nullptr) { // mouseControl_->mouseScrollCallback(pos); //} + const double speed = 4.75; + const double dt = getDt(); + if(pos < 0) { + PowerScaledScalar dist(speed * dt, 0.0); + distance(dist); + } else if(pos > 0) { + PowerScaledScalar dist(-speed * dt, 0.0); + distance(dist); + } } diff --git a/src/main.cpp b/src/main.cpp index cf97ebe9ff..ac958ba03d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -159,11 +159,11 @@ void mainMousePosCallback(double x, double y) OsEng.mousePositionCallback(static_cast(x), static_cast(y)); } -void mainMouseScrollCallback(double pos, double /*pos2*/) +void mainMouseScrollCallback(double posX, double posY) { // TODO use float instead if (_sgctEngine->isMaster()) - OsEng.mouseScrollWheelCallback(static_cast(pos)); + OsEng.mouseScrollWheelCallback(static_cast(posY)); } void mainEncodeFun() diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index dd741cc8b1..45324afa40 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -77,7 +77,10 @@ RenderableVolume::RenderableVolume(const ghoul::Dictionary& dictionary) : Render RenderableVolume::~RenderableVolume() { } -ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary) { +ghoul::opengl::Texture* RenderableVolume::loadVolume( + const std::string& filepath, + const ghoul::Dictionary& hintsDictionary) +{ if( ! FileSys.fileExists(filepath)) { LWARNING("Could not load volume, could not find '" << filepath << "'"); return nullptr; @@ -91,17 +94,20 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath glm::size3_t dimensions(1,1,1); double tempValue; - if (hintsDictionary.hasKey("Dimensions.1") && hintsDictionary.getValue("Dimensions.1", tempValue)) { + if (hintsDictionary.hasKey("Dimensions.1") && + hintsDictionary.getValue("Dimensions.1", tempValue)) { int intVal = static_cast(tempValue); if(intVal > 0) dimensions[0] = intVal; } - if (hintsDictionary.hasKey("Dimensions.2") && hintsDictionary.getValue("Dimensions.2", tempValue)) { + if (hintsDictionary.hasKey("Dimensions.2") && + hintsDictionary.getValue("Dimensions.2", tempValue)) { int intVal = static_cast(tempValue); if(intVal > 0) dimensions[1] = intVal; } - if (hintsDictionary.hasKey("Dimensions.3") && hintsDictionary.getValue("Dimensions.3", tempValue)) { + if (hintsDictionary.hasKey("Dimensions.3") && + hintsDictionary.getValue("Dimensions.3", tempValue)) { int intVal = static_cast(tempValue); if(intVal > 0) dimensions[2] = intVal; @@ -152,7 +158,9 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath } fclose(file); - return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, ghoul::opengl::Texture::FilterMode::Linear, ghoul::opengl::Texture::WrappingMode::ClampToBorder); + ghoul::opengl::Texture* t = new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, ghoul::opengl::Texture::FilterMode::Linear, ghoul::opengl::Texture::WrappingMode::ClampToBorder); + t->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); + return t; } KameleonWrapper::Model model; @@ -176,8 +184,9 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath fwrite(data, sizeof(float), length, file); fclose(file); } - return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, ghoul::opengl::Texture::FilterMode::Linear, ghoul::opengl::Texture::WrappingMode::ClampToBorder); - + ghoul::opengl::Texture* t = new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, ghoul::opengl::Texture::FilterMode::Linear, ghoul::opengl::Texture::WrappingMode::ClampToBorder); + t->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); + return t; } else if (hintsDictionary.hasKey("Variables")) { std::string xVariable, yVariable, zVariable; bool xVar, yVar, zVar; @@ -207,8 +216,16 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath // // delete fieldlinesData; // delete rhoData; + if(cache) { + FILE* file = fopen (cachepath.c_str(), "wb"); + int length = dimensions[0] *dimensions[1] *dimensions[2]; + fwrite(fieldlinesData, sizeof(float), length, file); + fclose(file); + } - return new ghoul::opengl::Texture(fieldlinesData, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); + ghoul::opengl::Texture* t = new ghoul::opengl::Texture(fieldlinesData, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT); + t->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); + return t; } } else { @@ -290,7 +307,9 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string // check if not a txt based texture if ( ! hasExtension(filepath, "txt")) { - return ghoul::opengl::loadTexture(f); + ghoul::opengl::Texture* t = ghoul::opengl::loadTexture(f); + t->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); + return t; } // it is a txt based texture @@ -420,17 +439,18 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string //LDEBUG("["<< position <<"] " << value); } - LDEBUG(weight << ", (" << - transferFunction[4*i+0] << ", " << - transferFunction[4*i+1] << ", " << - transferFunction[4*i+2] << ", " << - transferFunction[4*i+3] << ")"); + // LDEBUG(weight << ", (" << + // transferFunction[4*i+0] << ", " << + // transferFunction[4*i+1] << ", " << + // transferFunction[4*i+2] << ", " << + // transferFunction[4*i+3] << ")"); } - - return new ghoul::opengl::Texture(transferFunction, + ghoul::opengl::Texture* t = new ghoul::opengl::Texture(transferFunction, glm::size3_t(width,1,1),ghoul::opengl::Texture::Format::RGBA, - GL_RGBA, GL_FLOAT);; + GL_RGBA, GL_FLOAT, ghoul::opengl::Texture::FilterMode::Linear, + ghoul::opengl::Texture::WrappingMode::ClampToBorder); + return t; } } // namespace openspace diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index cb52808d40..64b9ec3772 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -42,10 +42,9 @@ namespace { namespace openspace { RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): - RenderableVolume(dictionary), _screenQuad(0), _boxScaling(1.0, 1.0, 1.0), - _programUpdateOnSave(false) { + RenderableVolume(dictionary), _boxScaling(1.0, 1.0, 1.0), + _updateTransferfunction(false) { - _shaderMutex = new std::mutex; _filename = ""; if(dictionary.hasKey("Volume")) { @@ -59,34 +58,8 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): if(dictionary.hasKey("Hints")) dictionary.getValue("Hints", _hintsDictionary); - std::string vshaderpath = ""; - std::string fshaderpath = ""; - - if (dictionary.hasKey("Shaders")) { - ghoul::Dictionary shaderDictionary; - if(dictionary.getValue("Shaders", shaderDictionary)) { - if (shaderDictionary.hasKey("VertexShader")) { - shaderDictionary.getValue("VertexShader", vshaderpath); - } - if (shaderDictionary.hasKey("FragmentShader")) { - shaderDictionary.getValue("FragmentShader", fshaderpath); - } - - vshaderpath = findPath(vshaderpath); - fshaderpath = findPath(fshaderpath); - - _vertexSourceFile = new ghoul::filesystem::File(vshaderpath, false); - _fragmentSourceFile = new ghoul::filesystem::File(fshaderpath, false); - - _twopassProgram = new ghoul::opengl::ProgramObject("TwoPassProgram"); - ghoul::opengl::ShaderObject* vertexShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeVertex,vshaderpath); - ghoul::opengl::ShaderObject* fragmentShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeFragment,fshaderpath); - _twopassProgram->attachObject(vertexShader); - _twopassProgram->attachObject(fragmentShader); - } - } - _transferFunction = nullptr; + _transferFunctionFile = nullptr; if (dictionary.hasKey("TransferFunction")) { std::string transferFunctionPath = ""; if(dictionary.getValue("TransferFunction", transferFunctionPath)) { @@ -95,12 +68,10 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): } if( _transferFunctionPath == "") { LERROR("No transferFunction!"); + } else { + _transferFunctionFile = new ghoul::filesystem::File(_transferFunctionPath, true); } - - if(dictionary.hasKey("UpdateOnSave")) { - dictionary.getValue("UpdateOnSave", _programUpdateOnSave); - } double tempValue; if(dictionary.hasKey("BoxScaling.1") && dictionary.getValue("BoxScaling.1", tempValue)) { @@ -137,56 +108,14 @@ bool RenderableVolumeGL::initialize() { _transferFunction->uploadTexture(); OsEng.configurationManager().setValue("firstVolume", _volume); OsEng.configurationManager().setValue("firstTransferFunction", _transferFunction); - //glBindImageTexture(2, *_volume, 0, GL_FALSE, 0, GL_READ_ONLY, _volume->type()); - - // ------ SETUP GEOMETRY ---------------- - const GLfloat size = 1.0f; - const GLfloat vertex_texcoord_data[] = { // square of two triangles (sigh) - // x y z s t - -size, -size, 0.0f, 0.0f, 0.0f, - size, size, 0.0f, 1.0f, 1.0f, - -size, size, 0.0f, 0.0f, 1.0f, - -size, -size, 0.0f, 0.0f, 0.0f, - size, -size, 0.0f, 1.0f, 0.0f, - size, size, 0.0f, 1.0f, 1.0f + + auto textureCallback = [this](const ghoul::filesystem::File& file) { + _updateTransferfunction = true; }; - - GLuint vertexPositionBuffer; - glGenVertexArrays(1, &_screenQuad); // generate array - glBindVertexArray(_screenQuad); // bind array - glGenBuffers(1, &vertexPositionBuffer); // generate buffer - glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_texcoord_data), vertex_texcoord_data, GL_STATIC_DRAW); - - // Vertex positions - GLuint vertexLocation = 2; - glEnableVertexAttribArray(vertexLocation); - glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), reinterpret_cast(0)); - - // Texture coordinates - GLuint texcoordLocation = 0; - glEnableVertexAttribArray(texcoordLocation); - glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)(3*sizeof(GLfloat))); - - glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer - glBindVertexArray(0); //unbind array - + _transferFunctionFile->setCallback(textureCallback); + _colorBoxRenderer->initialize(); - // ------ SETUP SHADERS ----------------- - auto privateCallback = [this](const ghoul::filesystem::File& file) { - safeShaderCompilation(); - }; - if(_programUpdateOnSave) { - _vertexSourceFile->setCallback(privateCallback); - _fragmentSourceFile->setCallback(privateCallback); - } - - _twopassProgram->compileShaderObjects(); - _twopassProgram->linkProgramObject(); - _twopassProgram->setUniform("texBack", 0); - _twopassProgram->setUniform("texFront", 1); - _twopassProgram->setUniform("texVolume", 2); return true; } @@ -196,7 +125,20 @@ bool RenderableVolumeGL::deinitialize() { } void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { - _stepSize = 0.01f; + if(_updateTransferfunction) { + _updateTransferfunction = false; + ghoul::opengl::Texture* transferFunction = loadTransferFunction(_transferFunctionPath); + if(transferFunction) { + const void* data = transferFunction->pixelData(); + glBindBuffer(GL_COPY_READ_BUFFER, *transferFunction); + _transferFunction->bind(); + glTexImage1D(GL_TEXTURE_1D, 0, _transferFunction->internalFormat(), _transferFunction->width(),0, _transferFunction->format(), _transferFunction->dataType(), data); + //delete data; + delete transferFunction; + LDEBUG("Updated transferfunction!"); + + } + } glm::mat4 transform ; glm::mat4 camTransform = camera->viewRotationMatrix(); @@ -208,44 +150,12 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { transform = glm::scale(transform, _boxScaling); _colorBoxRenderer->render(camera->viewProjectionMatrix(), transform); - /* - // Draw screenquad - _shaderMutex->lock(); - _twopassProgram->activate(); - _twopassProgram->setUniform("stepSize", _stepSize); - - // Set textures - glActiveTexture(GL_TEXTURE0); - _colorBoxRenderer->backFace()->bind(); - glActiveTexture(GL_TEXTURE1); - _colorBoxRenderer->frontFace()->bind(); - glActiveTexture(GL_TEXTURE2); - _volume->bind(); - - glBindVertexArray(_screenQuad); - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); - - _twopassProgram->deactivate(); - _shaderMutex->unlock(); - */ + } void RenderableVolumeGL::update() { } -void RenderableVolumeGL::safeShaderCompilation() { - /* - _shaderMutex->lock(); - _twopassProgram->rebuildFromFile(); - _twopassProgram->compileShaderObjects(); - _twopassProgram->linkProgramObject(); - _twopassProgram->setUniform("texBack", 0); - _twopassProgram->setUniform("texFront", 1); - _twopassProgram->setUniform("texVolume", 2); - _shaderMutex->unlock(); - */ -} } // namespace openspace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index da40fe000f..96891951c7 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -176,6 +176,7 @@ void RenderEngine::render() _abuffer->preRender(); _sceneGraph->render(_mainCamera); _abuffer->postRender(); + _abuffer->resolve(); /* // Print some useful information on the master viewport if (sgct::Engine::instance()->isMaster()) { diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index b34bee3aeb..0b2d4419c0 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -94,16 +94,27 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz int size = outDimensions.x*outDimensions.y*outDimensions.z; float* data = new float[size]; + double* doubleData = new double[size]; - float varMin = _model->getVariableAttribute(var, "actual_min").getAttributeFloat(); - float varMax = _model->getVariableAttribute(var, "actual_max").getAttributeFloat(); - - float stepX = (_xMax-_xMin)/(static_cast(outDimensions.x)); - float stepY = (_yMax-_yMin)/(static_cast(outDimensions.y)); - float stepZ = (_zMax-_zMin)/(static_cast(outDimensions.z)); + double varMin = _model->getVariableAttribute(var, "actual_min").getAttributeFloat(); + double varMax = _model->getVariableAttribute(var, "actual_max").getAttributeFloat(); + + double stepX = (_xMax-_xMin)/(static_cast(outDimensions.x)); + double stepY = (_yMax-_yMin)/(static_cast(outDimensions.y)); + double stepZ = (_zMax-_zMin)/(static_cast(outDimensions.z)); LDEBUG(var << "Min: " << varMin); LDEBUG(var << "Max: " << varMax); + + // HISTOGRAM + const int bins = 200; + const float truncLim = 0.9; + std::vector histogram (bins,0); + auto mapToHistogram = [varMin, varMax, bins](double val) { + double zeroToOne = (val-varMin)/(varMax-varMin); + zeroToOne *= static_cast(bins); + return static_cast(zeroToOne); + }; for (int x = 0; x < outDimensions.x; ++x) { progressBar(x, outDimensions.x); @@ -114,35 +125,37 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz int index = x + y*outDimensions.x + z*outDimensions.x*outDimensions.y; if(_type == Model::BATSRUS) { - float xPos = _xMin + stepX*x; - float yPos = _yMin + stepY*y; - float zPos = _zMin + stepZ*z; + double xPos = _xMin + stepX*x; + double yPos = _yMin + stepY*y; + double zPos = _zMin + stepZ*z; // get interpolated data value for (xPos, yPos, zPos) - float value = _interpolator->interpolate(var, xPos, yPos, zPos); + double value = _interpolator->interpolate(var, xPos, yPos, zPos); // scale to [0,1] - data[index] = (value-varMin)/(varMax-varMin); + //doubleData[index] = (value-varMin)/(varMax-varMin); + doubleData[index] = value; + histogram[mapToHistogram(value)]++; } else if (_type == Model::ENLIL) { // Put r in the [0..sqrt(3)] range - float rNorm = sqrt(3.0)*(float)x/(float)(outDimensions.x-1); + double rNorm = sqrt(3.0)*(double)x/(double)(outDimensions.x-1); // Put theta in the [0..PI] range - float thetaNorm = M_PI*(float)y/(float)(outDimensions.y-1); + double thetaNorm = M_PI*(double)y/(double)(outDimensions.y-1); // Put phi in the [0..2PI] range - float phiNorm = 2.0*M_PI*(float)z/(float)(outDimensions.z-1); + double phiNorm = 2.0*M_PI*(double)z/(double)(outDimensions.z-1); // Go to physical coordinates before sampling - float rPh = _xMin + rNorm*(_xMax-_xMin); - float thetaPh = thetaNorm; + double rPh = _xMin + rNorm*(_xMax-_xMin); + double thetaPh = thetaNorm; // phi range needs to be mapped to the slightly different model // range to avoid gaps in the data Subtract a small term to // avoid rounding errors when comparing to phiMax. - float phiPh = _zMin + phiNorm/(2.0*M_PI)*(_zMax-_zMin-0.000001); + double phiPh = _zMin + phiNorm/(2.0*M_PI)*(_zMax-_zMin-0.000001); - float varValue = 0.f; + double varValue = 0.f; // See if sample point is inside domain if (rPh < _xMin || rPh > _xMax || thetaPh < _yMin || thetaPh > _yMax || phiPh < _zMin || phiPh > _zMax) { @@ -163,7 +176,7 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz varValue = _interpolator->interpolate(var, rPh, thetaPh, phiPh); } - data[index] = (varValue-varMin)/(varMax-varMin); + doubleData[index] = (varValue-varMin)/(varMax-varMin); } } } @@ -171,6 +184,30 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz std::cout << std::endl; LINFO("Done!"); + int sum = 0; + int stop; + const int sumuntil = size * truncLim; + for(int i = 0; i < bins-1; ++i) { + sum += histogram[i]; + if(sum + histogram[i+1] > sumuntil) { + stop = i; + LDEBUG("===================="); + break; + } + LDEBUG(histogram[i]); + } + + double dist = varMax - varMin; + dist = (dist / static_cast(bins)) * static_cast(stop); + + varMax = varMin + dist; + for(int i = 0; i < size; ++i) { + double normalizedVal = (doubleData[i]-varMin)/(varMax-varMin); + + data[i] = static_cast(glm::clamp(normalizedVal, 0.0, 1.0)); + } + delete[] doubleData; + return data; } From 1bbf2e0148152232bc70204fade7067dd922a2f1 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Wed, 18 Jun 2014 11:13:20 -0400 Subject: [PATCH 022/113] Pointed to latest Openspace-data --- openspace-data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openspace-data b/openspace-data index 835261f477..df25ff25dd 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 835261f4775ac7a7e5fcd000b1e254d4c947e389 +Subproject commit df25ff25dd392ed68dfff075bd8babce7fb5c5e1 From 9226c6818123a57e49577ee1950114ba6c7a5855 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Wed, 18 Jun 2014 11:45:35 -0400 Subject: [PATCH 023/113] Pointing to latest Openspace-data --- openspace-data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openspace-data b/openspace-data index df25ff25dd..7b9a59556d 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit df25ff25dd392ed68dfff075bd8babce7fb5c5e1 +Subproject commit 7b9a59556dd521ce3f7a17a1b81ab39610c1758b From 3fe447274f53061f829e29f290b57596a448d493 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Mon, 23 Jun 2014 16:59:19 -0400 Subject: [PATCH 024/113] Added intermediate ABuffer class to handle shader - Refactored a lot of stuff --- include/openspace/abuffer/abuffer.h | 81 ++++++ .../openspace/abuffer/abufferSingleLinked.h | 31 +-- include/openspace/abuffer/abuffer_i.h | 3 - .../rendering/renderablefieldlines.h | 9 +- include/openspace/rendering/renderengine.h | 4 +- shaders/ABuffer/abufferAddToBuffer.hglsl | 30 +- shaders/ABuffer/abufferResolveFragment.glsl | 123 ++++++--- shaders/ABuffer/abufferSort.hglsl | 12 +- shaders/ABuffer/abufferStruct.hglsl | 34 ++- src/abuffer/abuffer.cpp | 241 ++++++++++++++++ src/abuffer/abufferSingleLinked.cpp | 258 ++++-------------- src/engine/openspaceengine.cpp | 1 - src/rendering/renderablefieldlines.cpp | 41 ++- src/rendering/renderengine.cpp | 2 + 14 files changed, 555 insertions(+), 315 deletions(-) create mode 100644 include/openspace/abuffer/abuffer.h create mode 100644 src/abuffer/abuffer.cpp diff --git a/include/openspace/abuffer/abuffer.h b/include/openspace/abuffer/abuffer.h new file mode 100644 index 0000000000..17eb4f4592 --- /dev/null +++ b/include/openspace/abuffer/abuffer.h @@ -0,0 +1,81 @@ +/***************************************************************************************** + * * + * 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 __ABUFFER_H__ +#define __ABUFFER_H__ + +#include + +#include +#include + +#include +#include + +namespace ghoul { + namespace opengl { + class Texture; + } +} + +namespace openspace { + +class ABuffer: public ABuffer_I { +public: + ABuffer(); + virtual ~ABuffer() {}; + virtual void resolve(); + +protected: + virtual std::string settings() = 0; + + bool initializeABuffer(); + + void generateShaderSource(); + bool updateShader(); + + std::string openspaceHeaders(); + std::string openspaceSamplerCalls(); + std::string openspaceSamplers(); + + unsigned int _width, _height, _totalPixels; + GLuint _screenQuad; + + bool _validShader; + std::string _fragmentShaderPath; + ghoul::filesystem::File* _fragmentShaderFile; + ghoul::opengl::ProgramObject* _resolveShader; + + std::vector > _volumes; + std::vector > _transferFunctions; + std::vector _samplers; + +private: + + + +}; // ABuffer +} // openspace + +#endif // __ABUFFER_H__ \ No newline at end of file diff --git a/include/openspace/abuffer/abufferSingleLinked.h b/include/openspace/abuffer/abufferSingleLinked.h index 5e946af48a..b800dfb856 100644 --- a/include/openspace/abuffer/abufferSingleLinked.h +++ b/include/openspace/abuffer/abufferSingleLinked.h @@ -25,14 +25,11 @@ #ifndef __ABUFFERSINGLELINKED_H__ #define __ABUFFERSINGLELINKED_H__ -#include - -#include -#include +#include namespace openspace { -class ABufferSingleLinked: public ABuffer_I { +class ABufferSingleLinked: public ABuffer { public: ABufferSingleLinked(); @@ -42,28 +39,20 @@ public: virtual void clear(); virtual void preRender(); virtual void postRender(); - virtual void resolve(); + + virtual std::string settings(); private: + GLuint *_data; + GLuint _anchorPointerTexture; + GLuint _anchorPointerTextureInitializer; + GLuint _atomicCounterBuffer; + GLuint _fragmentBuffer; + GLuint _fragmentTexture; - unsigned int width, height, totalPixels, maxFragments; - GLuint *data; - GLuint anchorPointerTexture; - GLuint anchorPointerTextureInitializer; - GLuint atomicCounterBuffer; - GLuint fragmentBuffer; - GLuint fragmentTexture; - GLuint _screenQuad; - ghoul::opengl::ProgramObject* _resolveShader; - ghoul::filesystem::File* _fragmentShaderFile; - std::string _fragmentShaderPath; - bool _updateShader; - - void generateShaderSource(); - bool updateShader(); }; // ABuffer_I } // openspace diff --git a/include/openspace/abuffer/abuffer_i.h b/include/openspace/abuffer/abuffer_i.h index 8ee04eedb7..04a8e4277c 100644 --- a/include/openspace/abuffer/abuffer_i.h +++ b/include/openspace/abuffer/abuffer_i.h @@ -25,9 +25,6 @@ #ifndef __ABUFFER_I_H__ #define __ABUFFER_I_H__ -#include -#include - namespace openspace { class ABuffer_I { diff --git a/include/openspace/rendering/renderablefieldlines.h b/include/openspace/rendering/renderablefieldlines.h index e26c7c2b54..1b0941b750 100644 --- a/include/openspace/rendering/renderablefieldlines.h +++ b/include/openspace/rendering/renderablefieldlines.h @@ -32,12 +32,6 @@ #include #include -#ifdef __APPLE__ - #include -#else - #include -#endif - namespace openspace { class RenderableFieldlines : public Renderable { @@ -61,8 +55,6 @@ private: ghoul::opengl::ProgramObject *_fieldlinesProgram, *_seedpointsProgram; GLuint _VAO, _seedpointVAO; - std::mutex* _shaderMutex; - ghoul::filesystem::File* _vertexSourceFile; ghoul::filesystem::File* _fragmentSourceFile; @@ -70,6 +62,7 @@ private: std::vector _lineCount, _seedpointCount; bool _programUpdateOnSave; + bool _update; void safeShaderCompilation(); }; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 52c32db385..be597cb8b0 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -30,7 +30,7 @@ #include #include -#include +#include namespace openspace { @@ -61,7 +61,7 @@ private: Camera* _mainCamera; SceneGraph* _sceneGraph; - ABuffer_I* _abuffer; + ABuffer* _abuffer; }; } // namespace openspace diff --git a/shaders/ABuffer/abufferAddToBuffer.hglsl b/shaders/ABuffer/abufferAddToBuffer.hglsl index 2127bf8715..2833d59425 100644 --- a/shaders/ABuffer/abufferAddToBuffer.hglsl +++ b/shaders/ABuffer/abufferAddToBuffer.hglsl @@ -3,10 +3,38 @@ layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; +ABufferStruct_t createGeometryFragment(vec4 fragColor, vec4 position = vec4(0), float z = gl_FragCoord.z) { + ABufferStruct_t frag; + _col_(frag, fragColor); + _z_(frag, z); + _type_(frag, 0); + _pos_(frag, position); + return frag; +} + void addToBuffer(ABufferStruct_t frag) { uint index = atomicCounterIncrement(atomicCounterBuffer); + index *= 2; uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); _next_(frag,old_head); - imageStore(fragmentTexture, int(index), _uvec4_(frag)); + + uvec4 p1 = uvec4(frag.z, frag.id, frag.rg, frag.ba); + uvec4 p2 = uvec4(floatBitsToUint(frag.position.x),floatBitsToUint(frag.position.y),floatBitsToUint(frag.position.z),floatBitsToUint(frag.position.w)); + + imageStore(fragmentTexture, int(index), p1); + imageStore(fragmentTexture, int(index+1), p2); +} + +ABufferStruct_t loadFromBuffer(uint id) { + + uvec4 u1 = imageLoad(fragmentTexture, int(id)); + uvec4 u2 = imageLoad(fragmentTexture, int(id+1)); + + vec4 position = vec4( uintBitsToFloat(u2.x), + uintBitsToFloat(u2.y), + uintBitsToFloat(u2.z), + uintBitsToFloat(u2.w)); + + return ABufferStruct_t(u1.x, u1.y, u1.z, u1.w, position); } \ No newline at end of file diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index 84c7720f25..f795c12475 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -1,39 +1,73 @@ +/***************************************************************************************** +* * +* 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 430 +// ================================================================================ +// Settings +// ================================================================================ +#pragma openspace insert SETTINGS +#define LOOP_LIMIT 800 +#define MAX_FRAGMENTS 16 +#define SHOWFUNC +const float stepSize = 0.01; +const float samplingRate = 1.0; + uniform int SCREEN_WIDTH; uniform int SCREEN_HEIGHT; -uniform float ALPHA_LIMIT = 0.95; +uniform float ALPHA_LIMIT = 0.98; in vec2 texCoord; out vec4 color; -// settings -#define LOOP_LIMIT 800 -#define MAX_FRAGMENTS 16 -#define SHOWFUNC - -// GENERATED CONTENT +// ================================================================================ +// Headers, +// volume and transferfunctions uniforms +// ================================================================================ #pragma openspace insert HEADERS -// END GENERATED CONTENT -const float stepSize = 0.01; -const float samplingRate = 1.0; float volumeStepSize[] = { stepSize }; - +// ================================================================================ +// The ABuffer specific includes and definitions +// ================================================================================ #include "abufferStruct.hglsl" ABufferStruct_t fragments[MAX_FRAGMENTS]; vec3 volume_direction[MAX_VOLUMES]; float volume_length[MAX_VOLUMES]; vec2 volume_zlength[MAX_VOLUMES]; +// float volume_zlength[MAX_VOLUMES]; vec3 volume_position[MAX_VOLUMES]; #include "abufferSort.hglsl" - +// ================================================================================ +// Blend functions +// ================================================================================ vec4 blend(vec4 src, vec4 dst) { vec4 o; o.a = src.a + dst.a * (1.0f - src.a); @@ -104,7 +138,7 @@ vec4 calculate_final_color(uint frag_count) { int volID = type -1; float p = 0.0f; - //const float l = volume_length[volID]; + // const float l = volume_length[volID]; const float S1 = volume_zlength[volID].x; const float S2 = volume_zlength[volID].y; const float L = S1 - S2; @@ -116,6 +150,21 @@ vec4 calculate_final_color(uint frag_count) { int max_iterations = int(l / volumeStepSize[volID]); int iterations = 0; vec3 position; + + + // const float S1 = volume_zlength[volID].x; + // const float S2 = volume_zlength[volID].y; + + // const float L = volume_zlength[volID]; + // const vec4 p1 = _pos_(startFrag); + // const vec4 p2 = _pos_(endFrag); + // const float dist = pscLength(p1, p2); + // // const float z1 = _z_(startFrag); + // // const float z2 = _z_(endFrag); + // const float l = (dist / L) * volume_length[volID]; + // int max_iterations = int(l / volumeStepSize[volID]); + // int iterations = 0; + // vec3 position; // MIP // vec4 tmp, color = vec4(0); @@ -136,13 +185,11 @@ vec4 calculate_final_color(uint frag_count) { for(int k = 0; k < max_iterations && k < LOOP_LIMIT; ++k) { //while(p < l && iterations < LOOP_LIMIT) { -// GENERATED CONTENT #pragma openspace insert SAMPLERCALLS -// END GENERATED CONTENT //final_color = blend(final_color, color*stepSize); - volume_position[volID] += volume_direction[volID]*volumeStepSize[volID]; + //volume_position[volID] += volume_direction[volID]*volumeStepSize[volID]; //p+= stepSize; //++iterations; } @@ -168,38 +215,48 @@ vec4 calculate_final_color(uint frag_count) { // if(frag_count > 0) // final_color = _col_(fragments[0]); + +// ================================================================================ +// Transferfunction visualizer +// ================================================================================ #ifdef SHOWFUNC - float showfunc_size = 20.0; - if(gl_FragCoord.y > float(SCREEN_HEIGHT) - showfunc_size) { - float normalizedIntensity = gl_FragCoord.x / float(SCREEN_WIDTH) ; - vec4 tfc = texture(transferFunction, normalizedIntensity); - final_color = tfc; - } else if(ceil(gl_FragCoord.y) == float(SCREEN_HEIGHT) - showfunc_size) { - const float intensity = 0.4; - final_color = vec4(intensity,intensity,intensity,1.0); - } + float showfunc_size = 20.0; + if(gl_FragCoord.y > float(SCREEN_HEIGHT) - showfunc_size) { + float normalizedIntensity = gl_FragCoord.x / float(SCREEN_WIDTH) ; + vec4 tfc = texture(transferFunction1, normalizedIntensity); + final_color = tfc; + } else if(ceil(gl_FragCoord.y) == float(SCREEN_HEIGHT) - showfunc_size) { + const float intensity = 0.4; + final_color = vec4(intensity,intensity,intensity,1.0); + } #endif + // if(frag_count == 1) { + // final_color = vec4(0.0,0.0,1.0,1.0); + // } else if(frag_count == 2) { + // final_color = vec4(volume_direction[0],1.0); + // } else { + // final_color = vec4(1.0,1.0,1.0,1.0); + // } + return final_color; } - +// ================================================================================ +// Main function +// ================================================================================ void main() { color = vec4(texCoord,0.0,1.0); int frag_count = build_local_fragments_list(); sort_fragments_list(frag_count); - - - color = calculate_final_color(frag_count); - - //color = vec4(float(frag_count) / 5.0, 0.0, 0.0, 1.0); } -// GENERATED CONTENT +// ================================================================================ +// The samplers implementations +// ================================================================================ #pragma openspace insert SAMPLERS -// END GENERATED CONTENT diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index c8becb8b00..a37bd85df2 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -1,10 +1,5 @@ -// texture bindings -layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; -layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; - -// atomic buffer bindings -layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; +#include "abufferAddToBuffer.hglsl" int build_local_fragments_list() { uint current; @@ -13,7 +8,7 @@ int build_local_fragments_list() { current = imageLoad(anchorPointerTexture, ivec2(gl_FragCoord.xy)).x; while(current != 0 && frag_count < MAX_FRAGMENTS) { - ABufferStruct_t item = _ABufferStruct_t_(imageLoad(fragmentTexture, int(current))); + ABufferStruct_t item = loadFromBuffer(current); current = _next_(item); fragments[frag_count] = item; @@ -70,8 +65,9 @@ void sort_fragments_list(uint frag_count) { volume_length[ii] = length(dir); volume_direction[ii] = normalize(dir); volume_zlength[ii].y = _z_(fragments[jj]); + // volume_zlength[ii] = pscLength(_pos_(fragments[jj]), startPosition); volumeStepSize[ii] = 1.0/(length(volume_direction[ii]*volume_dim[ii])); - //volume_length[ii] = pscLength(_pos_(fragments[jj]), startPosition); + // volume_length[ii] = pscLength(_pos_(fragments[jj]), startPosition); break; } } diff --git a/shaders/ABuffer/abufferStruct.hglsl b/shaders/ABuffer/abufferStruct.hglsl index f220fbb02f..6e050ffe05 100644 --- a/shaders/ABuffer/abufferStruct.hglsl +++ b/shaders/ABuffer/abufferStruct.hglsl @@ -5,13 +5,23 @@ //======================================================= // ABufferStruct_t declaration //======================================================= +// struct ABufferStruct_t { +// uint z; // the depth value +// uint id; // bits 0-28 next, bits 29-32 type +// vec4 color; // packed rgba +// //vec4 position; // packed position +// // uint padding1; +// // uint padding2; +// }; struct ABufferStruct_t { uint z; // the depth value uint id; // bits 0-28 next, bits 29-32 type - uint color; // packed rgba - uint position; // packed position + uint rg; // packed red green color + uint ba; // packed blue alpha color + vec4 position; // position }; + //======================================================= // Bitwise operations //======================================================= @@ -78,17 +88,23 @@ void _next_(inout ABufferStruct_t frag, uint id) { } vec4 _pos_(ABufferStruct_t frag) { - return unpackUnorm4x8(frag.position); + // return vec4(0.0,0.0,0.0,0.0); + return frag.position; + //return unpackUnorm4x8(frag.position); } void _pos_(inout ABufferStruct_t frag, vec4 position) { - frag.position = packUnorm4x8(position); + frag.position = position; + // frag.position = packUnorm4x8(position); } vec4 _col_(ABufferStruct_t frag) { - return unpackUnorm4x8(frag.color); + return vec4(unpackUnorm2x16(frag.rg),unpackUnorm2x16(frag.ba)); + //return unpackUnorm4x8(frag.color); } void _col_(inout ABufferStruct_t frag, vec4 color) { - frag.color = packUnorm4x8(color); + frag.rg = packUnorm2x16(color.rg); + frag.ba = packUnorm2x16(color.ba); + //frag.color = packUnorm4x8(color); } uint _type_(ABufferStruct_t frag) { @@ -100,10 +116,4 @@ void _type_(inout ABufferStruct_t frag, uint type) { //frag.type = type; } -ABufferStruct_t _ABufferStruct_t_(uvec4 frag) { - return ABufferStruct_t(frag.x, frag.y, frag.z, frag.w); -}; -uvec4 _uvec4_(ABufferStruct_t frag) { - return uvec4(frag.z, frag.id, frag.color, frag.position); -}; #endif \ No newline at end of file diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp new file mode 100644 index 0000000000..8b9630f63e --- /dev/null +++ b/src/abuffer/abuffer.cpp @@ -0,0 +1,241 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace { + std::string _loggerCat = "ABuffer"; + +std::string padGeneratedString(const std::string& content) { + std::string _content_ = "// GENERATED CONTENT\n" + content + "\n// END GENERATED CONTENT"; + return _content_; +} + +} + +namespace openspace { + +ABuffer::ABuffer(): _validShader(true) { + int x1, xSize, y1, ySize; + sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); + _width = xSize; + _height = ySize; + _totalPixels = _width * _height; + const std::string fragmentShaderSourcePath = absPath("${SHADERS}/ABuffer/abufferResolveFragment.glsl"); + _fragmentShaderFile = new ghoul::filesystem::File(fragmentShaderSourcePath, true); + _fragmentShaderPath = fragmentShaderSourcePath.substr(0, fragmentShaderSourcePath.length()-4) + "gglsl"; +} + +bool ABuffer::initializeABuffer() { + // ============================ + // SHADERS + // ============================ + auto shaderCallback = [this](const ghoul::filesystem::File& file) { + _validShader = false; + }; + _fragmentShaderFile->setCallback(shaderCallback); + + _resolveShader = nullptr; + generateShaderSource(); + updateShader(); + + // ============================ + // GEOMETRY (quad) + // ============================ + const GLfloat size = 1.0f; + const GLfloat vertex_data[] = { // square of two triangles (sigh) + // x y z w s t + -size, -size, 0.0f, 1.0f, + size, size, 0.0f, 1.0f, + -size, size, 0.0f, 1.0f, + -size, -size, 0.0f, 1.0f, + size, -size, 0.0f, 1.0f, + size, size, 0.0f, 1.0f, + }; + GLuint vertexPositionBuffer; + glGenVertexArrays(1, &_screenQuad); // generate array + glBindVertexArray(_screenQuad); // bind array + glGenBuffers(1, &vertexPositionBuffer); // generate buffer + glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, reinterpret_cast(0)); + glEnableVertexAttribArray(0); + + return true; +} + +void ABuffer::resolve() { + if( ! _validShader) { + _validShader = true; + generateShaderSource(); + updateShader(); + + } + + if(_resolveShader) { + _resolveShader->activate(); + int startAt = 0; + for(int i = 0; i < _volumes.size(); ++i) { + glActiveTexture(GL_TEXTURE0 + i); + _volumes.at(i).second->bind(); + startAt = i + 1; + } + for(int i = 0; i < _transferFunctions.size(); ++i) { + glActiveTexture(GL_TEXTURE0 + startAt + i); + _transferFunctions.at(i).second->bind(); + } + + glBindVertexArray(_screenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + + _resolveShader->deactivate(); + } +} + +bool ABuffer::updateShader() { + + using ghoul::opengl::ShaderObject; + using ghoul::opengl::ProgramObject; + ShaderObject* vs + = new ShaderObject(ShaderObject::ShaderType::ShaderTypeVertex, + absPath("${SHADERS}/ABuffer/abufferResolveVertex.glsl"), "Vertex"); + ShaderObject* fs + = new ShaderObject(ShaderObject::ShaderType::ShaderTypeFragment,_fragmentShaderPath, "Fragment"); + + ghoul::opengl::ProgramObject* resolveShader = new ProgramObject; + resolveShader->attachObject(vs); + resolveShader->attachObject(fs); + + if (!resolveShader->compileShaderObjects()) { + LERROR("Could not compile shader"); + return false; + } + if (!resolveShader->linkProgramObject()){ + LERROR("Could not link shader"); + return false; + } + + int startAt = 0; + for(int i = 0; i < _volumes.size(); ++i) { + resolveShader->setUniform(_volumes.at(i).first, i); + startAt = i + 1; + } + for(int i = 0; i < _transferFunctions.size(); ++i) { + resolveShader->setUniform(_transferFunctions.at(i).first, startAt + i); + } + + resolveShader->setUniform("SCREEN_WIDTH", static_cast(_width)); + resolveShader->setUniform("SCREEN_HEIGHT", static_cast(_height)); + + if(_resolveShader) + delete _resolveShader; + + _resolveShader = resolveShader; + LDEBUG("Successfully updated shader!"); + return true; +} + +void ABuffer::generateShaderSource() { + std::string line, source = ""; + std::ifstream fragmentShaderFile(_fragmentShaderFile->path()); + if(fragmentShaderFile.is_open()) { + while(std::getline(fragmentShaderFile, line)) { + if(line == "#pragma openspace insert HEADERS") { + line = padGeneratedString(openspaceHeaders()); + } else if(line == "#pragma openspace insert SAMPLERCALLS") { + line = padGeneratedString(openspaceSamplerCalls()); + } else if(line == "#pragma openspace insert SAMPLERS") { + line = padGeneratedString(openspaceSamplers()); + } else if(line == "#pragma openspace insert SETTINGS") { + line = padGeneratedString(settings()); + } + source += line + "\n"; + } + } + fragmentShaderFile.close(); + + std::ofstream fragmentShaderOut(_fragmentShaderPath); + fragmentShaderOut << source; + fragmentShaderOut.close(); +} + +std::string ABuffer::openspaceHeaders() { + + std::string headers; + headers += "#define MAX_VOLUMES " + std::to_string(_volumes.size()) + "\n"; + for (int i = 0; i < _volumes.size(); ++i) { + headers += "uniform sampler3D " + _volumes.at(i).first + ";\n"; + //headers += "void sampleVolume" + std::to_string(i+1) + "(inout vec4, vec3);\n"; + } + for (int i = 0; i < _transferFunctions.size(); ++i) { + headers += "uniform sampler1D " + _transferFunctions.at(i).first + ";\n"; + } + + for (int i = 0; i < _samplers.size(); ++i) { + auto found = _samplers.at(i).find_first_of('{'); + if(found!=std::string::npos) { + headers += _samplers.at(i).substr(0, found) + ";\n"; + } + } + + headers += "const vec3 volume_dim[] = {\n"; + for (int i = 0; i < _volumes.size(); ++i) { + glm::size3_t size = _volumes.at(i).second->dimensions(); + headers += " vec3(" + std::to_string(size[0]) + ".0," + std::to_string(size[1]) + ".0," + + std::to_string(size[2]) + ".0),\n"; + } + headers += "};\n"; + return headers; +} + +std::string ABuffer::openspaceSamplerCalls() { + std::string samplercalls; + for (int i = 0; i < _volumes.size(); ++i) { + samplercalls += "if((currentVolumeBitmask & (1 << " + std::to_string(i) + ")) == 1) {\n"; + samplercalls += "sampleVolume" + std::to_string(i + 1) + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; + samplercalls += "volume_position[" + std::to_string(i) + "] += volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];;\n"; + samplercalls += "}\n"; + } + return samplercalls; +} + +std::string ABuffer::openspaceSamplers() { + std::string samplers; + for (int i = 0; i < _samplers.size(); ++i) { + samplers += _samplers.at(i) + "\n"; + } + return samplers; +} + + +} // openspace \ No newline at end of file diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp index 8b64a1ae6f..fef69a2524 100644 --- a/src/abuffer/abufferSingleLinked.cpp +++ b/src/abuffer/abufferSingleLinked.cpp @@ -27,76 +27,28 @@ #include #include -#include #include #include +#include #define MAX_LAYERS 10 #define BUFFER_OFFSET(i) ((char *)NULL + (i)) namespace { std::string _loggerCat = "ABufferSingleLinked"; - -const std::string openspaceHeaders = R"( -#define MAX_VOLUMES 1 -// VOLUME1 -uniform sampler3D volume; -uniform sampler1D transferFunction; -void sampleVolume1(inout vec4 finalColor, vec3 position); - - -const vec3 volume_dim[] = { - vec3(300.0,100.0,100.0) -}; -)"; - -const std::string openspaceSamplerCalls = R"( -if((currentVolumeBitmask & (1 << 0)) == 1) - sampleVolume1(final_color,volume_position[volID]); -)"; - -const std::string openspaceSamplers = R"( -void sampleVolume1(inout vec4 finalColor, vec3 position) { - float intensity = texture(volume, position).x; - //intensity *=25.0; - //intensity = clamp(intensity*100.0, 0.0, 1.0); - vec4 color = texture(transferFunction, intensity); - blendStep(finalColor, color, stepSize); -} -)"; - } namespace openspace { -ABufferSingleLinked::ABufferSingleLinked() { - int x1, xSize, y1, ySize; - sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); - width = xSize; - height = ySize; - totalPixels = width * height; - maxFragments = totalPixels * MAX_LAYERS; - data = 0; - anchorPointerTexture = 0; - anchorPointerTextureInitializer = 0; - atomicCounterBuffer = 0; - fragmentBuffer = 0; - fragmentTexture = 0; - - const std::string fragmentShaderSourcePath = absPath("${SHADERS}/ABuffer/abufferResolveFragment.glsl"); - _fragmentShaderFile = new ghoul::filesystem::File(fragmentShaderSourcePath, true); - _updateShader = false; - _fragmentShaderPath = fragmentShaderSourcePath + ".ABuffer.gglsl"; - - generateShaderSource(); - - -} +ABufferSingleLinked::ABufferSingleLinked(): _data(0), _anchorPointerTexture(0), + _anchorPointerTextureInitializer(0), _atomicCounterBuffer(0), _fragmentBuffer(0), + _fragmentTexture(0) +{} ABufferSingleLinked::~ABufferSingleLinked() { - if(data != 0) - delete data; + if(_data != 0) + delete _data; if(_fragmentShaderFile) delete _fragmentShaderFile; @@ -104,90 +56,76 @@ ABufferSingleLinked::~ABufferSingleLinked() { if(_resolveShader) delete _resolveShader; - glDeleteTextures(1,&anchorPointerTexture); - glDeleteTextures(1,&fragmentTexture); - glDeleteBuffers(1,&anchorPointerTextureInitializer); - glDeleteBuffers(1,&atomicCounterBuffer); - glDeleteBuffers(1,&anchorPointerTextureInitializer); + glDeleteTextures(1,&_anchorPointerTexture); + glDeleteTextures(1,&_fragmentTexture); + glDeleteBuffers(1,&_anchorPointerTextureInitializer); + glDeleteBuffers(1,&_atomicCounterBuffer); + glDeleteBuffers(1,&_anchorPointerTextureInitializer); } bool ABufferSingleLinked::initialize() { // ============================ // BUFFERS // ============================ - glGenTextures(1, &anchorPointerTexture); - glBindTexture(GL_TEXTURE_2D, anchorPointerTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + glGenTextures(1, &_anchorPointerTexture); + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); - glGenBuffers(1, &anchorPointerTextureInitializer); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, anchorPointerTextureInitializer); - glBufferData(GL_PIXEL_UNPACK_BUFFER, totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW); + glGenBuffers(1, &_anchorPointerTextureInitializer); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + glBufferData(GL_PIXEL_UNPACK_BUFFER, _totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW); - data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); - memset(data, 0x00, totalPixels * sizeof(GLuint)); + _data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); + memset(_data, 0x00, _totalPixels * sizeof(GLuint)); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - glGenBuffers(1, &atomicCounterBuffer); - glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer); + glGenBuffers(1, &_atomicCounterBuffer); + glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, _atomicCounterBuffer); glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY); - glGenBuffers(1, &fragmentBuffer); - glBindBuffer(GL_TEXTURE_BUFFER, fragmentBuffer); - glBufferData(GL_TEXTURE_BUFFER, MAX_LAYERS*totalPixels*sizeof(GLfloat)*4, NULL, GL_DYNAMIC_COPY); + glGenBuffers(1, &_fragmentBuffer); + glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer); + glBufferData(GL_TEXTURE_BUFFER, MAX_LAYERS*_totalPixels*sizeof(GLfloat)*4, NULL, GL_DYNAMIC_COPY); - glGenTextures(1, &fragmentTexture); - glBindTexture(GL_TEXTURE_BUFFER, fragmentTexture); - glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, fragmentBuffer); + glGenTextures(1, &_fragmentTexture); + glBindTexture(GL_TEXTURE_BUFFER, _fragmentTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, _fragmentBuffer); glBindTexture(GL_TEXTURE_BUFFER, 0); - glBindImageTexture(1, fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); + // ============================ + // Volume and transferfunction data // ============================ - // SHADERS - // ============================ - auto shaderCallback = [this](const ghoul::filesystem::File& file) { - _updateShader = true; - }; - _fragmentShaderFile->setCallback(shaderCallback); + ghoul::opengl::Texture* volume = nullptr; + ghoul::opengl::Texture* tf = nullptr; + OsEng.configurationManager().getValue("firstVolume", volume); + OsEng.configurationManager().getValue("firstTransferFunction", tf); + if(volume) + _volumes.push_back(std::make_pair(std::string("volume1"), volume)); + if(tf) + _transferFunctions.push_back(std::make_pair(std::string("transferFunction1"), tf)); + _samplers.push_back(R"( +void sampleVolume1(inout vec4 finalColor, vec3 position) { + float intensity = texture(volume1, position).x; + vec4 color = texture(transferFunction1, intensity); + blendStep(finalColor, color, stepSize); +} +)"); - _resolveShader = nullptr; - updateShader(); - - // ============================ - // GEOMETRY (quad) - // ============================ - const GLfloat size = 1.0f; - const GLfloat vertex_data[] = { // square of two triangles (sigh) - // x y z w s t - -size, -size, 0.0f, 1.0f, - size, size, 0.0f, 1.0f, - -size, size, 0.0f, 1.0f, - -size, -size, 0.0f, 1.0f, - size, -size, 0.0f, 1.0f, - size, size, 0.0f, 1.0f, - }; - GLuint vertexPositionBuffer; - glGenVertexArrays(1, &_screenQuad); // generate array - glBindVertexArray(_screenQuad); // bind array - glGenBuffers(1, &vertexPositionBuffer); // generate buffer - glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(0); - - return true; + return initializeABuffer(); } void ABufferSingleLinked::clear() { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, anchorPointerTextureInitializer); - glBindTexture(GL_TEXTURE_2D, anchorPointerTexture); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); static const GLuint zero = 1; - glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer); + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(zero), &zero); glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0); } @@ -195,102 +133,18 @@ void ABufferSingleLinked::clear() { void ABufferSingleLinked::preRender() { // Bind head-pointer image for read-write - glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer); - glBindImageTexture(0, anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); - glBindImageTexture(1, fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); + glBindImageTexture(0, _anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); } void ABufferSingleLinked::postRender() { - if(_updateShader) { - _updateShader = false; - generateShaderSource(); - updateShader(); - - } } -void ABufferSingleLinked::resolve() { - - if(_resolveShader) { - ghoul::opengl::Texture* volume = nullptr; - ghoul::opengl::Texture* tf = nullptr; - OsEng.configurationManager().getValue("firstVolume", volume); - OsEng.configurationManager().getValue("firstTransferFunction", tf); - _resolveShader->activate(); - - if(volume) { - glActiveTexture(GL_TEXTURE0); - volume->bind(); - } - - if(tf) { - glActiveTexture(GL_TEXTURE1); - tf->bind(); - } - //LDEBUG("SCREEN_WIDTH" << width); - glBindVertexArray(_screenQuad); - glDrawArrays(GL_TRIANGLES, 0, 6); - _resolveShader->deactivate(); - } - +std::string ABufferSingleLinked::settings() { + return R"(#define SINGLE_LINKED)"; } -bool ABufferSingleLinked::updateShader() { - - using ghoul::opengl::ShaderObject; - using ghoul::opengl::ProgramObject; - ShaderObject* vs - = new ShaderObject(ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/ABuffer/abufferResolveVertex.glsl"), "Vertex"); - ShaderObject* fs - = new ShaderObject(ShaderObject::ShaderType::ShaderTypeFragment,_fragmentShaderPath, "Fragment"); - - ghoul::opengl::ProgramObject* resolveShader = new ProgramObject; - resolveShader->attachObject(vs); - resolveShader->attachObject(fs); - - if (!resolveShader->compileShaderObjects()) { - LERROR("Could not compile shader"); - return false; - } - if (!resolveShader->linkProgramObject()){ - LERROR("Could not link shader"); - return false; - } - resolveShader->setUniform("volume", 0); - resolveShader->setUniform("transferFunction", 1); - resolveShader->setUniform("SCREEN_WIDTH", static_cast(width)); - resolveShader->setUniform("SCREEN_HEIGHT", static_cast(height)); - - if(_resolveShader) - delete _resolveShader; - - _resolveShader = resolveShader; - LDEBUG("Successfully updated shader!"); - return true; -} - -void ABufferSingleLinked::generateShaderSource() { - std::string line, source = ""; - std::ifstream fragmentShaderFile(_fragmentShaderFile->path()); - if(fragmentShaderFile.is_open()) { - while(std::getline(fragmentShaderFile, line)) { - if(line == "#pragma openspace insert HEADERS") { - line = openspaceHeaders; - } else if(line == "#pragma openspace insert SAMPLERCALLS") { - line = openspaceSamplerCalls; - } else if(line == "#pragma openspace insert SAMPLERS") { - line = openspaceSamplers; - } - source += line + "\n"; - } - } - fragmentShaderFile.close(); - - std::ofstream fragmentShaderOut(_fragmentShaderPath); - fragmentShaderOut << source; - fragmentShaderOut.close(); -} } // openspace \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index ca1e7bbbab..3e63603abe 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -275,7 +275,6 @@ bool OpenSpaceEngine::initialize() _renderEngine->initialize(); sceneGraph->loadScene(sceneDescriptionPath, scenePath); sceneGraph->initialize(); - _renderEngine->setSceneGraph(sceneGraph); #ifdef FLARE_ONLY _flare = new Flare(); diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index 5d2882c467..135c610b24 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -34,8 +34,7 @@ namespace { namespace openspace { RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) : - Renderable(dictionary), _VAO(0), _programUpdateOnSave(false) { - _shaderMutex = new std::mutex; + Renderable(dictionary), _VAO(0), _programUpdateOnSave(false),_update(false) { if(dictionary.hasKey("Fieldlines")) { ghoul::Dictionary fieldlines; @@ -177,8 +176,9 @@ bool RenderableFieldlines::initialize() { // ------ SETUP SHADERS ----------------- auto privateCallback = [this](const ghoul::filesystem::File& file) { - safeShaderCompilation(); + _update = true; }; + if(_programUpdateOnSave) { _vertexSourceFile->setCallback(privateCallback); _fragmentSourceFile->setCallback(privateCallback); @@ -187,9 +187,6 @@ bool RenderableFieldlines::initialize() { _fieldlinesProgram->compileShaderObjects(); _fieldlinesProgram->linkProgramObject(); - //_seedpointsProgram->compileShaderObjects(); - //_seedpointsProgram->linkProgramObject(); - return true; } @@ -198,6 +195,12 @@ bool RenderableFieldlines::deinitialize() { } void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) { + + if(_update) { + _update = false; + safeShaderCompilation(); + } + glm::mat4 transform = camera->viewProjectionMatrix(); glm::mat4 camTransform = camera->viewRotationMatrix(); psc relative = thisPosition-camera->position(); @@ -208,43 +211,33 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) transform = glm::scale(transform, glm::vec3(0.036*0.5*0.5)); //transform = glm::scale(transform, glm::vec3(0.1)); // Scale to avoid depth buffer problems - - // ------ FIELDLINES ----------------- - _shaderMutex->lock(); + // Activate shader _fieldlinesProgram->activate(); _fieldlinesProgram->setUniform("modelViewProjection", transform); + // ------ FIELDLINES ----------------- glBindVertexArray(_VAO); glMultiDrawArrays(GL_LINE_STRIP, &_lineStart[0], &_lineCount[0], _lineStart.size()); glBindVertexArray(0); - _fieldlinesProgram->deactivate(); - _shaderMutex->unlock(); -/* // ------ SEEDPOINTS ----------------- - _shaderMutex->lock(); - _seedpointsProgram->activate(); - _seedpointsProgram->setUniform("modelViewProjection", transform); + // glBindVertexArray(_seedpointVAO); + // glPointSize(5); + // glMultiDrawArrays(GL_POINTS, &_lineStart[0], &_lineCount[0], _seedPoints.size()); + // glBindVertexArray(0); - glBindVertexArray(_seedpointVAO); - glPointSize(5); - glMultiDrawArrays(GL_POINTS, &_lineStart[0], &_lineCount[0], _seedPoints.size()); - glBindVertexArray(0); - _seedpointsProgram->deactivate(); - _shaderMutex->unlock(); -*/ + // Deactivate shader + _fieldlinesProgram->deactivate(); } void RenderableFieldlines::update() { } void RenderableFieldlines::safeShaderCompilation() { - _shaderMutex->lock(); _fieldlinesProgram->rebuildFromFile(); _fieldlinesProgram->compileShaderObjects(); _fieldlinesProgram->linkProgramObject(); - _shaderMutex->unlock(); } std::vector > RenderableFieldlines::getFieldlinesData(std::string filename, ghoul::Dictionary hintsDictionary) { diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 96891951c7..323d764e8e 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -55,6 +55,7 @@ RenderEngine::~RenderEngine() bool RenderEngine::initialize() { + // LDEBUG("RenderEngine::initialize()"); // init camera and set temporary position and scaling _mainCamera = new Camera(); _mainCamera->setScaling(glm::vec2(1.0, -8.0)); @@ -71,6 +72,7 @@ bool RenderEngine::initialize() bool RenderEngine::initializeGL() { + // LDEBUG("RenderEngine::initializeGL()"); sgct::SGCTWindow* wPtr = sgct::Engine::instance()->getActiveWindowPtr(); // TODO: Fix the power scaled coordinates in such a way that these values can be From fe701ddc5a8355a4b43d694bc82388fcb8ea893b Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Tue, 24 Jun 2014 11:31:06 -0400 Subject: [PATCH 025/113] ABuffer uses sampler files - RenderableVolumeGL provides a filepath to sampler - ABuffer reloads all sampler files for each recompilation - ABuffer has mostly private members --- include/openspace/abuffer/abuffer.h | 12 ++++-- .../openspace/rendering/renderablevolumegl.h | 7 +--- openspace-data | 2 +- src/abuffer/abuffer.cpp | 42 +++++++++++++++++++ src/abuffer/abufferSingleLinked.cpp | 21 +++------- src/rendering/renderablevolumegl.cpp | 10 +++++ 6 files changed, 69 insertions(+), 25 deletions(-) diff --git a/include/openspace/abuffer/abuffer.h b/include/openspace/abuffer/abuffer.h index 17eb4f4592..c23422ebb4 100644 --- a/include/openspace/abuffer/abuffer.h +++ b/include/openspace/abuffer/abuffer.h @@ -43,10 +43,15 @@ namespace openspace { class ABuffer: public ABuffer_I { public: + ABuffer(); - virtual ~ABuffer() {}; + virtual ~ABuffer(); virtual void resolve(); + void addVolume(const std::string& tag,ghoul::opengl::Texture* volume); + void addTransferFunction(const std::string& tag,ghoul::opengl::Texture* transferFunction); + void addSamplerfile(const std::string& filename); + protected: virtual std::string settings() = 0; @@ -60,6 +65,8 @@ protected: std::string openspaceSamplers(); unsigned int _width, _height, _totalPixels; + +private: GLuint _screenQuad; bool _validShader; @@ -69,10 +76,9 @@ protected: std::vector > _volumes; std::vector > _transferFunctions; + std::vector _samplerFiles; std::vector _samplers; -private: - }; // ABuffer diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index eb39fe3065..35083fc23a 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -36,12 +36,6 @@ #include #include -#ifdef __APPLE__ - #include -#else - #include -#endif - namespace openspace { class RenderableVolumeGL: public RenderableVolume { @@ -61,6 +55,7 @@ private: std::string _filename; std::string _transferFunctionPath; + std::string _samplerFilename; ghoul::filesystem::File* _transferFunctionFile; diff --git a/openspace-data b/openspace-data index 7b9a59556d..b4199564cb 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 7b9a59556dd521ce3f7a17a1b81ab39610c1758b +Subproject commit b4199564cb227d8896b23016f53b5317943cbdad diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 8b9630f63e..709aecff7a 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -56,6 +56,14 @@ ABuffer::ABuffer(): _validShader(true) { _fragmentShaderPath = fragmentShaderSourcePath.substr(0, fragmentShaderSourcePath.length()-4) + "gglsl"; } +ABuffer::~ABuffer() { + if(_fragmentShaderFile) + delete _fragmentShaderFile; + + if(_resolveShader) + delete _resolveShader; +} + bool ABuffer::initializeABuffer() { // ============================ // SHADERS @@ -122,6 +130,27 @@ void ABuffer::resolve() { } } +void ABuffer::addVolume(const std::string& tag,ghoul::opengl::Texture* volume) { + _volumes.push_back(std::make_pair(tag, volume)); +} + +void ABuffer::addTransferFunction(const std::string& tag,ghoul::opengl::Texture* transferFunction) { + _transferFunctions.push_back(std::make_pair(tag, transferFunction)); +} + +void ABuffer::addSamplerfile(const std::string& filename) { + if( ! FileSys.fileExists(filename)) + return; + + auto fileCallback = [this](const ghoul::filesystem::File& file) { + _validShader = false; + }; + ghoul::filesystem::File* file = new ghoul::filesystem::File(filename); + file->setCallback(fileCallback); + _samplerFiles.push_back(file); + _samplers.push_back(""); +} + bool ABuffer::updateShader() { using ghoul::opengl::ShaderObject; @@ -166,6 +195,19 @@ bool ABuffer::updateShader() { } void ABuffer::generateShaderSource() { + + for(int i = 0; i < _samplerFiles.size(); ++i) { + std::string line, source = ""; + std::ifstream samplerFile(_samplerFiles.at(i)->path()); + if(samplerFile.is_open()) { + while(std::getline(samplerFile, line)) { + source += line + "\n"; + } + } + samplerFile.close(); + _samplers.at(i) = source; + } + std::string line, source = ""; std::ifstream fragmentShaderFile(_fragmentShaderFile->path()); if(fragmentShaderFile.is_open()) { diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp index fef69a2524..41180baa91 100644 --- a/src/abuffer/abufferSingleLinked.cpp +++ b/src/abuffer/abufferSingleLinked.cpp @@ -50,12 +50,6 @@ ABufferSingleLinked::~ABufferSingleLinked() { if(_data != 0) delete _data; - if(_fragmentShaderFile) - delete _fragmentShaderFile; - - if(_resolveShader) - delete _resolveShader; - glDeleteTextures(1,&_anchorPointerTexture); glDeleteTextures(1,&_fragmentTexture); glDeleteBuffers(1,&_anchorPointerTextureInitializer); @@ -100,19 +94,16 @@ bool ABufferSingleLinked::initialize() { // ============================ ghoul::opengl::Texture* volume = nullptr; ghoul::opengl::Texture* tf = nullptr; + std::string sampler = ""; OsEng.configurationManager().getValue("firstVolume", volume); OsEng.configurationManager().getValue("firstTransferFunction", tf); + OsEng.configurationManager().getValue("firstSampler", sampler); if(volume) - _volumes.push_back(std::make_pair(std::string("volume1"), volume)); + addVolume("volume1", volume); if(tf) - _transferFunctions.push_back(std::make_pair(std::string("transferFunction1"), tf)); - _samplers.push_back(R"( -void sampleVolume1(inout vec4 finalColor, vec3 position) { - float intensity = texture(volume1, position).x; - vec4 color = texture(transferFunction1, intensity); - blendStep(finalColor, color, stepSize); -} -)"); + addTransferFunction("transferFunction1", tf); + if(sampler != "") + addSamplerfile(sampler); return initializeABuffer(); } diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index 64b9ec3772..55fee5bb38 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -66,11 +66,20 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): _transferFunctionPath = findPath(transferFunctionPath); } } + _samplerFilename = ""; + if (dictionary.hasKey("Sampler")) { + if(dictionary.getValue("Sampler", _samplerFilename)) { + _samplerFilename = findPath(_samplerFilename); + } + } if( _transferFunctionPath == "") { LERROR("No transferFunction!"); } else { _transferFunctionFile = new ghoul::filesystem::File(_transferFunctionPath, true); } + if( _samplerFilename == "") { + LERROR("No samplerfile!"); + } double tempValue; @@ -108,6 +117,7 @@ bool RenderableVolumeGL::initialize() { _transferFunction->uploadTexture(); OsEng.configurationManager().setValue("firstVolume", _volume); OsEng.configurationManager().setValue("firstTransferFunction", _transferFunction); + OsEng.configurationManager().setValue("firstSampler", _samplerFilename); auto textureCallback = [this](const ghoul::filesystem::File& file) { _updateTransferfunction = true; From 4033303fd026d1e9cbc0e1c4a432a83dc742d0e9 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Tue, 24 Jun 2014 12:07:03 -0400 Subject: [PATCH 026/113] Maade the solution slightly more robust to changes --- src/abuffer/abuffer.cpp | 16 ++++++++++++---- src/rendering/renderablevolumegl.cpp | 4 ++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 709aecff7a..2746c42949 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -263,10 +263,18 @@ std::string ABuffer::openspaceHeaders() { std::string ABuffer::openspaceSamplerCalls() { std::string samplercalls; for (int i = 0; i < _volumes.size(); ++i) { - samplercalls += "if((currentVolumeBitmask & (1 << " + std::to_string(i) + ")) == 1) {\n"; - samplercalls += "sampleVolume" + std::to_string(i + 1) + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; - samplercalls += "volume_position[" + std::to_string(i) + "] += volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];;\n"; - samplercalls += "}\n"; + + auto found1 = _samplers.at(i).find_first_not_of("void "); + auto found2 = _samplers.at(i).find_first_of("(",found1); + if(found1 != std::string::npos && found2 != std::string::npos) { + std::string functionName = _samplers.at(i).substr(found1, found2 - found1); + samplercalls += "if((currentVolumeBitmask & (1 << " + std::to_string(i) + ")) == 1) {\n"; + samplercalls += functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; + samplercalls += "volume_position[" + std::to_string(i) + "] += volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];;\n"; + samplercalls += "}\n"; + } + + } return samplercalls; } diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index 55fee5bb38..722ffc0802 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -106,6 +106,10 @@ RenderableVolumeGL::~RenderableVolumeGL() { delete _volume; if(_colorBoxRenderer) delete _colorBoxRenderer; + if(_transferFunctionFile) + delete _transferFunctionFile; + if(_transferFunction) + delete _transferFunction; } bool RenderableVolumeGL::initialize() { From 633c95a44b1cb20489fa3f1c55fcc10c6b2d92bd Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Tue, 24 Jun 2014 14:45:08 -0400 Subject: [PATCH 027/113] Started work on Samplers having IDs --- include/openspace/abuffer/abuffer.h | 2 +- .../openspace/rendering/renderablevolumegl.h | 1 + include/openspace/rendering/renderengine.h | 1 + shaders/ABuffer/abufferResolveFragment.glsl | 5 ----- src/abuffer/abuffer.cpp | 20 ++++++++++++++----- src/abuffer/abufferSingleLinked.cpp | 16 --------------- src/rendering/renderablevolumegl.cpp | 19 ++++++++++-------- src/rendering/renderengine.cpp | 4 ++++ 8 files changed, 33 insertions(+), 35 deletions(-) diff --git a/include/openspace/abuffer/abuffer.h b/include/openspace/abuffer/abuffer.h index c23422ebb4..0ba2c49782 100644 --- a/include/openspace/abuffer/abuffer.h +++ b/include/openspace/abuffer/abuffer.h @@ -50,7 +50,7 @@ public: void addVolume(const std::string& tag,ghoul::opengl::Texture* volume); void addTransferFunction(const std::string& tag,ghoul::opengl::Texture* transferFunction); - void addSamplerfile(const std::string& filename); + int addSamplerfile(const std::string& filename); protected: virtual std::string settings() = 0; diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index 35083fc23a..25a2629a77 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -66,6 +66,7 @@ private: glm::vec3 _boxScaling; bool _updateTransferfunction; + int _id; }; } // namespace openspace diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index be597cb8b0..2c64e84e5b 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -47,6 +47,7 @@ public: SceneGraph* sceneGraph(); Camera* camera() const; + ABuffer* abuffer() const; // sgct wrapped functions bool initializeGL(); diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index f795c12475..c4d61bf654 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -47,11 +47,6 @@ out vec4 color; // ================================================================================ #pragma openspace insert HEADERS - -float volumeStepSize[] = { - stepSize -}; - // ================================================================================ // The ABuffer specific includes and definitions // ================================================================================ diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 2746c42949..8df9b833c2 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -138,9 +138,9 @@ void ABuffer::addTransferFunction(const std::string& tag,ghoul::opengl::Texture* _transferFunctions.push_back(std::make_pair(tag, transferFunction)); } -void ABuffer::addSamplerfile(const std::string& filename) { +int ABuffer::addSamplerfile(const std::string& filename) { if( ! FileSys.fileExists(filename)) - return; + return -1; auto fileCallback = [this](const ghoul::filesystem::File& file) { _validShader = false; @@ -148,7 +148,10 @@ void ABuffer::addSamplerfile(const std::string& filename) { ghoul::filesystem::File* file = new ghoul::filesystem::File(filename); file->setCallback(fileCallback); _samplerFiles.push_back(file); + + int size = _samplers.size(); _samplers.push_back(""); + return size; } bool ABuffer::updateShader() { @@ -234,10 +237,9 @@ void ABuffer::generateShaderSource() { std::string ABuffer::openspaceHeaders() { std::string headers; - headers += "#define MAX_VOLUMES " + std::to_string(_volumes.size()) + "\n"; + headers += "#define MAX_VOLUMES " + std::to_string(_samplers.size()) + "\n"; for (int i = 0; i < _volumes.size(); ++i) { headers += "uniform sampler3D " + _volumes.at(i).first + ";\n"; - //headers += "void sampleVolume" + std::to_string(i+1) + "(inout vec4, vec3);\n"; } for (int i = 0; i < _transferFunctions.size(); ++i) { headers += "uniform sampler1D " + _transferFunctions.at(i).first + ";\n"; @@ -257,12 +259,20 @@ std::string ABuffer::openspaceHeaders() { + std::to_string(size[2]) + ".0),\n"; } headers += "};\n"; + + headers += "float volumeStepSize[] = {\n"; + for (int i = 0; i < _volumes.size(); ++i) { + glm::size3_t size = _volumes.at(i).second->dimensions(); + headers += " stepSize,\n"; + } + headers += "};\n"; + return headers; } std::string ABuffer::openspaceSamplerCalls() { std::string samplercalls; - for (int i = 0; i < _volumes.size(); ++i) { + for (int i = 0; i < _samplers.size(); ++i) { auto found1 = _samplers.at(i).find_first_not_of("void "); auto found2 = _samplers.at(i).find_first_of("(",found1); diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp index 41180baa91..84158f87d7 100644 --- a/src/abuffer/abufferSingleLinked.cpp +++ b/src/abuffer/abufferSingleLinked.cpp @@ -89,22 +89,6 @@ bool ABufferSingleLinked::initialize() { glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); - // ============================ - // Volume and transferfunction data - // ============================ - ghoul::opengl::Texture* volume = nullptr; - ghoul::opengl::Texture* tf = nullptr; - std::string sampler = ""; - OsEng.configurationManager().getValue("firstVolume", volume); - OsEng.configurationManager().getValue("firstTransferFunction", tf); - OsEng.configurationManager().getValue("firstSampler", sampler); - if(volume) - addVolume("volume1", volume); - if(tf) - addTransferFunction("transferFunction1", tf); - if(sampler != "") - addSamplerfile(sampler); - return initializeABuffer(); } diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index 722ffc0802..99f27a8883 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -43,7 +43,7 @@ namespace openspace { RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): RenderableVolume(dictionary), _boxScaling(1.0, 1.0, 1.0), - _updateTransferfunction(false) { + _updateTransferfunction(false), _id(-1) { _filename = ""; @@ -119,9 +119,11 @@ bool RenderableVolumeGL::initialize() { _volume->uploadTexture(); _transferFunction = loadTransferFunction(_transferFunctionPath); _transferFunction->uploadTexture(); - OsEng.configurationManager().setValue("firstVolume", _volume); - OsEng.configurationManager().setValue("firstTransferFunction", _transferFunction); - OsEng.configurationManager().setValue("firstSampler", _samplerFilename); + + // TODO: fix volume an transferfunction names + OsEng.renderEngine().abuffer()->addVolume("volume1", _volume); + OsEng.renderEngine().abuffer()->addTransferFunction("transferFunction1", _transferFunction); + _id = OsEng.renderEngine().abuffer()->addSamplerfile(_samplerFilename); auto textureCallback = [this](const ghoul::filesystem::File& file) { _updateTransferfunction = true; @@ -146,7 +148,9 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { const void* data = transferFunction->pixelData(); glBindBuffer(GL_COPY_READ_BUFFER, *transferFunction); _transferFunction->bind(); - glTexImage1D(GL_TEXTURE_1D, 0, _transferFunction->internalFormat(), _transferFunction->width(),0, _transferFunction->format(), _transferFunction->dataType(), data); + glTexImage1D( GL_TEXTURE_1D, 0, _transferFunction->internalFormat(), + _transferFunction->width(),0, _transferFunction->format(), + _transferFunction->dataType(), data); //delete data; delete transferFunction; LDEBUG("Updated transferfunction!"); @@ -154,15 +158,14 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { } } - glm::mat4 transform ; - glm::mat4 camTransform = camera->viewRotationMatrix(); psc relative = thisPosition-camera->position(); - transform = camTransform; + glm::mat4 transform = camera->viewRotationMatrix(); transform = glm::translate(transform, relative.vec3()); transform = glm::translate(transform, glm::vec3(-1.1,0.0,0.0)); transform = glm::scale(transform, _boxScaling); + // TODO: Use _id to identify this volume _colorBoxRenderer->render(camera->viewProjectionMatrix(), transform); } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 323d764e8e..70fd59661d 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -404,4 +404,8 @@ Camera* RenderEngine::camera() const { return _mainCamera; } +ABuffer* RenderEngine::abuffer() const { + return _abuffer; +} + } // namespace openspace From ec115030a46ce0adc20e6c0ad280c2a0c84a2a6b Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Tue, 24 Jun 2014 15:29:31 -0400 Subject: [PATCH 028/113] Added ID for sampler --- include/openspace/rendering/volumeraycasterbox.h | 4 ++-- shaders/exitpoints.frag | 4 +++- src/abuffer/abuffer.cpp | 6 +++--- src/rendering/renderablevolumegl.cpp | 2 +- src/rendering/volumeraycasterbox.cpp | 6 +++--- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/openspace/rendering/volumeraycasterbox.h b/include/openspace/rendering/volumeraycasterbox.h index 8597a1c265..4e0a3018d5 100644 --- a/include/openspace/rendering/volumeraycasterbox.h +++ b/include/openspace/rendering/volumeraycasterbox.h @@ -45,7 +45,7 @@ public: VolumeRaycasterBox(); ~VolumeRaycasterBox(); bool initialize(); - void render(const glm::mat4& MVP,const glm::mat4& transform = glm::mat4(1.0)); + void render(const glm::mat4& MVP, const glm::mat4& transform = glm::mat4(1.0), int type = 0); ghoul::opengl::Texture* backFace(); ghoul::opengl::Texture* frontFace(); @@ -56,7 +56,7 @@ private: ghoul::opengl::Texture *_backTexture, *_frontTexture; ghoul::opengl::ProgramObject *_boxProgram; sgct_utils::SGCTBox* _boundingBox; - GLint _MVPLocation, _modelTransformLocation; + GLint _MVPLocation, _modelTransformLocation, _typeLocation; glm::size2_t _dimensions; }; diff --git a/shaders/exitpoints.frag b/shaders/exitpoints.frag index fee208094a..de2db8ee15 100644 --- a/shaders/exitpoints.frag +++ b/shaders/exitpoints.frag @@ -1,5 +1,7 @@ #version 430 core +uniform int volumeType; + in vec3 vPosition; in vec3 worldPosition; out vec4 fragColor; @@ -13,7 +15,7 @@ void main() { ABufferStruct_t frag; _col_(frag, fragColor); _z_(frag, gl_FragCoord.z); - _type_(frag, 1); + _type_(frag, volumeType); _pos_(frag, vec4(worldPosition,0)); addToBuffer(frag); diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 8df9b833c2..b1af47bc7e 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -148,10 +148,10 @@ int ABuffer::addSamplerfile(const std::string& filename) { ghoul::filesystem::File* file = new ghoul::filesystem::File(filename); file->setCallback(fileCallback); _samplerFiles.push_back(file); - - int size = _samplers.size(); _samplers.push_back(""); - return size; + + // ID is one more than "actual" position since ID=0 is considered geometry + return _samplers.size(); } bool ABuffer::updateShader() { diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index 99f27a8883..518120649c 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -166,7 +166,7 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { transform = glm::scale(transform, _boxScaling); // TODO: Use _id to identify this volume - _colorBoxRenderer->render(camera->viewProjectionMatrix(), transform); + _colorBoxRenderer->render(camera->viewProjectionMatrix(), transform, _id); } diff --git a/src/rendering/volumeraycasterbox.cpp b/src/rendering/volumeraycasterbox.cpp index ad51b1eabd..4fb33a1bde 100644 --- a/src/rendering/volumeraycasterbox.cpp +++ b/src/rendering/volumeraycasterbox.cpp @@ -63,6 +63,7 @@ bool VolumeRaycasterBox::initialize() { OsEng.configurationManager().getValue("RaycastProgram", _boxProgram); _MVPLocation = _boxProgram->uniformLocation("modelViewProjection"); _modelTransformLocation = _boxProgram->uniformLocation("modelTransform"); + _typeLocation = _boxProgram->uniformLocation("volumeType"); // ------ SETUP FBO --------------------- _fbo = new FramebufferObject(); @@ -70,8 +71,6 @@ bool VolumeRaycasterBox::initialize() { // changed from getActiveXResolution to getCurrentViewportPixelCoords because // if there are more viewports in the same screen. - //size_t x = sgct::Engine::instance()->getActiveXResolution(); - //size_t y = sgct::Engine::instance()->getActiveYResolution(); int x1, xSize, y1, ySize; sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); size_t x = xSize; @@ -90,12 +89,13 @@ bool VolumeRaycasterBox::initialize() { return true; } -void VolumeRaycasterBox::render(const glm::mat4& MVP,const glm::mat4& transform) { +void VolumeRaycasterBox::render(const glm::mat4& MVP,const glm::mat4& transform, int type) { GLuint activeFBO = FramebufferObject::getActiveObject(); // Save SGCTs main FBO _fbo->activate(); _boxProgram->activate(); _boxProgram->setUniform(_MVPLocation, MVP); _boxProgram->setUniform(_modelTransformLocation, transform); + _boxProgram->setUniform(_typeLocation, type); sgct_core::Frustum::FrustumMode mode = sgct::Engine::instance()-> getActiveWindowPtr()-> From 437f511f48e943dd3c30da89422aac5602f1059f Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Wed, 25 Jun 2014 10:21:06 -0400 Subject: [PATCH 029/113] Cleaned up fragment shader in power scaling - Added Licence to shaders --- shaders/ABuffer/abufferAddToBuffer.hglsl | 23 ++++ shaders/ABuffer/abufferResolveFragment.glsl | 44 +++---- shaders/ABuffer/abufferResolveVertex.glsl | 24 ++++ shaders/ABuffer/abufferSort.hglsl | 25 +++- shaders/ABuffer/abufferStruct.hglsl | 24 ++++ shaders/PowerScaling/powerScaling.hglsl | 90 +++++++++++++ shaders/cubeFrag.glsl | 24 ++++ shaders/cubeVert.glsl | 24 ++++ shaders/exitpoints.frag | 24 ++++ shaders/exitpoints.vert | 24 ++++ shaders/pscstandard_fs.glsl | 139 ++++---------------- shaders/pscstandard_vs.glsl | 43 +++--- shaders/quadFrag.glsl | 24 ++++ shaders/quadVert.glsl | 24 ++++ shaders/quadVertFlare.glsl | 24 ++++ shaders/singlepassraycaster.frag | 24 ++++ shaders/singlepassraycaster.gs | 24 ++++ shaders/singlepassraycaster.vert | 24 ++++ shaders/twopassraycaster.frag | 24 ++++ shaders/twopassraycaster.vert | 24 ++++ 20 files changed, 545 insertions(+), 155 deletions(-) create mode 100644 shaders/PowerScaling/powerScaling.hglsl diff --git a/shaders/ABuffer/abufferAddToBuffer.hglsl b/shaders/ABuffer/abufferAddToBuffer.hglsl index 2833d59425..3ee940f0d7 100644 --- a/shaders/ABuffer/abufferAddToBuffer.hglsl +++ b/shaders/ABuffer/abufferAddToBuffer.hglsl @@ -1,3 +1,26 @@ +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index c4d61bf654..bbe589e045 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -1,26 +1,26 @@ /***************************************************************************************** -* * -* 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. * -****************************************************************************************/ + * * + * 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 430 diff --git a/shaders/ABuffer/abufferResolveVertex.glsl b/shaders/ABuffer/abufferResolveVertex.glsl index ded6af8a7a..301a151753 100644 --- a/shaders/ABuffer/abufferResolveVertex.glsl +++ b/shaders/ABuffer/abufferResolveVertex.glsl @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 430 in vec4 position; diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index a37bd85df2..2827499b11 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -1,4 +1,27 @@ - +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + #include "abufferAddToBuffer.hglsl" int build_local_fragments_list() { diff --git a/shaders/ABuffer/abufferStruct.hglsl b/shaders/ABuffer/abufferStruct.hglsl index 6e050ffe05..a63499ef6d 100644 --- a/shaders/ABuffer/abufferStruct.hglsl +++ b/shaders/ABuffer/abufferStruct.hglsl @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + #ifndef ABUFFERSTRUCT_H_HGLSL #define ABUFFERSTRUCT_H_HGLSL diff --git a/shaders/PowerScaling/powerScaling.hglsl b/shaders/PowerScaling/powerScaling.hglsl new file mode 100644 index 0000000000..66ddf647b1 --- /dev/null +++ b/shaders/PowerScaling/powerScaling.hglsl @@ -0,0 +1,90 @@ +/***************************************************************************************** + * * + * 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 POWERSCALING_H_HGLSL +#define POWERSCALING_H_HGLSL + +// Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD! + +const float k = 10.0; +const float s_far = 27.0f; //= gl_DepthRange.far; // 40 +const float s_farcutoff = 12.0f; +const float s_nearcutoff = 7.00f; +const float s_near = 0.00f;// gl_DepthRange.near; // 0.1 + +vec4 psc_normlization(vec4 invec) { + + float xymax = max(invec.x,invec.y); + + if(invec.z > 0.0f || invec.z < 0.0f) { + return invec / abs(invec.z); + } else if (xymax != 0.0f) { + return invec / xymax; + } else { + return invec / -.0; + } +} + +float pscDepth(vec4 position) { + float depth = 0.0f; + if(position.w <= 0.5) { + //depth = abs(position.z * pow(10, position.w)) / pow(k,s_far); + depth = (position.w+log(abs(position.z)))/pow(k, position.w); + } else if(position.w < 3.0) { + depth = position.w+log(abs(position.z))/pow(k, position.w); + } else { + depth = position.w+log(abs(position.z)); + } + + + // DEBUG + float depth_orig = depth; + float x = 0.0f; + float cutoffs = 0.0; + float orig_z = position.z; + + // calculate a normalized depth [0.0 1.0] + if((depth > s_near && depth <= s_nearcutoff) || (depth > s_farcutoff && depth < s_far)) { + + // completely linear interpolation [s_near .. depth .. s_far] + depth = (depth - s_near) / (s_far - s_near); + + } else if(depth > s_nearcutoff && depth < s_farcutoff) { + + // DEBUG + cutoffs = 1.0; + + // interpolate [10^s_nearcutoff .. 10^depth .. 10^s_farcutoff] + // calculate between 0..1 where the depth is + x = (pow(10,depth) - pow(10, s_nearcutoff)) / (pow(10,s_farcutoff) - pow(10, s_nearcutoff)); + + // remap the depth to the 0..1 depth buffer + depth = s_nearcutoff + x * (s_farcutoff - s_nearcutoff); + depth = (depth - s_near) / (s_far - s_near); + + } + return depth; +} + +#endif \ No newline at end of file diff --git a/shaders/cubeFrag.glsl b/shaders/cubeFrag.glsl index 0b6be3de9a..292f1396c8 100644 --- a/shaders/cubeFrag.glsl +++ b/shaders/cubeFrag.glsl @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 330 in vec4 color; diff --git a/shaders/cubeVert.glsl b/shaders/cubeVert.glsl index 68a1d89d43..38393b3e3f 100644 --- a/shaders/cubeVert.glsl +++ b/shaders/cubeVert.glsl @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 330 uniform mat4 projectionMatrix; diff --git a/shaders/exitpoints.frag b/shaders/exitpoints.frag index de2db8ee15..cc58d29e35 100644 --- a/shaders/exitpoints.frag +++ b/shaders/exitpoints.frag @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 430 core uniform int volumeType; diff --git a/shaders/exitpoints.vert b/shaders/exitpoints.vert index 15e86a76df..80145134b3 100644 --- a/shaders/exitpoints.vert +++ b/shaders/exitpoints.vert @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 430 core layout(location = 2) in vec3 vertPosition; diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index 85dc406b22..394ca42fc9 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -1,132 +1,47 @@ -/** -Copyright (C) 2012-2014 Jonas Strandstedt +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ -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 430 uniform float time; uniform sampler2D texture1; -vec3 light_position = vec3(40.0, 20.0, 100.0); - in vec2 vs_st; -//in vec3 vs_stp; in vec4 vs_normal; in vec4 vs_position; -out vec4 diffuse; - -const float k = 10.0; - #include "ABuffer/abufferStruct.hglsl" #include "ABuffer/abufferAddToBuffer.hglsl" - - -vec4 psc_normlization(vec4 invec) { - - float xymax = max(invec.x,invec.y); - - if(invec.z > 0.0f || invec.z < 0.0f) { - return invec / abs(invec.z); - } else if (xymax != 0.0f) { - return invec / xymax; - } else { - return invec / -.0; - } -} +#include "PowerScaling/powerScaling.hglsl" void main() { + float depth = pscDepth(vs_position); + vec4 diffuse = texture(texture1, vs_st); - // Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD! - float s_far = 27.0; //= gl_DepthRange.far; // 40 - float s_farcutoff = 12.0; - float s_nearcutoff = 7.0; - float s_near = 0.0f;// gl_DepthRange.near; // 0.1 - float depth; - - // the value can be normalized to 1 - - vec4 p = vs_position; - if(vs_position.w <= 0.5) { - //depth = abs(vs_position.z * pow(10, vs_position.w)) / pow(k,s_far); - depth = (vs_position.w+log(abs(vs_position.z)))/pow(k, vs_position.w); - } else if(vs_position.w < 3.0) { - depth = vs_position.w+log(abs(vs_position.z))/pow(k, vs_position.w); - } else { - depth = vs_position.w+log(abs(vs_position.z)); - } - - - // DEBUG - float depth_orig = depth; - float x = 0.0f; - float cutoffs = 0.0; - float orig_z = vs_position.z; - - // calculate a normalized depth [0.0 1.0] - if((depth > s_near && depth <= s_nearcutoff) || (depth > s_farcutoff && depth < s_far)) { - - // completely linear interpolation [s_near .. depth .. s_far] - depth = (depth - s_near) / (s_far - s_near); - - } else if(depth > s_nearcutoff && depth < s_farcutoff) { - - // DEBUG - cutoffs = 1.0; - - // interpolate [10^s_nearcutoff .. 10^depth .. 10^s_farcutoff] - // calculate between 0..1 where the depth is - x = (pow(10,depth) - pow(10, s_nearcutoff)) / (pow(10,s_farcutoff) - pow(10, s_nearcutoff)); - - // remap the depth to the 0..1 depth buffer - depth = s_nearcutoff + x * (s_farcutoff - s_nearcutoff); - depth = (depth - s_near) / (s_far - s_near); - - } else { - // where am I? - // do I need to be discarded? - // discard; - } - - - - - // set the depth - gl_FragDepth = depth; - //gl_FragDepth = 0.5; - - // color - diffuse = texture(texture1, vs_st); - //diffuse = vec4(vs_position.z,0.0, 0.0, 1.0); - // diffuse = vec4(vs_position.xyz * pow(10, vs_position.w), 1.0); - //diffuse = vec4(vs_st, 0.0, 1.0); - //diffuse = vec4(1.0,1.0, 0.0, 1.0); - //diffuse = vec4(depth*5,0.0, 0.0, 1.0); - //diffuse = vec4(vs_position.w,0.0, 0.0, 1.0); - //diffuse = vec4(1.0,0.0,0.0,1.0); - - ABufferStruct_t frag; - _col_(frag, diffuse); - _z_(frag, gl_FragDepth); - _type_(frag, 0); - _pos_(frag, vs_position); + ABufferStruct_t frag = createGeometryFragment(diffuse, vs_position, depth); addToBuffer(frag); - /* - uint index = atomicCounterIncrement(atomicCounterBuffer); - uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); - uvec4 item; - item.x = old_head; - item.y = packUnorm4x8(diffuse); - item.z = floatBitsToUint(gl_FragCoord.z / gl_FragCoord.w); - item.w = 0; - imageStore(fragmentTexture, int(index), item); -*/ discard; } \ No newline at end of file diff --git a/shaders/pscstandard_vs.glsl b/shaders/pscstandard_vs.glsl index be3ead04f7..c3de39f9dc 100644 --- a/shaders/pscstandard_vs.glsl +++ b/shaders/pscstandard_vs.glsl @@ -1,24 +1,27 @@ -/** -Copyright (C) 2012-2014 Jonas Strandstedt +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ -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 430 uniform mat4 ViewProjection; diff --git a/shaders/quadFrag.glsl b/shaders/quadFrag.glsl index 0b4adc27c0..a52ce0a5f5 100644 --- a/shaders/quadFrag.glsl +++ b/shaders/quadFrag.glsl @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 330 uniform sampler2D quadTex; diff --git a/shaders/quadVert.glsl b/shaders/quadVert.glsl index 2140173049..3221517490 100644 --- a/shaders/quadVert.glsl +++ b/shaders/quadVert.glsl @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 330 layout(location = 0) in vec2 texCoordinate; diff --git a/shaders/quadVertFlare.glsl b/shaders/quadVertFlare.glsl index a3c9b18411..12b7b9fe41 100644 --- a/shaders/quadVertFlare.glsl +++ b/shaders/quadVertFlare.glsl @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 330 in vec4 position; diff --git a/shaders/singlepassraycaster.frag b/shaders/singlepassraycaster.frag index 222c459ae3..e910176269 100644 --- a/shaders/singlepassraycaster.frag +++ b/shaders/singlepassraycaster.frag @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 400 core // Based on http://prideout.net/blog/?p=64 diff --git a/shaders/singlepassraycaster.gs b/shaders/singlepassraycaster.gs index a393169a32..fea6d6b415 100644 --- a/shaders/singlepassraycaster.gs +++ b/shaders/singlepassraycaster.gs @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 400 core // Based on http://prideout.net/blog/?p=64 diff --git a/shaders/singlepassraycaster.vert b/shaders/singlepassraycaster.vert index c33d4689b9..df013c63ae 100644 --- a/shaders/singlepassraycaster.vert +++ b/shaders/singlepassraycaster.vert @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 400 core // Based on http://prideout.net/blog/?p=64 diff --git a/shaders/twopassraycaster.frag b/shaders/twopassraycaster.frag index 1e9daf5cdb..1641c013dd 100644 --- a/shaders/twopassraycaster.frag +++ b/shaders/twopassraycaster.frag @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 400 core uniform sampler2D texBack, texFront; diff --git a/shaders/twopassraycaster.vert b/shaders/twopassraycaster.vert index 164a5e8643..f8453e0f57 100644 --- a/shaders/twopassraycaster.vert +++ b/shaders/twopassraycaster.vert @@ -1,3 +1,27 @@ +/***************************************************************************************** + * * + * 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 400 core layout(location = 0) in vec2 texCoordinate; From 83205d6de1bb2858ea4c33d6d12e44653a1c1e87 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Wed, 25 Jun 2014 15:10:05 -0400 Subject: [PATCH 030/113] Volume raycasting jittering - Added jitter to volume rendering, reducing artefacts - Added tracking of more shader files to update the resolve shader --- include/openspace/abuffer/abuffer.h | 3 +++ shaders/ABuffer/abufferSort.hglsl | 15 ++++++++++++++ shaders/pscstandard_fs.glsl | 8 +++++--- shaders/pscstandard_vs.glsl | 31 ++++++++++++----------------- src/abuffer/abuffer.cpp | 19 ++++++++++++++++++ src/abuffer/abufferSingleLinked.cpp | 1 - 6 files changed, 55 insertions(+), 22 deletions(-) diff --git a/include/openspace/abuffer/abuffer.h b/include/openspace/abuffer/abuffer.h index 0ba2c49782..96e35ec9dd 100644 --- a/include/openspace/abuffer/abuffer.h +++ b/include/openspace/abuffer/abuffer.h @@ -79,6 +79,9 @@ private: std::vector _samplerFiles; std::vector _samplers; + // Development functionality to update shader for changes in several files + std::vector _shaderFiles; + }; // ABuffer diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index 2827499b11..6eaf03eed4 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -56,6 +56,10 @@ float pscLength(vec4 v1, vec4 v2) { return length(vector.xyz)*pow(k,vector.w); } +float permute(float i) { + return mod((62.0*i*i + i), 961.0); // permutation polynomial; 62=2*31; 961=31*31 +} + void sort_fragments_list(uint frag_count) { uint i,j; ABufferStruct_t tmp; @@ -91,6 +95,17 @@ void sort_fragments_list(uint frag_count) { // volume_zlength[ii] = pscLength(_pos_(fragments[jj]), startPosition); volumeStepSize[ii] = 1.0/(length(volume_direction[ii]*volume_dim[ii])); // volume_length[ii] = pscLength(_pos_(fragments[jj]), startPosition); + + if(volumeStepSize[ii] < volume_length[ii]) { + // jittering + float x = gl_FragCoord.x; + float y = gl_FragCoord.y; + float jitterValue = float(permute(x + permute(y))) / 961.0; + jitterValue *= 0.004; + vec3 frontPosNew = startColor + (jitterValue*volume_length[ii])*volume_direction[ii]; + volume_position[ii] = frontPosNew; + } + break; } } diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index 394ca42fc9..380ca7f096 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -29,7 +29,8 @@ uniform sampler2D texture1; in vec2 vs_st; in vec4 vs_normal; -in vec4 vs_position; +in vec3 vs_position; +in float s; #include "ABuffer/abufferStruct.hglsl" #include "ABuffer/abufferAddToBuffer.hglsl" @@ -37,10 +38,11 @@ in vec4 vs_position; void main() { - float depth = pscDepth(vs_position); + vec4 position = vec4(vs_position,s); + float depth = pscDepth(position); vec4 diffuse = texture(texture1, vs_st); - ABufferStruct_t frag = createGeometryFragment(diffuse, vs_position, depth); + ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); addToBuffer(frag); discard; diff --git a/shaders/pscstandard_vs.glsl b/shaders/pscstandard_vs.glsl index c3de39f9dc..83ba34bbfd 100644 --- a/shaders/pscstandard_vs.glsl +++ b/shaders/pscstandard_vs.glsl @@ -31,13 +31,6 @@ uniform mat4 camrot; uniform vec2 scaling; uniform vec4 objpos; uniform float time; -uniform sampler2D texture1; -uniform sampler2D texture2; -uniform sampler2D texture3; -uniform float TessLevel; -uniform bool Wireframe; -uniform bool Lightsource; -uniform bool UseTexture; layout(location = 0) in vec4 in_position; //in vec3 in_position; @@ -47,10 +40,10 @@ layout(location = 2) in vec3 in_normal; out vec2 vs_st; out vec3 vs_stp; out vec4 vs_normal; -out vec4 vs_position; +out vec3 vs_position; +out float s; const float k = 10.0; -const float dgr_to_rad = 0.0174532925; vec4 psc_addition(vec4 v1, vec4 v2) { float ds = v2.w - v1.w; @@ -92,25 +85,27 @@ void main() //vec4 lvp = ModelTransform * in_position; // PSC addition; local vertex position and the object power scaled world position - vs_position = psc_addition(vec4(local_vertex_pos,in_position.w),objpos); - //vs_position = psc_addition(lvp,objpos); + vec4 position = psc_addition(vec4(local_vertex_pos,in_position.w),objpos); + //position = psc_addition(lvp,objpos); // PSC addition; rotated and viewscaled vertex and the cmaeras negative position - vs_position = psc_addition(vs_position,vec4(-campos.xyz,campos.w)); + position = psc_addition(position,vec4(-campos.xyz,campos.w)); // rotate the camera - local_vertex_pos = mat3(camrot) * vs_position.xyz; - vs_position = vec4(local_vertex_pos, vs_position.w); - //vs_position = camrot* vs_position; + local_vertex_pos = mat3(camrot) * position.xyz; + position = vec4(local_vertex_pos, position.w); + //position = camrot* position; // rescales the scene to fit inside the view frustum // is set from the main program, but these are decent values // scaling = vec2(1.0, -8.0); // project using the rescaled coordinates, - //vec4 vs_position_rescaled = psc_scaling(vs_position, scaling); - vec4 vs_position_rescaled = psc_to_meter(vs_position, scaling); - vs_position = vs_position_rescaled; + //vec4 vs_position_rescaled = psc_scaling(position, scaling); + vec4 vs_position_rescaled = psc_to_meter(position, scaling); + position = vs_position_rescaled; + vs_position = vs_position_rescaled.xyz; + s = vs_position_rescaled.w; // project the position to view space diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index b1af47bc7e..dbb26e40fc 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -62,6 +62,14 @@ ABuffer::~ABuffer() { if(_resolveShader) delete _resolveShader; + + for(auto file: _samplerFiles) { + delete file; + } + for(auto file: _shaderFiles) { + delete file; + } + } bool ABuffer::initializeABuffer() { @@ -73,6 +81,17 @@ bool ABuffer::initializeABuffer() { }; _fragmentShaderFile->setCallback(shaderCallback); + // Development functionality to update shader for changes in several files + auto addFunc = [this, shaderCallback](const std::string& path) { + ghoul::filesystem::File* f = new ghoul::filesystem::File(path, false); + f->setCallback(shaderCallback); + _shaderFiles.push_back(f); + }; + addFunc("${SHADERS}/ABuffer/abufferSort.hglsl"); + addFunc("${SHADERS}/ABuffer/abufferAddToBuffer.hglsl"); + addFunc("${SHADERS}/ABuffer/abufferStruct.hglsl"); + + _resolveShader = nullptr; generateShaderSource(); updateShader(); diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp index 84158f87d7..166ded0302 100644 --- a/src/abuffer/abufferSingleLinked.cpp +++ b/src/abuffer/abufferSingleLinked.cpp @@ -33,7 +33,6 @@ #include #define MAX_LAYERS 10 -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) namespace { std::string _loggerCat = "ABufferSingleLinked"; From b6b6a7f51bde1995263468b61a58e290249f0510 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Wed, 25 Jun 2014 15:27:22 -0400 Subject: [PATCH 031/113] Small jitterbug fix --- shaders/ABuffer/abufferSort.hglsl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index 6eaf03eed4..fd4de48f84 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -101,8 +101,7 @@ void sort_fragments_list(uint frag_count) { float x = gl_FragCoord.x; float y = gl_FragCoord.y; float jitterValue = float(permute(x + permute(y))) / 961.0; - jitterValue *= 0.004; - vec3 frontPosNew = startColor + (jitterValue*volume_length[ii])*volume_direction[ii]; + vec3 frontPosNew = startColor + (jitterValue*volumeStepSize[ii])*volume_direction[ii]; volume_position[ii] = frontPosNew; } From adec1fc215cfd92d7dcfeb458658bca0e09092fd Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Wed, 25 Jun 2014 16:44:07 -0400 Subject: [PATCH 032/113] Moved powescaling shader funcitonality - Added separete files for the power scaling algorithms - Added shader tracking and updating for the new files --- ...werScaling.hglsl => powerScaling_fs.hglsl} | 4 +- shaders/PowerScaling/powerScaling_vs.hglsl | 80 +++++++++++++++++++ shaders/pscstandard_fs.glsl | 2 +- shaders/pscstandard_vs.glsl | 63 ++------------- src/abuffer/abuffer.cpp | 3 + 5 files changed, 93 insertions(+), 59 deletions(-) rename shaders/PowerScaling/{powerScaling.hglsl => powerScaling_fs.hglsl} (98%) create mode 100644 shaders/PowerScaling/powerScaling_vs.hglsl diff --git a/shaders/PowerScaling/powerScaling.hglsl b/shaders/PowerScaling/powerScaling_fs.hglsl similarity index 98% rename from shaders/PowerScaling/powerScaling.hglsl rename to shaders/PowerScaling/powerScaling_fs.hglsl index 66ddf647b1..c227016f1d 100644 --- a/shaders/PowerScaling/powerScaling.hglsl +++ b/shaders/PowerScaling/powerScaling_fs.hglsl @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef POWERSCALING_H_HGLSL -#define POWERSCALING_H_HGLSL +#ifndef POWERSCALING_FS_H_HGLSL +#define POWERSCALING_FS_H_HGLSL // Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD! diff --git a/shaders/PowerScaling/powerScaling_vs.hglsl b/shaders/PowerScaling/powerScaling_vs.hglsl new file mode 100644 index 0000000000..0ec24564b7 --- /dev/null +++ b/shaders/PowerScaling/powerScaling_vs.hglsl @@ -0,0 +1,80 @@ +/***************************************************************************************** + * * + * 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 POWERSCALING_VS_H_HGLSL +#define POWERSCALING_VS_H_HGLSL + +const float k = 10.0; + +vec4 psc_addition(vec4 v1, vec4 v2) { + float ds = v2.w - v1.w; + if(ds >= 0) { + float p = pow(k,-ds); + return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w); + } else { + float p = pow(k,ds); + return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w); + } +} + +vec4 psc_to_meter(vec4 v1, vec2 v2) { + float factor = v2.x * pow(k,v2.y + v1.w); + return vec4(v1.xyz * factor, 1.0); +} + +vec4 psc_scaling(vec4 v1, vec2 v2) { + float ds = v2.y - v1.w; + if(ds >= 0) { + return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y); + } else { + return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w); + } +} + +vec4 pscTransform(vec4 vertexPosition, vec4 cameraPosition, vec2 scaling, mat4 modelTransform) { + vec3 local_vertex_pos = mat3(modelTransform) * vertexPosition.xyz; + //vec4 lvp = ModelTransform * vertexPosition; + + // PSC addition; local vertex position and the object power scaled world position + vec4 position = psc_addition(vec4(local_vertex_pos,vertexPosition.w),objpos); + //position = psc_addition(lvp,objpos); + + // PSC addition; rotated and viewscaled vertex and the cmaeras negative position + position = psc_addition(position,vec4(-cameraPosition.xyz,cameraPosition.w)); + + // rotate the camera + local_vertex_pos = mat3(camrot) * position.xyz; + position = vec4(local_vertex_pos, position.w); + //position = camrot* position; + + // rescales the scene to fit inside the view frustum + // is set from the main program, but these are decent values + // scaling = vec2(1.0, -8.0); + + // project using the rescaled coordinates, + //vec4 vs_position_rescaled = psc_scaling(position, scaling); + return psc_to_meter(position, scaling); +} + +#endif \ No newline at end of file diff --git a/shaders/pscstandard_fs.glsl b/shaders/pscstandard_fs.glsl index 380ca7f096..26a3d1987d 100644 --- a/shaders/pscstandard_fs.glsl +++ b/shaders/pscstandard_fs.glsl @@ -34,7 +34,7 @@ in float s; #include "ABuffer/abufferStruct.hglsl" #include "ABuffer/abufferAddToBuffer.hglsl" -#include "PowerScaling/powerScaling.hglsl" +#include "PowerScaling/powerScaling_fs.hglsl" void main() { diff --git a/shaders/pscstandard_vs.glsl b/shaders/pscstandard_vs.glsl index 83ba34bbfd..431602229b 100644 --- a/shaders/pscstandard_vs.glsl +++ b/shaders/pscstandard_vs.glsl @@ -43,71 +43,22 @@ out vec4 vs_normal; out vec3 vs_position; out float s; -const float k = 10.0; -vec4 psc_addition(vec4 v1, vec4 v2) { - float ds = v2.w - v1.w; - if(ds >= 0) { - float p = pow(k,-ds); - return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w); - } else { - float p = pow(k,ds); - return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w); - } -} - -vec4 psc_to_meter(vec4 v1, vec2 v2) { - float factor = v2.x * pow(k,v2.y + v1.w); - return vec4(v1.xyz * factor, 1.0); -} - -vec4 psc_scaling(vec4 v1, vec2 v2) { - float ds = v2.y - v1.w; - if(ds >= 0) { - return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y); - } else { - return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w); - } -} +#include "PowerScaling/powerScaling_vs.hglsl" void main() { // set variables vs_st = in_st; //vs_stp = in_position.xyz; + + // this is wrong for the normal. The normal transform is the transposed inverse of the model transform vs_normal = normalize(ModelTransform * vec4(in_normal,0)); - // fetch model and view translation - //vec4 vertex_translate = ModelTransform[3]; - - // rotate and scale vertex with model transform and add the translation - vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz; - //vec4 lvp = ModelTransform * in_position; - - // PSC addition; local vertex position and the object power scaled world position - vec4 position = psc_addition(vec4(local_vertex_pos,in_position.w),objpos); - //position = psc_addition(lvp,objpos); - - // PSC addition; rotated and viewscaled vertex and the cmaeras negative position - position = psc_addition(position,vec4(-campos.xyz,campos.w)); - - // rotate the camera - local_vertex_pos = mat3(camrot) * position.xyz; - position = vec4(local_vertex_pos, position.w); - //position = camrot* position; - - // rescales the scene to fit inside the view frustum - // is set from the main program, but these are decent values - // scaling = vec2(1.0, -8.0); - - // project using the rescaled coordinates, - //vec4 vs_position_rescaled = psc_scaling(position, scaling); - vec4 vs_position_rescaled = psc_to_meter(position, scaling); - position = vs_position_rescaled; - vs_position = vs_position_rescaled.xyz; - s = vs_position_rescaled.w; - + vec4 position = pscTransform(in_position, campos, scaling, ModelTransform); + vs_position = position.xyz; + s = position.w; // project the position to view space - gl_Position = ViewProjection * vs_position_rescaled; + gl_Position = ViewProjection * position; } \ No newline at end of file diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index dbb26e40fc..97313125d9 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -90,6 +90,9 @@ bool ABuffer::initializeABuffer() { addFunc("${SHADERS}/ABuffer/abufferSort.hglsl"); addFunc("${SHADERS}/ABuffer/abufferAddToBuffer.hglsl"); addFunc("${SHADERS}/ABuffer/abufferStruct.hglsl"); + addFunc("${SHADERS}/PowerScaling/powerScaling_fs.hglsl"); + addFunc("${SHADERS}/PowerScaling/powerScaling_vs.hglsl"); + _resolveShader = nullptr; From d378428dc4ad662812dbad997de4ce6c505ab8c1 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Thu, 26 Jun 2014 15:25:49 -0400 Subject: [PATCH 033/113] Crude PowerScale implementations - Added PowerScaling to RenderableVolumeGL and RenderableFieldlines - Removed the use of volumeraycasterbox since it used FBO and textures which was not used anymore. - Added a simple box implementation to RenderableVolumeGL that can have PowerScaled vertex positions TODO: The #include command needs to be extended in some way since the FieldLines passthrough shader can't access the PowerScaled includes in a good way. --- .../openspace/rendering/renderablevolumegl.h | 10 +- openspace-data | 2 +- shaders/exitpoints.frag | 13 +- shaders/exitpoints.vert | 33 ++++- shaders/pscstandard_vs.glsl | 1 - src/rendering/renderablefieldlines.cpp | 17 ++- src/rendering/renderablevolumegl.cpp | 121 ++++++++++++++++-- 7 files changed, 171 insertions(+), 26 deletions(-) diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index 25a2629a77..c368e41cfc 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -27,7 +27,6 @@ // open space includes #include -#include // ghoul includes #include @@ -36,6 +35,10 @@ #include #include + namespace sgct_utils { + class SGCTBox; +} + namespace openspace { class RenderableVolumeGL: public RenderableVolume { @@ -62,8 +65,11 @@ private: ghoul::opengl::Texture* _volume; ghoul::opengl::Texture* _transferFunction; - VolumeRaycasterBox* _colorBoxRenderer; + GLuint _boxArray; + ghoul::opengl::ProgramObject *_boxProgram; + sgct_utils::SGCTBox* _box; glm::vec3 _boxScaling; + GLint _MVPLocation, _modelTransformLocation, _typeLocation; bool _updateTransferfunction; int _id; diff --git a/openspace-data b/openspace-data index b4199564cb..8fa226790e 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit b4199564cb227d8896b23016f53b5317943cbdad +Subproject commit 8fa226790e939667b31c0e2020ba42708e3de7e6 diff --git a/shaders/exitpoints.frag b/shaders/exitpoints.frag index cc58d29e35..89fe78224b 100644 --- a/shaders/exitpoints.frag +++ b/shaders/exitpoints.frag @@ -28,20 +28,23 @@ uniform int volumeType; in vec3 vPosition; in vec3 worldPosition; -out vec4 fragColor; +in float s; #include "ABuffer/abufferStruct.hglsl" #include "ABuffer/abufferAddToBuffer.hglsl" +#include "PowerScaling/powerScaling_fs.hglsl" void main() { - fragColor = vec4(vPosition+0.5, 0.3); + vec4 fragColor = vec4(vPosition+0.5, 0.3); + vec4 position = vec4(worldPosition,s); + float depth = pscDepth(position); ABufferStruct_t frag; _col_(frag, fragColor); - _z_(frag, gl_FragCoord.z); + _z_(frag, depth); _type_(frag, volumeType); - _pos_(frag, vec4(worldPosition,0)); + _pos_(frag, position); addToBuffer(frag); - //discard; + discard; } \ No newline at end of file diff --git a/shaders/exitpoints.vert b/shaders/exitpoints.vert index 80145134b3..f8895ba4b3 100644 --- a/shaders/exitpoints.vert +++ b/shaders/exitpoints.vert @@ -24,15 +24,40 @@ #version 430 core -layout(location = 2) in vec3 vertPosition; +layout(location = 0) in vec4 vertPosition; + uniform mat4 modelViewProjection; uniform mat4 modelTransform; +uniform vec4 campos; +uniform mat4 camrot; +uniform vec2 scaling; +uniform vec4 objpos; +uniform float time; out vec3 vPosition; out vec3 worldPosition; +out float s; + +#include "PowerScaling/powerScaling_vs.hglsl" void main() { - vPosition = vertPosition; - worldPosition = (modelTransform *vec4(vPosition, 1.0)).xyz; - gl_Position = modelViewProjection *vec4(worldPosition, 1.0); + + //vs_st = in_st; + //vs_stp = in_position.xyz; + + vPosition = vertPosition.xyz; + + // this is wrong for the normal. The normal transform is the transposed inverse of the model transform + //vs_normal = normalize(modelTransform * vec4(in_normal,0)); + + vec4 position = pscTransform(vertPosition, campos, scaling, modelTransform); + worldPosition = position.xyz; + s = position.w; + + // project the position to view space + gl_Position = modelViewProjection * position; + + // vPosition = vertPosition.xyz; + // worldPosition = (modelTransform *vec4(vPosition, 1.0)).xyz; + // gl_Position = modelViewProjection *vec4(worldPosition, 1.0); } \ No newline at end of file diff --git a/shaders/pscstandard_vs.glsl b/shaders/pscstandard_vs.glsl index 431602229b..e9e1745dc9 100644 --- a/shaders/pscstandard_vs.glsl +++ b/shaders/pscstandard_vs.glsl @@ -43,7 +43,6 @@ out vec4 vs_normal; out vec3 vs_position; out float s; - #include "PowerScaling/powerScaling_vs.hglsl" void main() diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index 135c610b24..0b3fa49749 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -206,14 +206,27 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) psc relative = thisPosition-camera->position(); transform = transform*camTransform; - transform = glm::translate(transform, relative.vec3()); + //transform = glm::translate(transform, relative.vec3()); + transform = glm::mat4(1.0); transform = glm::rotate(transform, -90.0f, glm::vec3(1.0, 0.0, 0.0)); // Model has positive Z as up transform = glm::scale(transform, glm::vec3(0.036*0.5*0.5)); //transform = glm::scale(transform, glm::vec3(0.1)); // Scale to avoid depth buffer problems + psc currentPosition = thisPosition; + psc campos = camera->position(); + glm::mat4 camrot = camera->viewRotationMatrix(); + PowerScaledScalar scaling = camera->scaling(); + // Activate shader _fieldlinesProgram->activate(); - _fieldlinesProgram->setUniform("modelViewProjection", transform); + //_fieldlinesProgram->setUniform("modelViewProjection", transform); + + _fieldlinesProgram->setUniform("modelViewProjection", camera->viewProjectionMatrix()); + _fieldlinesProgram->setUniform("modelTransform", transform); + _fieldlinesProgram->setUniform("campos", campos.vec4()); + _fieldlinesProgram->setUniform("objpos", currentPosition.vec4()); + _fieldlinesProgram->setUniform("camrot", camrot); + _fieldlinesProgram->setUniform("scaling", scaling.vec2()); // ------ FIELDLINES ----------------- glBindVertexArray(_VAO); diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index 518120649c..bdcdc9ae79 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -34,6 +34,7 @@ #include #include +#include namespace { std::string _loggerCat = "RenderableVolumeGL"; @@ -42,7 +43,7 @@ namespace { namespace openspace { RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): - RenderableVolume(dictionary), _boxScaling(1.0, 1.0, 1.0), + RenderableVolume(dictionary), _box(nullptr), _boxScaling(1.0, 1.0, 1.0), _updateTransferfunction(false), _id(-1) { @@ -96,7 +97,6 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): _boxScaling[2] = tempValue; } - _colorBoxRenderer = new VolumeRaycasterBox(); setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling))); } @@ -104,12 +104,12 @@ RenderableVolumeGL::~RenderableVolumeGL() { deinitialize(); if(_volume) delete _volume; - if(_colorBoxRenderer) - delete _colorBoxRenderer; if(_transferFunctionFile) delete _transferFunctionFile; if(_transferFunction) delete _transferFunction; + if(_box) + delete _box; } bool RenderableVolumeGL::initialize() { @@ -130,7 +130,70 @@ bool RenderableVolumeGL::initialize() { }; _transferFunctionFile->setCallback(textureCallback); - _colorBoxRenderer->initialize(); + _box = new sgct_utils::SGCTBox(1.0f, sgct_utils::SGCTBox::Regular); + OsEng.configurationManager().getValue("RaycastProgram", _boxProgram); + _MVPLocation = _boxProgram->uniformLocation("modelViewProjection"); + _modelTransformLocation = _boxProgram->uniformLocation("modelTransform"); + _typeLocation = _boxProgram->uniformLocation("volumeType"); + + // ============================ + // GEOMETRY (quad) + // ============================ + const GLfloat size = 0.5f; + const GLfloat vertex_data[] = { // square of two triangles (sigh) + // x, y, z, s, + -size, -size, size, 0.0f, + size, size, size, 0.0f, + -size, size, size, 0.0f, + -size, -size, size, 0.0f, + size, -size, size, 0.0f, + size, size, size, 0.0f, + + -size, -size, -size, 0.0f, + size, size, -size, 0.0f, + -size, size, -size, 0.0f, + -size, -size, -size, 0.0f, + size, -size, -size, 0.0f, + size, size, -size, 0.0f, + + size, -size, -size, 0.0f, + size, size, size, 0.0f, + size, -size, size, 0.0f, + size, -size, -size, 0.0f, + size, size, -size, 0.0f, + size, size, size, 0.0f, + + -size, -size, -size, 0.0f, + -size, size, size, 0.0f, + -size, -size, size, 0.0f, + -size, -size, -size, 0.0f, + -size, size, -size, 0.0f, + -size, size, size, 0.0f, + + -size, size, -size, 0.0f, + size, size, size, 0.0f, + -size, size, size, 0.0f, + -size, size, -size, 0.0f, + size, size, -size, 0.0f, + size, size, size, 0.0f, + + -size, -size, -size, 0.0f, + size, -size, size, 0.0f, + -size, -size, size, 0.0f, + -size, -size, -size, 0.0f, + size, -size, -size, 0.0f, + size, -size, size, 0.0f, + }; + GLuint vertexPositionBuffer; + glGenVertexArrays(1, &_boxArray); // generate array + glBindVertexArray(_boxArray); // bind array + glGenBuffers(1, &vertexPositionBuffer); // generate buffer + glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, reinterpret_cast(0)); + //glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*7, reinterpret_cast(0)); + glEnableVertexAttribArray(0); + //glEnableVertexAttribArray(1); return true; @@ -151,22 +214,58 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { glTexImage1D( GL_TEXTURE_1D, 0, _transferFunction->internalFormat(), _transferFunction->width(),0, _transferFunction->format(), _transferFunction->dataType(), data); - //delete data; delete transferFunction; LDEBUG("Updated transferfunction!"); } } - psc relative = thisPosition-camera->position(); + //psc relative = thisPosition-camera->position(); - glm::mat4 transform = camera->viewRotationMatrix(); - transform = glm::translate(transform, relative.vec3()); - transform = glm::translate(transform, glm::vec3(-1.1,0.0,0.0)); + // glm::mat4 transform = camera->viewRotationMatrix(); + // transform = glm::translate(transform, relative.vec3()); + // transform = glm::translate(transform, glm::vec3(-1.1,0.0,0.0)); + // transform = glm::scale(transform, _boxScaling); + glm::mat4 transform = glm::mat4(1.0); transform = glm::scale(transform, _boxScaling); + // fetch data + psc currentPosition = thisPosition; + psc campos = camera->position(); + glm::mat4 camrot = camera->viewRotationMatrix(); + PowerScaledScalar scaling = camera->scaling(); + + psc addon(-1.1,0.0,0.0,0.0); + currentPosition += addon; + // TODO: Use _id to identify this volume - _colorBoxRenderer->render(camera->viewProjectionMatrix(), transform, _id); + _boxProgram->activate(); + // _boxProgram->setUniform(_MVPLocation, camera->viewProjectionMatrix()); + // _boxProgram->setUniform(_modelTransformLocation, transform); + _boxProgram->setUniform(_typeLocation, _id); + + _boxProgram->setUniform("modelViewProjection", camera->viewProjectionMatrix()); + _boxProgram->setUniform("modelTransform", transform); + _boxProgram->setUniform("campos", campos.vec4()); + _boxProgram->setUniform("objpos", currentPosition.vec4()); + _boxProgram->setUniform("camrot", camrot); + _boxProgram->setUniform("scaling", scaling.vec2()); + + // make sure GL_CULL_FACE is enabled (it should be) + glEnable(GL_CULL_FACE); + + // Draw backface + glCullFace(GL_FRONT); + glBindVertexArray(_boxArray); + glDrawArrays(GL_TRIANGLES, 0, 6*6); + // _box->draw(); + + // Draw frontface (now the normal cull face is is set) + glCullFace(GL_BACK); + glDrawArrays(GL_TRIANGLES, 0, 6*6); + // _box->draw(); + + _boxProgram->deactivate(); } From 24d38d0296f8913b49e2b44975226906f0bdd7fa Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Fri, 27 Jun 2014 15:18:34 -0400 Subject: [PATCH 034/113] Implemented tracing for Lorentz force trajectories --- .../rendering/renderablefieldlines.h | 6 +- include/openspace/util/kameleonwrapper.h | 17 +- src/rendering/renderablefieldlines.cpp | 87 ++++++---- src/util/kameleonwrapper.cpp | 158 +++++++++++++++++- 4 files changed, 220 insertions(+), 48 deletions(-) diff --git a/include/openspace/rendering/renderablefieldlines.h b/include/openspace/rendering/renderablefieldlines.h index e26c7c2b54..3f663c4f73 100644 --- a/include/openspace/rendering/renderablefieldlines.h +++ b/include/openspace/rendering/renderablefieldlines.h @@ -58,7 +58,7 @@ private: std::vector _filenames; std::vector _seedPoints; - ghoul::opengl::ProgramObject *_fieldlinesProgram, *_seedpointsProgram; + ghoul::opengl::ProgramObject *_fieldlinesProgram; GLuint _VAO, _seedpointVAO; std::mutex* _shaderMutex; @@ -66,8 +66,8 @@ private: ghoul::filesystem::File* _vertexSourceFile; ghoul::filesystem::File* _fragmentSourceFile; - std::vector _lineStart, _seedpointStart; - std::vector _lineCount, _seedpointCount; + std::vector _lineStart; + std::vector _lineCount; bool _programUpdateOnSave; void safeShaderCompilation(); diff --git a/include/openspace/util/kameleonwrapper.h b/include/openspace/util/kameleonwrapper.h index 4141bdec52..6b85680231 100644 --- a/include/openspace/util/kameleonwrapper.h +++ b/include/openspace/util/kameleonwrapper.h @@ -25,7 +25,6 @@ #ifndef KAMELEONWRAPPER_H_ #define KAMELEONWRAPPER_H_ -//#include #include namespace ccmc { @@ -43,12 +42,12 @@ public: BATSRUS // Magnetosphere }; - enum TraceDirection { + enum class TraceDirection { FORWARD = 1, BACK = -1 }; - enum FieldlineEnd { + enum class FieldlineEnd { NORTH, SOUTH, OUT @@ -60,15 +59,25 @@ public: float* getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions); - std::vector > getFieldLines(const std::string& xVar, + std::vector > getClassifiedFieldLines(const std::string& xVar, const std::string& yVar, const std::string& zVar, std::vector seedPoints, float stepSize); + std::vector > getFieldLines(const std::string& xVar, + const std::string& yVar, const std::string& zVar, + std::vector seedPoints, float stepSize, glm::vec3 color); + + std::vector > getLorentzTrajectories(std::vector seedPoints, + glm::vec3 color, float stepsize); + private: std::vector traceCartesianFieldline(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::vec3 seedPoint, float stepSize, TraceDirection direction, FieldlineEnd& end); + std::vector traceLorentzTrajectory(glm::vec3 seedPoint, + float stepsize, float eCharge); + void getGridVariables(std::string& x, std::string& y, std::string& z); void progressBar(int current, int end); glm::vec3 classifyFieldline(FieldlineEnd fEnd, FieldlineEnd bEnd); diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index 64dab8daaa..4527ad2cc6 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -94,14 +94,6 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) } } - _seedpointsProgram = new ghoul::opengl::ProgramObject("SeedpointsProgram"); - ghoul::opengl::ShaderObject* seedpointVertexShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeVertex, - "/home/hhellteg/openspace/openspace-data/scene/fieldlines/seedPoints.vert"); - ghoul::opengl::ShaderObject* seedpointFragmentShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeFragment, - "/home/hhellteg/openspace/openspace-data/scene/fieldlines/seedPoints.frag"); - _seedpointsProgram->attachObject(seedpointVertexShader); - _seedpointsProgram->attachObject(seedpointFragmentShader); - if(dictionary.hasKey("UpdateOnSave")) { dictionary.getValue("UpdateOnSave", _programUpdateOnSave); } @@ -129,14 +121,17 @@ bool RenderableFieldlines::initialize() { _lineCount.push_back(fieldlinesData[j].size()/2.0); prevEnd = prevEnd + fieldlinesData[j].size()/2.0; - _seedpointStart.push_back(j); - _seedpointCount.push_back(1); - vertexData.insert( vertexData.end(), fieldlinesData[j].begin(), fieldlinesData[j].end()); } } + LDEBUG("Number of vertices : " << vertexData.size()/2.0); - LDEBUG("Vertex orginal : " << vertexData.size()/2.0); + // Give seedpoints a color for visualizing as GL_POINTS + std::vector seedPointsData; + for (int i = 0; i < _seedPoints.size(); ++i) { + seedPointsData.push_back(_seedPoints[i]); + seedPointsData.push_back(glm::vec3(1.0, 0.0, 1.0)); + } // ------ FIELDLINES ----------------- GLuint vertexPositionBuffer; @@ -159,22 +154,27 @@ bool RenderableFieldlines::initialize() { glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer glBindVertexArray(0); //unbind array -// // ------ SEEDPOINTS ----------------- + // ------ SEEDPOINTS ----------------- GLuint seedpointPositionBuffer; glGenVertexArrays(1, &_seedpointVAO); // generate array glBindVertexArray(_seedpointVAO); // bind array glGenBuffers(1, &seedpointPositionBuffer); // generate buffer glBindBuffer(GL_ARRAY_BUFFER, seedpointPositionBuffer); // bind buffer - glBufferData(GL_ARRAY_BUFFER, _seedPoints.size()*sizeof(glm::vec3), &_seedPoints.front(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, seedPointsData.size()*sizeof(glm::vec3), &seedPointsData.front(), GL_STATIC_DRAW); // Vertex positions - GLuint seedpointLocation = 0; - glEnableVertexAttribArray(seedpointLocation); - glVertexAttribPointer(seedpointLocation, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), reinterpret_cast(0)); + glEnableVertexAttribArray(vertexLocation); + glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 2*sizeof(glm::vec3), reinterpret_cast(0)); + + // Texture coordinates + glEnableVertexAttribArray(texcoordLocation); + glVertexAttribPointer(texcoordLocation, 3, GL_FLOAT, GL_FALSE, 2*sizeof(glm::vec3), (void*)(sizeof(glm::vec3))); glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer glBindVertexArray(0); //unbind array + glPointSize(5); // size of seedpoints + // ------ SETUP SHADERS ----------------- auto privateCallback = [this](const ghoul::filesystem::File& file) { safeShaderCompilation(); @@ -187,9 +187,6 @@ bool RenderableFieldlines::initialize() { _fieldlinesProgram->compileShaderObjects(); _fieldlinesProgram->linkProgramObject(); - _seedpointsProgram->compileShaderObjects(); - _seedpointsProgram->linkProgramObject(); - return true; } @@ -211,25 +208,15 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) _shaderMutex->lock(); _fieldlinesProgram->activate(); _fieldlinesProgram->setUniform("modelViewProjection", transform); - glBindVertexArray(_VAO); glMultiDrawArrays(GL_LINE_STRIP, &_lineStart[0], &_lineCount[0], _lineStart.size()); - glBindVertexArray(0); - - _fieldlinesProgram->deactivate(); - _shaderMutex->unlock(); // ------ SEEDPOINTS ----------------- - _shaderMutex->lock(); - _seedpointsProgram->activate(); - _seedpointsProgram->setUniform("modelViewProjection", transform); - glBindVertexArray(_seedpointVAO); - glPointSize(5); glMultiDrawArrays(GL_POINTS, &_lineStart[0], &_lineCount[0], _seedPoints.size()); glBindVertexArray(0); - _seedpointsProgram->deactivate(); + _fieldlinesProgram->deactivate(); _shaderMutex->unlock(); } @@ -251,7 +238,11 @@ std::vector > RenderableFieldlines::getFieldlinesData(std KameleonWrapper::Model model; std::vector > fieldlinesData; + bool classification = false, lorentz = false; + glm::vec3 fieldlineColor = glm::vec3(1.0, 1.0, 1.0); // default color if no color or classification is specified + if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) { + // ------ MODEL ----------------- if (modelString == "BATSRUS") { model = KameleonWrapper::Model::BATSRUS; } else if (modelString == "ENLIL") { @@ -262,25 +253,35 @@ std::vector > RenderableFieldlines::getFieldlinesData(std return fieldlinesData; } + // ------ VARIBLES / LORENTZ ----------------- if (hintsDictionary.hasKey("Variables")) { bool xVar, yVar, zVar; xVar = hintsDictionary.getValue("Variables.1", xVariable); - yVar = hintsDictionary.getValue("Variables.2", yVariable); - zVar = hintsDictionary.getValue("Variables.3", zVariable); + if (xVar && xVariable == "Lorentz") { + lorentz = true; + } else { - if (!xVar || !yVar || !zVar) { - LWARNING("Error reading variables! Must be 3 and must exist in CDF data"); - return fieldlinesData; + yVar = hintsDictionary.getValue("Variables.2", yVariable); + zVar = hintsDictionary.getValue("Variables.3", zVariable); + + if (!xVar || !yVar || !zVar) { + LWARNING("Error reading variables! Must be 3 and must exist in CDF data"); + return fieldlinesData; + } } } else { LWARNING("Hints does not specify valid 'Variables'"); return fieldlinesData; } + // ------ STEPSIZE ----------------- if (!hintsDictionary.hasKey("Stepsize") || !hintsDictionary.getValue("Stepsize", stepSize)) { LDEBUG("No stepsize set for fieldlines. Setting to default value (" << stepSize << ")"); } + + // ------ SEEDPOINTS --------------- ghoul::Dictionary seedpointsDictionary; + _seedPoints.clear(); if (hintsDictionary.hasKey("Seedpoints") && hintsDictionary.getValue("Seedpoints", seedpointsDictionary)) { glm::vec3 seedPos; for (auto index : seedpointsDictionary.keys()) { @@ -288,10 +289,22 @@ std::vector > RenderableFieldlines::getFieldlinesData(std _seedPoints.push_back(seedPos); } } + + // ------ CLASSIFICATION & COLOR ----------- + hintsDictionary.getValue("Color", fieldlineColor); + hintsDictionary.getValue("Classification", classification); } KameleonWrapper kw(filename, model); - fieldlinesData = kw.getFieldLines(xVariable, yVariable, zVariable, _seedPoints, stepSize); + if (lorentz) { + fieldlinesData = kw.getLorentzTrajectories(_seedPoints, fieldlineColor, stepSize); + } else { + if (classification) + fieldlinesData = kw.getClassifiedFieldLines(xVariable, yVariable, zVariable, _seedPoints, stepSize); + else + fieldlinesData = kw.getFieldLines(xVariable, yVariable, zVariable, _seedPoints, stepSize, fieldlineColor); + } + return fieldlinesData; } diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 314074c0a0..ead509d8e0 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -229,7 +229,7 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c return data; } -std::vector > KameleonWrapper::getFieldLines( +std::vector > KameleonWrapper::getClassifiedFieldLines( const std::string& xVar, const std::string& yVar, const std::string& zVar, std::vector seedPoints, float stepSize ) { @@ -268,6 +268,67 @@ std::vector > KameleonWrapper::getFieldLines( return fieldLines; } +std::vector > KameleonWrapper::getFieldLines( + const std::string& xVar, const std::string& yVar, + const std::string& zVar, std::vector seedPoints, + float stepSize, glm::vec3 color ) { + assert(_model && _interpolator); + assert(_type == Model::ENLIL || _type == Model::BATSRUS); + LINFO("Creating " << seedPoints.size() << " fieldlines from variables " << xVar << " " << yVar << " " << zVar); + + std::vector fLine, bLine; + std::vector > fieldLines; + FieldlineEnd forwardEnd, backEnd; + + if (_type == Model::BATSRUS) { + for (glm::vec3 seedPoint : seedPoints) { + 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()); + + // write colors + std::vector line; + for (glm::vec3 position : bLine) { + line.push_back(position); + line.push_back(color); + } + + fieldLines.push_back(line); + } + } else { + LERROR("Fieldlines are only supported for BATSRUS model"); + } + + return fieldLines; +} + +std::vector > KameleonWrapper::getLorentzTrajectories( + std::vector seedPoints, glm::vec3 color, float stepsize) { + LINFO("Creating " << seedPoints.size() << " Lorentz force trajectories"); + + std::vector > trajectories; + std::vector plusTraj, minusTraj; + + for (auto seedPoint : seedPoints) { + plusTraj = traceLorentzTrajectory(seedPoint, stepsize, 1.0); + minusTraj = traceLorentzTrajectory(seedPoint, stepsize, -1.0); + + minusTraj.insert(minusTraj.begin(), plusTraj.rbegin(), plusTraj.rend()); + + // write colors + std::vector trajectory; + for (glm::vec3 position : minusTraj) { + trajectory.push_back(position); + trajectory.push_back(color); + } + trajectories.push_back(trajectory); + + } + + return trajectories; +} + std::vector KameleonWrapper::traceCartesianFieldline( const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::vec3 seedPoint, @@ -276,8 +337,7 @@ std::vector KameleonWrapper::traceCartesianFieldline( glm::vec3 color, pos, k1, k2, k3, k4; std::vector line; float stepX, stepY, stepZ; - int numSteps = 0; - int maxSteps = 5000; + int numSteps = 0, maxSteps = 5000; pos = seedPoint; _model->loadVariable(xVar); @@ -300,7 +360,7 @@ std::vector KameleonWrapper::traceCartesianFieldline( k1.y = _interpolator->interpolate(yID, pos.x, pos.y, pos.z); k1.z = _interpolator->interpolate(zID, pos.x, pos.y, pos.z); k1 = (float)direction*glm::normalize(k1); -// stepX*=stepSize, stepY*=stepSize, stepZ*=stepSize; + stepX=stepX*stepSize, stepY=stepY*stepSize, stepZ=stepZ*stepSize; k2.x = _interpolator->interpolate(xID, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); k2.y = _interpolator->interpolate(yID, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); k2.z = _interpolator->interpolate(zID, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z); @@ -335,6 +395,96 @@ std::vector KameleonWrapper::traceCartesianFieldline( return line; } +std::vector KameleonWrapper::traceLorentzTrajectory(glm::vec3 seedPoint, + float stepsize, float eCharge) { + glm::vec3 B, E, v0, k1, k2, k3, k4, sPos, tmpV; + float stepX = stepsize, stepY = stepsize, stepZ = stepsize; + + long int bxID = _model->getVariableID("bx"); + long int byID = _model->getVariableID("by"); + long int bzID = _model->getVariableID("bz"); + long int jxID = _model->getVariableID("jx"); + long int jyID = _model->getVariableID("jy"); + long int jzID = _model->getVariableID("jz"); + + std::vector trajectory; + glm::vec3 pos = seedPoint; + int numSteps = 0, maxSteps = 5000; + v0.x = _interpolator->interpolate("ux", pos.x, pos.y, pos.z); + v0.y = _interpolator->interpolate("uy", pos.x, pos.y, pos.z); + v0.z = _interpolator->interpolate("uz", pos.x, pos.y, pos.z); + v0 = glm::normalize(v0); + + // While we are inside the models boundries and not inside earth + while ((pos.x < _xMax && pos.x > _xMin && pos.y < _yMax && pos.y > _yMin && + pos.z < _zMax && pos.z > _zMin) && !(pos.x*pos.x + pos.y*pos.y + pos.z*pos.z < 1.0)) { + + // Save position + trajectory.push_back(pos); + + // Calculate new position with Lorentz force quation and Runge-Kutta 4th order + B.x = _interpolator->interpolate(bxID, pos.x, pos.y, pos.z); + B.y = _interpolator->interpolate(byID, pos.x, pos.y, pos.z); + B.z = _interpolator->interpolate(bzID, pos.x, pos.y, pos.z); + E.x = _interpolator->interpolate(jxID, pos.x, pos.y, pos.z); + E.y = _interpolator->interpolate(jyID, pos.x, pos.y, pos.z); + E.z = _interpolator->interpolate(jzID, pos.x, pos.y, pos.z); + k1 = eCharge*(E + glm::cross(v0, B)); + k1 = glm::normalize(k1); + + sPos = glm::vec3( pos.x+(stepX/2.0)*v0.x+(stepX*stepX/8.0)*k1.x, + pos.y+(stepY/2.0)*v0.y+(stepY*stepY/8.0)*k1.y, + pos.z+(stepZ/2.0)*v0.z+(stepZ*stepZ/8.0)*k1.z); + B.x = _interpolator->interpolate(bxID, sPos.x, sPos.y, sPos.z); + B.y = _interpolator->interpolate(byID, sPos.x, sPos.y, sPos.z); + B.z = _interpolator->interpolate(bzID, sPos.x, sPos.y, sPos.z); + E.x = _interpolator->interpolate(jxID, sPos.x, sPos.y, sPos.z); + E.y = _interpolator->interpolate(jyID, sPos.x, sPos.y, sPos.z); + E.z = _interpolator->interpolate(jzID, sPos.x, sPos.y, sPos.z); + tmpV = v0+(stepX/2.0f)*k1; + k2 = eCharge*(E + glm::cross(tmpV, B)); + k2 = glm::normalize(k2); + + B.x = _interpolator->interpolate(bxID, sPos.x, sPos.y, sPos.z); + B.y = _interpolator->interpolate(byID, sPos.x, sPos.y, sPos.z); + B.z = _interpolator->interpolate(bzID, sPos.x, sPos.y, sPos.z); + E.x = _interpolator->interpolate(jxID, sPos.x, sPos.y, sPos.z); + E.y = _interpolator->interpolate(jyID, sPos.x, sPos.y, sPos.z); + E.z = _interpolator->interpolate(jzID, sPos.x, sPos.y, sPos.z); + tmpV = v0+(stepX/2.0f)*k2; + k3 = eCharge*(E + glm::cross(tmpV, B)); + k3 = glm::normalize(k3); + + sPos = glm::vec3( pos.x+stepX*v0.x+(stepX*stepX/2.0)*k1.x, + pos.y+stepY*v0.y+(stepY*stepY/2.0)*k1.y, + pos.z+stepZ*v0.z+(stepZ*stepZ/2.0)*k1.z); + B.x = _interpolator->interpolate(bxID, sPos.x, sPos.y, sPos.z); + B.y = _interpolator->interpolate(byID, sPos.x, sPos.y, sPos.z); + B.z = _interpolator->interpolate(bzID, sPos.x, sPos.y, sPos.z); + E.x = _interpolator->interpolate(jxID, sPos.x, sPos.y, sPos.z); + E.y = _interpolator->interpolate(jyID, sPos.x, sPos.y, sPos.z); + E.z = _interpolator->interpolate(jzID, sPos.x, sPos.y, sPos.z); + tmpV = v0+stepX*k3; + k4 = eCharge*(E + glm::cross(tmpV, B)); + k4 = glm::normalize(k4); + + pos.x = pos.x + stepX*v0.x + (stepX*stepX/6.0)*(k1.x + k2.x + k3.x); + pos.y = pos.y + stepY*v0.y + (stepY*stepY/6.0)*(k1.y + k2.y + k3.y); + pos.z = pos.z + stepZ*v0.z + (stepZ*stepZ/6.0)*(k1.z + k2.z + k3.z); + + v0.x = v0.x + (stepX/6.0)*(k1.x + 2.0*k2.x + 2.0*k3.x + k4.z); + v0.y = v0.y + (stepY/6.0)*(k1.y + 2.0*k2.y + 2.0*k3.y + k4.y); + v0.z = v0.z + (stepZ/6.0)*(k1.z + 2.0*k2.z + 2.0*k3.z + k4.z); + + ++numSteps; + if (numSteps > maxSteps) { + LDEBUG("Max number of steps taken (" << maxSteps <<")"); + break; + } + } + return trajectory; +} + void KameleonWrapper::getGridVariables(std::string& x, std::string& y, std::string& z) { // get the grid system string std::string gridSystem = _model->getGlobalAttribute("grid_system_1").getAttributeString(); From 4dca06e776d6bc947d8e3951e9a2b6b595c709ae Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Tue, 1 Jul 2014 09:53:10 -0400 Subject: [PATCH 035/113] Fixed alignment of data in kameleonwrapper. This version is installed in the CCMC-lab --- src/rendering/renderablefieldlines.cpp | 6 +++--- src/util/kameleonwrapper.cpp | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index b249f336eb..ff4e76c669 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -129,7 +129,7 @@ bool RenderableFieldlines::initialize() { std::vector seedPointsData; for (int i = 0; i < _seedPoints.size(); ++i) { seedPointsData.push_back(_seedPoints[i]); - seedPointsData.push_back(glm::vec3(1.0, 0.0, 1.0)); + seedPointsData.push_back(glm::vec3(1.0, 0.5, 0.0)); } // ------ FIELDLINES ----------------- @@ -207,8 +207,8 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) transform = transform*camTransform; //transform = glm::translate(transform, relative.vec3()); transform = glm::mat4(1.0); - transform = glm::rotate(transform, -90.0f, glm::vec3(1.0, 0.0, 0.0)); // Model has positive Z as up - transform = glm::scale(transform, glm::vec3(0.036*0.5*0.5)); +// transform = glm::scale(transform, glm::vec3(0.036*0.5*0.5)); + transform = glm::scale(transform, glm::vec3(0.01)); //transform = glm::scale(transform, glm::vec3(0.1)); // Scale to avoid depth buffer problems psc currentPosition = thisPosition; diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 4331eed914..1fa2b423f6 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -36,6 +36,8 @@ #include #include +#include + namespace openspace { std::string _loggerCat = "KameleonWrapper"; @@ -122,7 +124,8 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz double zPos = _zMin + stepZ*z; // get interpolated data value for (xPos, yPos, zPos) - double value = _interpolator->interpolate(var, xPos, yPos, zPos); + // swap yPos and zPos because model has Z as up + double value = _interpolator->interpolate(var, xPos, zPos, yPos); // scale to [0,1] //doubleData[index] = (value-varMin)/(varMax-varMin); @@ -360,7 +363,6 @@ std::vector > KameleonWrapper::getLorentzTrajectories( trajectory.push_back(color); } trajectories.push_back(trajectory); - } return trajectories; @@ -389,8 +391,8 @@ std::vector KameleonWrapper::traceCartesianFieldline( while ((pos.x < _xMax && pos.x > _xMin && pos.y < _yMax && pos.y > _yMin && pos.z < _zMax && pos.z > _zMin) && !(pos.x*pos.x + pos.y*pos.y + pos.z*pos.z < 1.0)) { - // Save position - line.push_back(pos); + // Save position. Model has +Z as up + line.push_back(glm::vec3(pos.x, pos.z, pos.y)); // Calculate new position with Runge-Kutta 4th order k1.x = _interpolator->interpolate(xID, pos.x, pos.y, pos.z, stepX, stepY, stepZ); @@ -420,7 +422,8 @@ std::vector KameleonWrapper::traceCartesianFieldline( break; } } - line.push_back(pos); + // Save last position. Model has +Z as up + line.push_back(glm::vec3(pos.x, pos.z, pos.y)); if (pos.z > 0.0 && (pos.x*pos.x + pos.y*pos.y + pos.z*pos.z < 1.0)) end = FieldlineEnd::NORTH; @@ -456,8 +459,8 @@ std::vector KameleonWrapper::traceLorentzTrajectory(glm::vec3 seedPoi while ((pos.x < _xMax && pos.x > _xMin && pos.y < _yMax && pos.y > _yMin && pos.z < _zMax && pos.z > _zMin) && !(pos.x*pos.x + pos.y*pos.y + pos.z*pos.z < 1.0)) { - // Save position - trajectory.push_back(pos); + // Save position. Model has +Z as up + trajectory.push_back(glm::vec3(pos.x, pos.z, pos.y)); // Calculate new position with Lorentz force quation and Runge-Kutta 4th order B.x = _interpolator->interpolate(bxID, pos.x, pos.y, pos.z); @@ -519,6 +522,8 @@ std::vector KameleonWrapper::traceLorentzTrajectory(glm::vec3 seedPoi break; } } + // Save last position. Model has +Z as up + trajectory.push_back(glm::vec3(pos.x, pos.z, pos.y)); return trajectory; } From 610d5d5427c4b8e57225317d0a2745d29d17a104 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Tue, 1 Jul 2014 10:01:54 -0400 Subject: [PATCH 036/113] Added variable stepsize for volumes - When holding right mouse button the stepsize for volumes will be 1/5 - Added configuration files for ccmc lab --- config/sgct/ccmc_lab_all.xml | 65 +++++++++++++++++++++ config/sgct/ccmc_lab_work.xml | 47 +++++++++++++++ shaders/ABuffer/abufferResolveFragment.glsl | 51 +++++++++------- shaders/ABuffer/abufferSort.hglsl | 12 +++- src/abuffer/abuffer.cpp | 14 +++++ src/interaction/interactionhandler.cpp | 4 +- 6 files changed, 167 insertions(+), 26 deletions(-) create mode 100644 config/sgct/ccmc_lab_all.xml create mode 100644 config/sgct/ccmc_lab_work.xml diff --git a/config/sgct/ccmc_lab_all.xml b/config/sgct/ccmc_lab_all.xml new file mode 100644 index 0000000000..9c2fcd4958 --- /dev/null +++ b/config/sgct/ccmc_lab_all.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/config/sgct/ccmc_lab_work.xml b/config/sgct/ccmc_lab_work.xml new file mode 100644 index 0000000000..0c9f4069b6 --- /dev/null +++ b/config/sgct/ccmc_lab_work.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index bbe589e045..7e2c233a83 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -28,15 +28,20 @@ // Settings // ================================================================================ #pragma openspace insert SETTINGS -#define LOOP_LIMIT 800 +// #define LOOP_LIMIT 500 #define MAX_FRAGMENTS 16 -#define SHOWFUNC + +#define SHOWFUNC 0 + +#define PSCDEPTH 1 +#define ZDEPTH 2 +#define ZTYPE PSCDEPTH const float stepSize = 0.01; const float samplingRate = 1.0; uniform int SCREEN_WIDTH; uniform int SCREEN_HEIGHT; -uniform float ALPHA_LIMIT = 0.98; +uniform float ALPHA_LIMIT = 0.95; in vec2 texCoord; out vec4 color; @@ -54,10 +59,15 @@ out vec4 color; ABufferStruct_t fragments[MAX_FRAGMENTS]; vec3 volume_direction[MAX_VOLUMES]; float volume_length[MAX_VOLUMES]; -vec2 volume_zlength[MAX_VOLUMES]; -// float volume_zlength[MAX_VOLUMES]; vec3 volume_position[MAX_VOLUMES]; +#if ZTYPE == ZDEPTH + vec2 volume_zlength[MAX_VOLUMES]; +#elif ZTYPE == PSCDEPTH + float volume_zlength[MAX_VOLUMES]; +#endif + + #include "abufferSort.hglsl" // ================================================================================ @@ -132,8 +142,7 @@ vec4 calculate_final_color(uint frag_count) { if(bool(currentVolumeBitmask)) { int volID = type -1; float p = 0.0f; - - // const float l = volume_length[volID]; +#if ZTYPE == ZDEPTH const float S1 = volume_zlength[volID].x; const float S2 = volume_zlength[volID].y; const float L = S1 - S2; @@ -145,21 +154,21 @@ vec4 calculate_final_color(uint frag_count) { int max_iterations = int(l / volumeStepSize[volID]); int iterations = 0; vec3 position; +#elif ZTYPE == PSCDEPTH + const float L = volume_zlength[volID]; + const vec4 p1 = _pos_(startFrag); + const vec4 p2 = _pos_(endFrag); + const float dist = pscLength(p1, p2); + // const float z1 = _z_(startFrag); + // const float z2 = _z_(endFrag); + const float l = (dist / L) * volume_length[volID]; + int max_iterations = int(l / volumeStepSize[volID]); + int iterations = 0; + vec3 position; +#endif - // const float S1 = volume_zlength[volID].x; - // const float S2 = volume_zlength[volID].y; - // const float L = volume_zlength[volID]; - // const vec4 p1 = _pos_(startFrag); - // const vec4 p2 = _pos_(endFrag); - // const float dist = pscLength(p1, p2); - // // const float z1 = _z_(startFrag); - // // const float z2 = _z_(endFrag); - // const float l = (dist / L) * volume_length[volID]; - // int max_iterations = int(l / volumeStepSize[volID]); - // int iterations = 0; - // vec3 position; // MIP // vec4 tmp, color = vec4(0); @@ -177,7 +186,7 @@ vec4 calculate_final_color(uint frag_count) { // TransferFunction vec4 color = vec4(0); - for(int k = 0; k < max_iterations && k < LOOP_LIMIT; ++k) { + for(int k = 0; k < max_iterations && final_color.a < ALPHA_LIMIT && k < LOOP_LIMIT; ++k) { //while(p < l && iterations < LOOP_LIMIT) { #pragma openspace insert SAMPLERCALLS @@ -214,7 +223,7 @@ vec4 calculate_final_color(uint frag_count) { // ================================================================================ // Transferfunction visualizer // ================================================================================ -#ifdef SHOWFUNC +#if (SHOWFUNC >= 0) && (SHOWFUNC < MAX_TF) float showfunc_size = 20.0; if(gl_FragCoord.y > float(SCREEN_HEIGHT) - showfunc_size) { float normalizedIntensity = gl_FragCoord.x / float(SCREEN_WIDTH) ; diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index fd4de48f84..61381bc7d1 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -24,6 +24,8 @@ #include "abufferAddToBuffer.hglsl" +uniform float volumeStepFactor = 1.0f; + int build_local_fragments_list() { uint current; int frag_count = 0; @@ -84,17 +86,21 @@ void sort_fragments_list(uint frag_count) { if(start) { startColor = _col_(fragments[jj]).rgb; startPosition = _pos_(fragments[jj]); +#if ZTYPE == ZDEPTH volume_zlength[ii].x = _z_(fragments[jj]); +#endif start = false; } else { vec3 dir = _col_(fragments[jj]).rgb - startColor; volume_position[ii] = startColor; volume_length[ii] = length(dir); volume_direction[ii] = normalize(dir); + volumeStepSize[ii] = 1.0/(volumeStepFactor * length(volume_direction[ii]*volume_dim[ii])); +#if ZTYPE == ZDEPTH volume_zlength[ii].y = _z_(fragments[jj]); - // volume_zlength[ii] = pscLength(_pos_(fragments[jj]), startPosition); - volumeStepSize[ii] = 1.0/(length(volume_direction[ii]*volume_dim[ii])); - // volume_length[ii] = pscLength(_pos_(fragments[jj]), startPosition); +#elif ZTYPE == PSCDEPTH + volume_zlength[ii] = pscLength(_pos_(fragments[jj]), startPosition); +#endif if(volumeStepSize[ii] < volume_length[ii]) { // jittering diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 97313125d9..f8f8063726 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -145,6 +145,15 @@ void ABuffer::resolve() { _transferFunctions.at(i).second->bind(); } + // Decrease stepsize in volumes if right click is pressed + // TODO: Let the interactionhandler handle this + int val = sgct::Engine::getMouseButton(0, SGCT_MOUSE_BUTTON_RIGHT); + if(val) { + _resolveShader->setUniform("volumeStepFactor", 0.2f); + } else { + _resolveShader->setUniform("volumeStepFactor", 1.0f); + } + glBindVertexArray(_screenQuad); glDrawArrays(GL_TRIANGLES, 0, 6); @@ -260,6 +269,7 @@ std::string ABuffer::openspaceHeaders() { std::string headers; headers += "#define MAX_VOLUMES " + std::to_string(_samplers.size()) + "\n"; + headers += "#define MAX_TF " + std::to_string(_transferFunctions.size()) + "\n"; for (int i = 0; i < _volumes.size(); ++i) { headers += "uniform sampler3D " + _volumes.at(i).first + ";\n"; } @@ -274,13 +284,17 @@ std::string ABuffer::openspaceHeaders() { } } + size_t maxLoop = 0; headers += "const vec3 volume_dim[] = {\n"; for (int i = 0; i < _volumes.size(); ++i) { glm::size3_t size = _volumes.at(i).second->dimensions(); + for(int k = 0; k < 3; ++k) + maxLoop = glm::max(maxLoop, size[k]); headers += " vec3(" + std::to_string(size[0]) + ".0," + std::to_string(size[1]) + ".0," + std::to_string(size[2]) + ".0),\n"; } headers += "};\n"; + headers += "#define LOOP_LIMIT " + std::to_string(maxLoop) + "\n"; headers += "float volumeStepSize[] = {\n"; for (int i = 0; i < _volumes.size(); ++i) { diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 020ba82d3f..5a4dc136f0 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -396,9 +396,9 @@ void InteractionHandler::mouseButtonCallback(int key, int action) { //if(mouseControl_ != nullptr) { // mouseControl_->mouseButtonCallback(key,action); //} - if (key == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) + if (key == SGCT_MOUSE_BUTTON_LEFT && action == SGCT_PRESS) _leftMouseButtonDown = true; - else if (key == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) { + else if (key == SGCT_MOUSE_BUTTON_LEFT && action == SGCT_RELEASE) { _leftMouseButtonDown = false; _isMouseBeingPressedAndHeld = false; } From 1996acf997fcb8465f96d167a5684470c5510f0c Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Thu, 3 Jul 2014 14:42:43 -0400 Subject: [PATCH 037/113] Fieldline and seedpoint color now in RGBA instead of RGB --- .../rendering/renderablefieldlines.h | 3 +- include/openspace/util/kameleonwrapper.h | 22 +++++-- openspace-data | 2 +- src/rendering/renderablefieldlines.cpp | 60 ++++++++----------- src/util/kameleonwrapper.cpp | 45 +++++++------- 5 files changed, 64 insertions(+), 68 deletions(-) diff --git a/include/openspace/rendering/renderablefieldlines.h b/include/openspace/rendering/renderablefieldlines.h index c37f5649b6..e250a7e4d5 100644 --- a/include/openspace/rendering/renderablefieldlines.h +++ b/include/openspace/rendering/renderablefieldlines.h @@ -33,6 +33,7 @@ #include namespace openspace { + struct LinePoint; class RenderableFieldlines : public Renderable { public: @@ -46,7 +47,7 @@ public: virtual void update(); private: - std::vector > getFieldlinesData(std::string filename, ghoul::Dictionary hintsDictionary); + std::vector > getFieldlinesData(std::string filename, ghoul::Dictionary hintsDictionary); std::vector _hintsDictionaries; std::vector _filenames; diff --git a/include/openspace/util/kameleonwrapper.h b/include/openspace/util/kameleonwrapper.h index 6b85680231..fd8903f7a2 100644 --- a/include/openspace/util/kameleonwrapper.h +++ b/include/openspace/util/kameleonwrapper.h @@ -34,6 +34,16 @@ namespace ccmc { namespace openspace { +struct LinePoint { + glm::vec3 position; + glm::vec4 color; + + LinePoint(glm::vec3 pos, glm::vec4 col) { + position = pos; + color = col; + } +}; + class KameleonWrapper { public: @@ -59,16 +69,16 @@ public: float* getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions); - std::vector > getClassifiedFieldLines(const std::string& xVar, + std::vector > getClassifiedFieldLines(const std::string& xVar, const std::string& yVar, const std::string& zVar, std::vector seedPoints, float stepSize); - std::vector > getFieldLines(const std::string& xVar, + std::vector > getFieldLines(const std::string& xVar, const std::string& yVar, const std::string& zVar, - std::vector seedPoints, float stepSize, glm::vec3 color); + std::vector seedPoints, float stepSize, glm::vec4 color); - std::vector > getLorentzTrajectories(std::vector seedPoints, - glm::vec3 color, float stepsize); + std::vector > getLorentzTrajectories(std::vector seedPoints, + glm::vec4 color, float stepsize); private: std::vector traceCartesianFieldline(const std::string& xVar, @@ -80,7 +90,7 @@ private: void getGridVariables(std::string& x, std::string& y, std::string& z); void progressBar(int current, int end); - glm::vec3 classifyFieldline(FieldlineEnd fEnd, FieldlineEnd bEnd); + glm::vec4 classifyFieldline(FieldlineEnd fEnd, FieldlineEnd bEnd); ccmc::Model* _model; Model _type; diff --git a/openspace-data b/openspace-data index 8fa226790e..f858de10c6 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 8fa226790e939667b31c0e2020ba42708e3de7e6 +Subproject commit f858de10c6b9b30df2aa855e337063ecee9d8ee9 diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index ff4e76c669..50314e5838 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -53,10 +53,8 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) if(fieldline.hasKey("Hints")) fieldline.getValue("Hints", hintsDictionary); - // TODO Vectors of filenames and dictionaries _filenames.push_back(file); _hintsDictionaries.push_back(hintsDictionary); - } else LERROR("File not found!"); } @@ -72,12 +70,11 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) if (dictionary.hasKey("Shaders")) { ghoul::Dictionary shaderDictionary; if(dictionary.getValue("Shaders", shaderDictionary)) { - if (shaderDictionary.hasKey("VertexShader")) { + if (shaderDictionary.hasKey("VertexShader")) shaderDictionary.getValue("VertexShader", vshaderpath); - } - if (shaderDictionary.hasKey("FragmentShader")) { + + if (shaderDictionary.hasKey("FragmentShader")) shaderDictionary.getValue("FragmentShader", fshaderpath); - } vshaderpath = findPath(vshaderpath); fshaderpath = findPath(fshaderpath); @@ -97,11 +94,10 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) dictionary.getValue("UpdateOnSave", _programUpdateOnSave); } - setBoundingSphere(PowerScaledScalar::CreatePSS(5)); + setBoundingSphere(PowerScaledScalar::CreatePSS(5)); // FIXME a non-magic number perhaps } RenderableFieldlines::~RenderableFieldlines() { - } bool RenderableFieldlines::initialize() { @@ -109,28 +105,25 @@ bool RenderableFieldlines::initialize() { assert(_hintsDictionaries.size() != 0); int prevEnd = 0; - std::vector vertexData; - std::vector > fieldlinesData; + std::vector vertexData, seedPointsData; + std::vector > fieldlinesData; + glm::vec4 seedPointsColor = glm::vec4(1.0, 0.5, 0.0, 1.0); for (int i = 0; i < _filenames.size(); ++i) { fieldlinesData = getFieldlinesData(_filenames[i], _hintsDictionaries[i]); - for (int j = 0; j < fieldlinesData.size(); j++) { + for (int j = 0; j < fieldlinesData.size(); ++j) { _lineStart.push_back(prevEnd); - _lineCount.push_back(fieldlinesData[j].size()/2.0); - prevEnd = prevEnd + fieldlinesData[j].size()/2.0; - + _lineCount.push_back(fieldlinesData[j].size()); + prevEnd = prevEnd + fieldlinesData[j].size(); vertexData.insert( vertexData.end(), fieldlinesData[j].begin(), fieldlinesData[j].end()); } + // Give seedpoints a color for visualizing as GL_POINTS + for (glm::vec3 seedPoint : _seedPoints) { + seedPointsData.push_back(LinePoint(seedPoint, seedPointsColor)); + } } - LDEBUG("Number of vertices : " << vertexData.size()/2.0); - - // Give seedpoints a color for visualizing as GL_POINTS - std::vector seedPointsData; - for (int i = 0; i < _seedPoints.size(); ++i) { - seedPointsData.push_back(_seedPoints[i]); - seedPointsData.push_back(glm::vec3(1.0, 0.5, 0.0)); - } + LDEBUG("Number of vertices : " << vertexData.size()); // ------ FIELDLINES ----------------- GLuint vertexPositionBuffer; @@ -138,17 +131,17 @@ bool RenderableFieldlines::initialize() { glBindVertexArray(_VAO); // bind array glGenBuffers(1, &vertexPositionBuffer); // generate buffer glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer - glBufferData(GL_ARRAY_BUFFER, vertexData.size()*sizeof(glm::vec3), &vertexData.front(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, vertexData.size()*sizeof(LinePoint), &vertexData.front(), GL_STATIC_DRAW); // Vertex positions GLuint vertexLocation = 0; glEnableVertexAttribArray(vertexLocation); - glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 2*sizeof(glm::vec3), reinterpret_cast(0)); + glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(LinePoint), reinterpret_cast(0)); // Texture coordinates GLuint texcoordLocation = 1; glEnableVertexAttribArray(texcoordLocation); - glVertexAttribPointer(texcoordLocation, 3, GL_FLOAT, GL_FALSE, 2*sizeof(glm::vec3), (void*)(sizeof(glm::vec3))); + glVertexAttribPointer(texcoordLocation, 4, GL_FLOAT, GL_FALSE, sizeof(LinePoint), (void*)(sizeof(glm::vec3))); glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer glBindVertexArray(0); //unbind array @@ -159,15 +152,15 @@ bool RenderableFieldlines::initialize() { glBindVertexArray(_seedpointVAO); // bind array glGenBuffers(1, &seedpointPositionBuffer); // generate buffer glBindBuffer(GL_ARRAY_BUFFER, seedpointPositionBuffer); // bind buffer - glBufferData(GL_ARRAY_BUFFER, seedPointsData.size()*sizeof(glm::vec3), &seedPointsData.front(), GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, seedPointsData.size()*sizeof(LinePoint), &seedPointsData.front(), GL_STATIC_DRAW); // Vertex positions glEnableVertexAttribArray(vertexLocation); - glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 2*sizeof(glm::vec3), reinterpret_cast(0)); + glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(LinePoint), reinterpret_cast(0)); // Texture coordinates glEnableVertexAttribArray(texcoordLocation); - glVertexAttribPointer(texcoordLocation, 3, GL_FLOAT, GL_FALSE, 2*sizeof(glm::vec3), (void*)(sizeof(glm::vec3))); + glVertexAttribPointer(texcoordLocation, 4, GL_FLOAT, GL_FALSE, sizeof(LinePoint), (void*)(3*sizeof(float))); glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer glBindVertexArray(0); //unbind array @@ -194,7 +187,6 @@ bool RenderableFieldlines::deinitialize() { } void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) { - if(_update) { _update = false; safeShaderCompilation(); @@ -205,11 +197,8 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) psc relative = thisPosition-camera->position(); transform = transform*camTransform; - //transform = glm::translate(transform, relative.vec3()); transform = glm::mat4(1.0); -// transform = glm::scale(transform, glm::vec3(0.036*0.5*0.5)); transform = glm::scale(transform, glm::vec3(0.01)); - //transform = glm::scale(transform, glm::vec3(0.1)); // Scale to avoid depth buffer problems psc currentPosition = thisPosition; psc campos = camera->position(); @@ -218,7 +207,6 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) // Activate shader _fieldlinesProgram->activate(); - //_fieldlinesProgram->setUniform("modelViewProjection", transform); _fieldlinesProgram->setUniform("modelViewProjection", camera->viewProjectionMatrix()); _fieldlinesProgram->setUniform("modelTransform", transform); @@ -249,15 +237,15 @@ void RenderableFieldlines::safeShaderCompilation() { _fieldlinesProgram->linkProgramObject(); } -std::vector > RenderableFieldlines::getFieldlinesData(std::string filename, ghoul::Dictionary hintsDictionary) { +std::vector > RenderableFieldlines::getFieldlinesData(std::string filename, ghoul::Dictionary hintsDictionary) { std::string modelString; float stepSize = 0.5; // default if no stepsize is specified in hints std::string xVariable, yVariable, zVariable; KameleonWrapper::Model model; - std::vector > fieldlinesData; + std::vector > fieldlinesData; bool classification = false, lorentz = false; - glm::vec3 fieldlineColor = glm::vec3(1.0, 1.0, 1.0); // default color if no color or classification is specified + glm::vec4 fieldlineColor = glm::vec4(1.0, 1.0, 1.0, 1.0); // default color if no color or classification is specified if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) { // ------ MODEL ----------------- diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 1fa2b423f6..0ca5a7d9b5 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -269,7 +269,7 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c return data; } -std::vector > KameleonWrapper::getClassifiedFieldLines( +std::vector > KameleonWrapper::getClassifiedFieldLines( const std::string& xVar, const std::string& yVar, const std::string& zVar, std::vector seedPoints, float stepSize ) { @@ -278,8 +278,8 @@ std::vector > KameleonWrapper::getClassifiedFieldLines( LINFO("Creating " << seedPoints.size() << " fieldlines from variables " << xVar << " " << yVar << " " << zVar); std::vector fLine, bLine; - std::vector > fieldLines; - glm::vec3 color; + std::vector > fieldLines; + glm::vec4 color; FieldlineEnd forwardEnd, backEnd; if (_type == Model::BATSRUS) { @@ -293,10 +293,9 @@ std::vector > KameleonWrapper::getClassifiedFieldLines( color = classifyFieldline(forwardEnd, backEnd); // write colors - std::vector line; + std::vector line; for (glm::vec3 position : bLine) { - line.push_back(position); - line.push_back(color); + line.push_back(LinePoint(position, color)); } fieldLines.push_back(line); @@ -308,16 +307,16 @@ std::vector > KameleonWrapper::getClassifiedFieldLines( return fieldLines; } -std::vector > KameleonWrapper::getFieldLines( +std::vector > KameleonWrapper::getFieldLines( const std::string& xVar, const std::string& yVar, const std::string& zVar, std::vector seedPoints, - float stepSize, glm::vec3 color ) { + float stepSize, glm::vec4 color ) { assert(_model && _interpolator); assert(_type == Model::ENLIL || _type == Model::BATSRUS); LINFO("Creating " << seedPoints.size() << " fieldlines from variables " << xVar << " " << yVar << " " << zVar); std::vector fLine, bLine; - std::vector > fieldLines; + std::vector > fieldLines; FieldlineEnd forwardEnd, backEnd; if (_type == Model::BATSRUS) { @@ -328,10 +327,9 @@ std::vector > KameleonWrapper::getFieldLines( bLine.insert(bLine.begin(), fLine.rbegin(), fLine.rend()); // write colors - std::vector line; + std::vector line; for (glm::vec3 position : bLine) { - line.push_back(position); - line.push_back(color); + line.push_back(LinePoint(position, color)); } fieldLines.push_back(line); @@ -343,11 +341,11 @@ std::vector > KameleonWrapper::getFieldLines( return fieldLines; } -std::vector > KameleonWrapper::getLorentzTrajectories( - std::vector seedPoints, glm::vec3 color, float stepsize) { +std::vector > KameleonWrapper::getLorentzTrajectories( + std::vector seedPoints, glm::vec4 color, float stepsize) { LINFO("Creating " << seedPoints.size() << " Lorentz force trajectories"); - std::vector > trajectories; + std::vector > trajectories; std::vector plusTraj, minusTraj; for (auto seedPoint : seedPoints) { @@ -357,10 +355,9 @@ std::vector > KameleonWrapper::getLorentzTrajectories( minusTraj.insert(minusTraj.begin(), plusTraj.rbegin(), plusTraj.rend()); // write colors - std::vector trajectory; + std::vector trajectory; for (glm::vec3 position : minusTraj) { - trajectory.push_back(position); - trajectory.push_back(color); + trajectory.push_back(LinePoint(position, color)); } trajectories.push_back(trajectory); } @@ -567,23 +564,23 @@ void KameleonWrapper::progressBar(int current, int end) { _lastiProgress = iprogress; } -glm::vec3 KameleonWrapper::classifyFieldline(FieldlineEnd fEnd, FieldlineEnd bEnd) { - glm::vec3 color; +glm::vec4 KameleonWrapper::classifyFieldline(FieldlineEnd fEnd, FieldlineEnd bEnd) { + glm::vec4 color; if ( (fEnd == FieldlineEnd::NORTH || fEnd == FieldlineEnd::SOUTH) && (bEnd == FieldlineEnd::NORTH || bEnd == FieldlineEnd::SOUTH)) { // closed - color = glm::vec3(1.0, 0.0, 0.0); + color = glm::vec4(1.0, 0.0, 0.0, 1.0); } else if ((fEnd == FieldlineEnd::OUT && bEnd == FieldlineEnd::NORTH) || (bEnd == FieldlineEnd::OUT && fEnd == FieldlineEnd::NORTH)) { // north - color = glm::vec3(1.0, 1.0, 0.0); + color = glm::vec4(1.0, 1.0, 0.0, 1.0); } else if ((fEnd == FieldlineEnd::OUT && bEnd == FieldlineEnd::SOUTH) || (bEnd == FieldlineEnd::OUT && fEnd == FieldlineEnd::SOUTH)) { // south - color = glm::vec3(0.0, 1.0, 0.0); + color = glm::vec4(0.0, 1.0, 0.0, 1.0); } else if (fEnd == FieldlineEnd::OUT && bEnd == FieldlineEnd::OUT) { // solar wind - color = glm::vec3(0.0, 0.0, 1.0); + color = glm::vec4(0.0, 0.0, 1.0, 1.0); } return color; } From aff61620c8d1b8d1b698f81dd830cdcb6fd722f7 Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Mon, 7 Jul 2014 14:26:22 -0400 Subject: [PATCH 038/113] Added functionality for getting the model barycenter in kameleonwrapper and moving the raycasting box by an offset. Also cleaned up renderablevolumegl a bit --- .../openspace/rendering/renderablevolume.h | 1 + .../openspace/rendering/renderablevolumegl.h | 7 +--- src/rendering/renderablevolume.cpp | 32 +++++++++++++++++-- src/rendering/renderablevolumegl.cpp | 32 ++++--------------- src/util/kameleonwrapper.cpp | 21 ++++++++---- 5 files changed, 52 insertions(+), 41 deletions(-) diff --git a/include/openspace/rendering/renderablevolume.h b/include/openspace/rendering/renderablevolume.h index 870b8ee672..9c9c1c4b9c 100644 --- a/include/openspace/rendering/renderablevolume.h +++ b/include/openspace/rendering/renderablevolume.h @@ -42,6 +42,7 @@ public: protected: ghoul::opengl::Texture* loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary); + glm::vec3 getVolumeOffset(const std::string& filepath, const ghoul::Dictionary& hintsDictionary); ghoul::RawVolumeReader::ReadHints readHints(const ghoul::Dictionary& dictionary); ghoul::opengl::Texture* loadTransferFunction(const std::string& filepath); diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index c368e41cfc..b13ed7cc5a 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -35,10 +35,6 @@ #include #include - namespace sgct_utils { - class SGCTBox; -} - namespace openspace { class RenderableVolumeGL: public RenderableVolume { @@ -67,8 +63,7 @@ private: GLuint _boxArray; ghoul::opengl::ProgramObject *_boxProgram; - sgct_utils::SGCTBox* _box; - glm::vec3 _boxScaling; + glm::vec3 _boxScaling, _boxOffset; GLint _MVPLocation, _modelTransformLocation, _typeLocation; bool _updateTransferfunction; diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index 7d6efbd93f..e21d6edde8 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -79,8 +79,8 @@ RenderableVolume::~RenderableVolume() { ghoul::opengl::Texture* RenderableVolume::loadVolume( const std::string& filepath, - const ghoul::Dictionary& hintsDictionary) -{ + const ghoul::Dictionary& hintsDictionary) { + if( ! FileSys.fileExists(filepath)) { LWARNING("Could not load volume, could not find '" << filepath << "'"); return nullptr; @@ -174,7 +174,6 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume( } KameleonWrapper kw(filepath, model); - std::string variableString; if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) { float* data = kw.getUniformSampledValues(variableString, dimensions); @@ -220,6 +219,33 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume( return nullptr; } +glm::vec3 RenderableVolume::getVolumeOffset( + const std::string& filepath, + const ghoul::Dictionary& hintsDictionary) { + + std::string modelString = ""; + if (hintsDictionary.hasKey("Model")) + hintsDictionary.getValue("Model", modelString); + + if(modelString == "") { + LWARNING("Model not specified."); + return glm::vec3(0); + } + KameleonWrapper::Model model; + if (modelString == "BATSRUS") { + model = KameleonWrapper::Model::BATSRUS; + } else if (modelString == "ENLIL") { + model = KameleonWrapper::Model::ENLIL; + } else { + LWARNING("Hints does not specify a valid 'Model'"); + return glm::vec3(0); + } + + KameleonWrapper kw(filepath, model); + + return kw.getModelBarycenterOffset(); +} + ghoul::RawVolumeReader::ReadHints RenderableVolume::readHints(const ghoul::Dictionary& dictionary) { ghoul::RawVolumeReader::ReadHints hints; hints._dimensions = glm::ivec3(1, 1, 1); diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index bdcdc9ae79..a888b241d4 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -34,7 +35,6 @@ #include #include -#include namespace { std::string _loggerCat = "RenderableVolumeGL"; @@ -43,9 +43,8 @@ namespace { namespace openspace { RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): - RenderableVolume(dictionary), _box(nullptr), _boxScaling(1.0, 1.0, 1.0), + RenderableVolume(dictionary), _boxScaling(1.0, 1.0, 1.0), _updateTransferfunction(false), _id(-1) { - _filename = ""; if(dictionary.hasKey("Volume")) { @@ -80,8 +79,7 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): } if( _samplerFilename == "") { LERROR("No samplerfile!"); - } - + } double tempValue; if(dictionary.hasKey("BoxScaling.1") && dictionary.getValue("BoxScaling.1", tempValue)) { @@ -108,14 +106,13 @@ RenderableVolumeGL::~RenderableVolumeGL() { delete _transferFunctionFile; if(_transferFunction) delete _transferFunction; - if(_box) - delete _box; } bool RenderableVolumeGL::initialize() { assert(_filename != ""); // ------ VOLUME READING ---------------- _volume = loadVolume(_filename, _hintsDictionary); + _boxOffset = getVolumeOffset(_filename, _hintsDictionary); _volume->uploadTexture(); _transferFunction = loadTransferFunction(_transferFunctionPath); _transferFunction->uploadTexture(); @@ -130,7 +127,6 @@ bool RenderableVolumeGL::initialize() { }; _transferFunctionFile->setCallback(textureCallback); - _box = new sgct_utils::SGCTBox(1.0f, sgct_utils::SGCTBox::Regular); OsEng.configurationManager().getValue("RaycastProgram", _boxProgram); _MVPLocation = _boxProgram->uniformLocation("modelViewProjection"); _modelTransformLocation = _boxProgram->uniformLocation("modelTransform"); @@ -191,10 +187,7 @@ bool RenderableVolumeGL::initialize() { glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, reinterpret_cast(0)); - //glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*7, reinterpret_cast(0)); glEnableVertexAttribArray(0); - //glEnableVertexAttribArray(1); - return true; } @@ -220,12 +213,6 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { } } - //psc relative = thisPosition-camera->position(); - - // glm::mat4 transform = camera->viewRotationMatrix(); - // transform = glm::translate(transform, relative.vec3()); - // transform = glm::translate(transform, glm::vec3(-1.1,0.0,0.0)); - // transform = glm::scale(transform, _boxScaling); glm::mat4 transform = glm::mat4(1.0); transform = glm::scale(transform, _boxScaling); @@ -235,13 +222,11 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { glm::mat4 camrot = camera->viewRotationMatrix(); PowerScaledScalar scaling = camera->scaling(); - psc addon(-1.1,0.0,0.0,0.0); - currentPosition += addon; + psc addon(_boxOffset/100.0f); // TODO: Proper scaling/units + currentPosition += addon; // Move box to model barycenter // TODO: Use _id to identify this volume _boxProgram->activate(); - // _boxProgram->setUniform(_MVPLocation, camera->viewProjectionMatrix()); - // _boxProgram->setUniform(_modelTransformLocation, transform); _boxProgram->setUniform(_typeLocation, _id); _boxProgram->setUniform("modelViewProjection", camera->viewProjectionMatrix()); @@ -258,20 +243,15 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { glCullFace(GL_FRONT); glBindVertexArray(_boxArray); glDrawArrays(GL_TRIANGLES, 0, 6*6); - // _box->draw(); // Draw frontface (now the normal cull face is is set) glCullFace(GL_BACK); glDrawArrays(GL_TRIANGLES, 0, 6*6); - // _box->draw(); _boxProgram->deactivate(); - } void RenderableVolumeGL::update() { - } - } // namespace openspace diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 0ca5a7d9b5..3d2918d84c 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -65,12 +65,12 @@ KameleonWrapper::KameleonWrapper(const std::string& filename, Model model): _typ } getGridVariables(_xCoordVar, _yCoordVar, _zCoordVar); - _xMin = _model->getVariableAttribute(_xCoordVar, "actual_min").getAttributeFloat(); - _xMax = _model->getVariableAttribute(_xCoordVar, "actual_max").getAttributeFloat(); - _yMin = _model->getVariableAttribute(_yCoordVar, "actual_min").getAttributeFloat(); - _yMax = _model->getVariableAttribute(_yCoordVar, "actual_max").getAttributeFloat(); - _zMin = _model->getVariableAttribute(_zCoordVar, "actual_min").getAttributeFloat(); - _zMax = _model->getVariableAttribute(_zCoordVar, "actual_max").getAttributeFloat(); + _xMin = _model->getVariableAttribute(_xCoordVar, "actual_min").getAttributeFloat(); + _xMax = _model->getVariableAttribute(_xCoordVar, "actual_max").getAttributeFloat(); + _yMin = _model->getVariableAttribute(_yCoordVar, "actual_min").getAttributeFloat(); + _yMax = _model->getVariableAttribute(_yCoordVar, "actual_max").getAttributeFloat(); + _zMin = _model->getVariableAttribute(_zCoordVar, "actual_min").getAttributeFloat(); + _zMax = _model->getVariableAttribute(_zCoordVar, "actual_max").getAttributeFloat(); _lastiProgress = -1; // For progressbar } @@ -259,6 +259,7 @@ float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, c data[index + 3] = 1.0; // GL_RGB refuses to work. Workaround by doing a GL_RGBA with hardcoded alpha } else { LERROR("Only BATSRUS supported for getUniformSampledVectorValues (for now)"); + return data; } } } @@ -365,6 +366,14 @@ std::vector > KameleonWrapper::getLorentzTrajectories( return trajectories; } +glm::vec3 KameleonWrapper::getModelBarycenterOffset() { + glm::vec3 offset; + offset.x = _xMin+(std::abs(_xMin)+std::abs(_xMax))/2.0f; + offset.y = _yMin+(std::abs(_yMin)+std::abs(_yMax))/2.0f; + offset.z = _zMin+(std::abs(_zMin)+std::abs(_zMax))/2.0f; + return offset; +} + std::vector KameleonWrapper::traceCartesianFieldline( const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::vec3 seedPoint, From 576710f1efd353e56fabb453678e4d0975125a3b Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Tue, 8 Jul 2014 13:29:15 -0400 Subject: [PATCH 039/113] Added fixed ABuffer implementation --- include/openspace/abuffer/abuffer.h | 3 + .../openspace/abuffer/abufferSingleLinked.h | 2 +- include/openspace/abuffer/abufferdynamic.h | 60 ++++++++ include/openspace/abuffer/abufferfixed.h | 61 ++++++++ .../openspace/rendering/renderablevolumegl.h | 4 + shaders/ABuffer/abufferAddToBuffer.hglsl | 45 +++++- shaders/ABuffer/abufferResolveFragment.glsl | 93 ++++++++---- shaders/ABuffer/abufferSort.hglsl | 23 ++- shaders/ABuffer/abufferStruct.hglsl | 56 ++++--- shaders/exitpoints.frag | 4 +- src/abuffer/abuffer.cpp | 71 +++++++-- src/abuffer/abufferSingleLinked.cpp | 2 +- src/abuffer/abufferdynamic.cpp | 124 ++++++++++++++++ src/abuffer/abufferfixed.cpp | 137 ++++++++++++++++++ src/rendering/renderablevolumegl.cpp | 15 +- src/rendering/renderengine.cpp | 6 +- src/scenegraph/scenegraph.cpp | 110 ++++++-------- src/scenegraph/scenegraphnode.cpp | 5 +- src/util/kameleonwrapper.cpp | 45 ++++-- 19 files changed, 723 insertions(+), 143 deletions(-) create mode 100644 include/openspace/abuffer/abufferdynamic.h create mode 100644 include/openspace/abuffer/abufferfixed.h create mode 100644 src/abuffer/abufferdynamic.cpp create mode 100644 src/abuffer/abufferfixed.cpp diff --git a/include/openspace/abuffer/abuffer.h b/include/openspace/abuffer/abuffer.h index 96e35ec9dd..f7c2f9e032 100644 --- a/include/openspace/abuffer/abuffer.h +++ b/include/openspace/abuffer/abuffer.h @@ -63,6 +63,7 @@ protected: std::string openspaceHeaders(); std::string openspaceSamplerCalls(); std::string openspaceSamplers(); + std::string openspaceTransferFunction(); unsigned int _width, _height, _totalPixels; @@ -82,6 +83,8 @@ private: // Development functionality to update shader for changes in several files std::vector _shaderFiles; + float _volumeStepFactor; + }; // ABuffer diff --git a/include/openspace/abuffer/abufferSingleLinked.h b/include/openspace/abuffer/abufferSingleLinked.h index b800dfb856..c348abee52 100644 --- a/include/openspace/abuffer/abufferSingleLinked.h +++ b/include/openspace/abuffer/abufferSingleLinked.h @@ -54,7 +54,7 @@ private: -}; // ABuffer_I +}; // ABufferSingleLinked } // openspace #endif // __ABUFFERSINGLELINKED_H__ \ No newline at end of file diff --git a/include/openspace/abuffer/abufferdynamic.h b/include/openspace/abuffer/abufferdynamic.h new file mode 100644 index 0000000000..23959f08f1 --- /dev/null +++ b/include/openspace/abuffer/abufferdynamic.h @@ -0,0 +1,60 @@ +/***************************************************************************************** + * * + * 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 __ABUFFERDYNAMIC_H__ +#define __ABUFFERDYNAMIC_H__ + +#include + +namespace openspace { + +class ABufferDynamic: public ABuffer { +public: + + ABufferDynamic(); + virtual ~ABufferDynamic(); + virtual bool initialize(); + + virtual void clear(); + virtual void preRender(); + virtual void postRender(); + + virtual std::string settings(); + +private: + + GLuint *_data; + GLuint _anchorPointerTexture; + GLuint _anchorPointerTextureInitializer; + GLuint _atomicCounterBuffer; + GLuint _fragmentBuffer; + GLuint _fragmentTexture; + + + + +}; // ABufferDynamic +} // openspace + +#endif // __ABUFFERDYNAMIC_H__ \ No newline at end of file diff --git a/include/openspace/abuffer/abufferfixed.h b/include/openspace/abuffer/abufferfixed.h new file mode 100644 index 0000000000..cc211e0b57 --- /dev/null +++ b/include/openspace/abuffer/abufferfixed.h @@ -0,0 +1,61 @@ +/***************************************************************************************** + * * + * 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 __ABUFFERFIXED_H__ +#define __ABUFFERFIXED_H__ + +#include + +namespace openspace { + +class ABufferFixed: public ABuffer { +public: + + ABufferFixed(); + virtual ~ABufferFixed(); + virtual bool initialize(); + + virtual void clear(); + virtual void preRender(); + virtual void postRender(); + + virtual std::string settings(); + +private: + + GLuint *_data; + GLuint _anchorPointerTexture; + GLuint _anchorPointerTextureInitializer; + GLuint _atomicCounterBuffer; + GLuint _atomicCounterTexture; + GLuint _fragmentBuffer; + GLuint _fragmentTexture; + + + + +}; // ABufferFixed +} // openspace + +#endif // __ABUFFERFIXED_H__ \ No newline at end of file diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index c368e41cfc..56792624bc 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -57,6 +57,10 @@ private: ghoul::Dictionary _hintsDictionary; std::string _filename; + + std::string _transferFunctionName; + std::string _volumeName; + std::string _transferFunctionPath; std::string _samplerFilename; diff --git a/shaders/ABuffer/abufferAddToBuffer.hglsl b/shaders/ABuffer/abufferAddToBuffer.hglsl index 3ee940f0d7..92248796c0 100644 --- a/shaders/ABuffer/abufferAddToBuffer.hglsl +++ b/shaders/ABuffer/abufferAddToBuffer.hglsl @@ -22,11 +22,22 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; +#endif -ABufferStruct_t createGeometryFragment(vec4 fragColor, vec4 position = vec4(0), float z = gl_FragCoord.z) { +#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED +layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; +layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; + + #define _MAX_LAYERS_ 16 + #define _SCREEN_WIDTH_ 1280 + #define _SCREEN_HEIGHT_ 720 +#endif + +ABufferStruct_t createGeometryFragment(vec4 fragColor, vec4 position, float z = gl_FragCoord.z) { ABufferStruct_t frag; _col_(frag, fragColor); _z_(frag, z); @@ -37,6 +48,7 @@ ABufferStruct_t createGeometryFragment(vec4 fragColor, vec4 position = vec4(0), void addToBuffer(ABufferStruct_t frag) { +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED uint index = atomicCounterIncrement(atomicCounterBuffer); index *= 2; uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); @@ -47,17 +59,44 @@ void addToBuffer(ABufferStruct_t frag) { imageStore(fragmentTexture, int(index), p1); imageStore(fragmentTexture, int(index+1), p2); +#endif + +#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED + uint index = imageAtomicAdd(anchorPointerTexture, ivec2(gl_FragCoord.xy), 1); + if(index < _MAX_LAYERS_) { + int offset = (int(gl_FragCoord.y) * _SCREEN_WIDTH_ + int(gl_FragCoord.x))*_MAX_LAYERS_ + int(index)*2; + + uvec4 p1 = uvec4(frag.z, frag.id, frag.rg, frag.ba); + uvec4 p2 = uvec4(floatBitsToUint(frag.position.x),floatBitsToUint(frag.position.y),floatBitsToUint(frag.position.z),floatBitsToUint(frag.position.w)); + + imageStore(fragmentTexture, int(offset ), p1); + imageStore(fragmentTexture, int(offset+1), p2); + } else { + imageAtomicAdd(anchorPointerTexture, ivec2(gl_FragCoord.xy), -1); + } + +#endif + } ABufferStruct_t loadFromBuffer(uint id) { +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED uvec4 u1 = imageLoad(fragmentTexture, int(id)); - uvec4 u2 = imageLoad(fragmentTexture, int(id+1)); - + uvec4 u2 = imageLoad(fragmentTexture, int(id+1)); +#endif + +#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED + int offset = (int(gl_FragCoord.y) * _SCREEN_WIDTH_ + int(gl_FragCoord.x))*_MAX_LAYERS_ + int(id)*2; + uvec4 u1 = imageLoad(fragmentTexture, int(offset)); + uvec4 u2 = imageLoad(fragmentTexture, int(offset+1)); +#endif + vec4 position = vec4( uintBitsToFloat(u2.x), uintBitsToFloat(u2.y), uintBitsToFloat(u2.z), uintBitsToFloat(u2.w)); return ABufferStruct_t(u1.x, u1.y, u1.z, u1.w, position); + } \ No newline at end of file diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index 7e2c233a83..b230a51e23 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -28,15 +28,32 @@ // Settings // ================================================================================ #pragma openspace insert SETTINGS -// #define LOOP_LIMIT 500 #define MAX_FRAGMENTS 16 -#define SHOWFUNC 0 +#define SHOWFUNC +// #define JITTERING #define PSCDEPTH 1 #define ZDEPTH 2 -#define ZTYPE PSCDEPTH -const float stepSize = 0.01; +#define ZTYPE ZDEPTH + +// Math defintions +#define M_E 2.7182818284590452354 +#define M_LOG2E 1.4426950408889634074 /* log_2 e */ +#define M_LOG10E 0.43429448190325182765 /* log_10 e */ +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#define M_PI 3.14159265358979323846 /* pi */ +// #define M_PI 3.141592653589793238462643383279 /* pi */ +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#define M_PI_4 0.78539816339744830962 /* pi/4 */ +#define M_1_PI 0.31830988618379067154 /* 1/pi */ +#define M_2_PI 0.63661977236758134308 /* 2/pi */ +#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ + +const float stepSize = 0.01; const float samplingRate = 1.0; uniform int SCREEN_WIDTH; @@ -52,11 +69,36 @@ out vec4 color; // ================================================================================ #pragma openspace insert HEADERS +vec3 CartesianToSpherical(vec3 _cartesian) { + // Put cartesian in [-1..1] range first + vec3 cartesian = vec3(-1.0,-1.0,-1.0) + _cartesian * 2.0f; + + float r = length(cartesian); + float theta, phi; + + if (r == 0.0) { + theta = phi = 0.0; + } else { + theta = acos(cartesian.z/r) / M_PI; + phi = (M_PI + atan(cartesian.y, cartesian.x)) / (2.0*M_PI); + // phi = (M_PI + atan(cartesian.x, cartesian.y)) / (2.0*M_PI); + } + // r *= 0.57735026919; + r = r / sqrt(3.0f); + + // Sampler ignores w component + // return vec3(r, phi, theta); + return vec3(r, theta, phi); + // return vec3(r, phi*0.7, theta); +} + // ================================================================================ // The ABuffer specific includes and definitions // ================================================================================ #include "abufferStruct.hglsl" ABufferStruct_t fragments[MAX_FRAGMENTS]; + +#if MAX_VOLUMES > 0 vec3 volume_direction[MAX_VOLUMES]; float volume_length[MAX_VOLUMES]; vec3 volume_position[MAX_VOLUMES]; @@ -66,8 +108,7 @@ vec3 volume_position[MAX_VOLUMES]; #elif ZTYPE == PSCDEPTH float volume_zlength[MAX_VOLUMES]; #endif - - +#endif #include "abufferSort.hglsl" // ================================================================================ @@ -83,6 +124,7 @@ vec4 blend(vec4 src, vec4 dst) { void blendStep(inout vec4 dst, in vec4 src, in float stepSize) { src.a = 1.0 - pow(1.0 - src.a, stepSize ); + // src.a = 1.0 -(1.0 - src.a*stepSize); dst.rgb = dst.rgb + (1.0 - dst.a) * src.a * src.rgb; dst.a = dst.a + (1.0 -dst.a) * src.a; } @@ -126,20 +168,18 @@ vec4 calculate_final_color(uint frag_count) { int frag_count_1 = int(frag_count)-1; for(int i = 0; i < frag_count_1 && final_color.a < ALPHA_LIMIT; i++) { - //int maxFrags = int(frag_count)-1; - //for(int i = 0; i < frag_count; i++) { ABufferStruct_t startFrag = fragments[i]; ABufferStruct_t endFrag = fragments[i+1]; - //vec4 frag_color = _col_(startFrag); - //vec4 position = _pos_(startFrag); int type = int(_type_(startFrag)); - currentVolumeBitmask = currentVolumeBitmask ^ (type); if(type == 0) //blendStep(final_color, _col_(startFrag), stepSize); final_color = blend(final_color, _col_(startFrag)); - if(bool(currentVolumeBitmask)) { + +#if MAX_VOLUMES > 0 + currentVolumeBitmask = currentVolumeBitmask ^ type; + if(currentVolumeBitmask != 0) { int volID = type -1; float p = 0.0f; #if ZTYPE == ZDEPTH @@ -152,7 +192,6 @@ vec4 calculate_final_color(uint frag_count) { // const float z2 = _z_(endFrag); const float l = ((z1 - S1) / L - (z2 - S1) / L) * volume_length[volID]; int max_iterations = int(l / volumeStepSize[volID]); - int iterations = 0; vec3 position; #elif ZTYPE == PSCDEPTH const float L = volume_zlength[volID]; @@ -163,7 +202,6 @@ vec4 calculate_final_color(uint frag_count) { // const float z2 = _z_(endFrag); const float l = (dist / L) * volume_length[volID]; int max_iterations = int(l / volumeStepSize[volID]); - int iterations = 0; vec3 position; #endif @@ -199,6 +237,7 @@ vec4 calculate_final_color(uint frag_count) { } } +#endif @@ -223,26 +262,28 @@ vec4 calculate_final_color(uint frag_count) { // ================================================================================ // Transferfunction visualizer // ================================================================================ -#if (SHOWFUNC >= 0) && (SHOWFUNC < MAX_TF) - float showfunc_size = 20.0; - if(gl_FragCoord.y > float(SCREEN_HEIGHT) - showfunc_size) { - float normalizedIntensity = gl_FragCoord.x / float(SCREEN_WIDTH) ; - vec4 tfc = texture(transferFunction1, normalizedIntensity); - final_color = tfc; - } else if(ceil(gl_FragCoord.y) == float(SCREEN_HEIGHT) - showfunc_size) { - const float intensity = 0.4; - final_color = vec4(intensity,intensity,intensity,1.0); - } +#ifdef SHOWFUNC +#pragma openspace insert TRANSFERFUNC #endif // if(frag_count == 1) { - // final_color = vec4(0.0,0.0,1.0,1.0); + // final_color = vec4(1.0,0.0,0.0,1.0); // } else if(frag_count == 2) { - // final_color = vec4(volume_direction[0],1.0); + // final_color = vec4(0.0,1.0,0.0,1.0); + // // final_color = vec4(volume_direction[0],1.0); + // } else if(frag_count == 3) { + // final_color = vec4(0.0,0.0,1.0,1.0); + // // final_color = vec4(volume_direction[0],1.0); + // } else if(frag_count == 4) { + // final_color = vec4(1.0,1.0,0.0,1.0); + // // final_color = vec4(volume_direction[0],1.0); // } else { // final_color = vec4(1.0,1.0,1.0,1.0); // } + final_color.rgb = final_color.rgb * final_color.a; + final_color.a = 1.0; + return final_color; } diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index 61381bc7d1..5d05460117 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -27,6 +27,8 @@ uniform float volumeStepFactor = 1.0f; int build_local_fragments_list() { + +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED uint current; int frag_count = 0; @@ -42,6 +44,19 @@ int build_local_fragments_list() { } return frag_count; +#endif + +#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED + uint frag_count = imageLoad(anchorPointerTexture, ivec2(gl_FragCoord.xy)).x; + + int i; + for(i = 0; i < frag_count && i < MAX_FRAGMENTS; ++i) { + fragments[i] = loadFromBuffer(i); + } + + return int(frag_count); +#endif + } float pscLength(vec4 v1, vec4 v2) { @@ -75,12 +90,13 @@ void sort_fragments_list(uint frag_count) { fragments[j] = tmp; } +#if MAX_VOLUMES > 0 int ii, jj; for(ii = 0; ii < MAX_VOLUMES; ++ii) { bool start = true; vec3 startColor; vec4 startPosition; - for(jj = ii; jj < frag_count; ++jj) { + for(jj = 0; jj < frag_count; ++jj) { int type = int(_type_(fragments[jj])) - 1; if(type== ii) { if(start) { @@ -96,12 +112,13 @@ void sort_fragments_list(uint frag_count) { volume_length[ii] = length(dir); volume_direction[ii] = normalize(dir); volumeStepSize[ii] = 1.0/(volumeStepFactor * length(volume_direction[ii]*volume_dim[ii])); + volumeStepSizeOriginal[ii] = volumeStepSize[ii]; #if ZTYPE == ZDEPTH volume_zlength[ii].y = _z_(fragments[jj]); #elif ZTYPE == PSCDEPTH volume_zlength[ii] = pscLength(_pos_(fragments[jj]), startPosition); #endif - +#ifdef JITTERING if(volumeStepSize[ii] < volume_length[ii]) { // jittering float x = gl_FragCoord.x; @@ -110,12 +127,14 @@ void sort_fragments_list(uint frag_count) { vec3 frontPosNew = startColor + (jitterValue*volumeStepSize[ii])*volume_direction[ii]; volume_position[ii] = frontPosNew; } +#endif break; } } } } +#endif //volume_direction[0] = vec3(1.0,0.0,0.0); //volume_direction[0] = _col_(fragments[0]).rgb; } diff --git a/shaders/ABuffer/abufferStruct.hglsl b/shaders/ABuffer/abufferStruct.hglsl index a63499ef6d..0153aecad6 100644 --- a/shaders/ABuffer/abufferStruct.hglsl +++ b/shaders/ABuffer/abufferStruct.hglsl @@ -25,10 +25,17 @@ #ifndef ABUFFERSTRUCT_H_HGLSL #define ABUFFERSTRUCT_H_HGLSL +// The different kinds of implementation +#define ABUFFER_SINGLE_LINKED 1 +#define ABUFFER_FIXED 2 +#define ABUFFER_DYNAMIC 3 -//======================================================= +#define ABUFFER_IMPLEMENTATION ABUFFER_SINGLE_LINKED + + +//======================================================================================== // ABufferStruct_t declaration -//======================================================= +//======================================================================================== // struct ABufferStruct_t { // uint z; // the depth value // uint id; // bits 0-28 next, bits 29-32 type @@ -46,9 +53,9 @@ struct ABufferStruct_t { }; -//======================================================= +//======================================================================================== // Bitwise operations -//======================================================= +//======================================================================================== const uint mask_1 = 1; const uint mask_8 = 255; const uint mask_16 = 65535; @@ -92,9 +99,9 @@ int bitextract_i(in int pack, uint mask, uint shift) { return int( (uint(pack) >> shift) & (mask >> shift) ); } -//======================================================= +//======================================================================================== // Access functions -//======================================================= +//======================================================================================== float _z_(ABufferStruct_t frag) { return uintBitsToFloat(frag.z); } @@ -102,15 +109,6 @@ void _z_(inout ABufferStruct_t frag, float z) { frag.z = floatBitsToUint(z); } -uint _next_(ABufferStruct_t frag) { - return bitextract_u(frag.id, mask_id_next, shift_id_next); - //return frag.id; -} -void _next_(inout ABufferStruct_t frag, uint id) { - bitinsert_u(frag.id, id, mask_id_next, shift_id_next); - //frag.id = id; -} - vec4 _pos_(ABufferStruct_t frag) { // return vec4(0.0,0.0,0.0,0.0); return frag.position; @@ -132,12 +130,34 @@ void _col_(inout ABufferStruct_t frag, vec4 color) { } uint _type_(ABufferStruct_t frag) { - return bitextract_u(frag.id, mask_id_type, shift_id_type); - //return frag.type; +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED + return bitextract_u(frag.id, mask_id_type, shift_id_type); +#else + return frag.id; +#endif } void _type_(inout ABufferStruct_t frag, uint type) { +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED bitinsert_u(frag.id, type, mask_id_type, shift_id_type); - //frag.type = type; +#else + frag.id = type; +#endif } +//======================================================================================== +// Implementation specific functions +//======================================================================================== + +// _next_ is only needed for the single linked implementation +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED +uint _next_(ABufferStruct_t frag) { + return bitextract_u(frag.id, mask_id_next, shift_id_next); + //return frag.id; +} +void _next_(inout ABufferStruct_t frag, uint id) { + bitinsert_u(frag.id, id, mask_id_next, shift_id_next); + //frag.id = id; +} +#endif + #endif \ No newline at end of file diff --git a/shaders/exitpoints.frag b/shaders/exitpoints.frag index 89fe78224b..71dac97245 100644 --- a/shaders/exitpoints.frag +++ b/shaders/exitpoints.frag @@ -35,10 +35,12 @@ in float s; #include "PowerScaling/powerScaling_fs.hglsl" void main() { - vec4 fragColor = vec4(vPosition+0.5, 0.3); + vec4 fragColor = vec4(vPosition+0.5, 1.0); vec4 position = vec4(worldPosition,s); float depth = pscDepth(position); + gl_FragDepth = depth; + ABufferStruct_t frag; _col_(frag, fragColor); _z_(frag, depth); diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index f8f8063726..744e27a402 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -91,9 +91,7 @@ bool ABuffer::initializeABuffer() { addFunc("${SHADERS}/ABuffer/abufferAddToBuffer.hglsl"); addFunc("${SHADERS}/ABuffer/abufferStruct.hglsl"); addFunc("${SHADERS}/PowerScaling/powerScaling_fs.hglsl"); - addFunc("${SHADERS}/PowerScaling/powerScaling_vs.hglsl"); - - + addFunc("${SHADERS}/PowerScaling/powerScaling_vs.hglsl"); _resolveShader = nullptr; generateShaderSource(); @@ -148,10 +146,10 @@ void ABuffer::resolve() { // Decrease stepsize in volumes if right click is pressed // TODO: Let the interactionhandler handle this int val = sgct::Engine::getMouseButton(0, SGCT_MOUSE_BUTTON_RIGHT); - if(val) { - _resolveShader->setUniform("volumeStepFactor", 0.2f); - } else { - _resolveShader->setUniform("volumeStepFactor", 1.0f); + float volumeStepFactor = (val) ? 0.2: 1.0; + if(volumeStepFactor != _volumeStepFactor) { + _volumeStepFactor = volumeStepFactor; + _resolveShader->setUniform("volumeStepFactor", _volumeStepFactor); } glBindVertexArray(_screenQuad); @@ -254,6 +252,8 @@ void ABuffer::generateShaderSource() { line = padGeneratedString(openspaceSamplers()); } else if(line == "#pragma openspace insert SETTINGS") { line = padGeneratedString(settings()); + } else if(line == "#pragma openspace insert TRANSFERFUNC") { + line = padGeneratedString(openspaceTransferFunction()); } source += line + "\n"; } @@ -270,6 +270,8 @@ std::string ABuffer::openspaceHeaders() { std::string headers; headers += "#define MAX_VOLUMES " + std::to_string(_samplers.size()) + "\n"; headers += "#define MAX_TF " + std::to_string(_transferFunctions.size()) + "\n"; + + for (int i = 0; i < _volumes.size(); ++i) { headers += "uniform sampler3D " + _volumes.at(i).first + ";\n"; } @@ -284,6 +286,9 @@ std::string ABuffer::openspaceHeaders() { } } + if(_volumes.size() < 1) + return headers; + size_t maxLoop = 0; headers += "const vec3 volume_dim[] = {\n"; for (int i = 0; i < _volumes.size(); ++i) { @@ -294,6 +299,7 @@ std::string ABuffer::openspaceHeaders() { + std::to_string(size[2]) + ".0),\n"; } headers += "};\n"; + headers += "#define LOOP_LIMIT " + std::to_string(maxLoop) + "\n"; headers += "float volumeStepSize[] = {\n"; @@ -303,6 +309,13 @@ std::string ABuffer::openspaceHeaders() { } headers += "};\n"; + headers += "float volumeStepSizeOriginal[] = {\n"; + for (int i = 0; i < _volumes.size(); ++i) { + glm::size3_t size = _volumes.at(i).second->dimensions(); + headers += " stepSize,\n"; + } + headers += "};\n"; + return headers; } @@ -310,13 +323,23 @@ std::string ABuffer::openspaceSamplerCalls() { std::string samplercalls; for (int i = 0; i < _samplers.size(); ++i) { - auto found1 = _samplers.at(i).find_first_not_of("void "); + auto found1 = _samplers.at(i).find_first_not_of("vec4 "); auto found2 = _samplers.at(i).find_first_of("(",found1); if(found1 != std::string::npos && found2 != std::string::npos) { std::string functionName = _samplers.at(i).substr(found1, found2 - found1); - samplercalls += "if((currentVolumeBitmask & (1 << " + std::to_string(i) + ")) == 1) {\n"; - samplercalls += functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; - samplercalls += "volume_position[" + std::to_string(i) + "] += volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];;\n"; + samplercalls += "if((currentVolumeBitmask & (1 << " + std::to_string(i) + ")) == "+std::to_string(i+1)+") {\n"; + samplercalls += " vec4 c = " + functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; + // samplercalls += " if(c.a < 0.1) { \n"; + // samplercalls += " if( volumeStepSize[" + std::to_string(i) + "] < 16.0*volumeStepSizeOriginal[" + std::to_string(i) + "]) \n"; + // samplercalls += " volumeStepSize[" + std::to_string(i) + "] *= 2.0; \n"; + // samplercalls += " } else {\n"; + // samplercalls += " //volume_position[" + std::to_string(i) + "] -= volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];\n"; + // samplercalls += " volumeStepSize[" + std::to_string(i) + "] = volumeStepSizeOriginal[" + std::to_string(i) + "]; \n"; + // samplercalls += " //c = " + functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; + // samplercalls += " } \n"; + samplercalls += " blendStep(final_color, c, volumeStepSize[" + std::to_string(i) + "]);\n"; + // samplercalls += " blendStep(final_color, c, stepSize);\n"; + samplercalls += " volume_position[" + std::to_string(i) + "] += volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];\n"; samplercalls += "}\n"; } @@ -333,5 +356,31 @@ std::string ABuffer::openspaceSamplers() { return samplers; } +std::string ABuffer::openspaceTransferFunction() { + std::string tf; + tf += "float showfunc_size = 20.0;\n"; + tf += "float SCREEN_HEIGHTf = float(SCREEN_HEIGHT);\n"; + tf += "float SCREEN_WIDTHf = float(SCREEN_WIDTH);\n"; + for(int i = 0; i < _transferFunctions.size(); ++i) { + tf += "if( gl_FragCoord.y > SCREEN_HEIGHTf-showfunc_size*"+std::to_string(i+1)+ + " && gl_FragCoord.y < SCREEN_HEIGHTf-showfunc_size*"+std::to_string(i)+") {\n"; + tf += " float normalizedIntensity = gl_FragCoord.x / SCREEN_WIDTHf ;\n"; + tf += " vec4 tfc = texture("+ _transferFunctions.at(i).first +", normalizedIntensity);\n"; + tf += " final_color = tfc;\n"; + tf += " float cmpf = SCREEN_HEIGHTf-showfunc_size*"+std::to_string(i+1)+" + tfc.a*showfunc_size;\n"; + tf += " if(gl_FragCoord.y > cmpf) {\n"; + tf += " final_color = vec4(0,0,0,0);\n"; + tf += " } else {\n"; + tf += " final_color.a = 1.0;\n"; + tf += " }\n"; + tf += "} else if(ceil(gl_FragCoord.y) == SCREEN_HEIGHTf - showfunc_size*"+std::to_string(i+1)+") {\n"; + tf += " const float intensity = 0.4;\n"; + tf += " final_color = vec4(intensity,intensity,intensity,1.0);\n"; + tf += "}\n"; + } + + return tf; +} + } // openspace \ No newline at end of file diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp index 166ded0302..f1a09b3c2d 100644 --- a/src/abuffer/abufferSingleLinked.cpp +++ b/src/abuffer/abufferSingleLinked.cpp @@ -117,7 +117,7 @@ void ABufferSingleLinked::postRender() { } std::string ABufferSingleLinked::settings() { - return R"(#define SINGLE_LINKED)"; + return R"()"; } diff --git a/src/abuffer/abufferdynamic.cpp b/src/abuffer/abufferdynamic.cpp new file mode 100644 index 0000000000..8943905eda --- /dev/null +++ b/src/abuffer/abufferdynamic.cpp @@ -0,0 +1,124 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include + +#include +#include + +#include +#include +#include + +#define MAX_LAYERS 10 + +namespace { + std::string _loggerCat = "ABufferDynamic"; +} + +namespace openspace { + +ABufferDynamic::ABufferDynamic(): _data(0), _anchorPointerTexture(0), + _anchorPointerTextureInitializer(0), _atomicCounterBuffer(0), _fragmentBuffer(0), + _fragmentTexture(0) +{} + +ABufferDynamic::~ABufferDynamic() { + if(_data != 0) + delete _data; + + glDeleteTextures(1,&_anchorPointerTexture); + glDeleteTextures(1,&_fragmentTexture); + glDeleteBuffers(1,&_anchorPointerTextureInitializer); + glDeleteBuffers(1,&_atomicCounterBuffer); + glDeleteBuffers(1,&_anchorPointerTextureInitializer); +} + +bool ABufferDynamic::initialize() { + // ============================ + // BUFFERS + // ============================ + glGenTextures(1, &_anchorPointerTexture); + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + + glGenBuffers(1, &_anchorPointerTextureInitializer); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + glBufferData(GL_PIXEL_UNPACK_BUFFER, _totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW); + + _data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); + memset(_data, 0x00, _totalPixels * sizeof(GLuint)); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + glGenBuffers(1, &_atomicCounterBuffer); + glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, _atomicCounterBuffer); + glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY); + + glGenBuffers(1, &_fragmentBuffer); + glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer); + glBufferData(GL_TEXTURE_BUFFER, MAX_LAYERS*_totalPixels*sizeof(GLfloat)*4, NULL, GL_DYNAMIC_COPY); + + glGenTextures(1, &_fragmentTexture); + glBindTexture(GL_TEXTURE_BUFFER, _fragmentTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, _fragmentBuffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); + + return initializeABuffer(); +} + +void ABufferDynamic::clear() { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + static const GLuint zero = 1; + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); + glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(zero), &zero); + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0); +} + +void ABufferDynamic::preRender() { + + // Bind head-pointer image for read-write + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); + glBindImageTexture(0, _anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); +} + +void ABufferDynamic::postRender() { + +} + +std::string ABufferDynamic::settings() { + return R"(#define ABUFFER_SINGLE_LINKED)"; +} + + +} // openspace \ No newline at end of file diff --git a/src/abuffer/abufferfixed.cpp b/src/abuffer/abufferfixed.cpp new file mode 100644 index 0000000000..36c5a7aeae --- /dev/null +++ b/src/abuffer/abufferfixed.cpp @@ -0,0 +1,137 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include + +#include +#include + +#include +#include +#include + +#define MAX_LAYERS 32 + +namespace { + std::string _loggerCat = "ABufferFixed"; +} + +namespace openspace { + +ABufferFixed::ABufferFixed(): _data(0), _anchorPointerTexture(0), + _anchorPointerTextureInitializer(0), _atomicCounterBuffer(0), _fragmentBuffer(0), + _fragmentTexture(0) +{} + +ABufferFixed::~ABufferFixed() { + if(_data != 0) + delete _data; + + glDeleteTextures(1,&_anchorPointerTexture); + glDeleteTextures(1,&_fragmentTexture); + // glDeleteTextures(1,&_atomicCounterTexture); + glDeleteBuffers(1,&_anchorPointerTextureInitializer); + // glDeleteBuffers(1,&_atomicCounterBuffer); + glDeleteBuffers(1,&_anchorPointerTextureInitializer); +} + +bool ABufferFixed::initialize() { + // ============================ + // BUFFERS + // ============================ + glGenTextures(1, &_anchorPointerTexture); + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + + glGenBuffers(1, &_anchorPointerTextureInitializer); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + glBufferData(GL_PIXEL_UNPACK_BUFFER, _totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW); + + _data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); + memset(_data, 0x00, _totalPixels * sizeof(GLuint)); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + + // glGenBuffers(1, &_atomicCounterBuffer); + // glBindBuffer(GL_TEXTURE_BUFFER, _atomicCounterBuffer); + // glBufferData(GL_TEXTURE_BUFFER, _totalPixels*sizeof(GLuint), NULL, GL_DYNAMIC_COPY); + + // glGenTextures(1, &_atomicCounterTexture); + // glBindTexture(GL_TEXTURE_2D, _atomicCounterTexture); + // glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, _atomicCounterBuffer); + // glBindTexture(GL_TEXTURE_BUFFER, 0); + + + glGenBuffers(1, &_fragmentBuffer); + glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer); + glBufferData(GL_TEXTURE_BUFFER, MAX_LAYERS*_totalPixels*sizeof(GLfloat)*4, NULL, GL_DYNAMIC_COPY); + + glGenTextures(1, &_fragmentTexture); + glBindTexture(GL_TEXTURE_BUFFER, _fragmentTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, _fragmentBuffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); + + return initializeABuffer(); +} + +void ABufferFixed::clear() { + + // Bind texture initializer + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + + // clear _anchorPointerTexture + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + + // // clear _atomicCounterTexture + // glBindTexture(GL_TEXTURE_2D, _atomicCounterTexture); + // glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + + // reset GL_PIXEL_UNPACK_BUFFER + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + +} + +void ABufferFixed::preRender() { + + // Bind head-pointer image for read-write + glBindImageTexture(0, _anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); + // glBindImageTexture(2, _atomicCounterTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); +} + +void ABufferFixed::postRender() { + +} + +std::string ABufferFixed::settings() { + return R"()"; +} + + +} // openspace \ No newline at end of file diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index bdcdc9ae79..ddbf548138 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -97,6 +97,13 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): _boxScaling[2] = tempValue; } + _volumeName = ""; + if (dictionary.hasKey("VolumeName")) + dictionary.getValue("VolumeName", _volumeName); + _transferFunctionName = ""; + if (dictionary.hasKey("TransferFunctionName")) + dictionary.getValue("TransferFunctionName", _transferFunctionName); + setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling))); } @@ -121,8 +128,8 @@ bool RenderableVolumeGL::initialize() { _transferFunction->uploadTexture(); // TODO: fix volume an transferfunction names - OsEng.renderEngine().abuffer()->addVolume("volume1", _volume); - OsEng.renderEngine().abuffer()->addTransferFunction("transferFunction1", _transferFunction); + OsEng.renderEngine().abuffer()->addVolume(_volumeName, _volume); + OsEng.renderEngine().abuffer()->addTransferFunction(_transferFunctionName, _transferFunction); _id = OsEng.renderEngine().abuffer()->addSamplerfile(_samplerFilename); auto textureCallback = [this](const ghoul::filesystem::File& file) { @@ -235,8 +242,8 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { glm::mat4 camrot = camera->viewRotationMatrix(); PowerScaledScalar scaling = camera->scaling(); - psc addon(-1.1,0.0,0.0,0.0); - currentPosition += addon; + // psc addon(-1.1,0.0,0.0,0.0); + // currentPosition += addon; // TODO: Use _id to identify this volume _boxProgram->activate(); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 70fd59661d..4e1123d11c 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -35,6 +35,8 @@ #include #include +#include +#include namespace { const std::string _loggerCat = "RenderEngine"; @@ -66,6 +68,8 @@ bool RenderEngine::initialize() OsEng.interactionHandler().setCamera(_mainCamera); _abuffer = new ABufferSingleLinked(); + // _abuffer = new ABufferFixed(); + // _abuffer = new ABufferDynamic(); return true; } @@ -82,7 +86,7 @@ bool RenderEngine::initializeGL() // set the close clip plane and the far clip plane to extreme values while in // development // sgct::Engine::instance()->setNearAndFarClippingPlanes(0.1f,100.0f); - sgct::Engine::instance()->setNearAndFarClippingPlanes(0.00001f, 100.0f); + sgct::Engine::instance()->setNearAndFarClippingPlanes(0.1f, 200.0f); // calculating the maximum field of view for the camera, used to // determine visibility of objects in the scene graph diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 75434d2a54..be80e87ac9 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -82,77 +82,63 @@ bool SceneGraph::initialize() using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; - // pscstandard + auto programCreator = [] ( const std::string& name, + const std::string& vpath, + const std::string& fpath) { - std::string programObjectName = "pscstandard"; - ProgramObject* po = new ProgramObject(programObjectName); - ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/pscstandard_vs.glsl"), - programObjectName + "Vertex"); - ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/pscstandard_fs.glsl"), - programObjectName + "Fragment"); + const std::string vsPath = absPath(vpath); + const std::string fsPath = absPath(fpath); + const ShaderObject::ShaderType vsType = ShaderObject::ShaderType::ShaderTypeVertex; + const ShaderObject::ShaderType fsType = ShaderObject::ShaderType::ShaderTypeFragment; + + ProgramObject* po = new ProgramObject(name); + ShaderObject* vs = new ShaderObject(vsType, vsPath, name + "Vertex"); + ShaderObject* fs = new ShaderObject(fsType, fsPath, name + "Fragment"); po->attachObject(vs); po->attachObject(fs); - if ( ! po->compileShaderObjects()) return false; - if ( ! po->linkProgramObject()) return false; - OsEng.ref().configurationManager().setValue("pscShader", po); - } + if ( po->compileShaderObjects() && po->linkProgramObject()) + return po; + + // unsuccessful compilation, cleanup and return nullptr + delete po; + po = nullptr; + return po; + }; + + ProgramObject* tmpProgram; + + // pscstandard + tmpProgram = programCreator("pscstandard", + "${SHADERS}/pscstandard_vs.glsl", + "${SHADERS}/pscstandard_fs.glsl"); + if( ! tmpProgram) return false; + OsEng.ref().configurationManager().setValue("pscShader", tmpProgram); // RaycastProgram - { - std::string programObjectName = "RaycastProgram"; - ProgramObject* po = new ProgramObject(programObjectName); - ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/exitpoints.vert"), - programObjectName + "Vertex"); - ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/exitpoints.frag"), - programObjectName + "Fragment"); - po->attachObject(vs); - po->attachObject(fs); - if ( ! po->compileShaderObjects()) return false; - if ( ! po->linkProgramObject()) return false; - OsEng.ref().configurationManager().setValue("RaycastProgram", po); - } + tmpProgram = programCreator("RaycastProgram", + "${SHADERS}/exitpoints.vert", + "${SHADERS}/exitpoints.frag"); + if( ! tmpProgram) return false; + OsEng.ref().configurationManager().setValue("RaycastProgram", tmpProgram); + // TwoPassProgram - { - std::string programObjectName = "TwoPassProgram"; - ProgramObject* po = new ProgramObject(programObjectName); - ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/twopassraycaster.vert"), - programObjectName + "Vertex"); - ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/twopassraycaster.frag"), - programObjectName + "Fragment"); - po->attachObject(vs); - po->attachObject(fs); - if ( ! po->compileShaderObjects()) return false; - if ( ! po->linkProgramObject()) return false; - po->setUniform("texBack", 0); - po->setUniform("texFront", 1); - po->setUniform("texVolume", 2); - OsEng.ref().configurationManager().setValue("TwoPassProgram", po); - } + tmpProgram = programCreator("TwoPassProgram", + "${SHADERS}/twopassraycaster.vert", + "${SHADERS}/twopassraycaster.frag"); + if( ! tmpProgram) return false; + tmpProgram->setUniform("texBack", 0); + tmpProgram->setUniform("texFront", 1); + tmpProgram->setUniform("texVolume", 2); + OsEng.ref().configurationManager().setValue("TwoPassProgram", tmpProgram); // Quad - { - std::string programObjectName = "Quad"; - ProgramObject* po = new ProgramObject(programObjectName); - ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/quadVert.glsl"), - programObjectName + "Vertex"); - ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/quadFrag.glsl"), - programObjectName + "Fragment"); - po->attachObject(vs); - po->attachObject(fs); - if ( ! po->compileShaderObjects()) return false; - if ( ! po->linkProgramObject()) return false; - po->setUniform("quadTex", 0); - OsEng.ref().configurationManager().setValue("Quad", po); - } + tmpProgram = programCreator("Quad", + "${SHADERS}/quadVert.glsl", + "${SHADERS}/quadFrag.glsl"); + if( ! tmpProgram) return false; + tmpProgram->setUniform("quadTex", 0); + OsEng.ref().configurationManager().setValue("Quad", tmpProgram); // Initialize all nodes for (auto node : _nodes) { diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index b0e5f25616..146f922a87 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -193,8 +193,9 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) // this node has an renderable if (_renderable) { // check if the renderable boundingsphere is visible - _renderableVisible = sphereInsideFrustum( - thisPosition, _renderable->getBoundingSphere(), camera); + // _renderableVisible = sphereInsideFrustum( + // thisPosition, _renderable->getBoundingSphere(), camera); + _renderableVisible = true; } // evaluate all the children, tail-recursive function(?) diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 1fa2b423f6..f9157f681f 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -126,11 +126,9 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz // get interpolated data value for (xPos, yPos, zPos) // swap yPos and zPos because model has Z as up double value = _interpolator->interpolate(var, xPos, zPos, yPos); - - // scale to [0,1] - //doubleData[index] = (value-varMin)/(varMax-varMin); doubleData[index] = value; histogram[mapToHistogram(value)]++; + } else if (_type == Model::ENLIL) { // Put r in the [0..sqrt(3)] range @@ -150,7 +148,7 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz // avoid rounding errors when comparing to phiMax. double phiPh = _zMin + phiNorm/(2.0*M_PI)*(_zMax-_zMin-0.000001); - double varValue = 0.f; + double value = 0.0; // See if sample point is inside domain if (rPh < _xMin || rPh > _xMax || thetaPh < _yMin || thetaPh > _yMax || phiPh < _zMin || phiPh > _zMax) { @@ -168,10 +166,12 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz // Convert from [0, 2pi] rad to [0, 360] degrees phiPh = phiPh*180.f/M_PI; // Sample - varValue = _interpolator->interpolate(var, rPh, thetaPh, phiPh); + value = _interpolator->interpolate(var, rPh, thetaPh, phiPh); + // value = _interpolator->interpolate(var, rPh, phiPh, thetaPh); } - doubleData[index] = (varValue-varMin)/(varMax-varMin); + doubleData[index] = value; + histogram[mapToHistogram(value)]++; } } } @@ -179,17 +179,34 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz std::cout << std::endl; LINFO("Done!"); + // for (int i = 0; i < outDimensions.x * outDimensions.y * outDimensions.z; ++i) + // { + // std::cout << std::setfill(' ') << std::setw(15) << doubleData[i] << ", "; + // if(i % 10 == 0) + // std::cout << std::endl; + // } + // + // for(int i = 0; i < bins-1; ++i) { + // // sum += histogram[i]; + // // if(sum + histogram[i+1] > sumuntil) { + // // stop = i; + // // LDEBUG("===================="); + // // break; + // // } + // LDEBUG("histogram[" << i << "]: " << histogram[i]); + // } + int sum = 0; int stop; const int sumuntil = size * truncLim; - for(int i = 0; i < bins-1; ++i) { + for(int i = 0; i < bins; ++i) { sum += histogram[i]; - if(sum + histogram[i+1] > sumuntil) { + if(sum > sumuntil) { stop = i; - LDEBUG("===================="); + // LDEBUG("===================="); break; } - LDEBUG(histogram[i]); + // LDEBUG("histogram[" << i << "]: " << histogram[i]); } double dist = varMax - varMin; @@ -201,8 +218,14 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz data[i] = static_cast(glm::clamp(normalizedVal, 0.0, 1.0)); } - delete[] doubleData; + // for(int i = 0; i < size; ++i) { + // double normalizedVal = (doubleData[i]-varMin)/(varMax-varMin); + // // data[i] = static_cast(glm::clamp(normalizedVal, 0.0, 1.0)); + // data[i] = static_cast(normalizedVal); + // } + + delete[] doubleData; return data; } From 114af3fb5b12d5f6f87a8a8fcdbdcc7340df9a1a Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Thu, 10 Jul 2014 15:22:57 -0400 Subject: [PATCH 040/113] Added an OpenSpace ShaderCreator - Global shader settings can now be added. - ShaderCreator builds the shader and stores a generated shader file with all included source. - Small TransferFunction bugfix --- .gitignore | 1 + ext/ghoul | 2 +- include/openspace/engine/openspaceengine.h | 10 +- include/openspace/util/shadercreator.h | 60 +++++++ shaders/ABuffer/abufferResolveFragment.glsl | 18 +- shaders/ABuffer/abufferStruct.hglsl | 11 +- src/abuffer/abuffer.cpp | 27 +-- src/engine/openspaceengine.cpp | 19 +++ src/rendering/renderablefieldlines.cpp | 8 +- src/rendering/renderablevolume.cpp | 8 +- src/rendering/renderengine.cpp | 9 +- src/scenegraph/scenegraph.cpp | 57 ++++++- src/util/shadercreator.cpp | 180 ++++++++++++++++++++ 13 files changed, 355 insertions(+), 55 deletions(-) create mode 100644 include/openspace/util/shadercreator.h create mode 100644 src/util/shadercreator.cpp diff --git a/.gitignore b/.gitignore index b86c3ed18d..eb0db62a4f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ ext/SGCT # generated glsl files *.gglsl +*.OpenSpaceGenerated.glsl # CMake stuff CMakeCache.txt diff --git a/ext/ghoul b/ext/ghoul index a616a2ce84..9199e2da7a 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit a616a2ce84ec0fd9d6573ef6690707ef4a841669 +Subproject commit 9199e2da7a2df7e4fe50437ba8a775f3178d8612 diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 66fdd720f3..3e1759955d 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -34,9 +34,15 @@ #include #include -//#define FLARE_ONLY +// #define FLARE_ONLY #include +#include + +#define ABUFFER_SINGLE_LINKED 1 +#define ABUFFER_FIXED 2 +#define ABUFFER_DYNAMIC 3 +#define ABUFFER_IMPLEMENTATION ABUFFER_SINGLE_LINKED namespace openspace { @@ -59,6 +65,7 @@ public: ghoul::opencl::CLContext& clContext(); InteractionHandler& interactionHandler(); RenderEngine& renderEngine(); + ShaderCreator& shaderBuilder(); // SGCT callbacks bool initializeGL(); @@ -90,6 +97,7 @@ private: ghoul::opencl::CLContext _context; sgct::SharedVector _synchronizationBuffer; + ShaderCreator _shaderBuilder; }; #define OsEng (openspace::OpenSpaceEngine::ref()) diff --git a/include/openspace/util/shadercreator.h b/include/openspace/util/shadercreator.h new file mode 100644 index 0000000000..9274d60715 --- /dev/null +++ b/include/openspace/util/shadercreator.h @@ -0,0 +1,60 @@ +/***************************************************************************************** + * * + * 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 __SHADERCREATOR_H__ +#define __SHADERCREATOR_H__ + + +#include + +#include + +namespace openspace { +class ShaderCreator { + +public: + ShaderCreator(); + ~ShaderCreator(); + + void createSourceFile(bool b); + void sourceFileExtension(const std::string& extension); + void sourceFileHeader(const std::string& header); + + ghoul::opengl::ProgramObject* buildShader(const std::string& name, const std::string& vpath, const std::string& fpath); + +private: + + void _generateSource(const std::string& filename); + std::string _loadSource(const std::string& filename, unsigned int depth = 0); + std::string _generateFilename(const std::string& filename); + + bool _createSourceFile; + std::string _sourceFileExtension; + std::string _sourceFileHeader; + unsigned int _maxDepth; + +}; +} + +#endif \ No newline at end of file diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index b230a51e23..75b1a615be 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -35,7 +35,7 @@ #define PSCDEPTH 1 #define ZDEPTH 2 -#define ZTYPE ZDEPTH +#define ZTYPE PSCDEPTH // Math defintions #define M_E 2.7182818284590452354 @@ -56,8 +56,8 @@ const float stepSize = 0.01; const float samplingRate = 1.0; -uniform int SCREEN_WIDTH; -uniform int SCREEN_HEIGHT; +// uniform int SCREEN_WIDTH; +// uniform int SCREEN_HEIGHT; uniform float ALPHA_LIMIT = 0.95; in vec2 texCoord; @@ -146,13 +146,12 @@ float globz(float z) { // return log(2.0*z-1.0); // return exp(2.0*z-1.0); // const float zNear = 0.1f; - // const float zFar = 1.0f; - // //float z_b = texture2D(depthBuffTex, vTexCoord).x; + // const float zFar = 100.0f; // float z_b = z; // float z_n = 2.0 * z_b - 1.0; // float z_e = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); // return z_e; - //return (2.0 * z - near - far) / (far - near); + // return (2.0 * z - near - far) / (far - near); } vec4 calculate_final_color(uint frag_count) { @@ -192,7 +191,6 @@ vec4 calculate_final_color(uint frag_count) { // const float z2 = _z_(endFrag); const float l = ((z1 - S1) / L - (z2 - S1) / L) * volume_length[volID]; int max_iterations = int(l / volumeStepSize[volID]); - vec3 position; #elif ZTYPE == PSCDEPTH const float L = volume_zlength[volID]; const vec4 p1 = _pos_(startFrag); @@ -202,7 +200,6 @@ vec4 calculate_final_color(uint frag_count) { // const float z2 = _z_(endFrag); const float l = (dist / L) * volume_length[volID]; int max_iterations = int(l / volumeStepSize[volID]); - vec3 position; #endif @@ -281,8 +278,8 @@ vec4 calculate_final_color(uint frag_count) { // final_color = vec4(1.0,1.0,1.0,1.0); // } - final_color.rgb = final_color.rgb * final_color.a; - final_color.a = 1.0; + // final_color.rgb = final_color.rgb * final_color.a; + // final_color.a = 1.0; return final_color; @@ -305,4 +302,3 @@ void main() { - diff --git a/shaders/ABuffer/abufferStruct.hglsl b/shaders/ABuffer/abufferStruct.hglsl index 0153aecad6..5c510c4bd0 100644 --- a/shaders/ABuffer/abufferStruct.hglsl +++ b/shaders/ABuffer/abufferStruct.hglsl @@ -25,12 +25,11 @@ #ifndef ABUFFERSTRUCT_H_HGLSL #define ABUFFERSTRUCT_H_HGLSL -// The different kinds of implementation -#define ABUFFER_SINGLE_LINKED 1 -#define ABUFFER_FIXED 2 -#define ABUFFER_DYNAMIC 3 - -#define ABUFFER_IMPLEMENTATION ABUFFER_SINGLE_LINKED +// The different kinds of implementation, set from OpenSpace +// #define ABUFFER_SINGLE_LINKED 1 +// #define ABUFFER_FIXED 2 +// #define ABUFFER_DYNAMIC 3 +// #define ABUFFER_IMPLEMENTATION ABUFFER_SINGLE_LINKED //======================================================================================== diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 744e27a402..7c2207d6fa 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -187,23 +187,11 @@ bool ABuffer::updateShader() { using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; - ShaderObject* vs - = new ShaderObject(ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/ABuffer/abufferResolveVertex.glsl"), "Vertex"); - ShaderObject* fs - = new ShaderObject(ShaderObject::ShaderType::ShaderTypeFragment,_fragmentShaderPath, "Fragment"); - - ghoul::opengl::ProgramObject* resolveShader = new ProgramObject; - resolveShader->attachObject(vs); - resolveShader->attachObject(fs); - - if (!resolveShader->compileShaderObjects()) { - LERROR("Could not compile shader"); - return false; - } - if (!resolveShader->linkProgramObject()){ - LERROR("Could not link shader"); - return false; + ShaderCreator sc = OsEng.shaderBuilder(); + ghoul::opengl::ProgramObject* resolveShader = sc.buildShader("ABuffer resolve", absPath("${SHADERS}/ABuffer/abufferResolveVertex.glsl"), _fragmentShaderPath); + if( ! resolveShader) { + LERROR("Resolve shader not updated"); + return false; } int startAt = 0; @@ -215,9 +203,6 @@ bool ABuffer::updateShader() { resolveShader->setUniform(_transferFunctions.at(i).first, startAt + i); } - resolveShader->setUniform("SCREEN_WIDTH", static_cast(_width)); - resolveShader->setUniform("SCREEN_HEIGHT", static_cast(_height)); - if(_resolveShader) delete _resolveShader; @@ -321,7 +306,7 @@ std::string ABuffer::openspaceHeaders() { std::string ABuffer::openspaceSamplerCalls() { std::string samplercalls; - for (int i = 0; i < _samplers.size(); ++i) { + for (int i = 1; i < 2; ++i) { auto found1 = _samplers.at(i).find_first_not_of("vec4 "); auto found2 = _samplers.at(i).find_first_of("(",found1); diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 3e63603abe..1ec31e84ce 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -225,6 +225,18 @@ bool OpenSpaceEngine::initialize() GLFWwindow* win = sgct::Engine::instance()->getActiveWindowPtr()->getWindowHandle(); glfwSwapBuffers(win); + int x1, xSize, y1, ySize; + sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); + std::string sourceHeader = ""; + sourceHeader += "#define SCREEN_WIDTH " + std::to_string(xSize) + "\n"; + sourceHeader += "#define SCREEN_HEIGHT " + std::to_string(ySize) + "\n"; + sourceHeader += "#define ABUFFER_SINGLE_LINKED " + std::to_string(ABUFFER_SINGLE_LINKED) + "\n"; + sourceHeader += "#define ABUFFER_FIXED " + std::to_string(ABUFFER_FIXED) + "\n"; + sourceHeader += "#define ABUFFER_DYNAMIC " + std::to_string(ABUFFER_DYNAMIC) + "\n"; + sourceHeader += "#define ABUFFER_IMPLEMENTATION " + std::to_string(ABUFFER_IMPLEMENTATION) + "\n"; + _shaderBuilder.createSourceFile(true); + _shaderBuilder.sourceFileHeader(sourceHeader); + // Register the filepaths from static function enables easy testing // registerFilePaths(); _context.createContextFromGLContext(); @@ -315,6 +327,13 @@ RenderEngine& OpenSpaceEngine::renderEngine() return *_renderEngine; } + +ShaderCreator& OpenSpaceEngine::shaderBuilder() +{ + // TODO custom assert (ticket #5) + return _shaderBuilder; +} + bool OpenSpaceEngine::initializeGL() { return _renderEngine->initializeGL(); diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index ff4e76c669..7fa62f4d0a 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -85,11 +85,9 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) _vertexSourceFile = new ghoul::filesystem::File(vshaderpath, false); _fragmentSourceFile = new ghoul::filesystem::File(fshaderpath, false); - _fieldlinesProgram = new ghoul::opengl::ProgramObject("FieldlinesProgram"); - ghoul::opengl::ShaderObject* vertexShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeVertex,vshaderpath); - ghoul::opengl::ShaderObject* fragmentShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeFragment,fshaderpath); - _fieldlinesProgram->attachObject(vertexShader); - _fieldlinesProgram->attachObject(fragmentShader); + + ShaderCreator sc = OsEng.shaderBuilder(); + _fieldlinesProgram = sc.buildShader("FieldlinesProgram", vshaderpath, fshaderpath); } } diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index 7d6efbd93f..2a7b04da9f 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -371,8 +371,8 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string transferFunction[i] = 0.0f; } - size_t lowerIndex = static_cast(floorf(lower*static_cast(width))); - size_t upperIndex = static_cast(floorf(upper*static_cast(width))); + size_t lowerIndex = static_cast(floorf(lower*static_cast(width-1))); + size_t upperIndex = static_cast(floorf(upper*static_cast(width-1))); // LDEBUG("width: " << width); // LDEBUG("lower: " << lower); @@ -385,9 +385,9 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string auto currentKey = prevKey + 1; auto lastKey = mappingKeys.end() -1; - for (size_t i=lowerIndex; i(i)/static_cast(width); + float fpos = static_cast(i)/static_cast(width-1); if (fpos > (*currentKey).position) { prevKey = currentKey; diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 4e1123d11c..a4aeee8566 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -67,10 +67,13 @@ bool RenderEngine::initialize() //if (sgct::Engine::instance()->isMaster()) OsEng.interactionHandler().setCamera(_mainCamera); +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED _abuffer = new ABufferSingleLinked(); - // _abuffer = new ABufferFixed(); - // _abuffer = new ABufferDynamic(); - +#elif ABUFFER_IMPLEMENTATION == ABUFFER_FIXED + _abuffer = new ABufferFixed(); +#elif ABUFFER_IMPLEMENTATION == ABUFFER_DYNAMIC + _abuffer = new ABufferDynamic(); +#endif return true; } diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index be80e87ac9..e9d7623f98 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -29,6 +29,7 @@ #include #include #include +#include // ghoul includes #include "ghoul/opengl/programobject.h" @@ -46,6 +47,9 @@ #include #include +#include + #include + namespace { const std::string _loggerCat = "SceneGraph"; const std::string _rootNodeName = "Root"; @@ -82,6 +86,55 @@ bool SceneGraph::initialize() using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; + ShaderCreator sc = OsEng.shaderBuilder(); + ProgramObject* tmpProgram; + + typedef std::chrono::high_resolution_clock clock_; + typedef std::chrono::duration > second_; + + std::chrono::time_point beg_(clock_::now()); + + + // pscstandard + tmpProgram = sc.buildShader("pscstandard", + "${SHADERS}/pscstandard_vs.glsl", + "${SHADERS}/pscstandard_fs.glsl"); + if( ! tmpProgram) return false; + OsEng.ref().configurationManager().setValue("pscShader", tmpProgram); + + // RaycastProgram + tmpProgram = sc.buildShader("RaycastProgram", + "${SHADERS}/exitpoints.vert", + "${SHADERS}/exitpoints.frag"); + if( ! tmpProgram) return false; + OsEng.ref().configurationManager().setValue("RaycastProgram", tmpProgram); + + + // // TwoPassProgram + // tmpProgram = sc.buildShader("TwoPassProgram", + // "${SHADERS}/twopassraycaster.vert", + // "${SHADERS}/twopassraycaster.frag"); + // if( ! tmpProgram) return false; + // tmpProgram->setUniform("texBack", 0); + // tmpProgram->setUniform("texFront", 1); + // tmpProgram->setUniform("texVolume", 2); + // OsEng.ref().configurationManager().setValue("TwoPassProgram", tmpProgram); + + // Quad + tmpProgram = sc.buildShader("Quad", + "${SHADERS}/quadVert.glsl", + "${SHADERS}/quadFrag.glsl"); + if( ! tmpProgram) return false; + tmpProgram->setUniform("quadTex", 0); + OsEng.ref().configurationManager().setValue("Quad", tmpProgram); + + + + double elapsed = std::chrono::duration_cast(clock_::now() - beg_).count(); + LERROR("Time to load shaders: " << elapsed); + + /* + auto programCreator = [] ( const std::string& name, const std::string& vpath, const std::string& fpath) @@ -104,9 +157,6 @@ bool SceneGraph::initialize() po = nullptr; return po; }; - - ProgramObject* tmpProgram; - // pscstandard tmpProgram = programCreator("pscstandard", "${SHADERS}/pscstandard_vs.glsl", @@ -139,6 +189,7 @@ bool SceneGraph::initialize() if( ! tmpProgram) return false; tmpProgram->setUniform("quadTex", 0); OsEng.ref().configurationManager().setValue("Quad", tmpProgram); + */ // Initialize all nodes for (auto node : _nodes) { diff --git a/src/util/shadercreator.cpp b/src/util/shadercreator.cpp new file mode 100644 index 0000000000..b4b1b0d930 --- /dev/null +++ b/src/util/shadercreator.cpp @@ -0,0 +1,180 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +// #include +// #include + +using ghoul::opengl::ProgramObject; +using ghoul::opengl::ShaderObject; + +namespace { + const std::string _loggerCat = "ShaderCreator"; + const std::string defaultSourceFileExtension = "OpenSpaceGenerated.glsl"; + const std::string separator = "//=====================================================================\n"; + const ShaderObject::ShaderType vsType = ShaderObject::ShaderType::ShaderTypeVertex; + const ShaderObject::ShaderType fsType = ShaderObject::ShaderType::ShaderTypeFragment; +} + +namespace openspace { +ShaderCreator::ShaderCreator(): + _createSourceFile(false), + _sourceFileExtension(defaultSourceFileExtension), + _sourceFileHeader(""), + _maxDepth(2) +{ + +} + +ShaderCreator::~ShaderCreator() { + +} + +void ShaderCreator::createSourceFile(bool b) { + _createSourceFile = b; +} + +void ShaderCreator::sourceFileExtension(const std::string& extension) { + if(extension != "") { + _sourceFileExtension = extension; + } +} + +void ShaderCreator::sourceFileHeader(const std::string& header) { + _sourceFileHeader = header; +} + +ghoul::opengl::ProgramObject* ShaderCreator::buildShader( + const std::string& name, const std::string& vpath, const std::string& fpath) +{ + std::string vsPath = absPath(vpath); + std::string fsPath = absPath(fpath); + + if( ! FileSys.fileExists(vsPath)) + return nullptr; + if( ! FileSys.fileExists(fsPath)) + return nullptr; + + if(_createSourceFile) { + _generateSource(vsPath); + _generateSource(fsPath); + + vsPath = _generateFilename(vsPath); + fsPath = _generateFilename(fsPath); + } + + ProgramObject* po = new ProgramObject(name); + ShaderObject* vs = new ShaderObject(vsType, vsPath, name + " Vertex"); + ShaderObject* fs = new ShaderObject(fsType, fsPath, name + " Fragment"); + po->attachObject(vs); + po->attachObject(fs); + if ( po->compileShaderObjects() && po->linkProgramObject()) + return po; + + // unsuccessful compilation, cleanup and return nullptr + delete po; + po = nullptr; + return po; +} + +void ShaderCreator::_generateSource(const std::string& filename) { + std::string generatedSource = ""; + if(_sourceFileHeader != "") + generatedSource += separator + "// HEADER\n" + separator + _sourceFileHeader + "\n"; + generatedSource += _loadSource(filename); + + std::ofstream of(_generateFilename(filename)); + of << generatedSource; + of.close(); +} + +std::string ShaderCreator::_loadSource(const std::string& filename, unsigned int depth) { + std::string contents = "", line; + std::ifstream f(filename); + + // Pre-allocate memory so the return string doesn't have to resize too often + // f.seekg( 0, std::ios::end ); + // unsigned int fsize = f.tellg(); + // f.seekg( 0); + // contents.reserve(fsize*3); + // line.reserve(fsize*3); + + contents += "\n"; + contents += separator; + contents += "// Filename: " + filename + "\n"; + // contents += "// Size: " + std::to_string(fsize) + "\n"; + contents += separator; + if(depth > _maxDepth) { + contents += "// TOO DEEP"; + return contents; + } + + if( ! FileSys.fileExists(filename)){ + contents += "// FILE NOT FOUND\n"; + return contents; + } + + boost::regex e1(R"(^\s*#include \"(.+)\"\s*)"); + boost::regex e2(R"(^\s*#include <(.+)>\s*)"); + while(std::getline(f, line)) { + boost::smatch m; + if(boost::regex_search(line, m, e1)) { + std::string includeFilename = m[1]; + includeFilename = filename.substr(0, filename.find_last_of("/")+1) + includeFilename; + line = _loadSource(includeFilename, depth + 1); + } else if(boost::regex_search(line, m, e2)) { + std::string includeFilename = m[1]; + line = _loadSource(absPath(includeFilename), depth + 1); + } + + contents += line + "\n"; + } + f.close(); + + return contents; +} + +std::string ShaderCreator::_generateFilename(const std::string& filename) { + // If way of confirming and creating a directory this could be a good solution + // to avoid cluttering in folders + // if(_cacheFolder != "") { + // size_t delimiter = filename.find_last_of("/"); + // std::string file = filename.substr(delimiter+1, filename.length() - delimiter); + // std::string path = filename.substr(0, filename.find_last_of("/")); + + // return path + "/" + _cacheFolder + "/" + file + "." + _sourceFileExtension; + // } + + return filename + "." + _sourceFileExtension; +} + +} \ No newline at end of file From bd38dd124e82aa4f6e98d3b7ab65e35385890fd9 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Mon, 14 Jul 2014 11:58:12 -0400 Subject: [PATCH 041/113] ABuffer bugfix, now supporting multiple (3+) volumes --- shaders/ABuffer/abufferResolveFragment.glsl | 7 +++-- shaders/exitpoints.vert | 1 - src/abuffer/abuffer.cpp | 9 ++++-- src/rendering/renderablevolumegl.cpp | 33 +++++++++++++-------- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index 75b1a615be..23746f32cb 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -32,6 +32,7 @@ #define SHOWFUNC // #define JITTERING +#define SHOWENLIL #define PSCDEPTH 1 #define ZDEPTH 2 @@ -171,13 +172,15 @@ vec4 calculate_final_color(uint frag_count) { ABufferStruct_t endFrag = fragments[i+1]; int type = int(_type_(startFrag)); - if(type == 0) + if(type == 0) { //blendStep(final_color, _col_(startFrag), stepSize); final_color = blend(final_color, _col_(startFrag)); + } else { + currentVolumeBitmask = currentVolumeBitmask ^ (1 << (type-1)); + } #if MAX_VOLUMES > 0 - currentVolumeBitmask = currentVolumeBitmask ^ type; if(currentVolumeBitmask != 0) { int volID = type -1; float p = 0.0f; diff --git a/shaders/exitpoints.vert b/shaders/exitpoints.vert index f8895ba4b3..a3295d3a6f 100644 --- a/shaders/exitpoints.vert +++ b/shaders/exitpoints.vert @@ -32,7 +32,6 @@ uniform vec4 campos; uniform mat4 camrot; uniform vec2 scaling; uniform vec4 objpos; -uniform float time; out vec3 vPosition; out vec3 worldPosition; diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 7c2207d6fa..98d4244691 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -180,6 +180,7 @@ int ABuffer::addSamplerfile(const std::string& filename) { _samplers.push_back(""); // ID is one more than "actual" position since ID=0 is considered geometry + //return 1 << (_samplers.size()-1); return _samplers.size(); } @@ -306,13 +307,15 @@ std::string ABuffer::openspaceHeaders() { std::string ABuffer::openspaceSamplerCalls() { std::string samplercalls; - for (int i = 1; i < 2; ++i) { + for (int i = 0; i < _samplers.size(); ++i) { auto found1 = _samplers.at(i).find_first_not_of("vec4 "); auto found2 = _samplers.at(i).find_first_of("(",found1); if(found1 != std::string::npos && found2 != std::string::npos) { std::string functionName = _samplers.at(i).substr(found1, found2 - found1); - samplercalls += "if((currentVolumeBitmask & (1 << " + std::to_string(i) + ")) == "+std::to_string(i+1)+") {\n"; + if(i == 0) + samplercalls += "#ifdef SHOWENLIL\n"; + samplercalls += "if((currentVolumeBitmask & (1 << " + std::to_string(i) + ")) == "+std::to_string(1 << i)+") {\n"; samplercalls += " vec4 c = " + functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; // samplercalls += " if(c.a < 0.1) { \n"; // samplercalls += " if( volumeStepSize[" + std::to_string(i) + "] < 16.0*volumeStepSizeOriginal[" + std::to_string(i) + "]) \n"; @@ -326,6 +329,8 @@ std::string ABuffer::openspaceSamplerCalls() { // samplercalls += " blendStep(final_color, c, stepSize);\n"; samplercalls += " volume_position[" + std::to_string(i) + "] += volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];\n"; samplercalls += "}\n"; + if(i == 0) + samplercalls += "#endif\n"; } diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index ddbf548138..80c96dd39c 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -61,6 +61,7 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): _transferFunction = nullptr; _transferFunctionFile = nullptr; + _transferFunctionPath = ""; if (dictionary.hasKey("TransferFunction")) { std::string transferFunctionPath = ""; if(dictionary.getValue("TransferFunction", transferFunctionPath)) { @@ -120,22 +121,28 @@ RenderableVolumeGL::~RenderableVolumeGL() { } bool RenderableVolumeGL::initialize() { - assert(_filename != ""); + // assert(_filename != ""); // ------ VOLUME READING ---------------- - _volume = loadVolume(_filename, _hintsDictionary); - _volume->uploadTexture(); - _transferFunction = loadTransferFunction(_transferFunctionPath); - _transferFunction->uploadTexture(); - // TODO: fix volume an transferfunction names - OsEng.renderEngine().abuffer()->addVolume(_volumeName, _volume); - OsEng.renderEngine().abuffer()->addTransferFunction(_transferFunctionName, _transferFunction); - _id = OsEng.renderEngine().abuffer()->addSamplerfile(_samplerFilename); + if(_filename != "") { + _volume = loadVolume(_filename, _hintsDictionary); + _volume->uploadTexture(); + OsEng.renderEngine().abuffer()->addVolume(_volumeName, _volume); + } - auto textureCallback = [this](const ghoul::filesystem::File& file) { - _updateTransferfunction = true; - }; - _transferFunctionFile->setCallback(textureCallback); + if(_transferFunctionPath != "") { + _transferFunction = loadTransferFunction(_transferFunctionPath); + _transferFunction->uploadTexture(); + OsEng.renderEngine().abuffer()->addTransferFunction(_transferFunctionName, _transferFunction); + + auto textureCallback = [this](const ghoul::filesystem::File& file) { + _updateTransferfunction = true; + }; + _transferFunctionFile->setCallback(textureCallback); + } + + // add the sampler and get the ID + _id = OsEng.renderEngine().abuffer()->addSamplerfile(_samplerFilename); _box = new sgct_utils::SGCTBox(1.0f, sgct_utils::SGCTBox::Regular); OsEng.configurationManager().getValue("RaycastProgram", _boxProgram); From e8ac32b8306b9481e724e046a28fb9e77a48f960 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Fri, 18 Jul 2014 12:17:45 -0400 Subject: [PATCH 042/113] Updated ghoul, initial volumes with different stepsize --- ext/ghoul | 2 +- shaders/ABuffer/abufferResolveFragment.glsl | 23 +++++++++++++++++---- src/abuffer/abuffer.cpp | 4 ++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 9199e2da7a..5c1957e9e2 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 9199e2da7a2df7e4fe50437ba8a775f3178d8612 +Subproject commit 5c1957e9e2e7bfd79d72788decc099e74043cf25 diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index 23746f32cb..63b89cf709 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -31,12 +31,12 @@ #define MAX_FRAGMENTS 16 #define SHOWFUNC -// #define JITTERING +#define JITTERING #define SHOWENLIL #define PSCDEPTH 1 #define ZDEPTH 2 -#define ZTYPE PSCDEPTH +#define ZTYPE ZDEPTH // Math defintions #define M_E 2.7182818284590452354 @@ -181,9 +181,24 @@ vec4 calculate_final_color(uint frag_count) { #if MAX_VOLUMES > 0 - if(currentVolumeBitmask != 0) { + if(currentVolumeBitmask > 0) { + + // TODO: Fix this non-working normalization for volumes with different stepsize + // float myMaxSteps = 0.0000001; + // for(int v = 0; v < MAX_VOLUMES; ++v) { + // if((currentVolumeBitmask & (1 << v)) > 0) { + // myMaxSteps = max(myMaxSteps, volume_length[v]/volumeStepSize[v]); + // } + // } + // for(int v = 0; v < MAX_VOLUMES; ++v) { + // if((currentVolumeBitmask & (1 << v)) > 0) { + // float aaa = volume_length[v]/myMaxSteps; + // volumeStepSize[v] = volumeStepSizeOriginal[v]*vec3(aaa); + // } + // } + + int volID = type -1; - float p = 0.0f; #if ZTYPE == ZDEPTH const float S1 = volume_zlength[volID].x; const float S2 = volume_zlength[volID].y; diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 98d4244691..274aa9859e 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -327,7 +327,11 @@ std::string ABuffer::openspaceSamplerCalls() { // samplercalls += " } \n"; samplercalls += " blendStep(final_color, c, volumeStepSize[" + std::to_string(i) + "]);\n"; // samplercalls += " blendStep(final_color, c, stepSize);\n"; + // samplercalls += " float aaa = volume_length[i]/myMaxSteps;\n"; samplercalls += " volume_position[" + std::to_string(i) + "] += volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];\n"; + // float aaa = ray[v].w/myMaxSteps; + // pos[v] += vec4(ray[v].xyz*vec3(aaa),aaa); + // samplercalls += " volume_position[" + std::to_string(i) + "] += volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];\n"; samplercalls += "}\n"; if(i == 0) samplercalls += "#endif\n"; From eb9863046752e58dfc713d2990a483bd50603704 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Fri, 18 Jul 2014 13:28:48 -0400 Subject: [PATCH 043/113] Added new openspace data --- openspace-data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openspace-data b/openspace-data index 8fa226790e..73b2b86788 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 8fa226790e939667b31c0e2020ba42708e3de7e6 +Subproject commit 73b2b86788038628721898e08a367588069afbac From ecf3a8539a4b23e3e4db03594f9391e85129f165 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Fri, 18 Jul 2014 14:00:09 -0400 Subject: [PATCH 044/113] Added missing file --- include/openspace/util/kameleonwrapper.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/openspace/util/kameleonwrapper.h b/include/openspace/util/kameleonwrapper.h index fd8903f7a2..1bd768e72a 100644 --- a/include/openspace/util/kameleonwrapper.h +++ b/include/openspace/util/kameleonwrapper.h @@ -80,6 +80,8 @@ public: std::vector > getLorentzTrajectories(std::vector seedPoints, glm::vec4 color, float stepsize); + glm::vec3 getModelBarycenterOffset(); + private: std::vector traceCartesianFieldline(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::vec3 seedPoint, From e99a98224c43e8a40f1a215ca3c72ec865a455eb Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Wed, 23 Jul 2014 16:06:49 -0400 Subject: [PATCH 045/113] Working ABuffer - Fixed the ABuffer rendering for intersecting volumes - Added keyboard callback for toggling renderables - Changed textures from ClampToBorder to ClampToEdge - Fixed transferfunctions to clamp to edge instead of fade to black --- config/sgct/single.xml | 2 +- .../interaction/interactionhandler.h | 6 + .../openspace/rendering/renderablevolumegl.h | 1 + include/openspace/scenegraph/scenegraphnode.h | 1 + openspace-data | 2 +- shaders/ABuffer/abufferResolveFragment.glsl | 153 ++++++++++++------ src/abuffer/abuffer.cpp | 5 +- src/interaction/interactionhandler.cpp | 13 ++ src/rendering/renderablevolume.cpp | 75 +++++---- src/rendering/renderablevolumegl.cpp | 81 +++++----- src/scenegraph/scenegraphnode.cpp | 22 ++- src/util/kameleonwrapper.cpp | 8 + 12 files changed, 246 insertions(+), 123 deletions(-) diff --git a/config/sgct/single.xml b/config/sgct/single.xml index 87e59f7b28..3ec20dd5db 100644 --- a/config/sgct/single.xml +++ b/config/sgct/single.xml @@ -8,7 +8,7 @@ - + diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index b8505beda2..80b867dd91 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -11,6 +11,8 @@ #include #include #include +#include +#include namespace openspace { @@ -56,6 +58,8 @@ public: void mouseButtonCallback(int key, int action); void mousePositionCallback(int x, int y); void mouseScrollWheelCallback(int pos); + + void addKeyCallback(int key, std::function f); private: glm::vec3 mapToTrackball(glm::vec2 mousePos); @@ -77,6 +81,8 @@ private: // for locking and unlocking std::mutex cameraGuard_; + + std::multimap > _keyCallbacks; }; diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index f7b82028fc..dce4c1942b 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -68,6 +68,7 @@ private: GLuint _boxArray; ghoul::opengl::ProgramObject *_boxProgram; glm::vec3 _boxScaling, _boxOffset; + float _w; GLint _MVPLocation, _modelTransformLocation, _typeLocation; bool _updateTransferfunction; diff --git a/include/openspace/scenegraph/scenegraphnode.h b/include/openspace/scenegraph/scenegraphnode.h index 9a8b847d97..531ca23089 100644 --- a/include/openspace/scenegraph/scenegraphnode.h +++ b/include/openspace/scenegraph/scenegraphnode.h @@ -90,6 +90,7 @@ private: // renderable Renderable* _renderable; bool _renderableVisible; + bool _renderableToggle; // bounding sphere bool _boundingSphereVisible; diff --git a/openspace-data b/openspace-data index 73b2b86788..2642f7b929 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 73b2b86788038628721898e08a367588069afbac +Subproject commit 2642f7b929d2fb6573f81ecec5d2823ef5506092 diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index 63b89cf709..1eb46ac089 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -30,9 +30,10 @@ #pragma openspace insert SETTINGS #define MAX_FRAGMENTS 16 -#define SHOWFUNC -#define JITTERING -#define SHOWENLIL +// #define SHOWFUNC +// #define JITTERING +#define SAMPLEFIRSTVOLUME +// #define COLORNORMALIZATION #define PSCDEPTH 1 #define ZDEPTH 2 @@ -59,7 +60,8 @@ const float samplingRate = 1.0; // uniform int SCREEN_WIDTH; // uniform int SCREEN_HEIGHT; -uniform float ALPHA_LIMIT = 0.95; +uniform float ALPHA_LIMIT = 0.99; +uniform float EPSILON = 0.01; in vec2 texCoord; out vec4 color; @@ -81,7 +83,9 @@ vec3 CartesianToSpherical(vec3 _cartesian) { theta = phi = 0.0; } else { theta = acos(cartesian.z/r) / M_PI; - phi = (M_PI + atan(cartesian.y, cartesian.x)) / (2.0*M_PI); + // float diff = -.0f; + phi = (M_PI + atan(cartesian.y, cartesian.x)) / (2.0*M_PI ); + // phi = (M_PI+radians(diff) + atan(cartesian.y, cartesian.x)) / (2.0*M_PI+radians(diff) ); // phi = (M_PI + atan(cartesian.x, cartesian.y)) / (2.0*M_PI); } // r *= 0.57735026919; @@ -142,6 +146,27 @@ void blendGeometry(inout vec4 color, ABufferStruct_t frag) { } */ +float volumeRaycastingDistance(in int id, in ABufferStruct_t startFrag, in ABufferStruct_t endFrag) { +#if ZTYPE == ZDEPTH + const float S1 = volume_zlength[id].x; + const float S2 = volume_zlength[id].y; + const float L = S1 - S2; + // const float z1 = globz(_z_(startFrag)); + // const float z2 = globz(_z_(endFrag)); + const float z1 = _z_(startFrag); + const float z2 = _z_(endFrag); + return ((z1 - S1) / L - (z2 - S1) / L) * volume_length[id]; +#elif ZTYPE == PSCDEPTH + const float L = volume_zlength[id]; + const vec4 p1 = _pos_(startFrag); + const vec4 p2 = _pos_(endFrag); + const float dist = pscLength(p1, p2); + // const float z1 = _z_(startFrag); + // const float z2 = _z_(endFrag); + return (dist / L) * volume_length[id]; +#endif +} + float globz(float z) { return z; // return log(2.0*z-1.0); @@ -183,59 +208,81 @@ vec4 calculate_final_color(uint frag_count) { #if MAX_VOLUMES > 0 if(currentVolumeBitmask > 0) { + int volbit = currentVolumeBitmask; + int endbittype = int(_type_(endFrag)); + if(endbittype > 0) + volbit = volbit ^ (1 << (endbittype-1)); + + // int volID = type -1; + // int volID = type-1; + int volID; + // TODO: Fix this non-working normalization for volumes with different stepsize - // float myMaxSteps = 0.0000001; - // for(int v = 0; v < MAX_VOLUMES; ++v) { - // if((currentVolumeBitmask & (1 << v)) > 0) { - // myMaxSteps = max(myMaxSteps, volume_length[v]/volumeStepSize[v]); - // } - // } + float myMaxSteps = 0.0000001; + float vlength; + for(int v = 0; v < MAX_VOLUMES; ++v) { + if((currentVolumeBitmask & (1 << v)) > 0) { + + // float l = volume_length[v]/volumeStepSize[v]; + // if(myMaxSteps < l) { + // myMaxSteps = l; + // volID = v; + // } + float l = volumeRaycastingDistance(v, startFrag, endFrag); + // myMaxSteps = max(myMaxSteps, L/volumeStepSizeOriginal[v]); + myMaxSteps = max(myMaxSteps, l/volumeStepSizeOriginal[v]); + + // if((volbit & (1 << v)) > 0) + // volID = v; + // if(volbit == 0) + // volID = v; + // if(type - 1 != v && type == endbittype) + // volID = v; + + // if(volID < 0) volID = v; + // volID = v; + } + } // for(int v = 0; v < MAX_VOLUMES; ++v) { // if((currentVolumeBitmask & (1 << v)) > 0) { // float aaa = volume_length[v]/myMaxSteps; // volumeStepSize[v] = volumeStepSizeOriginal[v]*vec3(aaa); // } // } - - - int volID = type -1; -#if ZTYPE == ZDEPTH - const float S1 = volume_zlength[volID].x; - const float S2 = volume_zlength[volID].y; - const float L = S1 - S2; - const float z1 = globz(_z_(startFrag)); - const float z2 = globz(_z_(endFrag)); - // const float z1 = _z_(startFrag); - // const float z2 = _z_(endFrag); - const float l = ((z1 - S1) / L - (z2 - S1) / L) * volume_length[volID]; - int max_iterations = int(l / volumeStepSize[volID]); -#elif ZTYPE == PSCDEPTH - const float L = volume_zlength[volID]; - const vec4 p1 = _pos_(startFrag); - const vec4 p2 = _pos_(endFrag); - const float dist = pscLength(p1, p2); - // const float z1 = _z_(startFrag); - // const float z2 = _z_(endFrag); - const float l = (dist / L) * volume_length[volID]; - int max_iterations = int(l / volumeStepSize[volID]); -#endif - - - - - // MIP - // vec4 tmp, color = vec4(0); - // while(p < l && iterations < LOOP_LIMIT) { - // tmp = texture(volume, volume_position[volID]); - // color = max(color, tmp); - // p+= stepSize; - // volume_position[volID] += direction*stepSize; - // ++iterations; + // float myMaxSteps = stepSize; + // for(int v = 0; v < MAX_VOLUMES; ++v) { + // if((currentVolumeBitmask & (1 << v)) > 0) { + // myMaxSteps = min(myMaxSteps, volumeStepSize[v]); + // } // } - // vec4 volume_color = vec4(color.r,color.r,color.r,color.r*2.0); - // if(volume_color.a < 0.1) volume_color = vec4(0.0,0.0,0.0,0.0); - // final_color = blend(final_color, volume_color); - + + for(int v = 0; v < MAX_VOLUMES; ++v) { + if((currentVolumeBitmask & (1 << v)) > 0) { + // float aaa = myMaxSteps; + float l = volumeRaycastingDistance(v, startFrag, endFrag); + float aaa = l/myMaxSteps; + // float aaa = volume_length[v]/myMaxSteps; + // volumeStepSize[v] = volumeStepSizeOriginal[v]*vec3(aaa); + // float aaa = volume_length[v]/volumeStepSizeOriginal[v]; + volumeStepSize[v] = aaa; + + // if(vlength >= volume_length[v]) { + // // vlength = volume_length[v]; + // const float S1 = volume_zlength[v].x; + // const float S2 = volume_zlength[v].y; + // const float L = S1 - S2; + // vlength = volume_length[v]; + // vlength = L; + // volID = v; + // } + // if(volID < 0) volID = v; + volID = v; + } + } + + + float l = volumeRaycastingDistance(volID, startFrag, endFrag); + int max_iterations = int(l / volumeStepSize[volID]); // TransferFunction vec4 color = vec4(0); @@ -296,8 +343,10 @@ vec4 calculate_final_color(uint frag_count) { // final_color = vec4(1.0,1.0,1.0,1.0); // } - // final_color.rgb = final_color.rgb * final_color.a; - // final_color.a = 1.0; +#ifdef COLORNORMALIZATION + final_color.rgb = final_color.rgb * final_color.a; + final_color.a = 1.0; +#endif return final_color; diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 274aa9859e..42a7367721 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -314,7 +314,7 @@ std::string ABuffer::openspaceSamplerCalls() { if(found1 != std::string::npos && found2 != std::string::npos) { std::string functionName = _samplers.at(i).substr(found1, found2 - found1); if(i == 0) - samplercalls += "#ifdef SHOWENLIL\n"; + samplercalls += "#ifdef SAMPLEFIRSTVOLUME\n"; samplercalls += "if((currentVolumeBitmask & (1 << " + std::to_string(i) + ")) == "+std::to_string(1 << i)+") {\n"; samplercalls += " vec4 c = " + functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; // samplercalls += " if(c.a < 0.1) { \n"; @@ -325,6 +325,7 @@ std::string ABuffer::openspaceSamplerCalls() { // samplercalls += " volumeStepSize[" + std::to_string(i) + "] = volumeStepSizeOriginal[" + std::to_string(i) + "]; \n"; // samplercalls += " //c = " + functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; // samplercalls += " } \n"; + samplercalls += " if(c.a > EPSILON)\n"; samplercalls += " blendStep(final_color, c, volumeStepSize[" + std::to_string(i) + "]);\n"; // samplercalls += " blendStep(final_color, c, stepSize);\n"; // samplercalls += " float aaa = volume_length[i]/myMaxSteps;\n"; @@ -358,7 +359,7 @@ std::string ABuffer::openspaceTransferFunction() { for(int i = 0; i < _transferFunctions.size(); ++i) { tf += "if( gl_FragCoord.y > SCREEN_HEIGHTf-showfunc_size*"+std::to_string(i+1)+ " && gl_FragCoord.y < SCREEN_HEIGHTf-showfunc_size*"+std::to_string(i)+") {\n"; - tf += " float normalizedIntensity = gl_FragCoord.x / SCREEN_WIDTHf ;\n"; + tf += " float normalizedIntensity = gl_FragCoord.x / (SCREEN_WIDTHf-1) ;\n"; tf += " vec4 tfc = texture("+ _transferFunctions.at(i).first +", normalizedIntensity);\n"; tf += " final_color = tfc;\n"; tf += " float cmpf = SCREEN_HEIGHTf-showfunc_size*"+std::to_string(i+1)+" + tfc.a*showfunc_size;\n"; diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 5a4dc136f0..9443a1f286 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -390,6 +390,14 @@ void InteractionHandler::keyboardCallback(int key, int action) { getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); } */ + // std::pair >::iterator, std::multimap >::iterator> ret; + if(action == SGCT_PRESS) { + auto ret = _keyCallbacks.equal_range(key); + for (auto it=ret.first; it!=ret.second; ++it) + it->second(); + } + + } void InteractionHandler::mouseButtonCallback(int key, int action) { @@ -428,5 +436,10 @@ void InteractionHandler::mouseScrollWheelCallback(int pos) { } } +void InteractionHandler::addKeyCallback(int key, std::function f) { + //std::map > > _keyCallbacks; + + _keyCallbacks.insert(std::make_pair(key, f)); +} } // namespace openspace diff --git a/src/rendering/renderablevolume.cpp b/src/rendering/renderablevolume.cpp index e7463558cd..7ecaf4274f 100644 --- a/src/rendering/renderablevolume.cpp +++ b/src/rendering/renderablevolume.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -81,6 +82,7 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume( const std::string& filepath, const ghoul::Dictionary& hintsDictionary) { + if( ! FileSys.fileExists(filepath)) { LWARNING("Could not load volume, could not find '" << filepath << "'"); return nullptr; @@ -92,6 +94,9 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume( return rawReader.read(filepath); } else if(hasExtension(filepath, "cdf")) { + ghoul::opengl::Texture::FilterMode filtermode = ghoul::opengl::Texture::FilterMode::Linear; + ghoul::opengl::Texture::WrappingMode wrappingmode = ghoul::opengl::Texture::WrappingMode::ClampToEdge; + glm::size3_t dimensions(1,1,1); double tempValue; if (hintsDictionary.hasKey("Dimensions.1") && @@ -158,9 +163,7 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume( } fclose(file); - ghoul::opengl::Texture* t = new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, ghoul::opengl::Texture::FilterMode::Linear, ghoul::opengl::Texture::WrappingMode::ClampToBorder); - t->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); - return t; + return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, filtermode, wrappingmode); } KameleonWrapper::Model model; @@ -183,9 +186,7 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume( fwrite(data, sizeof(float), length, file); fclose(file); } - ghoul::opengl::Texture* t = new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, ghoul::opengl::Texture::FilterMode::Linear, ghoul::opengl::Texture::WrappingMode::ClampToBorder); - t->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); - return t; + return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT, filtermode, wrappingmode); } else if (hintsDictionary.hasKey("Variables")) { std::string xVariable, yVariable, zVariable; bool xVar, yVar, zVar; @@ -205,9 +206,7 @@ ghoul::opengl::Texture* RenderableVolume::loadVolume( fclose(file); } - ghoul::opengl::Texture* t = new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT); - t->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); - return t; + return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::RGBA, GL_RGBA, GL_FLOAT, filtermode, wrappingmode); } } else { @@ -236,6 +235,7 @@ glm::vec3 RenderableVolume::getVolumeOffset( model = KameleonWrapper::Model::BATSRUS; } else if (modelString == "ENLIL") { model = KameleonWrapper::Model::ENLIL; + return glm::vec3(0); } else { LWARNING("Hints does not specify a valid 'Model'"); return glm::vec3(0); @@ -313,11 +313,14 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string if ( ! FileSys.fileExists(f)) { return nullptr; } + ghoul::opengl::Texture::FilterMode filtermode = ghoul::opengl::Texture::FilterMode::Linear; + ghoul::opengl::Texture::WrappingMode wrappingmode = ghoul::opengl::Texture::WrappingMode::ClampToEdge; + // check if not a txt based texture if ( ! hasExtension(filepath, "txt")) { ghoul::opengl::Texture* t = ghoul::opengl::loadTexture(f); - t->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder); + t->setWrapping(wrappingmode); return t; } @@ -346,7 +349,7 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string auto widthValidator = [](size_t in) { if(in > 0) return in; return static_cast(1); }; auto upperLowerValidator = [](float in) { return glm::clamp(in, 0.0f, 1.0f); }; - auto intensityValidator = [](float in) { if(in > 0.0f) return in; return 1.0f; }; + auto intensityValidator = [](float in) { return glm::clamp(in, 0.0f, 1.0f); }; std::string line; while (std::getline(in, line)) { @@ -381,15 +384,26 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string if (mappingKeys.size() < 1) { return nullptr; } + + // for(auto key: mappingKeys) { + // glm::vec4 rgba = key.color; + // LDEBUG("i: " << key.position << ", rgba: (" << rgba[0] << ", " << rgba[1] << ", " << rgba[2] << ", " << rgba[3] << ")"); + // } + // LDEBUG("insert...."); - mappingKeys.insert(mappingKeys.begin(), {lower}); - mappingKeys.push_back({upper}); - - - for(auto key: mappingKeys) { - glm::vec4 rgba = key.color; -// LDEBUG("i: " << key.position << ", rgba: (" << rgba[0] << ", " << rgba[1] << ", " << rgba[2] << ", " << rgba[3] << ")"); + if (mappingKeys.front().position > lower){ + mappingKeys.insert(mappingKeys.begin(), {lower,mappingKeys.front().color}); } + + if (mappingKeys.back().position < upper){ + mappingKeys.push_back({upper,mappingKeys.back().color}); + } + + + // for(auto key: mappingKeys) { + // glm::vec4 rgba = key.color; + // LDEBUG("i: " << key.position << ", rgba: (" << rgba[0] << ", " << rgba[1] << ", " << rgba[2] << ", " << rgba[3] << ")"); + // } // allocate new float array with zeros float* transferFunction = new float[width*4](); @@ -448,18 +462,25 @@ ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string //LDEBUG("["<< position <<"] " << value); } - // LDEBUG(weight << ", (" << - // transferFunction[4*i+0] << ", " << - // transferFunction[4*i+1] << ", " << - // transferFunction[4*i+2] << ", " << - // transferFunction[4*i+3] << ")"); + // LDEBUG(std::fixed << std::setw(10) << std::left << std::setprecision(8) << weight << ", (" << + // std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+0] << ", " << + // std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+1] << ", " << + // std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+2] << ", " << + // std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+3] << ")"); } - ghoul::opengl::Texture* t = new ghoul::opengl::Texture(transferFunction, + // for (int i = 0; i <= width; ++i) { + + // LDEBUG(std::fixed << "(" << + // std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+0] << ", " << + // std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+1] << ", " << + // std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+2] << ", " << + // std::setw(10) << std::left << std::setprecision(8) << transferFunction[4*i+3] << ")"); + // } + + return new ghoul::opengl::Texture(transferFunction, glm::size3_t(width,1,1),ghoul::opengl::Texture::Format::RGBA, - GL_RGBA, GL_FLOAT, ghoul::opengl::Texture::FilterMode::Linear, - ghoul::opengl::Texture::WrappingMode::ClampToBorder); - return t; + GL_RGBA, GL_FLOAT,filtermode, wrappingmode); } } // namespace openspace diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index ed0e62a719..9e4bca99a0 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -92,8 +92,11 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): _boxScaling[1] = tempValue; } if(dictionary.hasKey("BoxScaling.3") && dictionary.getValue("BoxScaling.3", tempValue)) { - if(tempValue > 0.0) - _boxScaling[2] = tempValue; + if(tempValue > 0.0) + _boxScaling[2] = tempValue; + } + if(dictionary.hasKey("BoxScaling.4") && dictionary.getValue("BoxScaling.4", tempValue)) { + _w = tempValue; } _volumeName = ""; @@ -103,7 +106,7 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): if (dictionary.hasKey("TransferFunctionName")) dictionary.getValue("TransferFunctionName", _transferFunctionName); - setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling))); + setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling)*pow(10,_w))); } RenderableVolumeGL::~RenderableVolumeGL() { @@ -160,47 +163,47 @@ bool RenderableVolumeGL::initialize() { const GLfloat size = 0.5f; const GLfloat vertex_data[] = { // square of two triangles (sigh) // x, y, z, s, - -size, -size, size, 0.0f, - size, size, size, 0.0f, - -size, size, size, 0.0f, - -size, -size, size, 0.0f, - size, -size, size, 0.0f, - size, size, size, 0.0f, + -size, -size, size, _w, + size, size, size, _w, + -size, size, size, _w, + -size, -size, size, _w, + size, -size, size, _w, + size, size, size, _w, - -size, -size, -size, 0.0f, - size, size, -size, 0.0f, - -size, size, -size, 0.0f, - -size, -size, -size, 0.0f, - size, -size, -size, 0.0f, - size, size, -size, 0.0f, + -size, -size, -size, _w, + size, size, -size, _w, + -size, size, -size, _w, + -size, -size, -size, _w, + size, -size, -size, _w, + size, size, -size, _w, - size, -size, -size, 0.0f, - size, size, size, 0.0f, - size, -size, size, 0.0f, - size, -size, -size, 0.0f, - size, size, -size, 0.0f, - size, size, size, 0.0f, + size, -size, -size, _w, + size, size, size, _w, + size, -size, size, _w, + size, -size, -size, _w, + size, size, -size, _w, + size, size, size, _w, - -size, -size, -size, 0.0f, - -size, size, size, 0.0f, - -size, -size, size, 0.0f, - -size, -size, -size, 0.0f, - -size, size, -size, 0.0f, - -size, size, size, 0.0f, + -size, -size, -size, _w, + -size, size, size, _w, + -size, -size, size, _w, + -size, -size, -size, _w, + -size, size, -size, _w, + -size, size, size, _w, - -size, size, -size, 0.0f, - size, size, size, 0.0f, - -size, size, size, 0.0f, - -size, size, -size, 0.0f, - size, size, -size, 0.0f, - size, size, size, 0.0f, + -size, size, -size, _w, + size, size, size, _w, + -size, size, size, _w, + -size, size, -size, _w, + size, size, -size, _w, + size, size, size, _w, - -size, -size, -size, 0.0f, - size, -size, size, 0.0f, - -size, -size, size, 0.0f, - -size, -size, -size, 0.0f, - size, -size, -size, 0.0f, - size, -size, size, 0.0f, + -size, -size, -size, _w, + size, -size, size, _w, + -size, -size, size, _w, + -size, -size, -size, _w, + size, -size, -size, _w, + size, -size, size, _w, }; GLuint vertexPositionBuffer; glGenVertexArrays(1, &_boxArray); // generate array diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 146f922a87..45f78eeb71 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -77,6 +77,25 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di } LDEBUG("Successfully create renderable for '" << result->_nodeName << "'"); } + + if (dictionary.hasKey("RenderableToggle")) { + std::string val; + dictionary.getValue("RenderableToggle", val); + + if(val.length() == 1) { + char c = std::toupper(val[0]); + int key = static_cast(c); + auto func = [result]() { + result->_renderableToggle = ! result->_renderableToggle; + }; + LERROR("Found key:" << key); + OsEng.interactionHandler().addKeyCallback(key, func); + } + + // LERROR("Found key:" << val); + // LERROR("key 1:" << static_cast('1')); + } + if (dictionary.hasKey(keyEphemeris)) { ghoul::Dictionary ephemerisDictionary; dictionary.getValue(keyEphemeris, ephemerisDictionary); @@ -116,6 +135,7 @@ SceneGraphNode::SceneGraphNode() , _ephemeris(new StaticEphemeris) , _renderable(nullptr) , _renderableVisible(false) + , _renderableToggle(true) , _boundingSphereVisible(false) { } @@ -212,7 +232,7 @@ void SceneGraphNode::render(const Camera* camera, const psc& parentPosition) if (!_boundingSphereVisible) { return; } - if (_renderableVisible) { + if (_renderableVisible && _renderableToggle) { // LDEBUG("Render"); _renderable->render(camera, thisPosition); } diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 023f96a698..ce0acd5376 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -213,10 +213,18 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz dist = (dist / static_cast(bins)) * static_cast(stop); varMax = varMin + dist; + LDEBUG(var << "Min: " << varMin); + LDEBUG(var << "Max: " << varMax); for(int i = 0; i < size; ++i) { double normalizedVal = (doubleData[i]-varMin)/(varMax-varMin); data[i] = static_cast(glm::clamp(normalizedVal, 0.0, 1.0)); + if(data[i] < 0.0) { + LERROR("Datapoint " << i << " less than 0"); + } + if(data[i] > 1.0) { + LERROR("Datapoint " << i << " more than 1"); + } } // for(int i = 0; i < size; ++i) { From 258e62caa21457231652078c757eea970a6d7348 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Thu, 24 Jul 2014 16:12:37 -0400 Subject: [PATCH 046/113] Cleaned up before beginning ABuffer dynamic impl. - Added support for more keys in RenderableToggle - Switched to Fixed ABuffer (needs to be fixed) - Removed commented code --- include/openspace/engine/openspaceengine.h | 2 +- shaders/ABuffer/abufferResolveFragment.glsl | 210 ++++++-------------- shaders/ABuffer/abufferSort.hglsl | 3 +- src/abuffer/abuffer.cpp | 8 +- src/scenegraph/scenegraphnode.cpp | 48 ++++- 5 files changed, 110 insertions(+), 161 deletions(-) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 3e1759955d..8e6d8da45b 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -42,7 +42,7 @@ #define ABUFFER_SINGLE_LINKED 1 #define ABUFFER_FIXED 2 #define ABUFFER_DYNAMIC 3 -#define ABUFFER_IMPLEMENTATION ABUFFER_SINGLE_LINKED +#define ABUFFER_IMPLEMENTATION ABUFFER_FIXED namespace openspace { diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index 1eb46ac089..6c3245cdff 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -28,16 +28,29 @@ // Settings // ================================================================================ #pragma openspace insert SETTINGS -#define MAX_FRAGMENTS 16 -// #define SHOWFUNC -// #define JITTERING -#define SAMPLEFIRSTVOLUME -// #define COLORNORMALIZATION +// Select type of depth calculations +#define PSCDEPTH 1 +#define ZDEPTH 2 +#define ZTYPE ZDEPTH + +// Maximum number of fragments +#define MAX_FRAGMENTS 16 // The size of the local fragment list +// #define VISUALIZE_TRANSFERFUNCTIONS // +#define USE_JITTERING // +// #define USE_COLORNORMALIZATION // + +// If you need to render a volume box but not sample the volume (debug purpose) +// #define SKIP_VOLUME_0 +// #define SKIP_VOLUME_1 +// #define SKIP_VOLUME_2 +// #define SKIP_VOLUME_3 + +// constants +const float stepSize = 0.01; +const float samplingRate = 1.0; +uniform float ALPHA_LIMIT = 0.99; -#define PSCDEPTH 1 -#define ZDEPTH 2 -#define ZTYPE ZDEPTH // Math defintions #define M_E 2.7182818284590452354 @@ -46,7 +59,6 @@ #define M_LN2 0.69314718055994530942 /* log_e 2 */ #define M_LN10 2.30258509299404568402 /* log_e 10 */ #define M_PI 3.14159265358979323846 /* pi */ -// #define M_PI 3.141592653589793238462643383279 /* pi */ #define M_PI_2 1.57079632679489661923 /* pi/2 */ #define M_PI_4 0.78539816339744830962 /* pi/4 */ #define M_1_PI 0.31830988618379067154 /* 1/pi */ @@ -54,17 +66,10 @@ #define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ #define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ #define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ - -const float stepSize = 0.01; -const float samplingRate = 1.0; - -// uniform int SCREEN_WIDTH; -// uniform int SCREEN_HEIGHT; -uniform float ALPHA_LIMIT = 0.99; -uniform float EPSILON = 0.01; +#define M_SQRT1_3 0.57735026919 /* 1/sqrt(3) */ in vec2 texCoord; -out vec4 color; +out vec4 out_color; // ================================================================================ // Headers, @@ -72,6 +77,30 @@ out vec4 color; // ================================================================================ #pragma openspace insert HEADERS +// ================================================================================ +// The ABuffer specific includes and definitions +// ================================================================================ +#include "abufferStruct.hglsl" +ABufferStruct_t fragments[MAX_FRAGMENTS]; + +#if MAX_VOLUMES > 0 + vec3 volume_direction[MAX_VOLUMES]; + float volume_length[MAX_VOLUMES]; + vec3 volume_position[MAX_VOLUMES]; + int volumes_in_fragment[MAX_VOLUMES]; + int volume_count = 0; + + #if ZTYPE == ZDEPTH + vec2 volume_zlength[MAX_VOLUMES]; + #elif ZTYPE == PSCDEPTH + float volume_zlength[MAX_VOLUMES]; + #endif +#endif +#include "abufferSort.hglsl" + +// ================================================================================ +// Helper functions functions +// ================================================================================ vec3 CartesianToSpherical(vec3 _cartesian) { // Put cartesian in [-1..1] range first vec3 cartesian = vec3(-1.0,-1.0,-1.0) + _cartesian * 2.0f; @@ -83,42 +112,15 @@ vec3 CartesianToSpherical(vec3 _cartesian) { theta = phi = 0.0; } else { theta = acos(cartesian.z/r) / M_PI; - // float diff = -.0f; phi = (M_PI + atan(cartesian.y, cartesian.x)) / (2.0*M_PI ); - // phi = (M_PI+radians(diff) + atan(cartesian.y, cartesian.x)) / (2.0*M_PI+radians(diff) ); - // phi = (M_PI + atan(cartesian.x, cartesian.y)) / (2.0*M_PI); } - // r *= 0.57735026919; - r = r / sqrt(3.0f); + r *= M_SQRT1_3; + // r = r / sqrt(3.0f); // Sampler ignores w component - // return vec3(r, phi, theta); return vec3(r, theta, phi); - // return vec3(r, phi*0.7, theta); } -// ================================================================================ -// The ABuffer specific includes and definitions -// ================================================================================ -#include "abufferStruct.hglsl" -ABufferStruct_t fragments[MAX_FRAGMENTS]; - -#if MAX_VOLUMES > 0 -vec3 volume_direction[MAX_VOLUMES]; -float volume_length[MAX_VOLUMES]; -vec3 volume_position[MAX_VOLUMES]; - -#if ZTYPE == ZDEPTH - vec2 volume_zlength[MAX_VOLUMES]; -#elif ZTYPE == PSCDEPTH - float volume_zlength[MAX_VOLUMES]; -#endif -#endif -#include "abufferSort.hglsl" - -// ================================================================================ -// Blend functions -// ================================================================================ vec4 blend(vec4 src, vec4 dst) { vec4 o; o.a = src.a + dst.a * (1.0f - src.a); @@ -133,18 +135,6 @@ void blendStep(inout vec4 dst, in vec4 src, in float stepSize) { dst.rgb = dst.rgb + (1.0 - dst.a) * src.a * src.rgb; dst.a = dst.a + (1.0 -dst.a) * src.a; } -/* -//Color geometry -void blendGeometry(inout vec4 color, ABufferStruct_t frag) { - //vec4 c; - //c.rg = unpackHalf2x16(frag.rg); - //c.ba = unpackHalf2x16(frag.ba); - vec4 c = _col_(frag); - c.a = clamp(c.a, 0.0,1.0); - blend(color, c, 0.01); - return; -} -*/ float volumeRaycastingDistance(in int id, in ABufferStruct_t startFrag, in ABufferStruct_t endFrag) { #if ZTYPE == ZDEPTH @@ -167,19 +157,6 @@ float volumeRaycastingDistance(in int id, in ABufferStruct_t startFrag, in ABuff #endif } -float globz(float z) { - return z; - // return log(2.0*z-1.0); - // return exp(2.0*z-1.0); - // const float zNear = 0.1f; - // const float zFar = 100.0f; - // float z_b = z; - // float z_n = 2.0 * z_b - 1.0; - // float z_e = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); - // return z_e; - // return (2.0 * z - near - far) / (far - near); -} - vec4 calculate_final_color(uint frag_count) { // volumeStepSize[volID] = 0.01; int currentVolumeBitmask = 0; @@ -208,94 +185,37 @@ vec4 calculate_final_color(uint frag_count) { #if MAX_VOLUMES > 0 if(currentVolumeBitmask > 0) { - int volbit = currentVolumeBitmask; - int endbittype = int(_type_(endFrag)); - if(endbittype > 0) - volbit = volbit ^ (1 << (endbittype-1)); - // int volID = type -1; - // int volID = type-1; int volID; - - // TODO: Fix this non-working normalization for volumes with different stepsize float myMaxSteps = 0.0000001; - float vlength; - for(int v = 0; v < MAX_VOLUMES; ++v) { - if((currentVolumeBitmask & (1 << v)) > 0) { - - // float l = volume_length[v]/volumeStepSize[v]; - // if(myMaxSteps < l) { - // myMaxSteps = l; - // volID = v; - // } - float l = volumeRaycastingDistance(v, startFrag, endFrag); - // myMaxSteps = max(myMaxSteps, L/volumeStepSizeOriginal[v]); - myMaxSteps = max(myMaxSteps, l/volumeStepSizeOriginal[v]); - - // if((volbit & (1 << v)) > 0) - // volID = v; - // if(volbit == 0) - // volID = v; - // if(type - 1 != v && type == endbittype) - // volID = v; - - // if(volID < 0) volID = v; - // volID = v; + if(volume_count > 1) { + for(int v = 0; v < volume_count; ++v) { + int vol = volumes_in_fragment[v]; + float l = volumeRaycastingDistance(vol, startFrag, endFrag); + myMaxSteps = max(myMaxSteps, l/volumeStepSizeOriginal[vol]); } - } - // for(int v = 0; v < MAX_VOLUMES; ++v) { - // if((currentVolumeBitmask & (1 << v)) > 0) { - // float aaa = volume_length[v]/myMaxSteps; - // volumeStepSize[v] = volumeStepSizeOriginal[v]*vec3(aaa); - // } - // } - // float myMaxSteps = stepSize; - // for(int v = 0; v < MAX_VOLUMES; ++v) { - // if((currentVolumeBitmask & (1 << v)) > 0) { - // myMaxSteps = min(myMaxSteps, volumeStepSize[v]); - // } - // } - for(int v = 0; v < MAX_VOLUMES; ++v) { - if((currentVolumeBitmask & (1 << v)) > 0) { - // float aaa = myMaxSteps; - float l = volumeRaycastingDistance(v, startFrag, endFrag); + for(int v = 0; v < volume_count; ++v) { + int vol = volumes_in_fragment[v]; + float l = volumeRaycastingDistance(vol, startFrag, endFrag); float aaa = l/myMaxSteps; - // float aaa = volume_length[v]/myMaxSteps; - // volumeStepSize[v] = volumeStepSizeOriginal[v]*vec3(aaa); - // float aaa = volume_length[v]/volumeStepSizeOriginal[v]; - volumeStepSize[v] = aaa; - - // if(vlength >= volume_length[v]) { - // // vlength = volume_length[v]; - // const float S1 = volume_zlength[v].x; - // const float S2 = volume_zlength[v].y; - // const float L = S1 - S2; - // vlength = volume_length[v]; - // vlength = L; - // volID = v; - // } - // if(volID < 0) volID = v; - volID = v; + volumeStepSize[vol] = aaa; + volID = vol; } + } else { + volID = type -1; } - float l = volumeRaycastingDistance(volID, startFrag, endFrag); int max_iterations = int(l / volumeStepSize[volID]); // TransferFunction vec4 color = vec4(0); for(int k = 0; k < max_iterations && final_color.a < ALPHA_LIMIT && k < LOOP_LIMIT; ++k) { - //while(p < l && iterations < LOOP_LIMIT) { #pragma openspace insert SAMPLERCALLS - //final_color = blend(final_color, color*stepSize); - //volume_position[volID] += volume_direction[volID]*volumeStepSize[volID]; - //p+= stepSize; - //++iterations; } } @@ -324,7 +244,7 @@ vec4 calculate_final_color(uint frag_count) { // ================================================================================ // Transferfunction visualizer // ================================================================================ -#ifdef SHOWFUNC +#ifdef VISUALIZE_TRANSFERFUNCTIONS #pragma openspace insert TRANSFERFUNC #endif @@ -343,7 +263,7 @@ vec4 calculate_final_color(uint frag_count) { // final_color = vec4(1.0,1.0,1.0,1.0); // } -#ifdef COLORNORMALIZATION +#ifdef USE_COLORNORMALIZATION final_color.rgb = final_color.rgb * final_color.a; final_color.a = 1.0; #endif @@ -356,10 +276,10 @@ vec4 calculate_final_color(uint frag_count) { // Main function // ================================================================================ void main() { - color = vec4(texCoord,0.0,1.0); + out_color = vec4(texCoord,0.0,1.0); int frag_count = build_local_fragments_list(); sort_fragments_list(frag_count); - color = calculate_final_color(frag_count); + out_color = calculate_final_color(frag_count); } // ================================================================================ diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index 5d05460117..71acc355b7 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -107,6 +107,7 @@ void sort_fragments_list(uint frag_count) { #endif start = false; } else { + volumes_in_fragment[volume_count++] = ii; vec3 dir = _col_(fragments[jj]).rgb - startColor; volume_position[ii] = startColor; volume_length[ii] = length(dir); @@ -118,7 +119,7 @@ void sort_fragments_list(uint frag_count) { #elif ZTYPE == PSCDEPTH volume_zlength[ii] = pscLength(_pos_(fragments[jj]), startPosition); #endif -#ifdef JITTERING +#ifdef USE_JITTERING if(volumeStepSize[ii] < volume_length[ii]) { // jittering float x = gl_FragCoord.x; diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index 42a7367721..920a87b24d 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -313,8 +313,7 @@ std::string ABuffer::openspaceSamplerCalls() { auto found2 = _samplers.at(i).find_first_of("(",found1); if(found1 != std::string::npos && found2 != std::string::npos) { std::string functionName = _samplers.at(i).substr(found1, found2 - found1); - if(i == 0) - samplercalls += "#ifdef SAMPLEFIRSTVOLUME\n"; + samplercalls += "#ifndef SKIP_VOLUME_"+std::to_string(i)+"\n"; samplercalls += "if((currentVolumeBitmask & (1 << " + std::to_string(i) + ")) == "+std::to_string(1 << i)+") {\n"; samplercalls += " vec4 c = " + functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; // samplercalls += " if(c.a < 0.1) { \n"; @@ -325,7 +324,7 @@ std::string ABuffer::openspaceSamplerCalls() { // samplercalls += " volumeStepSize[" + std::to_string(i) + "] = volumeStepSizeOriginal[" + std::to_string(i) + "]; \n"; // samplercalls += " //c = " + functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; // samplercalls += " } \n"; - samplercalls += " if(c.a > EPSILON)\n"; + // samplercalls += " if(c.a > EPSILON)\n"; samplercalls += " blendStep(final_color, c, volumeStepSize[" + std::to_string(i) + "]);\n"; // samplercalls += " blendStep(final_color, c, stepSize);\n"; // samplercalls += " float aaa = volume_length[i]/myMaxSteps;\n"; @@ -334,8 +333,7 @@ std::string ABuffer::openspaceSamplerCalls() { // pos[v] += vec4(ray[v].xyz*vec3(aaa),aaa); // samplercalls += " volume_position[" + std::to_string(i) + "] += volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];\n"; samplercalls += "}\n"; - if(i == 0) - samplercalls += "#endif\n"; + samplercalls += "#endif\n"; } diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 45f78eeb71..c62f15f8f1 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -40,6 +40,8 @@ #include #include +#include + namespace { const std::string _loggerCat = "SceneGraphNode"; } @@ -79,21 +81,49 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di } if (dictionary.hasKey("RenderableToggle")) { - std::string val; + std::string val = ""; dictionary.getValue("RenderableToggle", val); - if(val.length() == 1) { - char c = std::toupper(val[0]); - int key = static_cast(c); + if(val.length() > 0) { auto func = [result]() { result->_renderableToggle = ! result->_renderableToggle; }; - LERROR("Found key:" << key); - OsEng.interactionHandler().addKeyCallback(key, func); - } + int key = SGCT_KEY_UNKNOWN; - // LERROR("Found key:" << val); - // LERROR("key 1:" << static_cast('1')); + if(val.length() == 1) { + char c = std::toupper(val[0]); + key = static_cast(c); + } else if (boost::iequals(val, "left")) { + key = SGCT_KEY_LEFT; + } else if (boost::iequals(val, "right")) { + key = SGCT_KEY_RIGHT; + } else if (boost::iequals(val, "up")) { + key = SGCT_KEY_UP; + } else if (boost::iequals(val, "down")) { + key = SGCT_KEY_DOWN; + } else if (boost::iequals(val, "space")) { + key = SGCT_KEY_SPACE; + } else if (boost::iequals(val, "enter")) { + key = SGCT_KEY_ENTER; + } else if (boost::iequals(val, "backspace")) { + key = SGCT_KEY_BACKSPACE; + } else if (boost::iequals(val, "del")) { + key = SGCT_KEY_DEL; + } else if (boost::iequals(val, "delete")) { + key = SGCT_KEY_DELETE; + } else { + // Loop through all F keys + for(int i = 0; i < 25; ++i) { + std::string stringKey = "F" + std::to_string(i+1); + if(boost::iequals(val, stringKey)) { + key = SGCT_KEY_F1 + i; + } + } + } + + if(key != SGCT_KEY_UNKNOWN) + OsEng.interactionHandler().addKeyCallback(key, func); + } } if (dictionary.hasKey(keyEphemeris)) { From 3006c304860c8896abfacb7dfa5d776923c09901 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Mon, 28 Jul 2014 15:53:14 -0400 Subject: [PATCH 047/113] Added video export mode --- config/sgct/single.xml | 9 +++++++-- include/openspace/engine/openspaceengine.h | 7 ++++++- src/engine/openspaceengine.cpp | 23 ++++++++++++++++++++++ src/rendering/renderengine.cpp | 6 ++++-- src/scenegraph/scenegraphnode.cpp | 2 ++ 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/config/sgct/single.xml b/config/sgct/single.xml index 3ec20dd5db..eec3b163c1 100644 --- a/config/sgct/single.xml +++ b/config/sgct/single.xml @@ -1,12 +1,17 @@ - + - + + + + + + diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 8e6d8da45b..dae55381ab 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -42,7 +42,9 @@ #define ABUFFER_SINGLE_LINKED 1 #define ABUFFER_FIXED 2 #define ABUFFER_DYNAMIC 3 -#define ABUFFER_IMPLEMENTATION ABUFFER_FIXED +#define ABUFFER_IMPLEMENTATION ABUFFER_SINGLE_LINKED + +// #define OPENSPACE_VIDEO_EXPORT namespace openspace { @@ -90,6 +92,9 @@ private: ghoul::Dictionary* _configurationManager; InteractionHandler* _interactionHandler; RenderEngine* _renderEngine; +#ifdef OPENSPACE_VIDEO_EXPORT + bool _doVideoExport; +#endif #ifdef FLARE_ONLY Flare* _flare; #endif diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 1ec31e84ce..952f20b03e 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -224,6 +224,8 @@ bool OpenSpaceEngine::initialize() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLFWwindow* win = sgct::Engine::instance()->getActiveWindowPtr()->getWindowHandle(); glfwSwapBuffers(win); + int samples = sqrt(sgct::Engine::instance()->getActiveWindowPtr()->getNumberOfAASamples()); + LDEBUG("samples: " << samples); int x1, xSize, y1, ySize; sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); @@ -298,6 +300,10 @@ bool OpenSpaceEngine::initialize() DeviceIdentifier::ref().scanDevices(); _engine->_interactionHandler->connectDevices(); +#ifdef OPENSPACE_VIDEO_EXPORT + LINFO("OpenSpace compiled with video export; press Print Screen to start/stop recording"); +#endif + return true; } @@ -378,6 +384,17 @@ void OpenSpaceEngine::postDraw() if (sgct::Engine::instance()->isMaster()) { _interactionHandler->unlockControls(); } +#ifdef OPENSPACE_VIDEO_EXPORT + float speed = 0.01; + glm::vec3 euler(0.0, speed, 0.0); + glm::quat rot = glm::quat(euler); + glm::vec3 euler2(0.0, -speed, 0.0); + glm::quat rot2 = glm::quat(euler2); + _interactionHandler->orbit(rot); + _interactionHandler->rotate(rot2); + if(_doVideoExport) + sgct::Engine::instance()->takeScreenshot(); +#endif #ifdef FLARE_ONLY _flare->postDraw(); #endif @@ -388,6 +405,12 @@ void OpenSpaceEngine::keyboardCallback(int key, int action) if (sgct::Engine::instance()->isMaster()) { _interactionHandler->keyboardCallback(key, action); } +#ifdef OPENSPACE_VIDEO_EXPORT + // LDEBUG("key: " << key); + // LDEBUG("SGCT_KEY_PRINT_SCREEN: " << SGCT_KEY_PRINT_SCREEN); + if(action == SGCT_PRESS && key == SGCT_KEY_PRINT_SCREEN) + _doVideoExport = !_doVideoExport; +#endif #ifdef FLARE_ONLY _flare->keyboard(key, action); #endif diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index a4aeee8566..349df7d373 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -186,7 +186,8 @@ void RenderEngine::render() _sceneGraph->render(_mainCamera); _abuffer->postRender(); _abuffer->resolve(); -/* + +#ifndef OPENSPACE_VIDEO_EXPORT // Print some useful information on the master viewport if (sgct::Engine::instance()->isMaster()) { // Apple usually has retina screens @@ -222,7 +223,8 @@ void RenderEngine::render() sgct_text::FontManager::instance()->getFont("SGCTFont", FONT_SIZE), FONT_SIZE, FONT_SIZE * 2, "Scaling: (%.10f, %.2f)", scaling[0], scaling[1]); } - */ +#endif + } SceneGraph* RenderEngine::sceneGraph() diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index c62f15f8f1..14a5d80be1 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -225,6 +225,7 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) _boundingSphereVisible = false; _renderableVisible = false; +#ifndef OPENSPACE_VIDEO_EXPORT // check if camera is outside the node boundingsphere if (toCamera.length() > _boundingSphere) { // check if the boudningsphere is visible before avaluating children @@ -235,6 +236,7 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) return; } } +#endif // inside boudningsphere or parts of the sphere is visible, individual // children needs to be evaluated From 98677d99a7a7015d40a080754927ae754bb1bb66 Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Tue, 29 Jul 2014 09:20:58 -0400 Subject: [PATCH 048/113] Added presentation scene --- openspace-data | 2 +- openspace.cfg | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/openspace-data b/openspace-data index 2642f7b929..97facd7529 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 2642f7b929d2fb6573f81ecec5d2823ef5506092 +Subproject commit 97facd7529857a70a49b3b34d47df2b9d4311ba8 diff --git a/openspace.cfg b/openspace.cfg index 4becaf05a8..bd8e9588fa 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -6,7 +6,8 @@ return { SHADERS = "${BASE_PATH}/shaders", OPENSPACE_DATA = "${BASE_PATH}/openspace-data", TESTDIR = "${BASE_PATH}/src/tests", - SCENEPATH = "${OPENSPACE_DATA}/scene", + -- SCENEPATH = "${OPENSPACE_DATA}/scene", + SCENEPATH = "${OPENSPACE_DATA}/ABufferVolumes", CONFIG = "${BASE_PATH}/config" }, SGCTConfig = "${SGCT}/single.xml", From 033880080f4fd0958cf6f53e577e754d0ee01218 Mon Sep 17 00:00:00 2001 From: Hans-Christian Helltegen Date: Tue, 29 Jul 2014 09:39:08 -0400 Subject: [PATCH 049/113] Added Ashers seedpoints --- openspace-data | 2 +- src/rendering/renderablefieldlines.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openspace-data b/openspace-data index 2642f7b929..6548d06674 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 2642f7b929d2fb6573f81ecec5d2823ef5506092 +Subproject commit 6548d06674595fea03588d82d84ba606f4d132f0 diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index 8f9d68bca7..c750ddcd9a 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -217,9 +217,9 @@ void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) glBindVertexArray(_VAO); glMultiDrawArrays(GL_LINE_STRIP, &_lineStart[0], &_lineCount[0], _lineStart.size()); - // ------ SEEDPOINTS ----------------- - glBindVertexArray(_seedpointVAO); - glMultiDrawArrays(GL_POINTS, &_lineStart[0], &_lineCount[0], _seedPoints.size()); +// // ------ SEEDPOINTS ----------------- +// glBindVertexArray(_seedpointVAO); +// glMultiDrawArrays(GL_POINTS, &_lineStart[0], &_lineCount[0], _seedPoints.size()); glBindVertexArray(0); // Deactivate shader From 61f2f51cb056bf2296610244c4b38d0b6220fe42 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 19 Aug 2014 12:14:34 +0200 Subject: [PATCH 050/113] Compile fixes of SpiceManager for Mac --- CMakeLists.txt | 4 +++- ext/ghoul | 2 +- include/openspace/interface/interface.h | 2 +- include/openspace/util/spicemanager.h | 31 ++++++++++++++++++------- openspace-data | 2 +- src/flare/CLProgram.cpp | 26 ++++++++++----------- src/flare/flare.cpp | 4 ++-- src/interface/interface.cpp | 2 +- src/util/spicemanager.cpp | 1 - 9 files changed, 44 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e2ce9a511..3bb7d3ed56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,9 @@ cmake_minimum_required (VERSION 2.8) project (OpenSpace) -SET(CMAKE_EXE_LINKER_FLAGS /NODEFAULTLIB:\"LIBCMTD.lib\") +if (WIN32) + SET(CMAKE_EXE_LINKER_FLAGS /NODEFAULTLIB:\"LIBCMTD.lib\") +endif () set(OPENSPACE_BASE_DIR "${PROJECT_SOURCE_DIR}") set(OPENSPACE_EXT_DIR "${OPENSPACE_BASE_DIR}/ext") diff --git a/ext/ghoul b/ext/ghoul index 56bec558ea..c673a62b41 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 56bec558ea276fad9cd784aff046e9fedbf691cd +Subproject commit c673a62b417a24feb61039df08d1406fc99fac7e diff --git a/include/openspace/interface/interface.h b/include/openspace/interface/interface.h index dcdfcb8fda..3d82632246 100644 --- a/include/openspace/interface/interface.h +++ b/include/openspace/interface/interface.h @@ -66,7 +66,7 @@ private: void handleNodes(); void loadIntoNodes(const boost::property_tree::ptree& tree, std::string parent = "", const int depth = 0); - OpenSpaceEngine* _engine; + // OpenSpaceEngine* _engine; std::vector _nodes; }; diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 7490e008c8..328021bb3c 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -92,19 +92,19 @@ public: * \param kernelPoolValueName Item for which values are desired. ("RADII", "NUT_PREC_ANGLES", etc. ) * \return Whether the function succeeded or not */ - bool SpiceManager::getValueFromID(const std::string& bodyname, + bool getValueFromID(const std::string& bodyname, const std::string& kernelPoolValueName, double& value) const; /* Overloaded method for 3dim vectors, see above specification.*/ - bool SpiceManager::getValueFromID(const std::string& bodyname, + bool getValueFromID(const std::string& bodyname, const std::string& kernelPoolValueName, glm::dvec3& value) const; /* Overloaded method for 4dim vectors, see above specification.*/ - bool SpiceManager::getValueFromID(const std::string& bodyname, + bool getValueFromID(const std::string& bodyname, const std::string& kernelPoolValueName, glm::dvec4& value) const; /* Overloaded method for Ndim vectors, see above specification.*/ - bool SpiceManager::getValueFromID(const std::string& bodyname, + bool getValueFromID(const std::string& bodyname, const std::string& kernelPoolValueName, std::vector& values, unsigned int num) const; @@ -337,7 +337,7 @@ private: struct spiceKernel { std::string path; std::string name; - int id; + unsigned int id; }; std::vector _loadedKernels; unsigned int _kernelCount = 0; @@ -382,6 +382,21 @@ public: data = new double[N*N]; empty = true; } + + void transform(glm::dvec3& position) { + assert(!empty); // transformation matrix is empty + + double *state; + double *state_t; + state = new double[N]; + state_t = new double[N]; + + COPY(state, &position); + mxvg_c(data, state, N, N, state_t); + + COPY(&position, state_t); + } + /** As the spice function mxvg_c requires a 6dim vector * the two 3dim state vectors are packed into 'state'. * Transformed values are then copied back from state_t @@ -394,8 +409,8 @@ public: * the method ignores its second argument. */ void transform(glm::dvec3& position, - glm::dvec3& velocity = glm::dvec3()){ - assert(("transformation matrix is empty", !empty)); + glm::dvec3& velocity) { + assert(!empty); // transformation matrix is empty double *state; double *state_t; @@ -414,7 +429,7 @@ public: * asserts matrix has been filled */ inline double operator()(int i, int j) const{ - assert(("transformation matrix is empty", !empty)); + assert(!empty); // transformation matrix is empty return data[j + i*N]; } }; diff --git a/openspace-data b/openspace-data index 42865a2858..6548d06674 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 42865a28580b0195ef7b82b175df8ef9f73f46bc +Subproject commit 6548d06674595fea03588d82d84ba606f4d132f0 diff --git a/src/flare/CLProgram.cpp b/src/flare/CLProgram.cpp index 1012c0dd9a..3e0d102798 100644 --- a/src/flare/CLProgram.cpp +++ b/src/flare/CLProgram.cpp @@ -2,6 +2,7 @@ * Author: Victor Sand (victor.sand@gmail.com) * */ + //#include #include #include @@ -248,14 +249,13 @@ bool CLProgram::ReleaseBuffer(unsigned int _argNr) { bool CLProgram::PrepareProgram() { //ghoulFinishGL(); -/* -#ifdef __APPLE__ +//#ifdef __APPLE__ //glFlushRenderAPPLE(); - glFinish(); + // glFinish(); //glFlush(); -#else -*/ + //#else + glFinish(); // Let OpenCL take control of the shared GL textures @@ -341,15 +341,13 @@ bool CLProgram::FinishProgram() { LERROR("Failed to finish program"); return false; } - /* -#else - error_ = clFinish(clManager_->commandQueues_[CLManager::EXECUTE]); - if (!clManager_->CheckSuccess(error_, "FinishProgram, clFinish")) { - ERROR("Failed to finish program"); - return false; - } -#endif -*/ + //#else + //error_ = clFinish(clManager_->commandQueues_[CLManager::EXECUTE]); + //if (!clManager_->CheckSuccess(error_, "FinishProgram, clFinish")) { + // ERROR("Failed to finish program"); + // return false; + //} + //#endif return true; } diff --git a/src/flare/flare.cpp b/src/flare/flare.cpp index 55243e0c2f..da196970cc 100644 --- a/src/flare/flare.cpp +++ b/src/flare/flare.cpp @@ -27,13 +27,13 @@ using namespace osp; Flare::Flare() : Renderable(ghoul::Dictionary()) + , _oldTime(0.f) + , _currentTime(0.f) , _leftMouseButton(false) , _currentMouseX(0) , _currentMouseY(0) , _lastMouseX(0) , _lastMouseY(0) - , _oldTime(0.f) - , _currentTime(0.f) { setBoundingSphere(PowerScaledScalar::CreatePSS(sqrt(3.0f))); } diff --git a/src/interface/interface.cpp b/src/interface/interface.cpp index f2e44d1509..f7082931db 100644 --- a/src/interface/interface.cpp +++ b/src/interface/interface.cpp @@ -33,7 +33,7 @@ */ namespace openspace { -Interface::Interface(OpenSpaceEngine* engine) : _engine(engine) {} +Interface::Interface(OpenSpaceEngine* ) {} Interface::~Interface() {} void Interface::callback(const char* receivedChars) { diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 18302d4002..dd6db4ad75 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -281,7 +281,6 @@ bool SpiceManager::getFieldOfView(const std::string& naifInstrumentId, double boresightVector[], std::vector& bounds, int& nrReturned) const{ - int n; int found; int naifId; int maxVectors = 12; From 3a0d15c9330e7cfa9eb7d6a24d986631139b99dc Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 20 Aug 2014 15:57:50 +0200 Subject: [PATCH 051/113] Make use of CommandlineParser to parse configuration file for OpenSpaceEngine; make error handing of SPICE code more reliable --- include/openspace/engine/openspaceengine.h | 16 ++- src/engine/openspaceengine.cpp | 134 +++++++++++++++------ src/main.cpp | 4 +- src/util/spicemanager.cpp | 28 ++++- 4 files changed, 133 insertions(+), 49 deletions(-) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 66fdd720f3..0de70e6479 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -38,13 +38,20 @@ #include +namespace ghoul { + namespace cmdparser { + class CommandlineCommand; + class CommandlineParser; + } +} + namespace openspace { class ScriptEngine; class OpenSpaceEngine { public: - static void create(int argc, char** argv, std::vector& sgctArguments); + static bool create(int argc, char** argv, std::vector& sgctArguments); static void destroy(); static OpenSpaceEngine& ref(); @@ -75,14 +82,17 @@ public: void decode(); private: - OpenSpaceEngine(); + OpenSpaceEngine(std::string programName); ~OpenSpaceEngine(); - + + bool gatherCommandlineArguments(); + static OpenSpaceEngine* _engine; ghoul::Dictionary* _configurationManager; InteractionHandler* _interactionHandler; RenderEngine* _renderEngine; + ghoul::cmdparser::CommandlineParser* _commandlineParser; #ifdef FLARE_ONLY Flare* _flare; #endif diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index e51191af36..383d8877d5 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -43,7 +43,7 @@ #include #include #include -#include +#include using namespace ghoul::filesystem; using namespace ghoul::logging; @@ -53,17 +53,25 @@ namespace { const std::string _configurationFile = "openspace.cfg"; const std::string _basePathToken = "${BASE_PATH}"; const std::string _sgctDefaultConfigFile = "${SGCT}/single.xml"; + + const std::string _sgctConfigArgumentCommand = "-config"; + + struct { + std::string configurationName; + } commandlineArgumentPlaceholders; } +using namespace ghoul::cmdparser; + namespace openspace { OpenSpaceEngine* OpenSpaceEngine::_engine = nullptr; -OpenSpaceEngine::OpenSpaceEngine() - : _configurationManager(nullptr) - , _interactionHandler(nullptr) - , _renderEngine(nullptr) -//, _scriptEngine(nullptr) +OpenSpaceEngine::OpenSpaceEngine(std::string programName) + : _configurationManager(new ghoul::Dictionary) + , _interactionHandler(new InteractionHandler) + , _renderEngine(new RenderEngine) + , _commandlineParser(new CommandlineParser(programName, true)) { } @@ -72,13 +80,12 @@ OpenSpaceEngine::~OpenSpaceEngine() delete _configurationManager; delete _interactionHandler; delete _renderEngine; - - // TODO deallocate script engine when starting to use it - // delete _scriptEngine; + delete _commandlineParser; Spice::deinit(); Time::deinit(); DeviceIdentifier::deinit(); + FileSystem::deinitialize(); LogManager::deinitialize(); } @@ -87,6 +94,16 @@ OpenSpaceEngine& OpenSpaceEngine::ref() assert(_engine); return *_engine; } + +bool OpenSpaceEngine::gatherCommandlineArguments() +{ + // TODO: Get commandline arguments from all modules + + CommandlineCommand* configurationFileCommand = new SingleCommand(&commandlineArgumentPlaceholders.configurationName, "-config", "-c", "Provides the path to the OpenSpace configuration file"); + _commandlineParser->addCommand(configurationFileCommand); + + return true; +} void OpenSpaceEngine::registerPathsFromDictionary(const ghoul::Dictionary& dictionary) { @@ -97,10 +114,12 @@ void OpenSpaceEngine::registerPathsFromDictionary(const ghoul::Dictionary& dicti const std::string fullKey = ghoul::filesystem::FileSystem::TokenOpeningBraces + key + ghoul::filesystem::FileSystem::TokenClosingBraces; - LDEBUG(fullKey << ": " << p); + LDEBUG("Registering path " << fullKey << ": " << p); bool override = (_basePathToken == fullKey); + if (override) + LINFO("Overriding base path with '" << p << "'"); FileSys.registerPathToken(fullKey, p, override); } } @@ -155,61 +174,98 @@ bool OpenSpaceEngine::findConfiguration(std::string& filename) } } -void OpenSpaceEngine::create(int argc, char** argv, +bool OpenSpaceEngine::create(int argc, char** argv, std::vector& sgctArguments) { // TODO custom assert (ticket #5) assert(_engine == nullptr); - // initialize ghoul logging + // initialize Ghoul logging LogManager::initialize(LogManager::LogLevel::Debug, true); LogMgr.addLog(new ConsoleLog); - // TODO change so initialize is not called in the create function + + // Initialize FileSystem ghoul::filesystem::FileSystem::initialize(); - - // TODO parse arguments if filename is specified, if not use default - std::string configurationFilePath = ""; - - LDEBUG("Finding configuration"); - if (!OpenSpaceEngine::findConfiguration(configurationFilePath)) { - LFATAL("Could not find OpenSpace configuration file!"); - assert(false); + + + // Sanity check of values + if (argc < 1) { + LFATAL("No arguments were passed to the function"); + return false; } + + // create other objects + LDEBUG("Creating OpenSpaceEngine"); + _engine = new OpenSpaceEngine(std::string(argv[0])); + + + // Query modules for commandline arguments + const bool gatherSuccess = _engine->gatherCommandlineArguments(); + if (!gatherSuccess) + return false; + - LINFO(FileSys.absolutePath(configurationFilePath)); - - // create objects - _engine = new OpenSpaceEngine; - _engine->_renderEngine = new RenderEngine; - _engine->_interactionHandler = new InteractionHandler; - _engine->_configurationManager = new ghoul::Dictionary; + // Parse commandline arguments + std::vector remainingArguments; + _engine->_commandlineParser->setCommandLine(argc, argv, &sgctArguments); + const bool executeSuccess = _engine->_commandlineParser->execute(); + if (!executeSuccess) + return false; + + + // Find configuration + std::string configurationFilePath = commandlineArgumentPlaceholders.configurationName; + if (configurationFilePath.empty()) { + LDEBUG("Finding configuration"); + const bool findConfigurationSuccess = OpenSpaceEngine::findConfiguration(configurationFilePath); + if (!findConfigurationSuccess) { + LFATAL("Could not find OpenSpace configuration file!"); + return false; + } + } + LINFO("Configuration Path: '" << FileSys.absolutePath(configurationFilePath) << "'"); + // Registering base path LDEBUG("Registering base path"); if (!OpenSpaceEngine::registerBasePathFromConfigurationFile(configurationFilePath)) { LFATAL("Could not register base path"); - assert(false); + return false; } - ghoul::Dictionary& configuration = *(_engine->_configurationManager); + + // Loading configuration from disk + LDEBUG("Loading configuration from disk"); + ghoul::Dictionary& configuration = _engine->configurationManager(); ghoul::lua::loadDictionaryFromFile(configurationFilePath, configuration); - if (configuration.hasKey(constants::openspaceengine::keyPaths)) { + const bool hasKey = configuration.hasKey(constants::openspaceengine::keyPaths); + const bool hasValue = configuration.hasValue(constants::openspaceengine::keyPaths); + if (hasKey && hasValue) { ghoul::Dictionary pathsDictionary; - if (configuration.getValue(constants::openspaceengine::keyPaths, pathsDictionary)) - OpenSpaceEngine::registerPathsFromDictionary(pathsDictionary); + configuration.getValue(constants::openspaceengine::keyPaths, pathsDictionary); + OpenSpaceEngine::registerPathsFromDictionary(pathsDictionary); + } + else { + LFATAL("Configuration file does not contain paths token '" << constants::openspaceengine::keyPaths << "'"); + return false; } + + // Determining SGCT configuration file + LDEBUG("Determining SGCT configuration file"); std::string sgctConfigurationPath = _sgctDefaultConfigFile; if (configuration.hasKey(constants::openspaceengine::keyConfigSgct)) configuration.getValue(constants::openspaceengine::keyConfigSgct, sgctConfigurationPath); - sgctArguments.push_back(argv[0]); - sgctArguments.push_back("-config"); - sgctArguments.push_back(absPath(sgctConfigurationPath)); - - for (int i = 1; i < argc; ++i) - sgctArguments.push_back(argv[i]); + + // Prepend the outgoing sgctArguments with the program name + // as well as the configuration file that sgct is supposed to use + sgctArguments.insert(sgctArguments.begin(), argv[0]); + sgctArguments.insert(sgctArguments.begin() + 1, _sgctConfigArgumentCommand); + sgctArguments.insert(sgctArguments.begin() + 2, absPath(sgctConfigurationPath)); + + return true; } void OpenSpaceEngine::destroy() diff --git a/src/main.cpp b/src/main.cpp index cf97ebe9ff..d2e0bd86f1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,7 +51,9 @@ int main(int argc, char** argv) { // create the OpenSpace engine and get arguments for the sgct engine std::vector sgctArguments; - openspace::OpenSpaceEngine::create(argc, argv, sgctArguments); + const bool success = openspace::OpenSpaceEngine::create(argc, argv, sgctArguments); + if (!success) + return EXIT_FAILURE; // create sgct engine c arguments int newArgc = static_cast(sgctArguments.size()); diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index dd6db4ad75..9ab3bb44ed 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -31,6 +31,7 @@ #include "openspace/util/spicemanager.h" #include "ghoul/filesystem/filesystem.h" +#include "ghoul/logging/logmanager.h" namespace { const std::string _loggerCat = "SpiceManager"; @@ -223,10 +224,18 @@ bool SpiceManager::getTargetPosition(const std::string& target, //method to put error out... spkpos_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), aberrationCorrection.c_str(), observer.c_str(), pos, &lightTime); - - if (pos[0] == NULL || pos[1] == NULL || pos[2] == NULL) - return false; + + int failed = failed_c(); + if(failed) { + char msg[1024]; + getmsg_c ( "LONG", 1024, msg ); + LERROR("Error retrieving position of target '" + target + "'"); + LERROR("Spice reported: " + std::string(msg)); + reset_c(); + return false; + } + memcpy(&targetPosition, pos, sizeof(double)* 3); return true; @@ -244,11 +253,18 @@ bool SpiceManager::getTargetState(const std::string& target, spkezr_c(target.c_str(), ephemerisTime, referenceFrame.c_str(), aberrationCorrection.c_str(), observer.c_str(), state, &lightTime); + + int failed = failed_c(); + if(failed) { + char msg[1024]; + getmsg_c ( "LONG", 1024, msg ); + LERROR("Error retrieving state of target '" + target + "'"); + LERROR("Spice reported: " + std::string(msg)); + reset_c(); + return false; + } for (int i = 0; i < 3; i++){ - if (state[i] == NULL || state[i + 3] == NULL){ - return false; - } memcpy(&targetPosition, state , sizeof(double)* 3); memcpy(&targetVelocity, state +3, sizeof(double)* 3); } From 26a7fbe47e7dc5fb823b7446263785131cc0d27a Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 20 Aug 2014 16:55:07 +0200 Subject: [PATCH 052/113] Code cleanup of Ephemeris classes and SceneGraph --- ext/ghoul | 2 +- include/openspace/scenegraph/ephemeris.h | 4 +- include/openspace/scenegraph/scenegraph.h | 6 +-- include/openspace/scenegraph/scenegraphnode.h | 8 ++-- include/openspace/scenegraph/spiceephemeris.h | 12 +++--- .../openspace/scenegraph/staticephemeris.h | 9 ++-- include/openspace/util/constants.h | 11 ++++- src/scenegraph/ephemeris.cpp | 8 ++++ src/scenegraph/scenegraph.cpp | 18 ++++---- src/scenegraph/scenegraphnode.cpp | 2 + src/scenegraph/spiceephemeris.cpp | 41 +++++++++++++------ src/scenegraph/staticephemeris.cpp | 30 ++++++-------- 12 files changed, 89 insertions(+), 62 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index c673a62b41..8a78a05ffd 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit c673a62b417a24feb61039df08d1406fc99fac7e +Subproject commit 8a78a05ffd85a046d276d55e2328cb495c98a398 diff --git a/include/openspace/scenegraph/ephemeris.h b/include/openspace/scenegraph/ephemeris.h index c73b14e692..b8e13e8b8d 100644 --- a/include/openspace/scenegraph/ephemeris.h +++ b/include/openspace/scenegraph/ephemeris.h @@ -36,9 +36,9 @@ public: Ephemeris(const ghoul::Dictionary& dictionary); virtual ~Ephemeris(); - virtual bool initialize() = 0; + virtual bool initialize(); virtual const psc& position() const = 0; - virtual void update() = 0; + virtual void update(); protected: Ephemeris(); diff --git a/include/openspace/scenegraph/scenegraph.h b/include/openspace/scenegraph/scenegraph.h index 56249fe426..6ccdc4feb7 100644 --- a/include/openspace/scenegraph/scenegraph.h +++ b/include/openspace/scenegraph/scenegraph.h @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef SCENEGRAPH_H -#define SCENEGRAPH_H +#ifndef __SCENEGRAPH_H__ +#define __SCENEGRAPH_H__ // std includes #include @@ -105,4 +105,4 @@ private: } // namespace openspace -#endif \ No newline at end of file +#endif // __SCENEGRAPH_H__ \ No newline at end of file diff --git a/include/openspace/scenegraph/scenegraphnode.h b/include/openspace/scenegraph/scenegraphnode.h index 2269d7d7cf..25bbd3e2c3 100644 --- a/include/openspace/scenegraph/scenegraphnode.h +++ b/include/openspace/scenegraph/scenegraphnode.h @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef SCENEGRAPHNODE_H -#define SCENEGRAPHNODE_H +#ifndef __SCENEGRAPHNODE_H__ +#define __SCENEGRAPHNODE_H__ // open space includes #include @@ -42,6 +42,8 @@ namespace openspace { class SceneGraphNode { public: + static std::string RootNodeName; + // constructors & destructor SceneGraphNode(); ~SceneGraphNode(); @@ -100,4 +102,4 @@ private: } // namespace openspace -#endif +#endif // __SCENEGRAPHNODE_H__ diff --git a/include/openspace/scenegraph/spiceephemeris.h b/include/openspace/scenegraph/spiceephemeris.h index 70c404e10c..3229b09428 100644 --- a/include/openspace/scenegraph/spiceephemeris.h +++ b/include/openspace/scenegraph/spiceephemeris.h @@ -31,20 +31,20 @@ namespace openspace { -class SpiceEphemeris: public Ephemeris { +class SpiceEphemeris : public Ephemeris { public: SpiceEphemeris(const ghoul::Dictionary& dictionary); virtual ~SpiceEphemeris(); virtual bool initialize(); virtual const psc& position() const; virtual void update(); -protected: -private: - std::string _targetName, _originName; - int _target, _origin; +private: + std::string _targetName; + std::string _originName; + int _target; + int _origin; psc _position; - }; } // namespace openspace diff --git a/include/openspace/scenegraph/staticephemeris.h b/include/openspace/scenegraph/staticephemeris.h index e5d8001db8..71b5d02a5b 100644 --- a/include/openspace/scenegraph/staticephemeris.h +++ b/include/openspace/scenegraph/staticephemeris.h @@ -33,14 +33,11 @@ class StaticEphemeris: public Ephemeris { public: StaticEphemeris(const ghoul::Dictionary& dictionary = ghoul::Dictionary()); - virtual ~StaticEphemeris(); - virtual bool initialize(); - virtual const psc& position() const; - virtual void update(); -protected: + ~StaticEphemeris(); + const psc& position() const; + private: psc _position; - }; } // namespace openspace diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index 5327fb8357..6c004dbda2 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -63,12 +63,19 @@ namespace planetgeometry { const std::string keyType = "Type"; } // namespace planetgeometry - - namespace ephemeris { const std::string keyType = "Type"; } // namespace ephemeris +namespace staticephemeris { + const std::string keyPosition = "Position"; +} // namespace staticephemeris + +namespace spiceephemeris { + const std::string keyBody = "Body"; + const std::string keyOrigin = "Observer"; +} // namespace spiceephemeris + } // namespace constants } // namespace openspace diff --git a/src/scenegraph/ephemeris.cpp b/src/scenegraph/ephemeris.cpp index dc7e2a5833..ae2d5080d8 100644 --- a/src/scenegraph/ephemeris.cpp +++ b/src/scenegraph/ephemeris.cpp @@ -55,11 +55,19 @@ Ephemeris* Ephemeris::createFromDictionary(const ghoul::Dictionary& dictionary) Ephemeris::Ephemeris() { } + Ephemeris::Ephemeris(const ghoul::Dictionary& dictionary) { } + Ephemeris::~Ephemeris() { } + +bool Ephemeris::initialize() { + return true; +} + +void Ephemeris::update() {} } // namespace openspace \ No newline at end of file diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 17a55e4158..1e5276ccbb 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -47,10 +47,8 @@ #include namespace { -const std::string _loggerCat = "SceneGraph"; -const std::string _rootNodeName = "Root"; -const std::string _moduleExtension = ".mod"; - + const std::string _loggerCat = "SceneGraph"; + const std::string _moduleExtension = ".mod"; } namespace openspace { @@ -64,8 +62,8 @@ void printTree(SceneGraphNode* node, std::string pre = "") } SceneGraph::SceneGraph() - : _focus("Root") - , _position("Root") + : _focus(SceneGraphNode::RootNodeName) + , _position(SceneGraphNode::RootNodeName) , _root(nullptr) { } @@ -206,8 +204,8 @@ bool SceneGraph::deinitialize() _nodes.erase(_nodes.begin(), _nodes.end()); _allNodes.erase(_allNodes.begin(), _allNodes.end()); - _focus = ""; - _position = ""; + _focus.clear(); + _position.clear(); return true; } @@ -243,9 +241,9 @@ bool SceneGraph::loadScene(const std::string& sceneDescriptionFilePath, // initialize the root node _root = new SceneGraphNode(); - _root->setName(_rootNodeName); + _root->setName(SceneGraphNode::RootNodeName); _nodes.push_back(_root); - _allNodes.emplace(_rootNodeName, _root); + _allNodes.emplace(SceneGraphNode::RootNodeName, _root); Dictionary dictionary; loadDictionaryFromFile(sceneDescriptionFilePath, dictionary); diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index b0b3e752df..b6488bd38e 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -45,6 +45,8 @@ const std::string _loggerCat = "SceneGraphNode"; } namespace openspace { + +std::string SceneGraphNode::RootNodeName = "Root"; SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& dictionary) { diff --git a/src/scenegraph/spiceephemeris.cpp b/src/scenegraph/spiceephemeris.cpp index 69dc501e17..482a60d61e 100644 --- a/src/scenegraph/spiceephemeris.cpp +++ b/src/scenegraph/spiceephemeris.cpp @@ -24,32 +24,49 @@ #include +#include #include +namespace { + const std::string _loggerCat = "SpiceEphemeris"; +} + namespace openspace { -SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary): _targetName(""), - _originName(""), - _target(0), - _origin(0), - _position() +using namespace constants::spiceephemeris; + +SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary) + : _targetName("") + , _originName("") + , _target(0) + , _origin(0) + , _position() { - dictionary.getValue("Body", _targetName); - dictionary.getValue("Observer", _originName); + const bool hasBody = dictionary.hasKeyAndValue(keyBody); + if (hasBody) + dictionary.getValue(keyBody, _targetName); + else + LERROR("SpiceEphemeris does not contain the key '" << keyBody << "'"); + + const bool hasObserver = dictionary.hasKeyAndValue(keyOrigin); + if (hasObserver) + dictionary.getValue(keyOrigin, _originName); + else + LERROR("SpiceEphemeris does not contain the key '" << keyOrigin << "'"); } + SpiceEphemeris::~SpiceEphemeris() {} -bool SpiceEphemeris::initialize() { - - if (_targetName != "" && _originName != "") { +bool SpiceEphemeris::initialize() +{ + if (!_targetName.empty() && !_originName.empty()) { int bsuccess = 0; int osuccess = 0; Spice::ref().bod_NameToInt(_targetName, &_target, &bsuccess); Spice::ref().bod_NameToInt(_originName, &_origin, &osuccess); - if (bsuccess && osuccess) { + if (bsuccess && osuccess) return true; - } } return false; diff --git a/src/scenegraph/staticephemeris.cpp b/src/scenegraph/staticephemeris.cpp index f87e737c0e..fc1cc8ea18 100644 --- a/src/scenegraph/staticephemeris.cpp +++ b/src/scenegraph/staticephemeris.cpp @@ -24,31 +24,27 @@ #include +#include + namespace openspace { -StaticEphemeris::StaticEphemeris(const ghoul::Dictionary& dictionary) { - double x = 0.0, y = 0.0, z = 0.0, e = 0.0; - if (dictionary.hasKey("Position.1")) { - dictionary.getValue("Position.1", x); - dictionary.getValue("Position.2", y); - dictionary.getValue("Position.3", z); - dictionary.getValue("Position.4", e); +using namespace constants::staticephemeris; + +StaticEphemeris::StaticEphemeris(const ghoul::Dictionary& dictionary) + : _position(0.f, 0.f, 0.f, 0.f) +{ + const bool hasPosition = dictionary.hasKeyAndValue(keyPosition); + if (hasPosition) { + glm::vec4 tmp; + dictionary.getValue(keyPosition, tmp); + _position = tmp; } - _position = psc(x, y, z, e); } StaticEphemeris::~StaticEphemeris() {} -bool StaticEphemeris::initialize() { - return true; -} - -const psc& StaticEphemeris::position() const { +const psc& StaticEphemeris::position() const { return _position; } -void StaticEphemeris::update() { - -} - } // namespace openspace \ No newline at end of file From 5793498ddf743179c15ba6ba9d3567b1869ef9fc Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 21 Aug 2014 18:44:42 +0200 Subject: [PATCH 053/113] Added first version of ScriptEngine, allowing Lua script to set propety values --- ext/ghoul | 2 +- include/openspace/engine/openspaceengine.h | 6 +- include/openspace/query/query.h | 10 +- include/openspace/scenegraph/scenegraph.h | 2 + include/openspace/scenegraph/scenegraphnode.h | 9 +- include/openspace/scripting/scriptengine.h | 56 ++++++ include/openspace/scripting/scriptfunctions.h | 36 ++++ src/CMakeLists.txt | 6 + src/engine/openspaceengine.cpp | 26 ++- src/interaction/interactionhandler.cpp | 8 +- src/query/query.cpp | 23 ++- src/scenegraph/scenegraph.cpp | 33 +++- src/scenegraph/scenegraphnode.cpp | 16 +- src/scripting/scriptengine.cpp | 177 ++++++++++++++++++ src/scripting/scriptfunctions.cpp | 83 ++++++++ 15 files changed, 458 insertions(+), 35 deletions(-) create mode 100644 include/openspace/scripting/scriptengine.h create mode 100644 include/openspace/scripting/scriptfunctions.h create mode 100644 src/scripting/scriptengine.cpp create mode 100644 src/scripting/scriptfunctions.cpp diff --git a/ext/ghoul b/ext/ghoul index 8a78a05ffd..17608b8800 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 8a78a05ffd85a046d276d55e2328cb495c98a398 +Subproject commit 17608b8800d412f99b6eef8e9dcc4741c5a1f38c diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 0de70e6479..3026d19d79 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -47,8 +48,6 @@ namespace ghoul { namespace openspace { -class ScriptEngine; - class OpenSpaceEngine { public: static bool create(int argc, char** argv, std::vector& sgctArguments); @@ -66,6 +65,7 @@ public: ghoul::opencl::CLContext& clContext(); InteractionHandler& interactionHandler(); RenderEngine& renderEngine(); + ScriptEngine& scriptEngine(); // SGCT callbacks bool initializeGL(); @@ -92,11 +92,11 @@ private: ghoul::Dictionary* _configurationManager; InteractionHandler* _interactionHandler; RenderEngine* _renderEngine; + ScriptEngine* _scriptEngine; ghoul::cmdparser::CommandlineParser* _commandlineParser; #ifdef FLARE_ONLY Flare* _flare; #endif - // ScriptEngine* _scriptEngine; ghoul::opencl::CLContext _context; sgct::SharedVector _synchronizationBuffer; diff --git a/include/openspace/query/query.h b/include/openspace/query/query.h index 3d2bbd1249..f985a31b7d 100644 --- a/include/openspace/query/query.h +++ b/include/openspace/query/query.h @@ -29,12 +29,16 @@ namespace openspace { +namespace properties { + class Property; +} class SceneGraph; class SceneGraphNode; -SceneGraph* getSceneGraph(); - -SceneGraphNode* getSceneGraphNode(const std::string& name); +SceneGraph* sceneGraph(); +SceneGraphNode* sceneGraphNode(const std::string& name); +properties::Property* property(const std::string& uri); +properties::Property* property(const std::string& nodeName, const std::string& propertyName); } // namespace diff --git a/include/openspace/scenegraph/scenegraph.h b/include/openspace/scenegraph/scenegraph.h index 6ccdc4feb7..b41cd79532 100644 --- a/include/openspace/scenegraph/scenegraph.h +++ b/include/openspace/scenegraph/scenegraph.h @@ -95,6 +95,8 @@ public: SceneGraphNode* sceneGraphNode(const std::string& name) const; private: + bool registerScriptFunctions(); + std::string _focus, _position; // actual scenegraph diff --git a/include/openspace/scenegraph/scenegraphnode.h b/include/openspace/scenegraph/scenegraphnode.h index 25bbd3e2c3..775e844a05 100644 --- a/include/openspace/scenegraph/scenegraphnode.h +++ b/include/openspace/scenegraph/scenegraphnode.h @@ -63,8 +63,8 @@ public: void setName(const std::string& name); void setParent(SceneGraphNode* parent); - const psc& getPosition() const; - psc getWorldPosition() const; + const psc& position() const; + psc worldPosition() const; std::string nodeName() const; SceneGraphNode* parent() const; @@ -73,13 +73,14 @@ public: // bounding sphere PowerScaledScalar calculateBoundingSphere(); - SceneGraphNode* get(const std::string& name); + SceneGraphNode* childNode(const std::string& name); void print() const; // renderable void setRenderable(Renderable* renderable); - const Renderable* getRenderable() const; + const Renderable* renderable() const; + Renderable* renderable(); private: // essential diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h new file mode 100644 index 0000000000..81b9f77c05 --- /dev/null +++ b/include/openspace/scripting/scriptengine.h @@ -0,0 +1,56 @@ +/***************************************************************************************** + * * + * 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 __SCRIPTENGINE_H__ +#define __SCRIPTENGINE_H__ + +#include +#include + +class ScriptEngine { +public: + struct LuaLibrary { + std::string name; + std::vector> functions; + }; + + ScriptEngine(); + + bool initialize(); + void deinitialize(); + + bool addLibrary(const LuaLibrary& library); + bool hasLibrary(const std::string& name); + + bool runScript(std::string script); + +private: + bool isLibraryNameAllowed(const std::string& name); + void addLibraryFunctions(const LuaLibrary& library, bool replace); + + lua_State* _state; + std::set _registeredLibraries; +}; + +#endif // __SCRIPTENGINE_H__ diff --git a/include/openspace/scripting/scriptfunctions.h b/include/openspace/scripting/scriptfunctions.h new file mode 100644 index 0000000000..ae0bd4b9f7 --- /dev/null +++ b/include/openspace/scripting/scriptfunctions.h @@ -0,0 +1,36 @@ +/***************************************************************************************** + * * + * 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 __SCRIPTFUNCTIONS_H__ +#define __SCRIPTFUNCTIONS_H__ + +struct lua_State; + +// Properties + +static int property_setValue(lua_State* L); +static int property_getValue(lua_State* L); + + +#endif // __SCRIPTFUNCTIONS_H__ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 310b700bc5..58bb285bd1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -84,6 +84,12 @@ file(GLOB SCENEGRAPH_HEADER ${HEADER_ROOT_DIR}/openspace/scenegraph/*.h ${HEADER set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${SCENEGRAPH_HEADER}) source_group(SceneGraph FILES ${SCENEGRAPH_SOURCE} ${SCENEGRAPH_HEADER}) +file(GLOB SCRIPTING_SOURCE ${SOURCE_ROOT_DIR}/scripting/*.cpp) +set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${SCRIPTING_SOURCE}) +file(GLOB SCRIPTING_HEADER ${HEADER_ROOT_DIR}/openspace/scripting/*.h) +set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${SCRIPTING_HEADER}) +source_group(Scripting FILES ${SCRIPTING_SOURCE} ${SCRIPTING_HEADER}) + file(GLOB UTIL_SOURCE ${SOURCE_ROOT_DIR}/util/*.cpp) set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${UTIL_SOURCE}) file(GLOB UTIL_HEADER ${HEADER_ROOT_DIR}/openspace/util/*.h) diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 383d8877d5..209917c5ea 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -71,6 +71,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) : _configurationManager(new ghoul::Dictionary) , _interactionHandler(new InteractionHandler) , _renderEngine(new RenderEngine) + , _scriptEngine(new ScriptEngine) , _commandlineParser(new CommandlineParser(programName, true)) { } @@ -78,9 +79,15 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName) OpenSpaceEngine::~OpenSpaceEngine() { delete _configurationManager; + _configurationManager = nullptr; delete _interactionHandler; + _interactionHandler = nullptr; delete _renderEngine; + _renderEngine = nullptr; + delete _scriptEngine; + _scriptEngine = nullptr; delete _commandlineParser; + _commandlineParser = nullptr; Spice::deinit(); Time::deinit(); @@ -308,6 +315,12 @@ bool OpenSpaceEngine::initialize() Spice::ref().loadDefaultKernels(); FactoryManager::initialize(); + scriptEngine().initialize(); + scriptEngine().addLibrary(ScriptEngine::LuaLibrary()); + + _engine->scriptEngine().runScript("return mylib.mysin(4)"); + + // Load scenegraph SceneGraph* sceneGraph = new SceneGraph; _renderEngine->setSceneGraph(sceneGraph); @@ -355,7 +368,7 @@ bool OpenSpaceEngine::initialize() ghoul::Dictionary& OpenSpaceEngine::configurationManager() { // TODO custom assert (ticket #5) - assert(_configurationManager != nullptr); + assert(_configurationManager); return *_configurationManager; } @@ -367,17 +380,24 @@ ghoul::opencl::CLContext& OpenSpaceEngine::clContext() InteractionHandler& OpenSpaceEngine::interactionHandler() { // TODO custom assert (ticket #5) - assert(_configurationManager != nullptr); + assert(_interactionHandler); return *_interactionHandler; } RenderEngine& OpenSpaceEngine::renderEngine() { // TODO custom assert (ticket #5) - assert(_configurationManager != nullptr); + assert(_renderEngine); return *_renderEngine; } +ScriptEngine& OpenSpaceEngine::scriptEngine() +{ + // TODO custom assert (ticket #5) + assert(_scriptEngine); + return *_scriptEngine; +} + bool OpenSpaceEngine::initializeGL() { return _renderEngine->initializeGL(); diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index b9a18a634e..b14d945a7d 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -119,7 +119,7 @@ Camera * InteractionHandler::getCamera() const { const psc InteractionHandler::getOrigin() const { if(node_) - return node_->getWorldPosition(); + return node_->worldPosition(); return psc(); } @@ -155,7 +155,7 @@ void InteractionHandler::orbit(const glm::quat &rotation) { // should be changed to something more dynamic =) psc origin; if(node_) { - origin = node_->getWorldPosition(); + origin = node_->worldPosition(); } psc relative_origin_coordinate = relative - origin; @@ -175,7 +175,7 @@ void InteractionHandler::distance(const PowerScaledScalar &distance) { psc relative = camera_->position(); psc origin; if(node_) { - origin = node_->getWorldPosition(); + origin = node_->worldPosition(); } psc relative_origin_coordinate = relative - origin; @@ -246,7 +246,7 @@ glm::vec3 InteractionHandler::mapToCamera(glm::vec3 trackballPos) { //Get x,y,z axis vectors of current camera view glm::vec3 currentViewYaxis = glm::normalize(camera_->lookUpVector()); - psc viewDir = camera_->position() - node_->getWorldPosition(); + psc viewDir = camera_->position() - node_->worldPosition(); glm::vec3 currentViewZaxis = glm::normalize(viewDir.vec3()); glm::vec3 currentViewXaxis = glm::normalize(glm::cross(currentViewYaxis, currentViewZaxis)); diff --git a/src/query/query.cpp b/src/query/query.cpp index 5e814b0f9a..aabd8f3eb4 100644 --- a/src/query/query.cpp +++ b/src/query/query.cpp @@ -25,6 +25,7 @@ #include #include +#include namespace openspace { @@ -32,15 +33,29 @@ namespace { const std::string _loggerCat = "Query"; } -SceneGraph* getSceneGraph() +SceneGraph* sceneGraph() { return OsEng.renderEngine().sceneGraph(); } -SceneGraphNode* getSceneGraphNode(const std::string& name) +SceneGraphNode* sceneGraphNode(const std::string& name) { - SceneGraph* sceneGraph = getSceneGraph(); - return sceneGraph->sceneGraphNode(name); + const SceneGraph* graph = sceneGraph(); + return graph->sceneGraphNode(name); +} + +properties::Property* property(const std::string& uri) +{ + const size_t separator = uri.find('.'); + return property(uri.substr(0, separator), uri.substr(separator)); +} + +properties::Property* property(const std::string& nodeName, const std::string& propertyName) +{ + SceneGraphNode* node = sceneGraphNode(nodeName); + Renderable* propertyOwner = node->renderable(); + properties::Property* property = propertyOwner->property(propertyName);; + return property; } } // namespace diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 1e5276ccbb..d8d52d2fe6 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -24,10 +24,12 @@ // open space includes #include -#include -#include -#include #include +#include +#include +#include +#include +#include #include // ghoul includes @@ -76,7 +78,12 @@ SceneGraph::~SceneGraph() bool SceneGraph::initialize() { LDEBUG("Initializing SceneGraph"); - + + const bool scriptSuccess = registerScriptFunctions(); + if (!scriptSuccess) + return false; + + LDEBUG("Creating ProgramObjects"); using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; @@ -182,7 +189,7 @@ bool SceneGraph::initialize() glm::vec2 scaling{1.0f, -boundf[1]}; boundf[0] *= 5.0f; - psc cameraPosition = positionNode->getPosition(); + psc cameraPosition = positionNode->position(); cameraPosition += psc(glm::vec4(0.f, 0.f, boundf)); c->setPosition(cameraPosition); c->setCameraDirection(glm::vec3(0, 0, -1)); @@ -335,6 +342,22 @@ SceneGraphNode* SceneGraph::root() const { return _root; } + +bool SceneGraph::registerScriptFunctions() +{ + LDEBUG("Registering Script Functions"); + + + ScriptEngine::LuaLibrary l = { + "", + { + { "setPropertyValue", &property_setValue}, + { "getPropertyValue", &property_getValue}, + { NULL, NULL } + } + }; + return true; +} SceneGraphNode* SceneGraph::sceneGraphNode(const std::string& name) const { auto it = _allNodes.find(name); diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index b6488bd38e..54c7fb25ab 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -98,7 +98,7 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di parentName = "Root"; } - SceneGraphNode* parentNode = getSceneGraphNode(parentName); + SceneGraphNode* parentNode = sceneGraphNode(parentName); if (parentNode == nullptr) { LFATAL("Could not find parent named '" << parentName << "' for '" << result->_nodeName << "'." @@ -242,16 +242,16 @@ void SceneGraphNode::setParent(SceneGraphNode* parent) _parent = parent; } -const psc& SceneGraphNode::getPosition() const +const psc& SceneGraphNode::position() const { return _ephemeris->position(); } -psc SceneGraphNode::getWorldPosition() const +psc SceneGraphNode::worldPosition() const { // recursive up the hierarchy if there are parents available if (_parent) { - return _ephemeris->position() + _parent->getWorldPosition(); + return _ephemeris->position() + _parent->worldPosition(); } else { return _ephemeris->position(); } @@ -285,7 +285,7 @@ PowerScaledScalar SceneGraphNode::calculateBoundingSphere() for (size_t i = 0; i < _children.size(); ++i) { // when positions is dynamic, change this part to fins the most distant // position - PowerScaledScalar child = _children.at(i)->getPosition().length() + PowerScaledScalar child = _children.at(i)->position().length() + _children.at(i)->calculateBoundingSphere(); if (child > maxChild) { maxChild = child; @@ -309,7 +309,7 @@ void SceneGraphNode::setRenderable(Renderable* renderable) update(); } -const Renderable* SceneGraphNode::getRenderable() const +const Renderable* SceneGraphNode::renderable() const { return _renderable; } @@ -346,13 +346,13 @@ bool SceneGraphNode::sphereInsideFrustum(const psc s_pos, const PowerScaledScala } } -SceneGraphNode* SceneGraphNode::get(const std::string& name) +SceneGraphNode* SceneGraphNode::childNode(const std::string& name) { if (_nodeName == name) return this; else for (auto it : _children) { - SceneGraphNode* tmp = it->get(name); + SceneGraphNode* tmp = it->childNode(name); if (tmp != nullptr) { return tmp; } diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp new file mode 100644 index 0000000000..cdeb177aaf --- /dev/null +++ b/src/scripting/scriptengine.cpp @@ -0,0 +1,177 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include + +namespace { + const std::string _loggerCat = "ScriptEngine"; + + const std::string _openspaceLibraryName = "openspace"; +} + +ScriptEngine::ScriptEngine() + : _state(nullptr) +{ +} + +bool ScriptEngine::initialize() { + _state = luaL_newstate(); + LDEBUG("Creating Lua state"); + if (_state == nullptr) { + LFATAL("Error creating new Lua state: Memory allocation error"); + return false; + } + LDEBUG("Open Lua libraries"); + luaL_openlibs(_state); + + LDEBUG("Add OpenSpace modules"); + + lua_newtable(_state); + lua_setglobal(_state, _openspaceLibraryName.c_str()); + + return true; +} + +void ScriptEngine::deinitialize() { + lua_close(_state); + _state = nullptr; +} + +bool ScriptEngine::addLibrary(const ScriptEngine::LuaLibrary& library) { + assert(_state); + if (library.functions.empty()) { + LERROR("Lua library '" << library.name << "' does not have any functions"); + return false; + } + + lua_getglobal(_state, _openspaceLibraryName.c_str()); + if (library.name.empty()) { + addLibraryFunctions(library, true); + } + else { + const bool allowed = isLibraryNameAllowed(library.name); + if (!allowed) + return false; + + lua_pushstring(_state, library.name.c_str()); + lua_newtable(_state); + addLibraryFunctions(library, false); + lua_settable(_state, -3); + + _registeredLibraries.insert(ghoul::hashCRC32(library.name)); + } + return true; +} + +bool ScriptEngine::runScript(std::string script) { + int status = luaL_loadstring(_state, script.c_str()); + if (status != LUA_OK) { + LERROR("Error loading script: '" << lua_tostring(_state, -1) << "'"); + return false; + } + + LDEBUG("Executing script"); + if (lua_pcall(_state, 0, LUA_MULTRET, 0)) { + LERROR("Error executing script: " << lua_tostring(_state, -1)); + return false; + } + + return true; +} + +bool ScriptEngine::hasLibrary(const std::string& name) +{ + const unsigned int hash = ghoul::hashCRC32(name); + return (_registeredLibraries.find(hash) != _registeredLibraries.end()); +} + +bool ScriptEngine::isLibraryNameAllowed(const std::string& name) +{ + bool result = false; + lua_getglobal(_state, _openspaceLibraryName.c_str()); + const bool hasOpenSpaceLibrary = lua_istable(_state, -1); + if (!hasOpenSpaceLibrary) { + LFATAL("OpenSpace library was not created in initialize method"); + return false; + } + lua_getfield(_state, -1, name.c_str()); + const int type = lua_type(_state, -1); + switch (type) { + case LUA_TNONE: + case LUA_TNIL: + result = true; + break; + case LUA_TBOOLEAN: + LERROR("Library name '" << name << "' specifies a boolean"); + break; + case LUA_TLIGHTUSERDATA: + LERROR("Library name '" << name << "' specifies a light user data"); + break; + case LUA_TNUMBER: + LERROR("Library name '" << name << "' specifies a number"); + break; + case LUA_TSTRING: + LERROR("Library name '" << name << "' specifies a string"); + break; + case LUA_TTABLE: { + if (hasLibrary(name)) + LERROR("Library with name '" << name << "' has been registered before"); + else + LERROR("Library name '" << name << "' specifies a table"); + break; + } + case LUA_TFUNCTION: + LERROR("Library name '" << name << "' specifies a function"); + break; + case LUA_TUSERDATA: + LERROR("Library name '" << name << "' specifies a user data"); + break; + case LUA_TTHREAD: + LERROR("Library name '" << name << "' specifies a thread"); + break; + } + + lua_pop(_state, 1); + return result; +} + +void ScriptEngine::addLibraryFunctions(const LuaLibrary& library, bool replace) +{ + for (std::pair p : library.functions) { + if (!replace) { + lua_getfield(_state, -1, p.first.c_str()); + const bool isNil = lua_isnil(_state, -1); + if (!isNil) { + LERROR("Function name '" << p.first << "' was already assigned"); + return; + } + } + lua_pushstring(_state, p.first.c_str()); + lua_pushcfunction(_state, p.second); + lua_settable(_state, -3); + } +} diff --git a/src/scripting/scriptfunctions.cpp b/src/scripting/scriptfunctions.cpp new file mode 100644 index 0000000000..f5943fe788 --- /dev/null +++ b/src/scripting/scriptfunctions.cpp @@ -0,0 +1,83 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include + +#include + +using namespace openspace; +using namespace openspace::properties; + +static int property_setValue(lua_State* L) +{ + const std::string _loggerCat = "property_setValue"; + using ghoul::lua::luaTypeToString; + + // TODO Check for argument number (ab) + std::string nodeName = luaL_checkstring(L, -3); + std::string propertyName = luaL_checkstring(L, -2); + const int type = lua_type(L, -1); + boost::any propertyValue; + switch (type) { + case LUA_TNONE: + case LUA_TLIGHTUSERDATA: + case LUA_TTABLE: + case LUA_TFUNCTION: + case LUA_TUSERDATA: + case LUA_TTHREAD: + LERROR("Function parameter was of type '" << luaTypeToString(type) << "'"); + return 0; + case LUA_TNIL: + propertyValue = 0; + break; + case LUA_TBOOLEAN: + propertyValue = lua_toboolean(L, -1); + break; + case LUA_TNUMBER: + propertyValue = lua_tonumber(L, -1); + break; + case LUA_TSTRING: + propertyValue = std::string(lua_tostring(L, -1)); + break; + } + + Property* prop = property(nodeName, propertyName); + if (!prop) { + LERROR("Property at " << nodeName << "." << propertyName << + " could not be found"); + return 0; + } + + prop->set(propertyValue); + + return 0; +} + +static int property_getValue(lua_State* L) +{ + +} From 1782857c729fd5dc6a9fcff7ed234e33718682c3 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 21 Aug 2014 18:52:47 +0200 Subject: [PATCH 054/113] Bugfix accessing properties --- include/openspace/scripting/scriptfunctions.h | 4 ++-- src/scenegraph/scenegraph.cpp | 5 ++--- src/scenegraph/scenegraphnode.cpp | 5 +++++ src/scripting/scriptfunctions.cpp | 10 +++++----- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/openspace/scripting/scriptfunctions.h b/include/openspace/scripting/scriptfunctions.h index ae0bd4b9f7..59c58c84f2 100644 --- a/include/openspace/scripting/scriptfunctions.h +++ b/include/openspace/scripting/scriptfunctions.h @@ -29,8 +29,8 @@ struct lua_State; // Properties -static int property_setValue(lua_State* L); -static int property_getValue(lua_State* L); +int property_setValue(lua_State* L); +//static int property_getValue(lua_State* L); #endif // __SCRIPTFUNCTIONS_H__ diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index d8d52d2fe6..57409ebcd2 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -351,9 +351,8 @@ bool SceneGraph::registerScriptFunctions() ScriptEngine::LuaLibrary l = { "", { - { "setPropertyValue", &property_setValue}, - { "getPropertyValue", &property_getValue}, - { NULL, NULL } + { "setPropertyValue", &property_setValue} +// { "getPropertyValue", &property_getValue}, } }; return true; diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 54c7fb25ab..f7e19c560f 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -309,6 +309,11 @@ void SceneGraphNode::setRenderable(Renderable* renderable) update(); } +Renderable* SceneGraphNode::renderable() +{ + return _renderable; +} + const Renderable* SceneGraphNode::renderable() const { return _renderable; diff --git a/src/scripting/scriptfunctions.cpp b/src/scripting/scriptfunctions.cpp index f5943fe788..9f0a6577c3 100644 --- a/src/scripting/scriptfunctions.cpp +++ b/src/scripting/scriptfunctions.cpp @@ -32,7 +32,7 @@ using namespace openspace; using namespace openspace::properties; -static int property_setValue(lua_State* L) +int property_setValue(lua_State* L) { const std::string _loggerCat = "property_setValue"; using ghoul::lua::luaTypeToString; @@ -77,7 +77,7 @@ static int property_setValue(lua_State* L) return 0; } -static int property_getValue(lua_State* L) -{ - -} +//int property_getValue(lua_State* L) +//{ +// +//} From 79174d5b6cc43d45880a11ec99112a8fc6ba2c30 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 29 Aug 2014 13:04:20 +0200 Subject: [PATCH 055/113] Cleaned up scripts directory Made scripts runnable at startup Added printing functions and remapped default Lua printing --- ext/ghoul | 2 +- include/openspace/engine/openspaceengine.h | 4 +- include/openspace/scripting/scriptengine.h | 12 ++- include/openspace/scripting/scriptfunctions.h | 12 +++ include/openspace/util/constants.h | 1 + openspace.cfg | 5 +- scripts/DefaultConfig.lua | 16 ---- scripts/ExtraConfigScript.lua | 15 ---- scripts/config.lua | 5 -- scripts/config2.lua | 6 -- scripts/defaultSettings.cfg | 4 - scripts/default_startup.lua | 1 + src/engine/openspaceengine.cpp | 32 ++++++- src/query/query.cpp | 13 +++ src/scenegraph/scenegraph.cpp | 5 +- src/scripting/scriptengine.cpp | 83 ++++++++++++++++++- src/scripting/scriptfunctions.cpp | 64 +++++++++++++- 17 files changed, 221 insertions(+), 59 deletions(-) delete mode 100644 scripts/DefaultConfig.lua delete mode 100644 scripts/ExtraConfigScript.lua delete mode 100644 scripts/config.lua delete mode 100644 scripts/config2.lua delete mode 100644 scripts/defaultSettings.cfg create mode 100644 scripts/default_startup.lua diff --git a/ext/ghoul b/ext/ghoul index 17608b8800..54dfc9b508 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 17608b8800d412f99b6eef8e9dcc4741c5a1f38c +Subproject commit 54dfc9b50825c392662cab0c7c42724a38734ef2 diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 3026d19d79..ef98decc83 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -65,7 +65,7 @@ public: ghoul::opencl::CLContext& clContext(); InteractionHandler& interactionHandler(); RenderEngine& renderEngine(); - ScriptEngine& scriptEngine(); + scripting::ScriptEngine& scriptEngine(); // SGCT callbacks bool initializeGL(); @@ -92,7 +92,7 @@ private: ghoul::Dictionary* _configurationManager; InteractionHandler* _interactionHandler; RenderEngine* _renderEngine; - ScriptEngine* _scriptEngine; + scripting::ScriptEngine* _scriptEngine; ghoul::cmdparser::CommandlineParser* _commandlineParser; #ifdef FLARE_ONLY Flare* _flare; diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index 81b9f77c05..83c3795b18 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -28,6 +28,9 @@ #include #include +namespace openspace { +namespace scripting { + class ScriptEngine { public: struct LuaLibrary { @@ -43,14 +46,21 @@ public: bool addLibrary(const LuaLibrary& library); bool hasLibrary(const std::string& name); - bool runScript(std::string script); + bool runScript(const std::string& script); + bool runScriptFile(const std::string& filename); private: bool isLibraryNameAllowed(const std::string& name); void addLibraryFunctions(const LuaLibrary& library, bool replace); + void addBaseLibrary(); + void remapPrintFunction(); + lua_State* _state; std::set _registeredLibraries; }; + +} // namespace scripting +} // namespace openspace #endif // __SCRIPTENGINE_H__ diff --git a/include/openspace/scripting/scriptfunctions.h b/include/openspace/scripting/scriptfunctions.h index 59c58c84f2..9fbad7229e 100644 --- a/include/openspace/scripting/scriptfunctions.h +++ b/include/openspace/scripting/scriptfunctions.h @@ -27,10 +27,22 @@ struct lua_State; +namespace openspace { +namespace scripting { + +// Helper functions +int printDebug(lua_State* L); +int printInfo(lua_State* L); +int printWarning(lua_State* L); +int printError(lua_State* L); +int printFatal(lua_State* L); + // Properties int property_setValue(lua_State* L); //static int property_getValue(lua_State* L); +} // namespace scripting +} // namespace openspace #endif // __SCRIPTFUNCTIONS_H__ diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index 6c004dbda2..2fde16e5f5 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -34,6 +34,7 @@ namespace openspaceengine { const std::string keyPathScene = "Paths.SCENEPATH"; const std::string keyConfigSgct = "SGCTConfig"; const std::string keyConfigScene = "Scene"; + const std::string keyStartupScript = "StartupScripts"; } // namespace openspaceengine namespace scenegraph { diff --git a/openspace.cfg b/openspace.cfg index 4becaf05a8..9b45f4704d 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -12,5 +12,8 @@ return { SGCTConfig = "${SGCT}/single.xml", --SGCTConfig = "${SGCT}/two_nodes.xml", --SGCTConfig = "${SGCT}/single_sbs_stereo.xml", - Scene = "${SCENEPATH}/default.scene" + Scene = "${SCENEPATH}/default.scene", + StartupScripts = { + "${SCRIPTS}/default_startup.lua" + } } \ No newline at end of file diff --git a/scripts/DefaultConfig.lua b/scripts/DefaultConfig.lua deleted file mode 100644 index 3e0738115a..0000000000 --- a/scripts/DefaultConfig.lua +++ /dev/null @@ -1,16 +0,0 @@ -{ - level1_string = "music1", - level1_integer = 2332, - level1_dictionary = - { - level2_string = "stuff", - level2_integer = 32, - level2_dictionary = { - level3_string = "levels", - level3_integer = 323232 - } - }, - level2_double = 3.4, - level2_boolean = true - -} \ No newline at end of file diff --git a/scripts/ExtraConfigScript.lua b/scripts/ExtraConfigScript.lua deleted file mode 100644 index a2b9ca86c5..0000000000 --- a/scripts/ExtraConfigScript.lua +++ /dev/null @@ -1,15 +0,0 @@ -musicname = "music2" -lyrics = "This is not, the greatest lyrics in the world. This is just a tribute" - -config = -{ - level1_string = musicname, - level1_lyrics = lyrics, - level1_secrets = - { - secret_stuff1 = "Password", - secret_stuff2 = "123456", - }, - level2_double = 4.3 - -} \ No newline at end of file diff --git a/scripts/config.lua b/scripts/config.lua deleted file mode 100644 index 1cd7d986d2..0000000000 --- a/scripts/config.lua +++ /dev/null @@ -1,5 +0,0 @@ -{ - setting1 = 1, - setting2 = 2, - t = {s = 1, t = 2, u = 3} -} \ No newline at end of file diff --git a/scripts/config2.lua b/scripts/config2.lua deleted file mode 100644 index db728fe51c..0000000000 --- a/scripts/config2.lua +++ /dev/null @@ -1,6 +0,0 @@ -{ - setting2 = 4, - setting3 = 1, - t = { s = 2, v = 0}, - tt = { t = { a = "a", b = "b", ff="2" }, u = { a = "a", b = "b" } } -} \ No newline at end of file diff --git a/scripts/defaultSettings.cfg b/scripts/defaultSettings.cfg deleted file mode 100644 index d93b7d07f8..0000000000 --- a/scripts/defaultSettings.cfg +++ /dev/null @@ -1,4 +0,0 @@ -{ - BasePathOffset = "../../.." - -} \ No newline at end of file diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua new file mode 100644 index 0000000000..a39eef89ee --- /dev/null +++ b/scripts/default_startup.lua @@ -0,0 +1 @@ +print "foo" \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 209917c5ea..9ef104ac1a 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -48,6 +48,8 @@ using namespace ghoul::filesystem; using namespace ghoul::logging; +using namespace openspace::scripting; + namespace { const std::string _loggerCat = "OpenSpaceEngine"; const std::string _configurationFile = "openspace.cfg"; @@ -316,9 +318,9 @@ bool OpenSpaceEngine::initialize() FactoryManager::initialize(); scriptEngine().initialize(); - scriptEngine().addLibrary(ScriptEngine::LuaLibrary()); +// scriptEngine().addLibrary(ScriptEngine::LuaLibrary()); - _engine->scriptEngine().runScript("return mylib.mysin(4)"); +// _engine->scriptEngine().runScript("return mylib.mysin(4)"); // Load scenegraph @@ -362,6 +364,32 @@ bool OpenSpaceEngine::initialize() DeviceIdentifier::ref().scanDevices(); _engine->_interactionHandler->connectDevices(); + // Run start up scripts + using ghoul::Dictionary; + using constants::openspaceengine::keyStartupScript; + const bool hasScript = _engine->configurationManager().hasKeyAndValue(keyStartupScript); + if (hasScript) { + Dictionary scripts; + _engine->configurationManager().getValue(keyStartupScript, scripts); + + for (size_t i = 0; i < scripts.size(); ++i) { + std::stringstream stream; + // Dictionary-size is 0-based; script numbers are 1-based + stream << (i + 1); + const std::string& key = stream.str(); + const bool hasKey = scripts.hasKeyAndValue(key); + if (!hasKey) { + LERROR("The startup scripts have to be declared in a simple array format"); + break; + } + + std::string scriptPath; + scripts.getValue(key, scriptPath); + const std::string absoluteScriptPath = absPath(scriptPath); + _engine->scriptEngine().runScriptFile(absoluteScriptPath); + } + } + return true; } diff --git a/src/query/query.cpp b/src/query/query.cpp index aabd8f3eb4..ffe1143f93 100644 --- a/src/query/query.cpp +++ b/src/query/query.cpp @@ -53,8 +53,21 @@ properties::Property* property(const std::string& uri) properties::Property* property(const std::string& nodeName, const std::string& propertyName) { SceneGraphNode* node = sceneGraphNode(nodeName); + if (!node) { + LERROR("Node '" << nodeName << "' did not exist"); + return nullptr; + } Renderable* propertyOwner = node->renderable(); + if (!propertyOwner) { + LERROR("Node '" << nodeName << "' is not a PropertyOwner"); + return nullptr; + } properties::Property* property = propertyOwner->property(propertyName);; + if (!property) { + LERROR("Node '" << nodeName << "' did not have property '" << + propertyName << "'"); + return nullptr; + } return property; } diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 57409ebcd2..f9001edd32 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -347,14 +347,17 @@ bool SceneGraph::registerScriptFunctions() { LDEBUG("Registering Script Functions"); + using namespace scripting; - ScriptEngine::LuaLibrary l = { + ScriptEngine::LuaLibrary sceneGraphLibrary = { "", { { "setPropertyValue", &property_setValue} // { "getPropertyValue", &property_getValue}, } }; + + OsEng.scriptEngine().addLibrary(sceneGraphLibrary); return true; } diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index cdeb177aaf..6ec891e83b 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -24,13 +24,26 @@ #include +#include + #include +#include #include +#include + +namespace openspace { +namespace scripting { + namespace { const std::string _loggerCat = "ScriptEngine"; const std::string _openspaceLibraryName = "openspace"; + const std::string _luaGlobalNamespace = "_G"; + const std::string _printFunctionName = "print"; + const lua_CFunction _printFunctionReplacement = printInfo; + + const int _setTableOffset = -3; // -1 (top) -1 (first argument) -1 (second argument) } ScriptEngine::ScriptEngine() @@ -50,9 +63,16 @@ bool ScriptEngine::initialize() { LDEBUG("Add OpenSpace modules"); + LDEBUG("Create openspace base library"); lua_newtable(_state); lua_setglobal(_state, _openspaceLibraryName.c_str()); + LDEBUG("Adding base functions"); + addBaseLibrary(); + + LDEBUG("Remap print function"); + remapPrintFunction(); + return true; } @@ -80,14 +100,16 @@ bool ScriptEngine::addLibrary(const ScriptEngine::LuaLibrary& library) { lua_pushstring(_state, library.name.c_str()); lua_newtable(_state); addLibraryFunctions(library, false); - lua_settable(_state, -3); + lua_settable(_state, _setTableOffset); _registeredLibraries.insert(ghoul::hashCRC32(library.name)); } return true; } -bool ScriptEngine::runScript(std::string script) { +bool ScriptEngine::runScript(const std::string& script) { + if (script.empty()) + return false; int status = luaL_loadstring(_state, script.c_str()); if (status != LUA_OK) { LERROR("Error loading script: '" << lua_tostring(_state, -1) << "'"); @@ -103,6 +125,29 @@ bool ScriptEngine::runScript(std::string script) { return true; } +bool ScriptEngine::runScriptFile(const std::string& filename) { + if (filename.empty()) { + LWARNING("Filename was empty"); + return false; + } + if (!FileSys.fileExists(filename)) { + LERROR("Script with name '" << filename << "' did not exist"); + return false; + } + std::ifstream file(filename.c_str()); + if (file.bad()) { + LERROR("Error opening file '" << filename << "'"); + return false; + } + + // Read the contents of the script + std::string script((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + + const bool runSuccess = runScript(script); + return runSuccess; +} + bool ScriptEngine::hasLibrary(const std::string& name) { const unsigned int hash = ghoul::hashCRC32(name); @@ -172,6 +217,38 @@ void ScriptEngine::addLibraryFunctions(const LuaLibrary& library, bool replace) } lua_pushstring(_state, p.first.c_str()); lua_pushcfunction(_state, p.second); - lua_settable(_state, -3); + lua_settable(_state, _setTableOffset); } } + +void ScriptEngine::addBaseLibrary() { + ScriptEngine::LuaLibrary sceneGraphLibrary = { + "", + { + { "setPropertyValue", &property_setValue} + // { "getPropertyValue", &property_getValue}, + } + }; + + LuaLibrary lib = { + "", + { + { "printDebug", &printDebug }, + { "printInfo", &printInfo }, + { "printWarning", &printWarning }, + { "printError", &printError }, + { "printFatal", &printFatal } + } + }; + addLibrary(lib); +} + +void ScriptEngine::remapPrintFunction() { + lua_getglobal(_state, _luaGlobalNamespace.c_str()); + lua_pushstring(_state, _printFunctionName.c_str()); + lua_pushcfunction(_state, _printFunctionReplacement); + lua_settable(_state, _setTableOffset); +} + +} // namespace scripting +} // namespace openspace diff --git a/src/scripting/scriptfunctions.cpp b/src/scripting/scriptfunctions.cpp index 9f0a6577c3..c5ffae260f 100644 --- a/src/scripting/scriptfunctions.cpp +++ b/src/scripting/scriptfunctions.cpp @@ -27,15 +27,72 @@ #include #include +#include #include -using namespace openspace; +namespace openspace { +namespace scripting { + using namespace openspace::properties; + +void printInternal(ghoul::logging::LogManager::LogLevel level, lua_State* L) { + using ghoul::lua::luaTypeToString; + const std::string _loggerCat = "print"; + + const int type = lua_type(L, -1); + switch (type) { + case LUA_TNONE: + case LUA_TLIGHTUSERDATA: + case LUA_TTABLE: + case LUA_TFUNCTION: + case LUA_TUSERDATA: + case LUA_TTHREAD: + LOG(level, "Function parameter was of type '" << + luaTypeToString(type) << "'"); + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + LOG(level, lua_toboolean(L, -1)); + break; + case LUA_TNUMBER: + LOG(level, lua_tonumber(L, -1)); + break; + case LUA_TSTRING: + LOG(level, lua_tostring(L, -1)); + break; + } +} + +int printDebug(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Debug, L); + return 0; +} +int printInfo(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Info, L); + return 0; +} + +int printWarning(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Warning, L); + return 0; +} + +int printError(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Error, L); + return 0; +} + +int printFatal(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Fatal, L); + return 0; +} + + int property_setValue(lua_State* L) { - const std::string _loggerCat = "property_setValue"; using ghoul::lua::luaTypeToString; + const std::string _loggerCat = "property_setValue"; // TODO Check for argument number (ab) std::string nodeName = luaL_checkstring(L, -3); @@ -81,3 +138,6 @@ int property_setValue(lua_State* L) //{ // //} + +} // namespace scripting +} // namespace openspace From 96719213317bf560e4baefcde6e10b3ab9cd3919 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 30 Aug 2014 10:01:11 +0200 Subject: [PATCH 056/113] More work towards a unified interface for accessing properties --- include/openspace/properties/propertyowner.h | 17 ++- include/openspace/query/query.h | 1 - include/openspace/scenegraph/scenegraphnode.h | 6 +- src/properties/propertyowner.cpp | 117 +++++++++++++++++- src/query/query.cpp | 31 +++-- src/rendering/renderable.cpp | 6 +- src/scenegraph/scenegraph.cpp | 8 +- src/scenegraph/scenegraphnode.cpp | 35 ++---- src/scripting/scriptfunctions.cpp | 8 +- 9 files changed, 168 insertions(+), 61 deletions(-) diff --git a/include/openspace/properties/propertyowner.h b/include/openspace/properties/propertyowner.h index 6211c877b4..6dfaf7c1af 100644 --- a/include/openspace/properties/propertyowner.h +++ b/include/openspace/properties/propertyowner.h @@ -35,27 +35,42 @@ namespace properties { class PropertyOwner { public: + static const char URISeparator = '.'; + PropertyOwner(); virtual ~PropertyOwner(); void setName(std::string name); virtual const std::string& name() const; + const std::vector& properties() const; Property* property(const std::string& id) const; + bool hasProperty(const std::string& id) const; + + const std::vector& subOwners() const; + PropertyOwner* subOwner(const std::string& name) const; + bool hasSubOwner(const std::string& name) const; void setPropertyGroupName(std::string groupID, std::string name); const std::string& propertyGroupName(const std::string& groupID) const; - + protected: void addProperty(Property* prop); void addProperty(Property& prop); + + void addPropertySubOwner(PropertyOwner* owner); + void addPropertySubOwner(PropertyOwner& owner); void removeProperty(Property* prop); void removeProperty(Property& prop); + + void removePropertySubOwner(PropertyOwner* owner); + void removePropertySubOwner(PropertyOwner& owner); private: std::string _name; std::vector _properties; + std::vector _subOwners; std::map _groupNames; }; diff --git a/include/openspace/query/query.h b/include/openspace/query/query.h index f985a31b7d..1bd1edf34b 100644 --- a/include/openspace/query/query.h +++ b/include/openspace/query/query.h @@ -38,7 +38,6 @@ class SceneGraphNode; SceneGraph* sceneGraph(); SceneGraphNode* sceneGraphNode(const std::string& name); properties::Property* property(const std::string& uri); -properties::Property* property(const std::string& nodeName, const std::string& propertyName); } // namespace diff --git a/include/openspace/scenegraph/scenegraphnode.h b/include/openspace/scenegraph/scenegraphnode.h index 775e844a05..b809f84ce4 100644 --- a/include/openspace/scenegraph/scenegraphnode.h +++ b/include/openspace/scenegraph/scenegraphnode.h @@ -28,6 +28,7 @@ // open space includes #include #include +#include #include #include @@ -40,7 +41,7 @@ namespace openspace { -class SceneGraphNode { +class SceneGraphNode : public properties::PropertyOwner { public: static std::string RootNodeName; @@ -61,11 +62,9 @@ public: // set & get void addNode(SceneGraphNode* child); - void setName(const std::string& name); void setParent(SceneGraphNode* parent); const psc& position() const; psc worldPosition() const; - std::string nodeName() const; SceneGraphNode* parent() const; const std::vector& children() const; @@ -86,7 +85,6 @@ private: // essential std::vector _children; SceneGraphNode* _parent; - std::string _nodeName; Ephemeris* _ephemeris; // renderable diff --git a/src/properties/propertyowner.cpp b/src/properties/propertyowner.cpp index 19dc8bd1cc..e5d332ffbc 100644 --- a/src/properties/propertyowner.cpp +++ b/src/properties/propertyowner.cpp @@ -37,6 +37,11 @@ bool propertyLess(Property* lhs, Property* rhs) { return lhs->identifier() < rhs->identifier(); } + +bool subOwnerLess(PropertyOwner* lhs, PropertyOwner* rhs) { + return lhs->name() < rhs->name(); +} + } PropertyOwner::PropertyOwner() @@ -64,17 +69,68 @@ Property* PropertyOwner::property(const std::string& id) const return prop->identifier() < str; }); - if (it == _properties.end() || (*it)->identifier() != id) + if (it == _properties.end() || (*it)->identifier() != id) { + // if we do not own the searched property, it must consist of a concatenated + // name and we can delegate it to a subowner + const size_t ownerSeparator = id.find(URISeparator); + if (ownerSeparator == std::string::npos) { + // if we do not own the property and there is no separator, it does not exist + LERROR("The identifier '" << id << "' did not exist in PropertyOwner '" << + name() << "'"); + return nullptr; + } + else { + const std::string ownerName = id.substr(0, ownerSeparator); + const std::string propertyName = id.substr(ownerSeparator); + + PropertyOwner* owner = subOwner(ownerName); + if (owner == nullptr) { + LERROR("Sub PropertyOwner '" << owner + << "' did not exist for PropertyOwner '" << name() << "'"); + return nullptr; + } + else { + // Recurse into the subOwner + return owner->property(propertyName); + } + } + } + else + return *it; +} + +bool PropertyOwner::hasProperty(const std::string& id) const { + return property(id) != nullptr; +} + +const std::vector& PropertyOwner::subOwners() const { + return _subOwners; +} + +PropertyOwner* PropertyOwner::subOwner(const std::string& name) const { + assert(std::is_sorted(_subOwners.begin(), _subOwners.end(), subOwnerLess)); + + std::vector::const_iterator it + = std::lower_bound(_subOwners.begin(), _subOwners.end(), name, + [](PropertyOwner* owner, const std::string& str) { + return owner->name() < str; + }); + + if (it == _subOwners.end() || (*it)->name() != name) return nullptr; else return *it; } + +bool PropertyOwner::hasSubOwner(const std::string& name) const { + return subOwner(name) != nullptr; +} void PropertyOwner::setPropertyGroupName(std::string groupID, std::string name) { _groupNames[std::move(groupID)] = std::move(name); } - + const std::string& PropertyOwner::propertyGroupName(const std::string& groupID) const { auto it = _groupNames.find(groupID); @@ -104,7 +160,8 @@ void PropertyOwner::addProperty(Property* prop) // If we found the property identifier, we need to bail out if (it != _properties.end() && (*it)->identifier() == prop->identifier()) { LERROR("Property identifier '" << prop->identifier() - << "' already present in PropertyOwner"); + << "' already present in PropertyOwner '" + << name() << "'"); return; } else { // Otherwise we have found the correct position to add it in @@ -117,6 +174,38 @@ void PropertyOwner::addProperty(Property& prop) { addProperty(&prop); } + +void PropertyOwner::addPropertySubOwner(openspace::properties::PropertyOwner* owner) { + assert(owner != nullptr); + assert(std::is_sorted(_subOwners.begin(), _subOwners.end(), subOwnerLess)); + + if (owner->name().empty()) { + LERROR("PropertyOwner did not have a name"); + return; + } + + // See if we can find the name of the propertyowner to add + std::vector::iterator it + = std::lower_bound(_subOwners.begin(), _subOwners.end(), owner->name(), + [](PropertyOwner* owner, const std::string& str) { + return owner->name() < str; + }); + + // If we found the propertyowner's name, we need to bail out + if (it != _subOwners.end() && (*it)->name() == owner->name()) { + LERROR("PropertyOwner '" << owner->name() + << "' already present in PropertyOwner '" << name() << "'"); + return; + } else { + // Otherwise we have found the correct position to add it in + _subOwners.insert(it, owner); + } + +} + +void PropertyOwner::addPropertySubOwner(openspace::properties::PropertyOwner& owner) { + addPropertySubOwner(&owner); +} void PropertyOwner::removeProperty(Property* prop) { @@ -142,6 +231,28 @@ void PropertyOwner::removeProperty(Property& prop) { removeProperty(&prop); } + +void PropertyOwner::removePropertySubOwner(openspace::properties::PropertyOwner* owner) { + assert(owner != nullptr); + + // See if we can find the name of the propertyowner to add + std::vector::iterator it + = std::lower_bound(_subOwners.begin(), _subOwners.end(), owner->name(), + [](PropertyOwner* owner, const std::string& str) { + return owner->name() < str; + }); + + // If we found the propertyowner, we can delete it + if (it != _subOwners.end() && (*it)->name() == owner->name()) { + _subOwners.erase(it); + } else + LERROR("PropertyOwner with name '" << owner->name() + << "' not found for removal."); +} + +void PropertyOwner::removePropertySubOwner(openspace::properties::PropertyOwner& owner) { + removePropertySubOwner(&owner); +} void PropertyOwner::setName(std::string name) { diff --git a/src/query/query.cpp b/src/query/query.cpp index ffe1143f93..404758a59f 100644 --- a/src/query/query.cpp +++ b/src/query/query.cpp @@ -30,7 +30,7 @@ namespace openspace { namespace { -const std::string _loggerCat = "Query"; + const std::string _loggerCat = "Query"; } SceneGraph* sceneGraph() @@ -46,28 +46,25 @@ SceneGraphNode* sceneGraphNode(const std::string& name) properties::Property* property(const std::string& uri) { - const size_t separator = uri.find('.'); - return property(uri.substr(0, separator), uri.substr(separator)); -} + // The URI consists of the following form at this stage: + // .{.}^(0..n) + + const size_t nodeNameSeparator = uri.find(properties::PropertyOwner::URISeparator); + if (nodeNameSeparator == std::string::npos) { + LERROR("Malformed URI '" << uri << "': At least one '" << nodeNameSeparator + << "' separator must be present."); + return nullptr; + } + const std::string nodeName = uri.substr(0, nodeNameSeparator); + const std::string remainingUri = uri.substr(nodeNameSeparator + 1); -properties::Property* property(const std::string& nodeName, const std::string& propertyName) -{ SceneGraphNode* node = sceneGraphNode(nodeName); if (!node) { LERROR("Node '" << nodeName << "' did not exist"); return nullptr; } - Renderable* propertyOwner = node->renderable(); - if (!propertyOwner) { - LERROR("Node '" << nodeName << "' is not a PropertyOwner"); - return nullptr; - } - properties::Property* property = propertyOwner->property(propertyName);; - if (!property) { - LERROR("Node '" << nodeName << "' did not have property '" << - propertyName << "'"); - return nullptr; - } + + properties::Property* property = node->property(remainingUri); return property; } diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 9a432b02d7..aaa7455428 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -60,9 +60,9 @@ Renderable* Renderable::createFromDictionary(const ghoul::Dictionary& dictionary Renderable::Renderable(const ghoul::Dictionary& dictionary) { - std::string name; - dictionary.getValue(constants::scenegraphnode::keyName, name); - setName(name); +// std::string name; +// dictionary.getValue(constants::scenegraphnode::keyName, name); + setName("Renderable"); } Renderable::~Renderable() diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index f9001edd32..49e396dc81 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -57,7 +57,7 @@ namespace openspace { void printTree(SceneGraphNode* node, std::string pre = "") { - LDEBUGC("Tree", pre << node->nodeName()); + LDEBUGC("Tree", pre << node->name()); const std::vector& children = node->children(); for (SceneGraphNode* child : children) printTree(child, pre + " "); @@ -155,9 +155,9 @@ bool SceneGraph::initialize() for (auto node : _nodes) { bool success = node->initialize(); if (success) - LDEBUG(node->nodeName() << " initialized successfully!"); + LDEBUG(node->name() << " initialized successfully!"); else - LWARNING(node->nodeName() << " not initialized."); + LWARNING(node->name() << " not initialized."); } // update the position of all nodes @@ -325,7 +325,7 @@ void SceneGraph::loadModule(const std::string& modulePath) SceneGraphNode* node = SceneGraphNode::createFromDictionary(element); - _allNodes.emplace(node->nodeName(), node); + _allNodes.emplace(node->name(), node); _nodes.push_back(node); } diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index f7e19c560f..5c1105c2b6 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -63,21 +63,22 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di << keyName << "' key"); return nullptr; } - dictionary.getValue(keyName, result->_nodeName); + std::string name; + dictionary.getValue(keyName, name); + result->setName(name); if (dictionary.hasValue(keyRenderable)) { ghoul::Dictionary renderableDictionary; dictionary.getValue(keyRenderable, renderableDictionary); renderableDictionary.setValue(keyPathModule, path); - renderableDictionary.setValue(keyName, result->_nodeName); result->_renderable = Renderable::createFromDictionary(renderableDictionary); if (result->_renderable == nullptr) { LERROR("Failed to create renderable for SceneGraphNode '" - << result->_nodeName << "'"); + << result->name() << "'"); return nullptr; } - LDEBUG("Successfully create renderable for '" << result->_nodeName << "'"); + LDEBUG("Successfully create renderable for '" << result->name() << "'"); } if (dictionary.hasKey(keyEphemeris)) { ghoul::Dictionary ephemerisDictionary; @@ -86,10 +87,10 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di result->_ephemeris = Ephemeris::createFromDictionary(ephemerisDictionary); if (result->_ephemeris == nullptr) { LERROR("Failed to create ephemeris for SceneGraphNode '" - << result->_nodeName << "'"); + << result->name() << "'"); return nullptr; } - LDEBUG("Successfully create ephemeris for '" << result->_nodeName << "'"); + LDEBUG("Successfully create ephemeris for '" << result->name() << "'"); } std::string parentName; @@ -101,20 +102,19 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di SceneGraphNode* parentNode = sceneGraphNode(parentName); if (parentNode == nullptr) { LFATAL("Could not find parent named '" - << parentName << "' for '" << result->_nodeName << "'." + << parentName << "' for '" << result->name() << "'." << " Check module definition order. Skipping module."); } parentNode->addNode(result); LDEBUG("Successfully created SceneGraphNode '" - << result->_nodeName << "'"); + << result->name() << "'"); return result; } SceneGraphNode::SceneGraphNode() : _parent(nullptr) - , _nodeName("") , _ephemeris(new StaticEphemeris) , _renderable(nullptr) , _renderableVisible(false) @@ -139,7 +139,7 @@ bool SceneGraphNode::initialize() bool SceneGraphNode::deinitialize() { - LDEBUG("Deinitialize: " << _nodeName); + LDEBUG("Deinitialize: " << name()); delete _renderable; _renderable = nullptr; @@ -153,7 +153,6 @@ bool SceneGraphNode::deinitialize() // reset variables _parent = nullptr; - _nodeName = ""; _renderableVisible = false; _boundingSphereVisible = false; _boundingSphere = PowerScaledScalar(0.0, 0.0); @@ -232,11 +231,6 @@ void SceneGraphNode::addNode(SceneGraphNode* child) _children.push_back(child); } -void SceneGraphNode::setName(const std::string& name) -{ - _nodeName = name; -} - void SceneGraphNode::setParent(SceneGraphNode* parent) { _parent = parent; @@ -257,11 +251,6 @@ psc SceneGraphNode::worldPosition() const } } -std::string SceneGraphNode::nodeName() const -{ - return _nodeName; -} - SceneGraphNode* SceneGraphNode::parent() const { return _parent; @@ -353,7 +342,7 @@ bool SceneGraphNode::sphereInsideFrustum(const psc s_pos, const PowerScaledScala SceneGraphNode* SceneGraphNode::childNode(const std::string& name) { - if (_nodeName == name) + if (this->name() == name) return this; else for (auto it : _children) { @@ -367,7 +356,7 @@ SceneGraphNode* SceneGraphNode::childNode(const std::string& name) void SceneGraphNode::print() const { - std::cout << _nodeName << std::endl; + std::cout << name() << std::endl; for (auto it : _children) { it->print(); } diff --git a/src/scripting/scriptfunctions.cpp b/src/scripting/scriptfunctions.cpp index c5ffae260f..7d1e90f32e 100644 --- a/src/scripting/scriptfunctions.cpp +++ b/src/scripting/scriptfunctions.cpp @@ -95,8 +95,7 @@ int property_setValue(lua_State* L) const std::string _loggerCat = "property_setValue"; // TODO Check for argument number (ab) - std::string nodeName = luaL_checkstring(L, -3); - std::string propertyName = luaL_checkstring(L, -2); + std::string uri = luaL_checkstring(L, -2); const int type = lua_type(L, -1); boost::any propertyValue; switch (type) { @@ -122,10 +121,9 @@ int property_setValue(lua_State* L) break; } - Property* prop = property(nodeName, propertyName); + Property* prop = property(uri); if (!prop) { - LERROR("Property at " << nodeName << "." << propertyName << - " could not be found"); + LERROR("Property with uri '" << uri << "' could not be found"); return 0; } From 5add1682d3a29c81d71b5539bd7d41fdcec362d6 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 31 Aug 2014 16:08:19 +0200 Subject: [PATCH 057/113] More work on properties Added notify method to templateproperty's set method Fixed names of subpropertyowners --- include/openspace/properties/property.h | 2 ++ include/openspace/properties/templateproperty.inl | 1 + scripts/default_startup.lua | 2 +- src/properties/property.cpp | 5 +++++ src/properties/propertyowner.cpp | 2 +- src/rendering/planets/planetgeometry.cpp | 1 + src/rendering/planets/renderableplanet.cpp | 13 ++++++------- src/rendering/renderable.cpp | 4 +--- src/scenegraph/scenegraphnode.cpp | 2 ++ 9 files changed, 20 insertions(+), 12 deletions(-) diff --git a/include/openspace/properties/property.h b/include/openspace/properties/property.h index 4dcadd5853..73ff57c67d 100644 --- a/include/openspace/properties/property.h +++ b/include/openspace/properties/property.h @@ -79,6 +79,8 @@ public: const ghoul::Dictionary& metaData() const; protected: + void notifyListeners(); + PropertyOwner* _owner; std::string _identifier; diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index 6b48c02473..68cf082c20 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -101,6 +101,7 @@ template void TemplateProperty::set(boost::any value) { try { _value = boost::any_cast(std::move(value)); + notifyListeners(); } catch (boost::bad_any_cast&) { LERRORC("TemplateProperty", "Illegal cast to '" << typeid(T).name() << "'"); diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index a39eef89ee..9acbddfa87 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -1 +1 @@ -print "foo" \ No newline at end of file +--openspace.setPropertyValue('Earth.renderable.colorTexture', '${OPENSPACE_DATA}/modules/mars/textures/mars.png') \ No newline at end of file diff --git a/src/properties/property.cpp b/src/properties/property.cpp index a44ffc32b2..6faab729e8 100644 --- a/src/properties/property.cpp +++ b/src/properties/property.cpp @@ -125,5 +125,10 @@ void Property::setPropertyOwner(PropertyOwner* owner) _owner = owner; } +void Property::notifyListeners() { + for (std::function& f : _onChangeCallbacks) + f(); +} + } // namespace properties } // namespace openspace diff --git a/src/properties/propertyowner.cpp b/src/properties/propertyowner.cpp index e5d332ffbc..9162bd1d2f 100644 --- a/src/properties/propertyowner.cpp +++ b/src/properties/propertyowner.cpp @@ -81,7 +81,7 @@ Property* PropertyOwner::property(const std::string& id) const } else { const std::string ownerName = id.substr(0, ownerSeparator); - const std::string propertyName = id.substr(ownerSeparator); + const std::string propertyName = id.substr(ownerSeparator + 1); PropertyOwner* owner = subOwner(ownerName); if (owner == nullptr) { diff --git a/src/rendering/planets/planetgeometry.cpp b/src/rendering/planets/planetgeometry.cpp index b9cef75f05..ca6e361414 100644 --- a/src/rendering/planets/planetgeometry.cpp +++ b/src/rendering/planets/planetgeometry.cpp @@ -62,6 +62,7 @@ PlanetGeometry* PlanetGeometry::createFromDictionary(const ghoul::Dictionary& di PlanetGeometry::PlanetGeometry() : _parent(nullptr) { + setName("PlanetGeometry"); } PlanetGeometry::~PlanetGeometry() diff --git a/src/rendering/planets/renderableplanet.cpp b/src/rendering/planets/renderableplanet.cpp index 79c08236bd..f6dd119ab2 100644 --- a/src/rendering/planets/renderableplanet.cpp +++ b/src/rendering/planets/renderableplanet.cpp @@ -68,10 +68,9 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) _colorTexturePath = path + "/" + texturePath; } - for (properties::Property* p : _geometry->properties()) - addProperty(p); + addPropertySubOwner(_geometry); - addProperty(_colorTexturePath); + addProperty(_colorTexturePath); _colorTexturePath.onChange(std::bind(&RenderablePlanet::loadTexture, this)); } @@ -107,10 +106,10 @@ bool RenderablePlanet::deinitialize() void RenderablePlanet::render(const Camera* camera, const psc& thisPosition) { - // TODO replace with more robust assert - // check so that the shader is set - assert(_programObject); - assert(_texture); + if (!_programObject) + return; + if (!_texture) + return; // activate shader _programObject->activate(); diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index aaa7455428..4527b7b3de 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -53,8 +53,6 @@ Renderable* Renderable::createFromDictionary(const ghoul::Dictionary& dictionary return nullptr; } - result->setName(name); - return result; } @@ -62,7 +60,7 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary) { // std::string name; // dictionary.getValue(constants::scenegraphnode::keyName, name); - setName("Renderable"); + setName("renderable"); } Renderable::~Renderable() diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 5c1105c2b6..a47037a30f 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -78,6 +78,7 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di << result->name() << "'"); return nullptr; } + result->addPropertySubOwner(result->_renderable); LDEBUG("Successfully create renderable for '" << result->name() << "'"); } if (dictionary.hasKey(keyEphemeris)) { @@ -90,6 +91,7 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di << result->name() << "'"); return nullptr; } + //result->addPropertySubOwner(result->_ephemeris); LDEBUG("Successfully create ephemeris for '" << result->name() << "'"); } From e7697a4ce05be0d6c5f4f515f5cf59764902692f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 31 Aug 2014 17:52:02 +0200 Subject: [PATCH 058/113] Enable setting and getting property values from Lua scripts --- ext/ghoul | 2 +- .../openspace/properties/numericalproperty.h | 4 + .../properties/numericalproperty.inl | 55 ++++++++- include/openspace/properties/property.h | 6 + .../openspace/properties/propertydelegate.h | 8 ++ .../openspace/properties/propertydelegate.inl | 14 +++ .../openspace/properties/templateproperty.inl | 3 +- include/openspace/scripting/scriptfunctions.h | 2 +- src/properties/property.cpp | 14 +++ src/properties/scalarproperty.cpp | 81 ++++++++++--- src/scenegraph/scenegraph.cpp | 4 +- src/scripting/scriptengine.cpp | 8 -- src/scripting/scriptfunctions.cpp | 111 +++++++++++++----- 13 files changed, 250 insertions(+), 62 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 54dfc9b508..f5f1f38f2f 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 54dfc9b50825c392662cab0c7c42724a38734ef2 +Subproject commit f5f1f38f2f52487cc445b9d226c6f416d1e72090 diff --git a/include/openspace/properties/numericalproperty.h b/include/openspace/properties/numericalproperty.h index 6050db32da..45d15f9d03 100644 --- a/include/openspace/properties/numericalproperty.h +++ b/include/openspace/properties/numericalproperty.h @@ -38,6 +38,10 @@ public: NumericalProperty(std::string identifier, std::string guiName, T value, T minimumValue, T maximumValue); + bool getLua(lua_State* state) const override; + bool setLua(lua_State* state) override; + int typeLua() const override; + virtual std::string className() const override; using TemplateProperty::operator=; diff --git a/include/openspace/properties/numericalproperty.inl b/include/openspace/properties/numericalproperty.inl index 5fe62f1b89..8d16ca33e9 100644 --- a/include/openspace/properties/numericalproperty.inl +++ b/include/openspace/properties/numericalproperty.inl @@ -22,6 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include + namespace openspace { namespace properties { @@ -34,31 +36,49 @@ namespace properties { template <> template <> \ TYPE PropertyDelegate>::defaultMinimumValue(); \ template <> template <> \ - TYPE PropertyDelegate>::defaultMaximumValue(); + TYPE PropertyDelegate>::defaultMaximumValue(); \ + template <> template <> \ + TYPE PropertyDelegate>::fromLuaValue( \ + lua_State* state, bool& success); \ + template <> template <> \ + bool PropertyDelegate>::toLuaValue( \ + lua_State* state, TYPE value); #define REGISTER_NUMERICALPROPERTY_SOURCE(CLASS_NAME, TYPE, \ - DEFAULT_VALUE, DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, DEFAULT_STEPPING) \ + DEFAULT_VALUE, DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, DEFAULT_STEPPING, \ + FROM_LUA_LAMBDA_EXPRESSION, TO_LUA_LAMBDA_EXPRESSION) \ template <> \ std::string PropertyDelegate>::className() { \ return #CLASS_NAME; \ } \ template <> \ std::string PropertyDelegate>::className() { \ - return #CLASS_NAME; \ + return #CLASS_NAME; \ } \ template <> template <> \ TYPE PropertyDelegate>::defaultValue() { \ - return DEFAULT_VALUE; \ + return DEFAULT_VALUE; \ } \ template <> template <> \ TYPE PropertyDelegate>::defaultMinimumValue() { \ - return DEFAULT_MIN_VALUE; \ + return DEFAULT_MIN_VALUE; \ } \ template <> template <> \ TYPE PropertyDelegate>::defaultMaximumValue() { \ - return DEFAULT_MAX_VALUE; \ + return DEFAULT_MAX_VALUE; \ +} \ + template <> template <> \ + TYPE PropertyDelegate>::fromLuaValue( \ + lua_State* state, bool& success) { \ + return FROM_LUA_LAMBDA_EXPRESSION(state, success); \ +} \ + template <> template <> \ + bool PropertyDelegate>::toLuaValue( \ + lua_State* state, TYPE value) { \ + return TO_LUA_LAMBDA_EXPRESSION(state, value); \ } + // Delegating constructors are necessary; automatic template deduction cannot // deduce template argument for 'U' if 'default' methods are used as default values in @@ -95,5 +115,28 @@ std::string NumericalProperty::className() const { return PropertyDelegate>::className(); } +template +bool NumericalProperty::setLua(lua_State* state) +{ + bool success; + T value = PropertyDelegate>::fromLuaValue(state, success); + if (success) + set(value); + return success; +} + +template +bool NumericalProperty::getLua(lua_State* state) const +{ + bool success = PropertyDelegate>::toLuaValue(state, TemplateProperty::_value); + return success; +} + +template +int openspace::properties::NumericalProperty::typeLua() const { + return LUA_TNUMBER; +} + + } // namespace properties } // namespace openspace diff --git a/include/openspace/properties/property.h b/include/openspace/properties/property.h index 73ff57c67d..aed1f96afb 100644 --- a/include/openspace/properties/property.h +++ b/include/openspace/properties/property.h @@ -32,6 +32,8 @@ #include #include +struct lua_State; + namespace openspace { namespace properties { @@ -49,6 +51,10 @@ public: virtual void set(boost::any value); virtual const std::type_info& type() const; + virtual bool getLua(lua_State* state) const; + virtual bool setLua(lua_State* state); + virtual int typeLua() const; + virtual void onChange(std::function callback); const std::string& identifier() const; diff --git a/include/openspace/properties/propertydelegate.h b/include/openspace/properties/propertydelegate.h index 9a090f317c..feeb411c05 100644 --- a/include/openspace/properties/propertydelegate.h +++ b/include/openspace/properties/propertydelegate.h @@ -27,6 +27,8 @@ #include +struct lua_State; + namespace openspace { namespace properties { @@ -43,6 +45,12 @@ public: template static U defaultMaximumValue(); + + template + static U fromLuaValue(lua_State* state, bool& success); + + template + static bool toLuaValue(lua_State* state, U value); }; } // namespace properties diff --git a/include/openspace/properties/propertydelegate.inl b/include/openspace/properties/propertydelegate.inl index 5af2f6013e..8088fb4b4b 100644 --- a/include/openspace/properties/propertydelegate.inl +++ b/include/openspace/properties/propertydelegate.inl @@ -57,5 +57,19 @@ U PropertyDelegate::defaultMaximumValue() { "Unimplemented PropertyDelegate::defaultMaximumValue specialization"); } +template +template +U PropertyDelegate::fromLuaValue(lua_State* state, bool& success) { + static_assert(sizeof(T) == 0, + "Unimplemented PropertyDelegate::fromLuaValue specialization"); +} + +template +template +bool PropertyDelegate::toLuaValue(lua_State* state, U value) { + static_assert(sizeof(T) == 0, + "Unimplemented PropertyDelegate::toLuaValue specialization"); +} + } // namespace properties } // namespace openspace diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index 68cf082c20..25648695d9 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -104,7 +104,8 @@ void TemplateProperty::set(boost::any value) { notifyListeners(); } catch (boost::bad_any_cast&) { - LERRORC("TemplateProperty", "Illegal cast to '" << typeid(T).name() << "'"); + LERRORC("TemplateProperty", "Illegal cast from '" << value.type().name() + << "' to '" << typeid(T).name() << "'"); } } diff --git a/include/openspace/scripting/scriptfunctions.h b/include/openspace/scripting/scriptfunctions.h index 9fbad7229e..a590cca1d0 100644 --- a/include/openspace/scripting/scriptfunctions.h +++ b/include/openspace/scripting/scriptfunctions.h @@ -40,7 +40,7 @@ int printFatal(lua_State* L); // Properties int property_setValue(lua_State* L); -//static int property_getValue(lua_State* L); +int property_getValue(lua_State* L); } // namespace scripting } // namespace openspace diff --git a/src/properties/property.cpp b/src/properties/property.cpp index 6faab729e8..7ea90bcbe7 100644 --- a/src/properties/property.cpp +++ b/src/properties/property.cpp @@ -24,6 +24,8 @@ #include "openspace/properties/property.h" +#include + namespace openspace { namespace properties { @@ -56,12 +58,24 @@ boost::any Property::get() const { return boost::any(); } +bool Property::getLua(lua_State* state) const { + return true; +} + void Property::set(boost::any value) {} +bool Property::setLua(lua_State* state) { + return true; +} + const std::type_info& Property::type() const { return typeid(void); } +int Property::typeLua() const { + return LUA_TNONE; +} + const std::string& Property::guiName() const { return _guiName; } diff --git a/src/properties/scalarproperty.cpp b/src/properties/scalarproperty.cpp index 7ee07390a4..b3562ac2e1 100644 --- a/src/properties/scalarproperty.cpp +++ b/src/properties/scalarproperty.cpp @@ -24,6 +24,8 @@ #include "openspace/properties/scalarproperty.h" +#include + #include using std::numeric_limits; @@ -31,52 +33,101 @@ using std::numeric_limits; namespace openspace { namespace properties { +#define DEFAULT_FROM_LUA_LAMBDA(TYPE, DEFAULT_VALUE) \ + [](lua_State* state, bool& success) -> TYPE { \ + success = (lua_isnumber(state, -1) == 1); \ + if (success) \ + return static_cast(lua_tonumber(state, -1)); \ + else \ + return DEFAULT_VALUE; \ + } + +#define DEFAULT_TO_LUA_LAMBDA(TYPE) \ + [](lua_State* state, TYPE value) -> bool { \ + lua_pushnumber(state, static_cast(value)); \ + return true; \ + } + // char16_t and char32_t are not supported on Visual Studio 2013 and are defined to // be equal to unsigned short and unsigned int which causes a compile error REGISTER_TEMPLATEPROPERTY_SOURCE(BoolProperty, bool, false); REGISTER_NUMERICALPROPERTY_SOURCE(CharProperty, char, char(0), - numeric_limits::lowest(), numeric_limits::max(), char(1)); + numeric_limits::lowest(), numeric_limits::max(), char(1), + DEFAULT_FROM_LUA_LAMBDA(char, char(0)), DEFAULT_TO_LUA_LAMBDA(char)); + //REGISTER_NUMERICALPROPERTY_SOURCE(Char16Property, char16_t, char16_t(0), // numeric_limits::lowest(), numeric_limits::max(), char16_t(1)); + //REGISTER_NUMERICALPROPERTY_SOURCE(Char32Property, char32_t, char32_t(0), // numeric_limits::lowest(), numeric_limits::max(), char32_t(1)); + REGISTER_NUMERICALPROPERTY_SOURCE(WCharProperty, wchar_t, wchar_t(0), - numeric_limits::lowest(), numeric_limits::max(), wchar_t(1)); + numeric_limits::lowest(), numeric_limits::max(), wchar_t(1), + DEFAULT_FROM_LUA_LAMBDA(wchar_t, wchar_t(0)), DEFAULT_TO_LUA_LAMBDA(wchar_t)); + REGISTER_NUMERICALPROPERTY_SOURCE(SignedCharProperty, signed char, (signed char)(0), numeric_limits::lowest(), numeric_limits::max(), - (signed char)0); + (signed char)0, DEFAULT_FROM_LUA_LAMBDA(signed char, (signed char)(0)), + DEFAULT_TO_LUA_LAMBDA(signed char)); + REGISTER_NUMERICALPROPERTY_SOURCE(UCharProperty, unsigned char, (unsigned char)0, numeric_limits::lowest(), numeric_limits::max(), - (unsigned char)1); + (unsigned char)1, DEFAULT_FROM_LUA_LAMBDA(unsigned char, (unsigned char)(0)), + DEFAULT_TO_LUA_LAMBDA(unsigned char)); + REGISTER_NUMERICALPROPERTY_SOURCE(ShortProperty, short, short(0), - numeric_limits::lowest(), numeric_limits::max(), short(1)); + numeric_limits::lowest(), numeric_limits::max(), short(1), + DEFAULT_FROM_LUA_LAMBDA(short, short(0)), DEFAULT_TO_LUA_LAMBDA(short)); + REGISTER_NUMERICALPROPERTY_SOURCE(UShortProperty, unsigned short, (unsigned short)(0), numeric_limits::lowest(), numeric_limits::max(), - (unsigned short)1); + (unsigned short)1, DEFAULT_FROM_LUA_LAMBDA(unsigned short, (unsigned short)(0)), + DEFAULT_TO_LUA_LAMBDA(unsigned short)); + REGISTER_NUMERICALPROPERTY_SOURCE(IntProperty, int, int(0), - numeric_limits::lowest(), numeric_limits::max(), int(1)); + numeric_limits::lowest(), numeric_limits::max(), int(1), + DEFAULT_FROM_LUA_LAMBDA(int, int(0)), DEFAULT_TO_LUA_LAMBDA(int)); + REGISTER_NUMERICALPROPERTY_SOURCE(UIntProperty, unsigned int, (unsigned int)0, numeric_limits::lowest(), numeric_limits::max(), - (unsigned int)1); + (unsigned int)1, DEFAULT_FROM_LUA_LAMBDA(unsigned int, (unsigned int)(0)), + DEFAULT_TO_LUA_LAMBDA(unsigned int)); + REGISTER_NUMERICALPROPERTY_SOURCE(LongProperty, long, long(0), - numeric_limits::lowest(), numeric_limits::max(), long(1)); + numeric_limits::lowest(), numeric_limits::max(), long(1), + DEFAULT_FROM_LUA_LAMBDA(long, long(0)), DEFAULT_TO_LUA_LAMBDA(long)); + REGISTER_NUMERICALPROPERTY_SOURCE(ULongProperty, unsigned long, (unsigned long)0, numeric_limits::lowest(), numeric_limits::max(), - (unsigned long)1); + (unsigned long)1, DEFAULT_FROM_LUA_LAMBDA(unsigned long, (unsigned long)(0)), + DEFAULT_TO_LUA_LAMBDA(unsigned long)); + REGISTER_NUMERICALPROPERTY_SOURCE(LongLongProperty, long long, (long long)0, - numeric_limits::lowest(), numeric_limits::max(), (long long)1); + numeric_limits::lowest(), numeric_limits::max(), (long long)1, + DEFAULT_FROM_LUA_LAMBDA(long long, (long long)(0)), + DEFAULT_TO_LUA_LAMBDA(long long)); + REGISTER_NUMERICALPROPERTY_SOURCE(ULongLongProperty, unsigned long long, (unsigned long long)1, numeric_limits::lowest(), - numeric_limits::max(), (unsigned long long)1); + numeric_limits::max(), (unsigned long long)1, + DEFAULT_FROM_LUA_LAMBDA(unsigned long long, (unsigned long long)(0)), + DEFAULT_TO_LUA_LAMBDA(unsigned long long)); + REGISTER_NUMERICALPROPERTY_SOURCE(FloatProperty, float, 0.f, - numeric_limits::lowest(), numeric_limits::max(), 0.01f); + numeric_limits::lowest(), numeric_limits::max(), 0.01f, + DEFAULT_FROM_LUA_LAMBDA(float, float(0)), DEFAULT_TO_LUA_LAMBDA(float)); + REGISTER_NUMERICALPROPERTY_SOURCE(DoubleProperty, double, 0.0, - numeric_limits::lowest(), numeric_limits::max(), 0.01); + numeric_limits::lowest(), numeric_limits::max(), 0.01, + DEFAULT_FROM_LUA_LAMBDA(double, double(0)), DEFAULT_TO_LUA_LAMBDA(double)); + REGISTER_NUMERICALPROPERTY_SOURCE(LongDoubleProperty, long double, (long double)0, numeric_limits::lowest(), numeric_limits::max(), - (long double)0.01f); + (long double)0.01f, + DEFAULT_FROM_LUA_LAMBDA(long double, (long double)(0)), + DEFAULT_TO_LUA_LAMBDA(long double)); } // namespace properties } // namespace openspace diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 49e396dc81..71ffbaa5c4 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -352,8 +352,8 @@ bool SceneGraph::registerScriptFunctions() ScriptEngine::LuaLibrary sceneGraphLibrary = { "", { - { "setPropertyValue", &property_setValue} -// { "getPropertyValue", &property_getValue}, + { "setPropertyValue", &property_setValue}, + { "getPropertyValue", &property_getValue} } }; diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 6ec891e83b..6d90fdb3da 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -222,14 +222,6 @@ void ScriptEngine::addLibraryFunctions(const LuaLibrary& library, bool replace) } void ScriptEngine::addBaseLibrary() { - ScriptEngine::LuaLibrary sceneGraphLibrary = { - "", - { - { "setPropertyValue", &property_setValue} - // { "getPropertyValue", &property_getValue}, - } - }; - LuaLibrary lib = { "", { diff --git a/src/scripting/scriptfunctions.cpp b/src/scripting/scriptfunctions.cpp index 7d1e90f32e..8cc8ebe79a 100644 --- a/src/scripting/scriptfunctions.cpp +++ b/src/scripting/scriptfunctions.cpp @@ -29,6 +29,7 @@ #include #include +#include namespace openspace { namespace scripting { @@ -97,29 +98,34 @@ int property_setValue(lua_State* L) // TODO Check for argument number (ab) std::string uri = luaL_checkstring(L, -2); const int type = lua_type(L, -1); - boost::any propertyValue; - switch (type) { - case LUA_TNONE: - case LUA_TLIGHTUSERDATA: - case LUA_TTABLE: - case LUA_TFUNCTION: - case LUA_TUSERDATA: - case LUA_TTHREAD: - LERROR("Function parameter was of type '" << luaTypeToString(type) << "'"); - return 0; - case LUA_TNIL: - propertyValue = 0; - break; - case LUA_TBOOLEAN: - propertyValue = lua_toboolean(L, -1); - break; - case LUA_TNUMBER: - propertyValue = lua_tonumber(L, -1); - break; - case LUA_TSTRING: - propertyValue = std::string(lua_tostring(L, -1)); - break; - } + // boost::any propertyValue; + // switch (type) { + // case LUA_TNONE: + // case LUA_TLIGHTUSERDATA: + // case LUA_TFUNCTION: + // case LUA_TUSERDATA: + // case LUA_TTHREAD: + // LERROR("Function parameter was of type '" << luaTypeToString(type) << "'"); + // return 0; + // case LUA_TNIL: + // propertyValue = 0; + // break; + // case LUA_TBOOLEAN: + // propertyValue = lua_toboolean(L, -1); + // break; + // case LUA_TNUMBER: + // propertyValue = lua_tonumber(L, -1); + // break; + // case LUA_TSTRING: + // propertyValue = std::string(lua_tostring(L, -1)); + // break; + //case LUA_TTABLE: { + // ghoul::Dictionary d; + // ghoul::lua::populateDictionary(L, d); + // propertyValue = d; + // break; + //} + // } Property* prop = property(uri); if (!prop) { @@ -127,15 +133,64 @@ int property_setValue(lua_State* L) return 0; } - prop->set(propertyValue); + //if (propertyValue.type() != prop->type()) { + if (type != prop->typeLua()) + LERROR("Property '" << uri << "' does not accept input of type '" + << luaTypeToString(type) << "'. Requested type: '" + << luaTypeToString(prop->typeLua() << "'"); + } + else + prop->setLua(L); + //prop->set(propertyValue); return 0; } -//int property_getValue(lua_State* L) -//{ -// -//} +int property_getValue(lua_State* L) { + const std::string _loggerCat = "property_getValue"; + + // TODO Check for argument number (ab) + std::string uri = luaL_checkstring(L, -1); + + Property* prop = property(uri); + if (!prop) { + LERROR("Property with uri '" << uri << "' could not be found"); + lua_pushnil(L); + } + else { + prop->getLua(L); + + //switch (type) { + // case LUA_TNONE: + // case LUA_TLIGHTUSERDATA: + // case LUA_TFUNCTION: + // case LUA_TUSERDATA: + // case LUA_TTHREAD: + // LERROR("Function parameter was of type '" << luaTypeToString(type) + // << "'"); + // return 0; + // case LUA_TNIL: + // propertyValue = 0; + // break; + // case LUA_TBOOLEAN: + // propertyValue = lua_toboolean(L, -1); + // break; + // case LUA_TNUMBER: + // propertyValue = lua_tonumber(L, -1); + // break; + // case LUA_TSTRING: + // propertyValue = std::string(lua_tostring(L, -1)); + // break; + // case LUA_TTABLE: { + // ghoul::Dictionary d; + // ghoul::lua::populateDictionary(L, d); + // propertyValue = d; + // break; + // } + //} +} + return 1; +} } // namespace scripting } // namespace openspace From 667dc6a3fc5e69f4078b5d842165322851ab82ec Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 1 Sep 2014 18:02:59 +0200 Subject: [PATCH 059/113] Started work on alternate property definition to take Lua scripting into account --- ext/ghoul | 2 +- src/properties/scalarproperty.cpp | 2 +- src/properties/vectorproperty.cpp | 70 +++++++++++++++++++++++++------ 3 files changed, 60 insertions(+), 14 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index f5f1f38f2f..d44211f170 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit f5f1f38f2f52487cc445b9d226c6f416d1e72090 +Subproject commit d44211f170f2929738eec687ded811a1581014e7 diff --git a/src/properties/scalarproperty.cpp b/src/properties/scalarproperty.cpp index b3562ac2e1..8a24537977 100644 --- a/src/properties/scalarproperty.cpp +++ b/src/properties/scalarproperty.cpp @@ -33,7 +33,7 @@ using std::numeric_limits; namespace openspace { namespace properties { -#define DEFAULT_FROM_LUA_LAMBDA(TYPE, DEFAULT_VALUE) \ +#define DEFAULT_FROM_LUA_LAMBDA(TYPE, DEFAULT_VALUE, FUNCTION) \ [](lua_State* state, bool& success) -> TYPE { \ success = (lua_isnumber(state, -1) == 1); \ if (success) \ diff --git a/src/properties/vectorproperty.cpp b/src/properties/vectorproperty.cpp index 99b1dddead..64d894387e 100644 --- a/src/properties/vectorproperty.cpp +++ b/src/properties/vectorproperty.cpp @@ -24,6 +24,10 @@ #include "openspace/properties/vectorproperty.h" +#include + +#include + #include using std::numeric_limits; @@ -31,46 +35,88 @@ using std::numeric_limits; namespace openspace { namespace properties { +#define DEFAULT_FROM_LUA_LAMBDA_2(TYPE, DEFAULT_VALUE) \ + [](lua_State* state, bool& success) -> TYPE { \ + success = (lua_isnumber(state, -1) == 1) && (lua_isnumber(state, -2) == 1); \ + if (success) { \ + + } + +#define DEFAULT_TO_LUA_LAMBDA(TYPE) \ + [](lua_State* state, TYPE value) -> bool { \ + \ + } + REGISTER_TEMPLATEPROPERTY_SOURCE(BVec2Property, glm::bvec2, glm::bvec2(false)); REGISTER_TEMPLATEPROPERTY_SOURCE(BVec3Property, glm::bvec3, glm::bvec3(false)); REGISTER_TEMPLATEPROPERTY_SOURCE(BVec4Property, glm::bvec4, glm::bvec4(false)); REGISTER_NUMERICALPROPERTY_SOURCE(Vec2Property, glm::vec2, glm::vec2(0), glm::vec2(numeric_limits::lowest()), glm::vec2(numeric_limits::max()), - glm::vec2(0.01f)); + glm::vec2(0.01f), DEFAULT_FROM_LUA_LAMBDA(glm::vec2, glm::vec2(0)), + DEFAULT_TO_LUA_LAMBDA(glm::vec2)); + REGISTER_NUMERICALPROPERTY_SOURCE(Vec3Property, glm::vec3, glm::vec3(0), glm::vec3(numeric_limits::lowest()), glm::vec3(numeric_limits::max()), - glm::vec3(0.01f)); + glm::vec3(0.01f), DEFAULT_FROM_LUA_LAMBDA(glm::vec3, glm::vec3(0)), + DEFAULT_TO_LUA_LAMBDA(glm::vec3)); + REGISTER_NUMERICALPROPERTY_SOURCE(Vec4Property, glm::vec4, glm::vec4(0), glm::vec4(numeric_limits::lowest()), glm::vec4(numeric_limits::max()), - glm::vec4(0.01f)); + glm::vec4(0.01f), DEFAULT_FROM_LUA_LAMBDA(glm::vec4, glm::vec4(0)), + DEFAULT_TO_LUA_LAMBDA(glm::vec4)); + REGISTER_NUMERICALPROPERTY_SOURCE(DVec2Property, glm::dvec2, glm::dvec2(0), glm::dvec2(numeric_limits::lowest()), - glm::dvec2(numeric_limits::max()), glm::dvec2(0.01)); + glm::dvec2(numeric_limits::max()), glm::dvec2(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dvec2, glm::dvec2(0)), + DEFAULT_TO_LUA_LAMBDA(glm::dvec2)); + REGISTER_NUMERICALPROPERTY_SOURCE(DVec3Property, glm::dvec3, glm::dvec3(0), glm::dvec3(numeric_limits::lowest()), - glm::dvec3(numeric_limits::max()), glm::dvec3(0.01)); + glm::dvec3(numeric_limits::max()), glm::dvec3(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dvec3, glm::dvec3(0)), + DEFAULT_TO_LUA_LAMBDA(glm::dvec3)); + REGISTER_NUMERICALPROPERTY_SOURCE(DVec4Property, glm::dvec4, glm::dvec4(0), glm::dvec4(numeric_limits::lowest()), - glm::dvec4(numeric_limits::max()), glm::dvec4(0.01)); + glm::dvec4(numeric_limits::max()), glm::dvec4(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dvec4, glm::dvec4(0)), + DEFAULT_TO_LUA_LAMBDA(glm::dvec4)); + REGISTER_NUMERICALPROPERTY_SOURCE(IVec2Property, glm::ivec2, glm::ivec2(0), glm::ivec2(numeric_limits::lowest()), glm::ivec2(numeric_limits::max()), - glm::ivec2(1)); + glm::ivec2(1), DEFAULT_FROM_LUA_LAMBDA(glm::ivec2, glm::ivec2(0)), + DEFAULT_TO_LUA_LAMBDA(glm::ivec2)); + REGISTER_NUMERICALPROPERTY_SOURCE(IVec3Property, glm::ivec3, glm::ivec3(0), glm::ivec3(numeric_limits::lowest()), glm::ivec3(numeric_limits::max()), - glm::ivec3(1)); + glm::ivec3(1), DEFAULT_FROM_LUA_LAMBDA(glm::ivec3, glm::ivec3(0)), + DEFAULT_TO_LUA_LAMBDA(glm::ivec3)); + REGISTER_NUMERICALPROPERTY_SOURCE(IVec4Property, glm::ivec4, glm::ivec4(0), glm::ivec4(numeric_limits::lowest()), glm::ivec4(numeric_limits::max()), - glm::ivec4(1)); + glm::ivec4(1), DEFAULT_FROM_LUA_LAMBDA(glm::ivec4, glm::ivec4(0)), + DEFAULT_TO_LUA_LAMBDA(glm::ivec4)); + REGISTER_NUMERICALPROPERTY_SOURCE(UVec2Property, glm::uvec2, glm::uvec2(0), glm::uvec2(numeric_limits::lowest()), - glm::uvec2(numeric_limits::max()), glm::uvec2(1)); + glm::uvec2(numeric_limits::max()), glm::uvec2(1), + DEFAULT_FROM_LUA_LAMBDA(glm::uvec2, glm::uvec2(0)), + DEFAULT_TO_LUA_LAMBDA(glm::uvec2)); + REGISTER_NUMERICALPROPERTY_SOURCE(UVec3Property, glm::uvec3, glm::uvec3(0), glm::uvec3(numeric_limits::lowest()), - glm::uvec3(numeric_limits::max()), glm::uvec3(1)); + glm::uvec3(numeric_limits::max()), glm::uvec3(1), + DEFAULT_FROM_LUA_LAMBDA(glm::uvec3, glm::uvec3(0)), + DEFAULT_TO_LUA_LAMBDA(glm::uvec3)); + REGISTER_NUMERICALPROPERTY_SOURCE(UVec4Property, glm::uvec4, glm::uvec4(0), glm::uvec4(numeric_limits::lowest()), - glm::uvec4(numeric_limits::max()), glm::uvec4(1)); + glm::uvec4(numeric_limits::max()), glm::uvec4(1), + DEFAULT_FROM_LUA_LAMBDA(glm::uvec4, glm::uvec4(0)), + DEFAULT_TO_LUA_LAMBDA(glm::uvec4)); + } // namespace properties } // namespace openspace From d90e35372aa9a7e4c1dac85e960d2225ed2e27f3 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 2 Sep 2014 20:04:42 +0200 Subject: [PATCH 060/113] Added possibility to specify a conversion function between C++ and Lua for properties --- src/properties/matrixproperty.cpp | 547 ++++++++++++++++++++++++------ src/properties/scalarproperty.cpp | 2 +- src/properties/vectorproperty.cpp | 115 +++++-- src/scripting/scriptfunctions.cpp | 3 +- 4 files changed, 532 insertions(+), 135 deletions(-) diff --git a/src/properties/matrixproperty.cpp b/src/properties/matrixproperty.cpp index 15964307ca..9cf11e40d6 100644 --- a/src/properties/matrixproperty.cpp +++ b/src/properties/matrixproperty.cpp @@ -31,144 +31,487 @@ using std::numeric_limits; namespace openspace { namespace properties { +#define DEFAULT_FROM_LUA_LAMBDA_4(TYPE, DEFAULT_VALUE) \ + [](lua_State* state, bool& success) -> TYPE { \ + success = (lua_isnumber(state, -1) == 1) && \ + (lua_isnumber(state, -2) == 1) && \ + (lua_isnumber(state, -3) == 1) && \ + (lua_isnumber(state, -4) == 1); \ + if (success) \ + return TYPE( \ + static_cast(lua_tonumber(state, -1)), \ + static_cast(lua_tonumber(state, -2)), \ + static_cast(lua_tonumber(state, -3)), \ + static_cast(lua_tonumber(state, -4))); \ + else \ + return DEFAULT_VALUE;\ + } + +#define DEFAULT_FROM_LUA_LAMBDA_6(TYPE, DEFAULT_VALUE) \ + [](lua_State* state, bool& success) -> TYPE { \ + success = (lua_isnumber(state, -1) == 1) && \ + (lua_isnumber(state, -2) == 1) && \ + (lua_isnumber(state, -3) == 1) && \ + (lua_isnumber(state, -4) == 1) && \ + (lua_isnumber(state, -5) == 1) && \ + (lua_isnumber(state, -6) == 1); \ + if (success) \ + return TYPE( \ + static_cast(lua_tonumber(state, -1)), \ + static_cast(lua_tonumber(state, -2)), \ + static_cast(lua_tonumber(state, -3)), \ + static_cast(lua_tonumber(state, -4)), \ + static_cast(lua_tonumber(state, -5)), \ + static_cast(lua_tonumber(state, -6))); \ + else \ + return DEFAULT_VALUE;\ + } + +#define DEFAULT_FROM_LUA_LAMBDA_8(TYPE, DEFAULT_VALUE) \ + [](lua_State* state, bool& success) -> TYPE { \ + success = (lua_isnumber(state, -1) == 1) && \ + (lua_isnumber(state, -2) == 1) && \ + (lua_isnumber(state, -3) == 1) && \ + (lua_isnumber(state, -4) == 1) && \ + (lua_isnumber(state, -5) == 1) && \ + (lua_isnumber(state, -6) == 1) && \ + (lua_isnumber(state, -7) == 1) && \ + (lua_isnumber(state, -8) == 1); \ + if (success) \ + return TYPE( \ + static_cast(lua_tonumber(state, -1)), \ + static_cast(lua_tonumber(state, -2)), \ + static_cast(lua_tonumber(state, -3)), \ + static_cast(lua_tonumber(state, -4)), \ + static_cast(lua_tonumber(state, -5)), \ + static_cast(lua_tonumber(state, -6)), \ + static_cast(lua_tonumber(state, -7)), \ + static_cast(lua_tonumber(state, -8))); \ + else \ + return DEFAULT_VALUE;\ + } + +#define DEFAULT_FROM_LUA_LAMBDA_9(TYPE, DEFAULT_VALUE) \ + [](lua_State* state, bool& success) -> TYPE { \ + success = (lua_isnumber(state, -1) == 1) && \ + (lua_isnumber(state, -2) == 1) && \ + (lua_isnumber(state, -3) == 1) && \ + (lua_isnumber(state, -4) == 1) && \ + (lua_isnumber(state, -5) == 1) && \ + (lua_isnumber(state, -6) == 1) && \ + (lua_isnumber(state, -7) == 1) && \ + (lua_isnumber(state, -8) == 1) && \ + (lua_isnumber(state, -9) == 1); \ + if (success) \ + return TYPE( \ + static_cast(lua_tonumber(state, -1)), \ + static_cast(lua_tonumber(state, -2)), \ + static_cast(lua_tonumber(state, -3)), \ + static_cast(lua_tonumber(state, -4)), \ + static_cast(lua_tonumber(state, -5)), \ + static_cast(lua_tonumber(state, -6)), \ + static_cast(lua_tonumber(state, -7)), \ + static_cast(lua_tonumber(state, -8)), \ + static_cast(lua_tonumber(state, -9))); \ + else \ + return DEFAULT_VALUE;\ + } + +#define DEFAULT_FROM_LUA_LAMBDA_12(TYPE, DEFAULT_VALUE) \ + [](lua_State* state, bool& success) -> TYPE { \ + success = (lua_isnumber(state, -1) == 1) && \ + (lua_isnumber(state, -2) == 1) && \ + (lua_isnumber(state, -3) == 1) && \ + (lua_isnumber(state, -4) == 1) && \ + (lua_isnumber(state, -5) == 1) && \ + (lua_isnumber(state, -6) == 1) && \ + (lua_isnumber(state, -7) == 1) && \ + (lua_isnumber(state, -8) == 1) && \ + (lua_isnumber(state, -9) == 1) && \ + (lua_isnumber(state, -10) == 1) && \ + (lua_isnumber(state, -11) == 1) && \ + (lua_isnumber(state, -12) == 1); \ + if (success) \ + return TYPE( \ + static_cast(lua_tonumber(state, -1)), \ + static_cast(lua_tonumber(state, -2)), \ + static_cast(lua_tonumber(state, -3)), \ + static_cast(lua_tonumber(state, -4)), \ + static_cast(lua_tonumber(state, -5)), \ + static_cast(lua_tonumber(state, -6)), \ + static_cast(lua_tonumber(state, -7)), \ + static_cast(lua_tonumber(state, -8)), \ + static_cast(lua_tonumber(state, -9)), \ + static_cast(lua_tonumber(state, -10)), \ + static_cast(lua_tonumber(state, -11)), \ + static_cast(lua_tonumber(state, -12))); \ + else \ + return DEFAULT_VALUE;\ +} + +#define DEFAULT_FROM_LUA_LAMBDA_16(TYPE, DEFAULT_VALUE) \ + [](lua_State* state, bool& success) -> TYPE { \ + success = (lua_isnumber(state, -1) == 1) && \ + (lua_isnumber(state, -2) == 1) && \ + (lua_isnumber(state, -3) == 1) && \ + (lua_isnumber(state, -4) == 1) && \ + (lua_isnumber(state, -5) == 1) && \ + (lua_isnumber(state, -6) == 1) && \ + (lua_isnumber(state, -7) == 1) && \ + (lua_isnumber(state, -8) == 1) && \ + (lua_isnumber(state, -9) == 1) && \ + (lua_isnumber(state, -10) == 1) && \ + (lua_isnumber(state, -11) == 1) && \ + (lua_isnumber(state, -12) == 1) && \ + (lua_isnumber(state, -13) == 1) && \ + (lua_isnumber(state, -14) == 1) && \ + (lua_isnumber(state, -15) == 1) && \ + (lua_isnumber(state, -16) == 1); \ + if (success) \ + return TYPE( \ + static_cast(lua_tonumber(state, -1)), \ + static_cast(lua_tonumber(state, -2)), \ + static_cast(lua_tonumber(state, -3)), \ + static_cast(lua_tonumber(state, -4)), \ + static_cast(lua_tonumber(state, -5)), \ + static_cast(lua_tonumber(state, -6)), \ + static_cast(lua_tonumber(state, -7)), \ + static_cast(lua_tonumber(state, -8)), \ + static_cast(lua_tonumber(state, -9)), \ + static_cast(lua_tonumber(state, -10)), \ + static_cast(lua_tonumber(state, -11)), \ + static_cast(lua_tonumber(state, -12)), \ + static_cast(lua_tonumber(state, -13)), \ + static_cast(lua_tonumber(state, -14)), \ + static_cast(lua_tonumber(state, -15)), \ + static_cast(lua_tonumber(state, -16))); \ + else \ + return DEFAULT_VALUE;\ + } + REGISTER_NUMERICALPROPERTY_SOURCE(Mat2Property, glm::mat2x2, glm::mat2x2(0), glm::mat2x2(numeric_limits::lowest()), - glm::mat2x2(numeric_limits::max()), glm::mat2x2(0.01f)); + glm::mat2x2(numeric_limits::max()), glm::mat2x2(0.01f), + DEFAULT_FROM_LUA_LAMBDA_4(glm::mat2x2, glm::mat2x2(0)), + [](lua_State* state, glm::mat2x2 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(Mat2x3Property, glm::mat2x3, glm::mat2x3(0), glm::mat2x3(numeric_limits::lowest()), - glm::mat2x3(numeric_limits::max()), glm::mat2x3(0.01f)); + glm::mat2x3(numeric_limits::max()), glm::mat2x3(0.01f), + DEFAULT_FROM_LUA_LAMBDA_6(glm::mat2x3, glm::mat2x3(0)), + [](lua_State* state, glm::mat2x3 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(Mat2x4Property, glm::mat2x4, glm::mat2x4(0), glm::mat2x4(numeric_limits::lowest()), - glm::mat2x4(numeric_limits::max()), glm::mat2x4(0.01f)); + glm::mat2x4(numeric_limits::max()), glm::mat2x4(0.01f), + DEFAULT_FROM_LUA_LAMBDA_8(glm::mat2x4, glm::mat2x4(0)), + [](lua_State* state, glm::mat2x4 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[0][3])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + lua_pushnumber(state, static_cast(value[1][3])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(Mat3x2Property, glm::mat3x2, glm::mat3x2(0), glm::mat3x2(numeric_limits::lowest()), - glm::mat3x2(numeric_limits::max()), glm::mat3x2(0.01f)); + glm::mat3x2(numeric_limits::max()), glm::mat3x2(0.01f), + DEFAULT_FROM_LUA_LAMBDA_6(glm::mat3x2, glm::mat3x2(0)), + [](lua_State* state, glm::mat3x2 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(Mat3Property, glm::mat3x3, glm::mat3x3(0), glm::mat3x3(numeric_limits::lowest()), - glm::mat3x3(numeric_limits::max()), glm::mat3x3(0.01f)); + glm::mat3x3(numeric_limits::max()), glm::mat3x3(0.01f), + DEFAULT_FROM_LUA_LAMBDA_9(glm::mat3x3, glm::mat3x3(0)), + [](lua_State* state, glm::mat3x3 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + lua_pushnumber(state, static_cast(value[2][2])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(Mat3x4Property, glm::mat3x4, glm::mat3x4(0), glm::mat3x4(numeric_limits::lowest()), - glm::mat3x4(numeric_limits::max()), glm::mat3x4(0.01f)); + glm::mat3x4(numeric_limits::max()), glm::mat3x4(0.01f), + DEFAULT_FROM_LUA_LAMBDA_12(glm::mat3x4, glm::mat3x4(0)), + [](lua_State* state, glm::mat3x4 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[0][3])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + lua_pushnumber(state, static_cast(value[1][3])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + lua_pushnumber(state, static_cast(value[2][2])); + lua_pushnumber(state, static_cast(value[2][3])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(Mat4x2Property, glm::mat4x2, glm::mat4x2(0), glm::mat4x2(numeric_limits::lowest()), - glm::mat4x2(numeric_limits::max()), glm::mat4x2(0.01f)); + glm::mat4x2(numeric_limits::max()), glm::mat4x2(0.01f), + DEFAULT_FROM_LUA_LAMBDA_8(glm::mat4x2, glm::mat4x2(0)), + [](lua_State* state, glm::mat4x2 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + lua_pushnumber(state, static_cast(value[3][0])); + lua_pushnumber(state, static_cast(value[3][1])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(Mat4x3Property, glm::mat4x3, glm::mat4x3(0), glm::mat4x3(numeric_limits::lowest()), - glm::mat4x3(numeric_limits::max()), glm::mat4x3(0.01f)); + glm::mat4x3(numeric_limits::max()), glm::mat4x3(0.01f), + DEFAULT_FROM_LUA_LAMBDA_12(glm::mat4x3, glm::mat4x3(0)), + [](lua_State* state, glm::mat4x3 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + lua_pushnumber(state, static_cast(value[2][2])); + lua_pushnumber(state, static_cast(value[3][0])); + lua_pushnumber(state, static_cast(value[3][1])); + lua_pushnumber(state, static_cast(value[3][2])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(Mat4Property, glm::mat4x4, glm::mat4x4(0), glm::mat4x4(numeric_limits::lowest()), - glm::mat4x4(numeric_limits::max()), glm::mat4x4(0.01f)); + glm::mat4x4(numeric_limits::max()), glm::mat4x4(0.01f), + DEFAULT_FROM_LUA_LAMBDA_16(glm::mat4x4, glm::mat4x4(0)), + [](lua_State* state, glm::mat4x4 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[0][3])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + lua_pushnumber(state, static_cast(value[1][3])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + lua_pushnumber(state, static_cast(value[2][2])); + lua_pushnumber(state, static_cast(value[2][3])); + lua_pushnumber(state, static_cast(value[3][0])); + lua_pushnumber(state, static_cast(value[3][1])); + lua_pushnumber(state, static_cast(value[3][2])); + lua_pushnumber(state, static_cast(value[3][3])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(DMat2Property, glm::dmat2x2, glm::dmat2x2(0), glm::dmat2x2(numeric_limits::lowest()), - glm::dmat2x2(numeric_limits::max()), glm::dmat2x2(0.01)); + glm::dmat2x2(numeric_limits::max()), glm::dmat2x2(0.01), + DEFAULT_FROM_LUA_LAMBDA_4(glm::dmat2x2, glm::dmat2x2(0)), + [](lua_State* state, glm::dmat2x2 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(DMat2x3Property, glm::dmat2x3, glm::dmat2x3(0), glm::dmat2x3(numeric_limits::lowest()), - glm::dmat2x3(numeric_limits::max()), glm::dmat2x3(0.01)); + glm::dmat2x3(numeric_limits::max()), glm::dmat2x3(0.01), + DEFAULT_FROM_LUA_LAMBDA_6(glm::dmat2x3, glm::dmat2x3(0)), + [](lua_State* state, glm::dmat2x3 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(DMat2x4Property, glm::dmat2x4, glm::dmat2x4(0), glm::dmat2x4(numeric_limits::lowest()), - glm::dmat2x4(numeric_limits::max()), glm::dmat2x4(0.01)); + glm::dmat2x4(numeric_limits::max()), glm::dmat2x4(0.01), + DEFAULT_FROM_LUA_LAMBDA_8(glm::dmat2x4, glm::dmat2x4(0)), + [](lua_State* state, glm::dmat2x4 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[0][3])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + lua_pushnumber(state, static_cast(value[1][3])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(DMat3x2Property, glm::dmat3x2, glm::dmat3x2(0), glm::dmat3x2(numeric_limits::lowest()), - glm::dmat3x2(numeric_limits::max()), glm::dmat3x2(0.01)); + glm::dmat3x2(numeric_limits::max()), glm::dmat3x2(0.01), + DEFAULT_FROM_LUA_LAMBDA_6(glm::dmat3x2, glm::dmat3x2(0)), + [](lua_State* state, glm::dmat3x2 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(DMat3Property, glm::dmat3x3, glm::dmat3x3(0), glm::dmat3x3(numeric_limits::lowest()), - glm::dmat3x3(numeric_limits::max()), glm::dmat3x3(0.01)); + glm::dmat3x3(numeric_limits::max()), glm::dmat3x3(0.01), + DEFAULT_FROM_LUA_LAMBDA_9(glm::dmat3x3, glm::dmat3x3(0)), + [](lua_State* state, glm::dmat3x3 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + lua_pushnumber(state, static_cast(value[2][2])); + return true; + } +); + REGISTER_NUMERICALPROPERTY_SOURCE(DMat3x4Property, glm::dmat3x4, glm::dmat3x4(0), glm::dmat3x4(numeric_limits::lowest()), - glm::dmat3x4(numeric_limits::max()), glm::dmat3x4(0.01)); + glm::dmat3x4(numeric_limits::max()), glm::dmat3x4(0.01), + DEFAULT_FROM_LUA_LAMBDA_12(glm::dmat3x4, glm::dmat3x4(0)), + [](lua_State* state, glm::dmat3x4 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[0][3])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + lua_pushnumber(state, static_cast(value[1][3])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + lua_pushnumber(state, static_cast(value[2][2])); + lua_pushnumber(state, static_cast(value[2][3])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(DMat4x2Property, glm::dmat4x2, glm::dmat4x2(0), glm::dmat4x2(numeric_limits::lowest()), - glm::dmat4x2(numeric_limits::max()), glm::dmat4x2(0.01)); + glm::dmat4x2(numeric_limits::max()), glm::dmat4x2(0.01), + DEFAULT_FROM_LUA_LAMBDA_8(glm::dmat4x2, glm::dmat4x2(0)), + [](lua_State* state, glm::dmat4x2 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + lua_pushnumber(state, static_cast(value[3][0])); + lua_pushnumber(state, static_cast(value[3][1])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(DMat4x3Property, glm::dmat4x3, glm::dmat4x3(0), glm::dmat4x3(numeric_limits::lowest()), - glm::dmat4x3(numeric_limits::max()), glm::dmat4x3(0.01)); + glm::dmat4x3(numeric_limits::max()), glm::dmat4x3(0.01), + DEFAULT_FROM_LUA_LAMBDA_12(glm::dmat4x3, glm::dmat4x3(0)), + [](lua_State* state, glm::dmat4x3 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + lua_pushnumber(state, static_cast(value[2][2])); + lua_pushnumber(state, static_cast(value[3][0])); + lua_pushnumber(state, static_cast(value[3][1])); + lua_pushnumber(state, static_cast(value[3][2])); + return true; + } + ); + REGISTER_NUMERICALPROPERTY_SOURCE(DMat4Property, glm::dmat4x4, glm::dmat4x4(0), glm::dmat4x4(numeric_limits::lowest()), - glm::dmat4x4(numeric_limits::max()), glm::dmat4x4(0.01)); - - - - -//REGISTER_NUMERICALPROPERTY_SOURCE(Vec2Property, glm::vec2, glm::vec2(0), -// glm::vec2(numeric_limits::lowest()), glm::vec2(numeric_limits::max()), -// glm::vec2(0.01f)); -//REGISTER_NUMERICALPROPERTY_SOURCE(Vec3Property, glm::vec3, glm::vec3(0), -// glm::vec3(numeric_limits::lowest()), glm::vec3(numeric_limits::max()), -// glm::vec3(0.01f)); -//REGISTER_NUMERICALPROPERTY_SOURCE(Vec4Property, glm::vec4, glm::vec4(0), -// glm::vec4(numeric_limits::lowest()), glm::vec4(numeric_limits::max()), -// glm::vec4(0.01f)); -//REGISTER_NUMERICALPROPERTY_SOURCE(DVec2Property, glm::dvec2, glm::dvec2(0), -// glm::dvec2(numeric_limits::lowest()), -// glm::dvec2(numeric_limits::max()), glm::dvec2(0.01)); -//REGISTER_NUMERICALPROPERTY_SOURCE(DVec3Property, glm::dvec3, glm::dvec3(0), -// glm::dvec3(numeric_limits::lowest()), -// glm::dvec3(numeric_limits::max()), glm::dvec3(0.01)); -//REGISTER_NUMERICALPROPERTY_SOURCE(DVec4Property, glm::dvec4, glm::dvec4(0), -// glm::dvec4(numeric_limits::lowest()), -// glm::dvec4(numeric_limits::max()), glm::dvec4(0.01)); -//REGISTER_NUMERICALPROPERTY_SOURCE(IVec2Property, glm::ivec2, glm::ivec2(0), -// glm::ivec2(numeric_limits::lowest()), glm::ivec2(numeric_limits::max()), -// glm::ivec2(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(IVec3Property, glm::ivec3, glm::ivec3(0), -// glm::ivec3(numeric_limits::lowest()), glm::ivec3(numeric_limits::max()), -// glm::ivec3(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(IVec4Property, glm::ivec4, glm::ivec4(0), -// glm::ivec4(numeric_limits::lowest()), glm::ivec4(numeric_limits::max()), -// glm::ivec4(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(UVec2Property, glm::uvec2, glm::uvec2(0), -// glm::uvec2(numeric_limits::lowest()), -// glm::uvec2(numeric_limits::max()), glm::uvec2(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(UVec3Property, glm::uvec3, glm::uvec3(0), -// glm::uvec3(numeric_limits::lowest()), -// glm::uvec3(numeric_limits::max()), glm::uvec3(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(UVec4Property, glm::uvec4, glm::uvec4(0), -// glm::uvec4(numeric_limits::lowest()), -// glm::uvec4(numeric_limits::max()), glm::uvec4(1)); - - -//REGISTER_NUMERICALPROPERTY_SOURCE(CharProperty, char, char(0), -// numeric_limits::min(), numeric_limits::max(), char(1)); -////REGISTER_NUMERICALPROPERTY_SOURCE(Char16Property, char16_t, char16_t(0), -//// numeric_limits::min(), numeric_limits::max(), char16_t(1)); -////REGISTER_NUMERICALPROPERTY_SOURCE(Char32Property, char32_t, char32_t(0), -//// numeric_limits::min(), numeric_limits::max(), char32_t(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(WCharProperty, wchar_t, wchar_t(0), -// numeric_limits::min(), numeric_limits::max(), wchar_t(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(SignedCharProperty, signed char, signed char(0), -// numeric_limits::min(), numeric_limits::max(), -// signed char(0)); -//REGISTER_NUMERICALPROPERTY_SOURCE(UCharProperty, unsigned char, unsigned char(0), -// numeric_limits::min(), numeric_limits::max(), -// unsigned char(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(ShortProperty, short, short(0), -// numeric_limits::min(), numeric_limits::max(), short(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(UShortProperty, unsigned short, unsigned short(0), -// numeric_limits::min(), numeric_limits::max(), -// unsigned short(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(IntProperty, int, int(0), -// numeric_limits::min(), numeric_limits::max(), int(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(UIntProperty, unsigned int, unsigned int(0), -// numeric_limits::min(), numeric_limits::max(), -// unsigned int(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(LongProperty, long, long(0), -// numeric_limits::min(), numeric_limits::max(), long(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(ULongProperty, unsigned long, unsigned long(0), -// numeric_limits::min(), numeric_limits::max(), -// unsigned long(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(LongLongProperty, long long, long long(0), -// numeric_limits::min(), numeric_limits::max(), long long(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(ULongLongProperty, unsigned long long, -// unsigned long long(1), numeric_limits::min(), -// numeric_limits::max(), unsigned long long(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(FloatProperty, float, 0.f, -// numeric_limits::min(), numeric_limits::max(), 0.01f); -//REGISTER_NUMERICALPROPERTY_SOURCE(DoubleProperty, double, 0.0, -// numeric_limits::min(), numeric_limits::max(), 0.01); -//REGISTER_NUMERICALPROPERTY_SOURCE(LongDoubleProperty, long double, long double(0), -// numeric_limits::min(), numeric_limits::max(), -// long double(0.01f)); - + glm::dmat4x4(numeric_limits::max()), glm::dmat4x4(0.01), + DEFAULT_FROM_LUA_LAMBDA_16(glm::dmat4x4, glm::dmat4x4(0)), + [](lua_State* state, glm::dmat4x4 value) -> bool { + lua_pushnumber(state, static_cast(value[0][0])); + lua_pushnumber(state, static_cast(value[0][1])); + lua_pushnumber(state, static_cast(value[0][2])); + lua_pushnumber(state, static_cast(value[0][3])); + lua_pushnumber(state, static_cast(value[1][0])); + lua_pushnumber(state, static_cast(value[1][1])); + lua_pushnumber(state, static_cast(value[1][2])); + lua_pushnumber(state, static_cast(value[1][3])); + lua_pushnumber(state, static_cast(value[2][0])); + lua_pushnumber(state, static_cast(value[2][1])); + lua_pushnumber(state, static_cast(value[2][2])); + lua_pushnumber(state, static_cast(value[2][3])); + lua_pushnumber(state, static_cast(value[3][0])); + lua_pushnumber(state, static_cast(value[3][1])); + lua_pushnumber(state, static_cast(value[3][2])); + lua_pushnumber(state, static_cast(value[3][3])); + return true; + } + ); } // namespace properties } // namespace openspace diff --git a/src/properties/scalarproperty.cpp b/src/properties/scalarproperty.cpp index 8a24537977..b3562ac2e1 100644 --- a/src/properties/scalarproperty.cpp +++ b/src/properties/scalarproperty.cpp @@ -33,7 +33,7 @@ using std::numeric_limits; namespace openspace { namespace properties { -#define DEFAULT_FROM_LUA_LAMBDA(TYPE, DEFAULT_VALUE, FUNCTION) \ +#define DEFAULT_FROM_LUA_LAMBDA(TYPE, DEFAULT_VALUE) \ [](lua_State* state, bool& success) -> TYPE { \ success = (lua_isnumber(state, -1) == 1); \ if (success) \ diff --git a/src/properties/vectorproperty.cpp b/src/properties/vectorproperty.cpp index 64d894387e..ff9193347d 100644 --- a/src/properties/vectorproperty.cpp +++ b/src/properties/vectorproperty.cpp @@ -38,14 +38,69 @@ namespace properties { #define DEFAULT_FROM_LUA_LAMBDA_2(TYPE, DEFAULT_VALUE) \ [](lua_State* state, bool& success) -> TYPE { \ success = (lua_isnumber(state, -1) == 1) && (lua_isnumber(state, -2) == 1); \ - if (success) { \ - + if (success) \ + return TYPE( \ + static_cast(lua_tonumber(state, -1)), \ + static_cast(lua_tonumber(state, -2))); \ + else \ + return DEFAULT_VALUE; \ } -#define DEFAULT_TO_LUA_LAMBDA(TYPE) \ - [](lua_State* state, TYPE value) -> bool { \ - \ - } +#define DEFAULT_FROM_LUA_LAMBDA_3(TYPE, DEFAULT_VALUE) \ + [](lua_State* state, bool& success) -> TYPE { \ + success = (lua_isnumber(state, -1) == 1) && \ + (lua_isnumber(state, -2) == 1) && \ + (lua_isnumber(state, -3) == 1); \ + if (success) \ + return TYPE( \ + static_cast(lua_tonumber(state, -1)), \ + static_cast(lua_tonumber(state, -2)), \ + static_cast(lua_tonumber(state, -3))); \ + else \ + return DEFAULT_VALUE; \ +} + +#define DEFAULT_FROM_LUA_LAMBDA_4(TYPE, DEFAULT_VALUE) \ + [](lua_State* state, bool& success) -> TYPE { \ + success = (lua_isnumber(state, -1) == 1) && \ + (lua_isnumber(state, -2) == 1) && \ + (lua_isnumber(state, -3) == 1) && \ + (lua_isnumber(state, -4) == 1); \ + if (success) \ + return TYPE( \ + static_cast(lua_tonumber(state, -1)), \ + static_cast(lua_tonumber(state, -2)), \ + static_cast(lua_tonumber(state, -3)), \ + static_cast(lua_tonumber(state, -4))); \ + else \ + return DEFAULT_VALUE; \ +} + +#define DEFAULT_TO_LUA_LAMBDA_2(TYPE) \ + [](lua_State* state, TYPE value) -> bool { \ + lua_pushnumber(state, static_cast(value.x)); \ + lua_pushnumber(state, static_cast(value.y)); \ + return true; \ + } + +#define DEFAULT_TO_LUA_LAMBDA_3(TYPE) \ + [](lua_State* state, TYPE value) -> bool { \ + lua_pushnumber(state, static_cast(value.x)); \ + lua_pushnumber(state, static_cast(value.y)); \ + lua_pushnumber(state, static_cast(value.z)); \ + return true; \ + \ +} + +#define DEFAULT_TO_LUA_LAMBDA_4(TYPE) \ + [](lua_State* state, TYPE value) -> bool { \ + lua_pushnumber(state, static_cast(value.x)); \ + lua_pushnumber(state, static_cast(value.y)); \ + lua_pushnumber(state, static_cast(value.z)); \ + lua_pushnumber(state, static_cast(value.w)); \ + return true; \ + \ +} REGISTER_TEMPLATEPROPERTY_SOURCE(BVec2Property, glm::bvec2, glm::bvec2(false)); REGISTER_TEMPLATEPROPERTY_SOURCE(BVec3Property, glm::bvec3, glm::bvec3(false)); @@ -53,69 +108,69 @@ REGISTER_TEMPLATEPROPERTY_SOURCE(BVec4Property, glm::bvec4, glm::bvec4(false)); REGISTER_NUMERICALPROPERTY_SOURCE(Vec2Property, glm::vec2, glm::vec2(0), glm::vec2(numeric_limits::lowest()), glm::vec2(numeric_limits::max()), - glm::vec2(0.01f), DEFAULT_FROM_LUA_LAMBDA(glm::vec2, glm::vec2(0)), - DEFAULT_TO_LUA_LAMBDA(glm::vec2)); + glm::vec2(0.01f), DEFAULT_FROM_LUA_LAMBDA_2(glm::vec2, glm::vec2(0)), + DEFAULT_TO_LUA_LAMBDA_2(glm::vec2)); REGISTER_NUMERICALPROPERTY_SOURCE(Vec3Property, glm::vec3, glm::vec3(0), glm::vec3(numeric_limits::lowest()), glm::vec3(numeric_limits::max()), - glm::vec3(0.01f), DEFAULT_FROM_LUA_LAMBDA(glm::vec3, glm::vec3(0)), - DEFAULT_TO_LUA_LAMBDA(glm::vec3)); + glm::vec3(0.01f), DEFAULT_FROM_LUA_LAMBDA_3(glm::vec3, glm::vec3(0)), + DEFAULT_TO_LUA_LAMBDA_3(glm::vec3)); REGISTER_NUMERICALPROPERTY_SOURCE(Vec4Property, glm::vec4, glm::vec4(0), glm::vec4(numeric_limits::lowest()), glm::vec4(numeric_limits::max()), - glm::vec4(0.01f), DEFAULT_FROM_LUA_LAMBDA(glm::vec4, glm::vec4(0)), - DEFAULT_TO_LUA_LAMBDA(glm::vec4)); + glm::vec4(0.01f), DEFAULT_FROM_LUA_LAMBDA_4(glm::vec4, glm::vec4(0)), + DEFAULT_TO_LUA_LAMBDA_4(glm::vec4)); REGISTER_NUMERICALPROPERTY_SOURCE(DVec2Property, glm::dvec2, glm::dvec2(0), glm::dvec2(numeric_limits::lowest()), glm::dvec2(numeric_limits::max()), glm::dvec2(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dvec2, glm::dvec2(0)), - DEFAULT_TO_LUA_LAMBDA(glm::dvec2)); + DEFAULT_FROM_LUA_LAMBDA_2(glm::dvec2, glm::dvec2(0)), + DEFAULT_TO_LUA_LAMBDA_2(glm::dvec2)); REGISTER_NUMERICALPROPERTY_SOURCE(DVec3Property, glm::dvec3, glm::dvec3(0), glm::dvec3(numeric_limits::lowest()), glm::dvec3(numeric_limits::max()), glm::dvec3(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dvec3, glm::dvec3(0)), - DEFAULT_TO_LUA_LAMBDA(glm::dvec3)); + DEFAULT_FROM_LUA_LAMBDA_3(glm::dvec3, glm::dvec3(0)), + DEFAULT_TO_LUA_LAMBDA_3(glm::dvec3)); REGISTER_NUMERICALPROPERTY_SOURCE(DVec4Property, glm::dvec4, glm::dvec4(0), glm::dvec4(numeric_limits::lowest()), glm::dvec4(numeric_limits::max()), glm::dvec4(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dvec4, glm::dvec4(0)), - DEFAULT_TO_LUA_LAMBDA(glm::dvec4)); + DEFAULT_FROM_LUA_LAMBDA_4(glm::dvec4, glm::dvec4(0)), + DEFAULT_TO_LUA_LAMBDA_4(glm::dvec4)); REGISTER_NUMERICALPROPERTY_SOURCE(IVec2Property, glm::ivec2, glm::ivec2(0), glm::ivec2(numeric_limits::lowest()), glm::ivec2(numeric_limits::max()), - glm::ivec2(1), DEFAULT_FROM_LUA_LAMBDA(glm::ivec2, glm::ivec2(0)), - DEFAULT_TO_LUA_LAMBDA(glm::ivec2)); + glm::ivec2(1), DEFAULT_FROM_LUA_LAMBDA_2(glm::ivec2, glm::ivec2(0)), + DEFAULT_TO_LUA_LAMBDA_2(glm::ivec2)); REGISTER_NUMERICALPROPERTY_SOURCE(IVec3Property, glm::ivec3, glm::ivec3(0), glm::ivec3(numeric_limits::lowest()), glm::ivec3(numeric_limits::max()), - glm::ivec3(1), DEFAULT_FROM_LUA_LAMBDA(glm::ivec3, glm::ivec3(0)), - DEFAULT_TO_LUA_LAMBDA(glm::ivec3)); + glm::ivec3(1), DEFAULT_FROM_LUA_LAMBDA_3(glm::ivec3, glm::ivec3(0)), + DEFAULT_TO_LUA_LAMBDA_3(glm::ivec3)); REGISTER_NUMERICALPROPERTY_SOURCE(IVec4Property, glm::ivec4, glm::ivec4(0), glm::ivec4(numeric_limits::lowest()), glm::ivec4(numeric_limits::max()), - glm::ivec4(1), DEFAULT_FROM_LUA_LAMBDA(glm::ivec4, glm::ivec4(0)), - DEFAULT_TO_LUA_LAMBDA(glm::ivec4)); + glm::ivec4(1), DEFAULT_FROM_LUA_LAMBDA_4(glm::ivec4, glm::ivec4(0)), + DEFAULT_TO_LUA_LAMBDA_4(glm::ivec4)); REGISTER_NUMERICALPROPERTY_SOURCE(UVec2Property, glm::uvec2, glm::uvec2(0), glm::uvec2(numeric_limits::lowest()), glm::uvec2(numeric_limits::max()), glm::uvec2(1), - DEFAULT_FROM_LUA_LAMBDA(glm::uvec2, glm::uvec2(0)), - DEFAULT_TO_LUA_LAMBDA(glm::uvec2)); + DEFAULT_FROM_LUA_LAMBDA_2(glm::uvec2, glm::uvec2(0)), + DEFAULT_TO_LUA_LAMBDA_2(glm::uvec2)); REGISTER_NUMERICALPROPERTY_SOURCE(UVec3Property, glm::uvec3, glm::uvec3(0), glm::uvec3(numeric_limits::lowest()), glm::uvec3(numeric_limits::max()), glm::uvec3(1), - DEFAULT_FROM_LUA_LAMBDA(glm::uvec3, glm::uvec3(0)), - DEFAULT_TO_LUA_LAMBDA(glm::uvec3)); + DEFAULT_FROM_LUA_LAMBDA_3(glm::uvec3, glm::uvec3(0)), + DEFAULT_TO_LUA_LAMBDA_3(glm::uvec3)); REGISTER_NUMERICALPROPERTY_SOURCE(UVec4Property, glm::uvec4, glm::uvec4(0), glm::uvec4(numeric_limits::lowest()), glm::uvec4(numeric_limits::max()), glm::uvec4(1), - DEFAULT_FROM_LUA_LAMBDA(glm::uvec4, glm::uvec4(0)), - DEFAULT_TO_LUA_LAMBDA(glm::uvec4)); + DEFAULT_FROM_LUA_LAMBDA_4(glm::uvec4, glm::uvec4(0)), + DEFAULT_TO_LUA_LAMBDA_4(glm::uvec4)); } // namespace properties diff --git a/src/scripting/scriptfunctions.cpp b/src/scripting/scriptfunctions.cpp index 8cc8ebe79a..cf7279f20d 100644 --- a/src/scripting/scriptfunctions.cpp +++ b/src/scripting/scriptfunctions.cpp @@ -137,8 +137,7 @@ int property_setValue(lua_State* L) if (type != prop->typeLua()) LERROR("Property '" << uri << "' does not accept input of type '" << luaTypeToString(type) << "'. Requested type: '" - << luaTypeToString(prop->typeLua() << "'"); - } + << luaTypeToString(prop->typeLua()) << "'"); else prop->setLua(L); //prop->set(propertyValue); From be3f7277064f69d7b3dc350cf9cf66b85ef8356e Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 2 Sep 2014 20:59:29 +0200 Subject: [PATCH 061/113] Apply to-Lua and from-Lua functionality to TemplateProperty as well --- .../properties/numericalproperty.inl | 168 ++++++++++++------ .../openspace/properties/propertydelegate.h | 2 + .../openspace/properties/propertydelegate.inl | 6 + include/openspace/properties/stringproperty.h | 14 +- .../openspace/properties/templateproperty.h | 5 + .../openspace/properties/templateproperty.inl | 68 ++++++- src/properties/scalarproperty.cpp | 15 +- src/properties/stringproperty.cpp | 31 +++- src/properties/vectorproperty.cpp | 65 ++++++- 9 files changed, 303 insertions(+), 71 deletions(-) diff --git a/include/openspace/properties/numericalproperty.inl b/include/openspace/properties/numericalproperty.inl index 8d16ca33e9..34f73111fd 100644 --- a/include/openspace/properties/numericalproperty.inl +++ b/include/openspace/properties/numericalproperty.inl @@ -27,58 +27,120 @@ namespace openspace { namespace properties { -#define REGISTER_NUMERICALPROPERTY_HEADER(CLASS_NAME, TYPE) \ - typedef NumericalProperty CLASS_NAME; \ - template <> std::string PropertyDelegate>::className(); \ - template <> std::string PropertyDelegate>::className(); \ - template <> template <> \ - TYPE PropertyDelegate>::defaultValue(); \ - template <> template <> \ - TYPE PropertyDelegate>::defaultMinimumValue(); \ - template <> template <> \ - TYPE PropertyDelegate>::defaultMaximumValue(); \ - template <> template <> \ - TYPE PropertyDelegate>::fromLuaValue( \ - lua_State* state, bool& success); \ - template <> template <> \ - bool PropertyDelegate>::toLuaValue( \ - lua_State* state, TYPE value); +#define REGISTER_NUMERICALPROPERTY_HEADER(CLASS_NAME, TYPE) \ + typedef NumericalProperty CLASS_NAME; \ + template <> \ + std::string PropertyDelegate>::className(); \ + template <> \ + std::string PropertyDelegate>::className(); \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultValue(); \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultMinimumValue(); \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultMaximumValue(); \ + template <> \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ + bool& success); \ + template <> \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ + bool& success); \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State* state, \ + TYPE value); \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State* state, \ + TYPE value); \ + template <> \ + int PropertyDelegate>::typeLua(); \ + template <> \ + int PropertyDelegate>::typeLua(); - -#define REGISTER_NUMERICALPROPERTY_SOURCE(CLASS_NAME, TYPE, \ - DEFAULT_VALUE, DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, DEFAULT_STEPPING, \ - FROM_LUA_LAMBDA_EXPRESSION, TO_LUA_LAMBDA_EXPRESSION) \ - template <> \ - std::string PropertyDelegate>::className() { \ - return #CLASS_NAME; \ -} \ - template <> \ - std::string PropertyDelegate>::className() { \ - return #CLASS_NAME; \ -} \ - template <> template <> \ - TYPE PropertyDelegate>::defaultValue() { \ - return DEFAULT_VALUE; \ -} \ - template <> template <> \ - TYPE PropertyDelegate>::defaultMinimumValue() { \ - return DEFAULT_MIN_VALUE; \ -} \ - template <> template <> \ - TYPE PropertyDelegate>::defaultMaximumValue() { \ - return DEFAULT_MAX_VALUE; \ -} \ - template <> template <> \ - TYPE PropertyDelegate>::fromLuaValue( \ - lua_State* state, bool& success) { \ - return FROM_LUA_LAMBDA_EXPRESSION(state, success); \ -} \ - template <> template <> \ - bool PropertyDelegate>::toLuaValue( \ - lua_State* state, TYPE value) { \ - return TO_LUA_LAMBDA_EXPRESSION(state, value); \ -} - +#define REGISTER_NUMERICALPROPERTY_SOURCE(CLASS_NAME, TYPE, DEFAULT_VALUE, \ + DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, \ + DEFAULT_STEPPING, FROM_LUA_LAMBDA_EXPRESSION, \ + TO_LUA_LAMBDA_EXPRESSION) \ + template <> \ + std::string PropertyDelegate>::className() \ + { \ + return #CLASS_NAME; \ + \ +} \ + template <> \ + std::string PropertyDelegate>::className() \ + { \ + return PropertyDelegate>::className(); \ + \ +} \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultValue() \ + { \ + return DEFAULT_VALUE; \ + \ +} \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultMinimumValue() \ + { \ + return DEFAULT_MIN_VALUE; \ + \ +} \ + template <> \ + template <> \ + TYPE PropertyDelegate>::defaultMaximumValue() \ + { \ + return DEFAULT_MAX_VALUE; \ + \ +} \ + template <> \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue(lua_State * state, \ + bool& success) \ + { \ + return FROM_LUA_LAMBDA_EXPRESSION(state, success); \ + \ +} \ + template <> \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue( \ + lua_State * state, bool& success) \ + { \ + return PropertyDelegate>::fromLuaValue(state, \ + success); \ + \ +} \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State * state, \ + TYPE value) \ + { \ + return TO_LUA_LAMBDA_EXPRESSION(state, value); \ + } \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State * state, \ + TYPE value) \ + { \ + return PropertyDelegate>::toLuaValue(state, value); \ + } \ + template <> \ + int PropertyDelegate>::typeLua() \ + { \ + return LUA_TNUMBER; \ + } \ + template <> \ + int PropertyDelegate>::typeLua() \ + { \ + return PropertyDelegate>::typeLua(); \ + } // Delegating constructors are necessary; automatic template deduction cannot // deduce template argument for 'U' if 'default' methods are used as default values in @@ -133,8 +195,8 @@ bool NumericalProperty::getLua(lua_State* state) const } template -int openspace::properties::NumericalProperty::typeLua() const { - return LUA_TNUMBER; +int NumericalProperty::typeLua() const { + return PropertyDelegate>::typeLua(); } diff --git a/include/openspace/properties/propertydelegate.h b/include/openspace/properties/propertydelegate.h index feeb411c05..a97ae67cf0 100644 --- a/include/openspace/properties/propertydelegate.h +++ b/include/openspace/properties/propertydelegate.h @@ -51,6 +51,8 @@ public: template static bool toLuaValue(lua_State* state, U value); + + static int typeLua(); }; } // namespace properties diff --git a/include/openspace/properties/propertydelegate.inl b/include/openspace/properties/propertydelegate.inl index 8088fb4b4b..7f0f57e344 100644 --- a/include/openspace/properties/propertydelegate.inl +++ b/include/openspace/properties/propertydelegate.inl @@ -71,5 +71,11 @@ bool PropertyDelegate::toLuaValue(lua_State* state, U value) { "Unimplemented PropertyDelegate::toLuaValue specialization"); } +template +int PropertyDelegate::typeLua() { + static_assert(sizeof(T) == 0, + "Unimplemented PropertyDelegate::luaType specialization"); +} + } // namespace properties } // namespace openspace diff --git a/include/openspace/properties/stringproperty.h b/include/openspace/properties/stringproperty.h index c1dc995c86..7fa08b1753 100644 --- a/include/openspace/properties/stringproperty.h +++ b/include/openspace/properties/stringproperty.h @@ -45,7 +45,19 @@ template <> template <> std::string PropertyDelegate>::defaultValue(); -//REGISTER_TEMPLATEPROPERTY_HEADER(StringProperty, std::string); +template <> +template <> +std::string PropertyDelegate>::fromLuaValue( + lua_State* state, bool& success); + +template <> +template <> +bool PropertyDelegate>::toLuaValue( + lua_State* state, std::string value); + +template <> +int PropertyDelegate>::typeLua(); + } // namespace properties diff --git a/include/openspace/properties/templateproperty.h b/include/openspace/properties/templateproperty.h index d38e0cc660..1906a4299f 100644 --- a/include/openspace/properties/templateproperty.h +++ b/include/openspace/properties/templateproperty.h @@ -41,6 +41,11 @@ public: virtual void set(boost::any value) override; virtual const std::type_info& type() const override; + bool getLua(lua_State* state) const override; + bool setLua(lua_State* state) override; + int typeLua() const override; + + operator T(); TemplateProperty& operator=(T val); diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index 25648695d9..2db1902329 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -31,20 +31,52 @@ namespace properties { std::string PropertyDelegate>::className(); \ template <> \ template <> \ - TYPE PropertyDelegate>::defaultValue(); - -#define REGISTER_TEMPLATEPROPERTY_SOURCE(CLASS_NAME, TYPE, DEFAULT_VALUE) \ + TYPE PropertyDelegate>::defaultValue(); \ template <> \ - std::string PropertyDelegate>::className() { \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue(lua_State* state, \ + bool& success); \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State* state, \ + TYPE value); \ + template <> \ + int PropertyDelegate>::typeLua(); + +#define REGISTER_TEMPLATEPROPERTY_SOURCE(CLASS_NAME, TYPE, DEFAULT_VALUE, \ + FROM_LUA_LAMBDA_EXPRESSION, \ + TO_LUA_LAMBDA_EXPRESSION, LUA_TYPE) \ + template <> \ + std::string PropertyDelegate>::className() \ + { \ return #CLASS_NAME; \ \ } \ template <> \ template <> \ - TYPE PropertyDelegate>::defaultValue() { \ + TYPE PropertyDelegate>::defaultValue() \ + { \ return DEFAULT_VALUE; \ - \ -} + } \ + template <> \ + template <> \ + TYPE PropertyDelegate>::fromLuaValue(lua_State * state, \ + bool& success) \ + { \ + return FROM_LUA_LAMBDA_EXPRESSION(state, success); \ + } \ + template <> \ + template <> \ + bool PropertyDelegate>::toLuaValue(lua_State * state, \ + TYPE value) \ + { \ + return TO_LUA_LAMBDA_EXPRESSION(state, value); \ + } \ + template <> \ + int PropertyDelegate>::typeLua() \ + { \ + return LUA_TYPE; \ + } // Delegating constructors are necessary; automatic template deduction cannot // deduce template argument for 'U' if 'default' methods are used as default values in @@ -114,5 +146,27 @@ const std::type_info& TemplateProperty::type() const { return typeid(T); } +template +bool TemplateProperty::setLua(lua_State* state) +{ + bool success; + T value = PropertyDelegate>::fromLuaValue(state, success); + if (success) + set(value); + return success; +} + +template +bool TemplateProperty::getLua(lua_State* state) const +{ + bool success = PropertyDelegate>::toLuaValue(state, _value); + return success; +} + +template +int TemplateProperty::typeLua() const { + return PropertyDelegate>::typeLua(); +} + } // namespace properties } // namespace openspace diff --git a/src/properties/scalarproperty.cpp b/src/properties/scalarproperty.cpp index b3562ac2e1..01ba23820f 100644 --- a/src/properties/scalarproperty.cpp +++ b/src/properties/scalarproperty.cpp @@ -51,7 +51,20 @@ namespace properties { // char16_t and char32_t are not supported on Visual Studio 2013 and are defined to // be equal to unsigned short and unsigned int which causes a compile error -REGISTER_TEMPLATEPROPERTY_SOURCE(BoolProperty, bool, false); +REGISTER_TEMPLATEPROPERTY_SOURCE(BoolProperty, bool, false, + [](lua_State* state, bool& success) -> bool { + success = (lua_isboolean(state, -1) == 1); + if (success) + return lua_toboolean(state, -1) == 1; + else + return false; + }, + [](lua_State* state, bool value) -> bool { + lua_pushboolean(state, value); + return true; + }, + LUA_TBOOLEAN + ); REGISTER_NUMERICALPROPERTY_SOURCE(CharProperty, char, char(0), numeric_limits::lowest(), numeric_limits::max(), char(1), diff --git a/src/properties/stringproperty.cpp b/src/properties/stringproperty.cpp index a60115cd29..1389f2c200 100644 --- a/src/properties/stringproperty.cpp +++ b/src/properties/stringproperty.cpp @@ -24,6 +24,8 @@ #include +#include + namespace openspace { namespace properties { @@ -50,12 +52,31 @@ std::string PropertyDelegate>::defaultValue +template <> +std::string PropertyDelegate>::fromLuaValue( + lua_State* state, bool& success) +{ + success = lua_isstring(state, -1) == 1; + if (success) + return lua_tostring(state, -1); + else + return ""; +} -//REGISTER_TEMPLATEPROPERTY_SOURCE(StringProperty, std::string, ""); -// -//std::string openspace::properties::StringProperty::className() const { -// return "StringProperty"; -//} +template <> +template <> +bool PropertyDelegate>::toLuaValue( + lua_State* state, std::string value) +{ + lua_pushstring(state, value.c_str()); + return true; +} + +template <> +int PropertyDelegate>::typeLua() { + return LUA_TSTRING; +} } // namespace properties } // namespace openspace diff --git a/src/properties/vectorproperty.cpp b/src/properties/vectorproperty.cpp index ff9193347d..ecd2f01f16 100644 --- a/src/properties/vectorproperty.cpp +++ b/src/properties/vectorproperty.cpp @@ -102,14 +102,71 @@ namespace properties { \ } -REGISTER_TEMPLATEPROPERTY_SOURCE(BVec2Property, glm::bvec2, glm::bvec2(false)); -REGISTER_TEMPLATEPROPERTY_SOURCE(BVec3Property, glm::bvec3, glm::bvec3(false)); -REGISTER_TEMPLATEPROPERTY_SOURCE(BVec4Property, glm::bvec4, glm::bvec4(false)); +REGISTER_TEMPLATEPROPERTY_SOURCE(BVec2Property, glm::bvec2, glm::bvec2(false), + [](lua_State* state, bool& success) -> glm::bvec2 { + success = (lua_isboolean(state, -1) == 1) && (lua_isboolean(state, -2) == 1); + if (success) + return glm::bvec2(lua_toboolean(state, -1), lua_toboolean(state, -2)); + else + return glm::bvec2(false); + }, + [](lua_State* state, glm::bvec2 value) -> bool { + lua_pushboolean(state, value.x); + lua_pushboolean(state, value.y); + return true; + }, + LUA_TTABLE + ); + +REGISTER_TEMPLATEPROPERTY_SOURCE(BVec3Property, glm::bvec3, glm::bvec3(false), + [](lua_State* state, bool& success) -> glm::bvec3 { + success = (lua_isboolean(state, -1) == 1) && + (lua_isboolean(state, -2) == 1) && + (lua_isboolean(state, -3) == 1); + if (success) + return glm::bvec3(lua_toboolean(state, -1), + lua_toboolean(state, -2), + lua_toboolean(state, -3)); + else + return glm::bvec3(false); + }, + [](lua_State* state, glm::bvec3 value) -> bool { + lua_pushboolean(state, value.x); + lua_pushboolean(state, value.y); + lua_pushboolean(state, value.z); + return true; + }, + LUA_TTABLE + ); + +REGISTER_TEMPLATEPROPERTY_SOURCE(BVec4Property, glm::bvec4, glm::bvec4(false), + [](lua_State* state, bool& success) -> glm::bvec4 { + success = (lua_isboolean(state, -1) == 1) && + (lua_isboolean(state, -2) == 1) && + (lua_isboolean(state, -3) == 1) && + (lua_isboolean(state, -4) == 1); + if (success) + return glm::bvec4(lua_toboolean(state, -1), + lua_toboolean(state, -2), + lua_toboolean(state, -3), + lua_toboolean(state, -4)); + else + return glm::bvec4(false); + }, + [](lua_State* state, glm::bvec4 value) -> bool { + lua_pushboolean(state, value.x); + lua_pushboolean(state, value.y); + lua_pushboolean(state, value.z); + lua_pushboolean(state, value.w); + return true; + }, + LUA_TTABLE + ); REGISTER_NUMERICALPROPERTY_SOURCE(Vec2Property, glm::vec2, glm::vec2(0), glm::vec2(numeric_limits::lowest()), glm::vec2(numeric_limits::max()), glm::vec2(0.01f), DEFAULT_FROM_LUA_LAMBDA_2(glm::vec2, glm::vec2(0)), - DEFAULT_TO_LUA_LAMBDA_2(glm::vec2)); + DEFAULT_TO_LUA_LAMBDA_2(glm::vec2)); // , LUA_TTABLE REGISTER_NUMERICALPROPERTY_SOURCE(Vec3Property, glm::vec3, glm::vec3(0), glm::vec3(numeric_limits::lowest()), glm::vec3(numeric_limits::max()), From 98edb338cb3933d5837f13fdb13bd98478b60ac7 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 2 Sep 2014 21:18:35 +0200 Subject: [PATCH 062/113] Removed empty files --- src/properties/numericalproperty.cpp | 26 -------------------------- src/properties/propertydelegate.cpp | 26 -------------------------- 2 files changed, 52 deletions(-) delete mode 100644 src/properties/numericalproperty.cpp delete mode 100644 src/properties/propertydelegate.cpp diff --git a/src/properties/numericalproperty.cpp b/src/properties/numericalproperty.cpp deleted file mode 100644 index 2242371adc..0000000000 --- a/src/properties/numericalproperty.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ - -#include "openspace/properties/numericalproperty.h" - diff --git a/src/properties/propertydelegate.cpp b/src/properties/propertydelegate.cpp deleted file mode 100644 index 8c77653821..0000000000 --- a/src/properties/propertydelegate.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ - -#include "openspace/properties/propertydelegate.h" - From ac80776a288f2a1afb93a131c76181fff062fbef Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 2 Sep 2014 21:20:10 +0200 Subject: [PATCH 063/113] Cleanup test code; removed warnings mostly and reenabled scenegraph test --- .../tests/test_powerscalecoordinates.inl | 16 ++-- include/openspace/tests/test_scenegraph.inl | 8 +- include/openspace/tests/test_spicemanager.inl | 91 +++++++++++-------- src/tests/main.cpp | 2 +- 4 files changed, 68 insertions(+), 49 deletions(-) diff --git a/include/openspace/tests/test_powerscalecoordinates.inl b/include/openspace/tests/test_powerscalecoordinates.inl index ce500fe3b1..d5666f6c96 100644 --- a/include/openspace/tests/test_powerscalecoordinates.inl +++ b/include/openspace/tests/test_powerscalecoordinates.inl @@ -25,6 +25,8 @@ #include "gtest/gtest.h" +#include + #include #include @@ -45,10 +47,10 @@ protected: TEST_F(PowerscaleCoordinatesTest, psc) { - openspace::psc reference(2.0, 1.0, 1.1, 1.0); + openspace::psc reference(2.f, 1.f, 1.1f, 1.f); - openspace::psc first(1.0,0.0,1.0,0.0); - openspace::psc second(1.9,1.0,1.0,1.0); + openspace::psc first(1.f, 0.f, 1.f, 0.f); + openspace::psc second(1.9f, 1.f, 1.f, 1.f); EXPECT_EQ(reference, first + second); EXPECT_TRUE(reference == (first + second)); @@ -63,10 +65,10 @@ TEST_F(PowerscaleCoordinatesTest, psc) { TEST_F(PowerscaleCoordinatesTest, pss) { - openspace::pss first(1.0,1.0); - openspace::pss second(1.0,-1.0); - EXPECT_EQ(openspace::pss(1.01,1.0), first + second); - EXPECT_EQ(openspace::pss(1.01,1.0), second + first); + openspace::pss first(1.f, 1.f); + openspace::pss second(1.f, -1.f); + EXPECT_EQ(openspace::pss(1.01f, 1.f), first + second); + EXPECT_EQ(openspace::pss(1.01f, 1.f), second + first); /* EXPECT_TRUE(first < (first + second)); bool retu =(second < (first + second)); diff --git a/include/openspace/tests/test_scenegraph.inl b/include/openspace/tests/test_scenegraph.inl index daef846cd0..186d955c45 100644 --- a/include/openspace/tests/test_scenegraph.inl +++ b/include/openspace/tests/test_scenegraph.inl @@ -55,8 +55,8 @@ TEST_F(SceneGraphTest, SceneGraphNode) { openspace::SceneGraphNode::createFromDictionary(ghoul::Dictionary()); // Should not have a renderable and position should be 0,0,0,0 (undefined). - EXPECT_EQ(nullptr, node->getRenderable()); - EXPECT_EQ(openspace::psc(), node->getPosition()); + EXPECT_EQ(nullptr, node->renderable()); + EXPECT_EQ(openspace::psc(), node->position()); delete node; ghoul::Dictionary nodeDictionary; @@ -83,10 +83,10 @@ TEST_F(SceneGraphTest, SceneGraphNode) { openspace::SceneGraphNode::createFromDictionary(nodeDictionary); // This node should have a renderable (probably no good values but an existing one) - EXPECT_TRUE(node->getRenderable()); + EXPECT_TRUE(node->renderable()); // position should be initialized - EXPECT_EQ(openspace::psc(1.0,1.0,1.0,1.0), node->getPosition()); + EXPECT_EQ(openspace::psc(1.0,1.0,1.0,1.0), node->position()); delete node; } diff --git a/include/openspace/tests/test_spicemanager.inl b/include/openspace/tests/test_spicemanager.inl index 24e62103fc..d69c69a657 100644 --- a/include/openspace/tests/test_spicemanager.inl +++ b/include/openspace/tests/test_spicemanager.inl @@ -22,6 +22,7 @@ * 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 "gtest/gtest.h" #include "openspace/util/spicemanager.h" @@ -49,7 +50,6 @@ protected: const int nrMetaKernels = 9; int which, handle, count = 0; char file[FILLEN], filtyp[TYPLEN], source[SRCLEN]; -int found; double abs_error = 0.00001; @@ -77,9 +77,10 @@ std::string fileType(char type[]){ TEST_F(SpiceManagerTest, loadSingleKernel){ loadLSKKernel(); //naif0008.tls is a text file, check if loaded. + SpiceBoolean found; kdata_c(0, "text", FILLEN, TYPLEN, SRCLEN, file, filtyp, source, &handle, &found); - ASSERT_TRUE(found) << "Kernel not loaded"; + ASSERT_TRUE(found == SPICETRUE) << "Kernel not loaded"; unload_c(LSK.c_str()); } @@ -93,6 +94,7 @@ TEST_F(SpiceManagerTest, loadMetaKernel){ "TEXT", "CK", "TEXT" }; // If one of the kernels does not load we expect a mismatch for (int i = 0; i < nrMetaKernels; i++){ + SpiceBoolean found; kdata_c(i, "all", FILLEN, TYPLEN, SRCLEN, file, filtyp, source, &handle, &found); EXPECT_EQ(fileType(filtyp), typeArr[i]) << "One or more kernels did not load properly"; } @@ -102,29 +104,33 @@ TEST_F(SpiceManagerTest, loadMetaKernel){ TEST_F(SpiceManagerTest, unloadKernelString){ loadLSKKernel(); //naif0008.tls is a text file, check if loaded. + SpiceBoolean found; kdata_c(0, "text", FILLEN, TYPLEN, SRCLEN, file, filtyp, source, &handle, &found); - ASSERT_TRUE(found); + ASSERT_TRUE(found == SPICETRUE); //unload using string keyword bool unloaded = openspace::SpiceManager::ref().unloadKernel("LEAPSECONDS"); EXPECT_TRUE(unloaded); + found = SPICEFALSE; kdata_c(0, "text", FILLEN, TYPLEN, SRCLEN, file, filtyp, source, &handle, &found); - EXPECT_FALSE(found); + EXPECT_FALSE(found == SPICETRUE); } // Try unloading kernel using integer as ID TEST_F(SpiceManagerTest, unloadKernelInteger){ int kernelID = loadLSKKernel(); //naif0008.tls is a text file, check if loaded. + SpiceBoolean found; kdata_c(0, "text", FILLEN, TYPLEN, SRCLEN, file, filtyp, source, &handle, &found); - ASSERT_TRUE(found); + ASSERT_TRUE(found == SPICETRUE); //unload using unique int ID bool unloaded = openspace::SpiceManager::ref().unloadKernel(kernelID); EXPECT_TRUE(unloaded) << "Kernel did not unload"; + found = SPICEFALSE; kdata_c(0, "text", FILLEN, TYPLEN, SRCLEN, file, filtyp, source, &handle, &found); - EXPECT_FALSE(found) << "One or more kernels still present in kernel-pool"; + EXPECT_FALSE(found == SPICETRUE) << "One or more kernels still present in kernel-pool"; } // Try unloading multiple kernels TEST_F(SpiceManagerTest, unloadMetaKernel){ @@ -136,6 +142,7 @@ TEST_F(SpiceManagerTest, unloadMetaKernel){ for (int i = 0; i < nrMetaKernels; i++){ // check kernelpool against typeArr + SpiceBoolean found; kdata_c(i, "all", FILLEN, TYPLEN, SRCLEN, file, filtyp, source, &handle, &found); EXPECT_EQ(fileType(filtyp), typeArr[i]) << "One or more kernels did not load properly"; } @@ -144,8 +151,9 @@ TEST_F(SpiceManagerTest, unloadMetaKernel){ for (int i = 0; i < nrMetaKernels; i++){ // the values should by now be unloaded + SpiceBoolean found; kdata_c(i, "all", FILLEN, TYPLEN, SRCLEN, file, filtyp, source, &handle, &found); - EXPECT_FALSE(found) << "Failed unloading kernel"; + EXPECT_FALSE(found == SPICETRUE) << "Failed unloading kernel"; } unload_c(META.c_str()); } @@ -153,13 +161,11 @@ TEST_F(SpiceManagerTest, unloadMetaKernel){ TEST_F(SpiceManagerTest, hasValue){ loadPCKKernel(); - int n; int naifId = 399; //Earth - double radii[3]; std::string kernelPoolValue = "RADII"; - found = openspace::SpiceManager::ref().hasValue(naifId, kernelPoolValue); + bool found = openspace::SpiceManager::ref().hasValue(naifId, kernelPoolValue); ASSERT_TRUE(found) << "Could not find value for specified kernel"; unload_c(PCK.c_str()); } @@ -171,7 +177,7 @@ TEST_F(SpiceManagerTest, getValueFromID_1D){ std::string value1D = "MAG_NORTH_POLE_LAT"; double return1D; - found = openspace::SpiceManager::ref().getValueFromID(target, value1D, return1D); + bool found = openspace::SpiceManager::ref().getValueFromID(target, value1D, return1D); ASSERT_TRUE(found) << "Could not retrieve value"; EXPECT_EQ(return1D, 78.565) << "Value not found / differs from expected return"; unload_c(PCK.c_str()); @@ -200,14 +206,14 @@ TEST_F(SpiceManagerTest, getValueFromID_ND){ std::vector returnND; unsigned int nr = 5; - found = openspace::SpiceManager::ref().getValueFromID(target, valueND, returnND, nr); + bool found = openspace::SpiceManager::ref().getValueFromID(target, valueND, returnND, nr); ASSERT_TRUE(found) << "Could not retrieve value for specified kernel"; std::vector controlVec{ 189870.0, 256900.0, 9000.0, 9000.0, 0.000003 }; ASSERT_EQ(controlVec.size(), returnND.size()) << "Vectors differ in size"; - for (int i = 0; i < nr; i++){ + for (unsigned int i = 0; i < nr; ++i){ EXPECT_EQ(controlVec[i], returnND[i]) << "Vector value not equal"; } unload_c(PCK.c_str()); @@ -240,7 +246,7 @@ TEST_F(SpiceManagerTest, getTargetPosition){ glm::dvec3 targetPosition; double lightTime = 0.0; - found = openspace::SpiceManager::ref().getTargetPosition("EARTH", et, "J2000", "LT+S", "CASSINI", + bool found = openspace::SpiceManager::ref().getTargetPosition("EARTH", et, "J2000", "LT+S", "CASSINI", targetPosition, lightTime); ASSERT_TRUE(found); EXPECT_DOUBLE_EQ(pos[0], targetPosition[0]) << "Position not found or differs from expected return"; @@ -263,7 +269,7 @@ TEST_F(SpiceManagerTest, getTargetState){ glm::dvec3 targetPosition; glm::dvec3 targetVelocity; double lightTime = 0.0; - found = openspace::SpiceManager::ref().getTargetState("EARTH", et, "J2000", "LT+S", "CASSINI", + bool found = openspace::SpiceManager::ref().getTargetState("EARTH", et, "J2000", "LT+S", "CASSINI", targetPosition, targetVelocity, lightTime); ASSERT_TRUE(found); //x,y,z @@ -291,7 +297,7 @@ TEST_F(SpiceManagerTest, getStateTransformMatrix){ glm::dvec3 velocity(state[3], state[4], state[5]); openspace::transformMatrix stateMatrix(6); - found = openspace::SpiceManager::ref().getStateTransformMatrix("J2000", + bool found = openspace::SpiceManager::ref().getStateTransformMatrix("J2000", "IAU_PHOEBE", et, stateMatrix); @@ -317,7 +323,6 @@ TEST_F(SpiceManagerTest, getPositionTransformMatrix){ loadMetaKernel(); double et; - double lt; double state[3] = { 1.0, 1.0, 1.0 }; double state_t[3]; double referenceMatrix[3][3]; @@ -327,7 +332,7 @@ TEST_F(SpiceManagerTest, getPositionTransformMatrix){ openspace::transformMatrix positionMatrix(3); glm::dvec3 position(state[0], state[1], state[2]); - found = openspace::SpiceManager::ref().getPositionTransformMatrix("CASSINI_HGA", + bool found = openspace::SpiceManager::ref().getPositionTransformMatrix("CASSINI_HGA", "J2000", et, positionMatrix); @@ -355,17 +360,16 @@ TEST_F(SpiceManagerTest, getFieldOfView){ int n; int cassini_ID; double et; - double lt; double boresight[3]; double bounds_ref[5][3]; char shape_ref[TYPLEN]; char name_ref[FILLEN]; str2et_c("2004 jun 11 19:32:00", &et); + SpiceBoolean found; bodn2c_c("CASSINI_ISS_NAC", &cassini_ID, &found); - if (!found){ - printf("error cannot locate ID for Cassini \n"); - } + ASSERT_TRUE(found == SPICETRUE) << "Cannot locate ID for Cassini"; + getfov_c(cassini_ID, 5, TYPLEN, TYPLEN, shape_ref, name_ref, boresight, &n, bounds_ref); std::string shape, name; @@ -379,7 +383,7 @@ TEST_F(SpiceManagerTest, getFieldOfView){ boresight, bounds, nrReturned); - ASSERT_TRUE(found); + ASSERT_TRUE(found == SPICETRUE); //check vectors have correct values for (int i = 0; i < nrReturned; i++){ for (int j = 0; j < 3; j++){ @@ -399,14 +403,17 @@ TEST_F(SpiceManagerTest, rectangularToLatitudal){ obspos[3], point_ref[3]; double dist, et, radius_ref, trgepc; int n, naifId; - int found; + bool found; + SpiceBoolean foundSpice; // First, find an intersection point to convert to rectangular coordinates str2et_c("2004 jun 11 19:32:00", &et); - bodn2c_c("CASSINI_ISS_NAC", &naifId, &found); + bodn2c_c("CASSINI_ISS_NAC", &naifId, &foundSpice); + ASSERT_TRUE(foundSpice == SPICETRUE); getfov_c(naifId, 4, FILLEN, FILLEN, shape, frame, bsight, &n, bounds); srfxpt_c("Ellipsoid", "PHOEBE", et, "LT+S", "CASSINI", frame, bsight, - point_ref, &dist, &trgepc, obspos, &found); + point_ref, &dist, &trgepc, obspos, &foundSpice); + ASSERT_TRUE(foundSpice == SPICETRUE); reclat_c(point_ref, &radius_ref, &lon, &lat); glm::dvec3 point(point_ref[0], point_ref[1], point_ref[2]); @@ -429,13 +436,17 @@ TEST_F(SpiceManagerTest, latitudinalToRectangular){ obspos[3], point_ref[3]; double dist, et, radius_ref, trgepc; int n, naifId; + SpiceBoolean foundSpice; // First, find an intersection point to convert to latitudinal coordinates // str2et_c("2004 jun 11 19:32:00", &et); - bodn2c_c("CASSINI_ISS_NAC", &naifId, &found); + bodn2c_c("CASSINI_ISS_NAC", &naifId, &foundSpice); + ASSERT_TRUE(foundSpice == SPICETRUE); getfov_c(naifId, 4, FILLEN, FILLEN, shape, frame, bsight, &n, bounds); + foundSpice = SPICEFALSE; srfxpt_c("Ellipsoid", "PHOEBE", et, "LT+S", "CASSINI", frame, bsight, - point_ref, &dist, &trgepc, obspos, &found); + point_ref, &dist, &trgepc, obspos, &foundSpice); + ASSERT_TRUE(foundSpice == SPICETRUE); reclat_c(point_ref, &radius_ref, &lon, &lat); @@ -449,7 +460,7 @@ TEST_F(SpiceManagerTest, latitudinalToRectangular){ latrec_c(radius_ref, lon, lat, rectangular_ref); glm::dvec3 coordinates; - found = openspace::SpiceManager::ref().latidudinalToRectangular(radius_ref, lon, lat, coordinates); + bool found = openspace::SpiceManager::ref().latidudinalToRectangular(radius_ref, lon, lat, coordinates); ASSERT_TRUE(found); ASSERT_NEAR(lon_ref, lon, abs_error) << "longitude is not set / has incorrect values"; @@ -463,14 +474,16 @@ TEST_F(SpiceManagerTest, planetocentricToRectangular){ double lat = -35.0; //initial values double lon = 100.0; double rectangular_ref[3]; - double radius; int naifId; + SpiceBoolean foundSpice; - bodn2c_c("EARTH", &naifId, &found); + bodn2c_c("EARTH", &naifId, &foundSpice); + ASSERT_TRUE(foundSpice == SPICETRUE); srfrec_c(naifId, lon*rpd_c(), lat*rpd_c(), rectangular_ref); glm::dvec3 rectangular; - found = openspace::SpiceManager::ref().planetocentricToRectangular("EARTH", lon, lat, rectangular); + bool found = openspace::SpiceManager::ref().planetocentricToRectangular("EARTH", lon, lat, rectangular); + ASSERT_TRUE(found); for (int i = 0; i < 3; i++){ EXPECT_EQ(rectangular[i], rectangular_ref[i]) << "Rectangular coordinates differ from expected output"; @@ -481,8 +494,11 @@ TEST_F(SpiceManagerTest, planetocentricToRectangular){ TEST_F(SpiceManagerTest, getSubObserverPoint){ loadMetaKernel(); - double et, targetEt_ref, targetEt; - double radii[3], subObserverPoint_ref[3], vectorToSurfacePoint_ref[3]; + double et; + double targetEt_ref; + double targetEt; + double subObserverPoint_ref[3]; + double vectorToSurfacePoint_ref[3]; static SpiceChar * method[2] = { "Intercept: ellipsoid", "Near point: ellipsoid" }; str2et_c("2004 jun 11 19:32:00", &et); @@ -494,7 +510,7 @@ TEST_F(SpiceManagerTest, getSubObserverPoint){ subpnt_c(method[i], "phoebe", et, "iau_phoebe", "lt+s", "earth", subObserverPoint_ref, &targetEt_ref, vectorToSurfacePoint_ref); - found = openspace::SpiceManager::ref().getSubObserverPoint(method[i], "phoebe", et, "iau_phoebe", + bool found = openspace::SpiceManager::ref().getSubObserverPoint(method[i], "phoebe", et, "iau_phoebe", "lt+s", "earth", subObserverPoint, targetEt, vectorToSurfacePoint); ASSERT_TRUE(found); @@ -513,7 +529,8 @@ TEST_F(SpiceManagerTest, getSubSolarPoint){ loadMetaKernel(); double et, targetEt_ref, targetEt; - double radii[3], subSolarPoint_ref[3], vectorToSurfacePoint_ref[3]; + double subSolarPoint_ref[3]; + double vectorToSurfacePoint_ref[3]; static SpiceChar * method[2] = { "Intercept: ellipsoid", "Near point: ellipsoid" }; str2et_c("2004 jun 11 19:32:00", &et); @@ -525,7 +542,7 @@ TEST_F(SpiceManagerTest, getSubSolarPoint){ subslr_c(method[i], "phoebe", et, "iau_phoebe", "lt+s", "earth", subSolarPoint_ref, &targetEt_ref, vectorToSurfacePoint_ref); - found = openspace::SpiceManager::ref().getSubSolarPoint(method[i], "phoebe", et, "iau_phoebe", + bool found = openspace::SpiceManager::ref().getSubSolarPoint(method[i], "phoebe", et, "iau_phoebe", "lt+s", "earth", subSolarPoint, targetEt, vectorToSurfacePoint); ASSERT_TRUE(found); diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 43f4fe2c2f..d39f84d5ea 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -34,7 +34,7 @@ #include #include //#include -//#include +#include #include #include #include From 5c664798cbae0c7dea53c64ec7e89982cbb37b84 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 2 Sep 2014 21:24:32 +0200 Subject: [PATCH 064/113] Adapted OpenSpace header in favor of Ghoul header in test cases --- .../tests/test_powerscalecoordinates.inl | 5 +-- include/openspace/tests/test_scenegraph.inl | 5 +-- include/openspace/tests/test_spicemanager.inl | 45 +++++++++---------- src/tests/main.cpp | 5 +-- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/include/openspace/tests/test_powerscalecoordinates.inl b/include/openspace/tests/test_powerscalecoordinates.inl index d5666f6c96..294cb139bb 100644 --- a/include/openspace/tests/test_powerscalecoordinates.inl +++ b/include/openspace/tests/test_powerscalecoordinates.inl @@ -1,9 +1,8 @@ /***************************************************************************************** * * - * GHOUL * - * General Helpful Open Utility Library * + * OpenSpace * * * - * Copyright (c) 2012-2014 * + * 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 * diff --git a/include/openspace/tests/test_scenegraph.inl b/include/openspace/tests/test_scenegraph.inl index 186d955c45..91d2293a4e 100644 --- a/include/openspace/tests/test_scenegraph.inl +++ b/include/openspace/tests/test_scenegraph.inl @@ -1,9 +1,8 @@ /***************************************************************************************** * * - * GHOUL * - * General Helpful Open Utility Library * + * OpenSpace * * * - * Copyright (c) 2012-2014 * + * 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 * diff --git a/include/openspace/tests/test_spicemanager.inl b/include/openspace/tests/test_spicemanager.inl index d69c69a657..e46e72d2a5 100644 --- a/include/openspace/tests/test_spicemanager.inl +++ b/include/openspace/tests/test_spicemanager.inl @@ -1,27 +1,26 @@ /***************************************************************************************** -* * -* GHOUL * -* General Helpful Open Utility Library * -* * -* Copyright (c) 2012-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. * -****************************************************************************************/ + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ #include #include "gtest/gtest.h" diff --git a/src/tests/main.cpp b/src/tests/main.cpp index d39f84d5ea..e9ba33f120 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -1,9 +1,8 @@ /***************************************************************************************** * * - * GHOUL * - * General Helpful Open Utility Library * + * OpenSpace * * * - * Copyright (c) 2012-2014 * + * 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 * From bbf707db1c1f21b1e55d9b25af72a1a90999e38f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 2 Sep 2014 23:58:06 +0200 Subject: [PATCH 065/113] Implemented first Lua serialization tests Fixed to-Lua and from-Lua functions for MatrixProperties --- include/openspace/properties/vectorproperty.h | 19 - .../openspace/tests/test_luaconversions.inl | 119 +++++ src/properties/matrixproperty.cpp | 442 ++---------------- 3 files changed, 170 insertions(+), 410 deletions(-) create mode 100644 include/openspace/tests/test_luaconversions.inl diff --git a/include/openspace/properties/vectorproperty.h b/include/openspace/properties/vectorproperty.h index 97124be115..583fe28c30 100644 --- a/include/openspace/properties/vectorproperty.h +++ b/include/openspace/properties/vectorproperty.h @@ -49,25 +49,6 @@ REGISTER_NUMERICALPROPERTY_HEADER(UVec2Property, glm::uvec2); REGISTER_NUMERICALPROPERTY_HEADER(UVec3Property, glm::uvec3); REGISTER_NUMERICALPROPERTY_HEADER(UVec4Property, glm::uvec4); -//REGISTER_NUMERICALPROPERTY_HEADER(CharProperty, char); -////REGISTER_NUMERICALPROPERTY_HEADER(Char16Property, char16_t); -////REGISTER_NUMERICALPROPERTY_HEADER(Char32Property, char32_t); -//REGISTER_NUMERICALPROPERTY_HEADER(WCharProperty, wchar_t); -//REGISTER_NUMERICALPROPERTY_HEADER(SignedCharProperty, signed char); -//REGISTER_NUMERICALPROPERTY_HEADER(UCharProperty, unsigned char); -//REGISTER_NUMERICALPROPERTY_HEADER(ShortProperty, short); -//REGISTER_NUMERICALPROPERTY_HEADER(UShortProperty, unsigned short); -//REGISTER_NUMERICALPROPERTY_HEADER(IntProperty, int); -//REGISTER_NUMERICALPROPERTY_HEADER(UIntProperty, unsigned int); -//REGISTER_NUMERICALPROPERTY_HEADER(LongProperty, long); -//REGISTER_NUMERICALPROPERTY_HEADER(ULongProperty, unsigned long); -//REGISTER_NUMERICALPROPERTY_HEADER(LongLongProperty, long long); -//REGISTER_NUMERICALPROPERTY_HEADER(ULongLongProperty, unsigned long long); -//REGISTER_NUMERICALPROPERTY_HEADER(FloatProperty, float); -//REGISTER_NUMERICALPROPERTY_HEADER(DoubleProperty, double); -//REGISTER_NUMERICALPROPERTY_HEADER(LongDoubleProperty, long double); - - } // namespace properties } // namespace openspace diff --git a/include/openspace/tests/test_luaconversions.inl b/include/openspace/tests/test_luaconversions.inl new file mode 100644 index 0000000000..8477615f07 --- /dev/null +++ b/include/openspace/tests/test_luaconversions.inl @@ -0,0 +1,119 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include + +class LuaConversionTest : public testing::Test { +protected: + lua_State* state; + + LuaConversionTest() { + state = luaL_newstate(); + luaL_openlibs(state); + } + + ~LuaConversionTest() { + lua_close(state); + } + + void reset() { + lua_close(state); + state = luaL_newstate(); + luaL_openlibs(state); + } +}; + +TEST_F(LuaConversionTest, LuaExecution) { + int status = luaL_loadstring(state, ""); + EXPECT_EQ(status, LUA_OK); +} + +#define CONVERSION_TEST_NUMERICAL(__NAME__, __TYPE__, __VALUE__) \ + TEST_F(LuaConversionTest, __NAME__) \ + { \ + using namespace openspace::properties; \ + bool success \ + = PropertyDelegate>::toLuaValue<__TYPE__>( \ + state, __VALUE__); \ + EXPECT_TRUE(success) << "toLuaValue"; \ + __TYPE__ value \ + = PropertyDelegate>::fromLuaValue<__TYPE__>( \ + state, success); \ + EXPECT_TRUE(success) << "fromLuaValue"; \ + EXPECT_EQ(value, __VALUE__) << "fromLuaValue"; \ + } + +CONVERSION_TEST_NUMERICAL(Char, char, 1); +CONVERSION_TEST_NUMERICAL(WChar, wchar_t, 1); +CONVERSION_TEST_NUMERICAL(SignedChar, signed char, 1); +CONVERSION_TEST_NUMERICAL(UnsignedChar, unsigned char, 1); +CONVERSION_TEST_NUMERICAL(Short, short, 1); +CONVERSION_TEST_NUMERICAL(UnsignedShort, unsigned short, 1); +CONVERSION_TEST_NUMERICAL(Int, int, 1); +CONVERSION_TEST_NUMERICAL(UnsignedInt, unsigned int, 1); +CONVERSION_TEST_NUMERICAL(Long, long, 1); +CONVERSION_TEST_NUMERICAL(UnsignedLong, unsigned long, 1); +CONVERSION_TEST_NUMERICAL(LongLong, long long, 1); +CONVERSION_TEST_NUMERICAL(UnsignedLongLong, unsigned long long, 1); +CONVERSION_TEST_NUMERICAL(Float, float, 1.f); +CONVERSION_TEST_NUMERICAL(Double, double, 1.0); +CONVERSION_TEST_NUMERICAL(LongDouble, long double, 1.0); + +CONVERSION_TEST_NUMERICAL(Vec2, glm::vec2, glm::vec2(1.f)); +CONVERSION_TEST_NUMERICAL(Vec3, glm::vec3, glm::vec3(1.f)); +CONVERSION_TEST_NUMERICAL(Vec4, glm::vec4, glm::vec4(1.f)); +CONVERSION_TEST_NUMERICAL(DVec2, glm::dvec2, glm::dvec2(1.0)); +CONVERSION_TEST_NUMERICAL(DVec3, glm::dvec3, glm::dvec3(1.0)); +CONVERSION_TEST_NUMERICAL(DVec4, glm::dvec4, glm::dvec4(1.0)); +CONVERSION_TEST_NUMERICAL(IVec2, glm::ivec2, glm::ivec2(1)); +CONVERSION_TEST_NUMERICAL(IVec3, glm::ivec3, glm::ivec3(1)); +CONVERSION_TEST_NUMERICAL(IVec4, glm::ivec4, glm::ivec4(1)); +CONVERSION_TEST_NUMERICAL(UVec2, glm::uvec2, glm::uvec2(1)); +CONVERSION_TEST_NUMERICAL(UVec3, glm::uvec3, glm::uvec3(1)); +CONVERSION_TEST_NUMERICAL(UVec4, glm::uvec4, glm::uvec4(1)); + +CONVERSION_TEST_NUMERICAL(Mat2x2, glm::mat2x2, glm::mat2x2(1.f)); +CONVERSION_TEST_NUMERICAL(Mat2x3, glm::mat2x3, glm::mat2x3(1.f)); +CONVERSION_TEST_NUMERICAL(Mat2x4, glm::mat2x4, glm::mat2x4(1.f)); +CONVERSION_TEST_NUMERICAL(Mat3x2, glm::mat3x2, glm::mat3x2(1.f)); +CONVERSION_TEST_NUMERICAL(Mat3x3, glm::mat3x3, glm::mat3x3(1.f)); +CONVERSION_TEST_NUMERICAL(Mat3x4, glm::mat3x4, glm::mat3x4(1.f)); +CONVERSION_TEST_NUMERICAL(Mat4x2, glm::mat4x2, glm::mat4x2(1.f)); +CONVERSION_TEST_NUMERICAL(Mat4x3, glm::mat4x3, glm::mat4x3(1.f)); +CONVERSION_TEST_NUMERICAL(Mat4x4, glm::mat4x4, glm::mat4x4(1.f)); +CONVERSION_TEST_NUMERICAL(DMat2x2, glm::dmat2x2, glm::dmat2x2(1.f)); +CONVERSION_TEST_NUMERICAL(DMat2x3, glm::dmat2x3, glm::dmat2x3(1.f)); +CONVERSION_TEST_NUMERICAL(DMat2x4, glm::dmat2x4, glm::dmat2x4(1.f)); +CONVERSION_TEST_NUMERICAL(DMat3x2, glm::dmat3x2, glm::dmat3x2(1.f)); +CONVERSION_TEST_NUMERICAL(DMat3x3, glm::dmat3x3, glm::dmat3x3(1.f)); +CONVERSION_TEST_NUMERICAL(DMat3x4, glm::dmat3x4, glm::dmat3x4(1.f)); +CONVERSION_TEST_NUMERICAL(DMat4x2, glm::dmat4x2, glm::dmat4x2(1.f)); +CONVERSION_TEST_NUMERICAL(DMat4x3, glm::dmat4x3, glm::dmat4x3(1.f)); +CONVERSION_TEST_NUMERICAL(DMat4x4, glm::dmat4x4, glm::dmat4x4(1.f)); diff --git a/src/properties/matrixproperty.cpp b/src/properties/matrixproperty.cpp index 9cf11e40d6..ed5c1d0a0d 100644 --- a/src/properties/matrixproperty.cpp +++ b/src/properties/matrixproperty.cpp @@ -31,486 +31,146 @@ using std::numeric_limits; namespace openspace { namespace properties { -#define DEFAULT_FROM_LUA_LAMBDA_4(TYPE, DEFAULT_VALUE) \ - [](lua_State* state, bool& success) -> TYPE { \ - success = (lua_isnumber(state, -1) == 1) && \ - (lua_isnumber(state, -2) == 1) && \ - (lua_isnumber(state, -3) == 1) && \ - (lua_isnumber(state, -4) == 1); \ - if (success) \ - return TYPE( \ - static_cast(lua_tonumber(state, -1)), \ - static_cast(lua_tonumber(state, -2)), \ - static_cast(lua_tonumber(state, -3)), \ - static_cast(lua_tonumber(state, -4))); \ - else \ - return DEFAULT_VALUE;\ - } +#define DEFAULT_FROM_LUA_LAMBDA(__TYPE__) \ + [](lua_State * state, bool& success) -> __TYPE__ { \ + __TYPE__ result; \ + int number = 1; \ + for (__TYPE__::size_type i = 0; i < __TYPE__::row_size(); ++i) { \ + for (__TYPE__::size_type j = 0; j < __TYPE__::col_size(); ++j) { \ + lua_getfield(state, -1, std::to_string(number).c_str()); \ + if (lua_isnumber(state, -1) != 1) { \ + success = false; \ + return __TYPE__(0); \ + } else { \ + result[i][j] \ + = static_cast<__TYPE__::value_type>(lua_tonumber(state, -1)); \ + lua_pop(state, 1); \ + ++number; \ + } \ + } \ + } \ + return result; \ + } -#define DEFAULT_FROM_LUA_LAMBDA_6(TYPE, DEFAULT_VALUE) \ - [](lua_State* state, bool& success) -> TYPE { \ - success = (lua_isnumber(state, -1) == 1) && \ - (lua_isnumber(state, -2) == 1) && \ - (lua_isnumber(state, -3) == 1) && \ - (lua_isnumber(state, -4) == 1) && \ - (lua_isnumber(state, -5) == 1) && \ - (lua_isnumber(state, -6) == 1); \ - if (success) \ - return TYPE( \ - static_cast(lua_tonumber(state, -1)), \ - static_cast(lua_tonumber(state, -2)), \ - static_cast(lua_tonumber(state, -3)), \ - static_cast(lua_tonumber(state, -4)), \ - static_cast(lua_tonumber(state, -5)), \ - static_cast(lua_tonumber(state, -6))); \ - else \ - return DEFAULT_VALUE;\ - } - -#define DEFAULT_FROM_LUA_LAMBDA_8(TYPE, DEFAULT_VALUE) \ - [](lua_State* state, bool& success) -> TYPE { \ - success = (lua_isnumber(state, -1) == 1) && \ - (lua_isnumber(state, -2) == 1) && \ - (lua_isnumber(state, -3) == 1) && \ - (lua_isnumber(state, -4) == 1) && \ - (lua_isnumber(state, -5) == 1) && \ - (lua_isnumber(state, -6) == 1) && \ - (lua_isnumber(state, -7) == 1) && \ - (lua_isnumber(state, -8) == 1); \ - if (success) \ - return TYPE( \ - static_cast(lua_tonumber(state, -1)), \ - static_cast(lua_tonumber(state, -2)), \ - static_cast(lua_tonumber(state, -3)), \ - static_cast(lua_tonumber(state, -4)), \ - static_cast(lua_tonumber(state, -5)), \ - static_cast(lua_tonumber(state, -6)), \ - static_cast(lua_tonumber(state, -7)), \ - static_cast(lua_tonumber(state, -8))); \ - else \ - return DEFAULT_VALUE;\ - } - -#define DEFAULT_FROM_LUA_LAMBDA_9(TYPE, DEFAULT_VALUE) \ - [](lua_State* state, bool& success) -> TYPE { \ - success = (lua_isnumber(state, -1) == 1) && \ - (lua_isnumber(state, -2) == 1) && \ - (lua_isnumber(state, -3) == 1) && \ - (lua_isnumber(state, -4) == 1) && \ - (lua_isnumber(state, -5) == 1) && \ - (lua_isnumber(state, -6) == 1) && \ - (lua_isnumber(state, -7) == 1) && \ - (lua_isnumber(state, -8) == 1) && \ - (lua_isnumber(state, -9) == 1); \ - if (success) \ - return TYPE( \ - static_cast(lua_tonumber(state, -1)), \ - static_cast(lua_tonumber(state, -2)), \ - static_cast(lua_tonumber(state, -3)), \ - static_cast(lua_tonumber(state, -4)), \ - static_cast(lua_tonumber(state, -5)), \ - static_cast(lua_tonumber(state, -6)), \ - static_cast(lua_tonumber(state, -7)), \ - static_cast(lua_tonumber(state, -8)), \ - static_cast(lua_tonumber(state, -9))); \ - else \ - return DEFAULT_VALUE;\ - } - -#define DEFAULT_FROM_LUA_LAMBDA_12(TYPE, DEFAULT_VALUE) \ - [](lua_State* state, bool& success) -> TYPE { \ - success = (lua_isnumber(state, -1) == 1) && \ - (lua_isnumber(state, -2) == 1) && \ - (lua_isnumber(state, -3) == 1) && \ - (lua_isnumber(state, -4) == 1) && \ - (lua_isnumber(state, -5) == 1) && \ - (lua_isnumber(state, -6) == 1) && \ - (lua_isnumber(state, -7) == 1) && \ - (lua_isnumber(state, -8) == 1) && \ - (lua_isnumber(state, -9) == 1) && \ - (lua_isnumber(state, -10) == 1) && \ - (lua_isnumber(state, -11) == 1) && \ - (lua_isnumber(state, -12) == 1); \ - if (success) \ - return TYPE( \ - static_cast(lua_tonumber(state, -1)), \ - static_cast(lua_tonumber(state, -2)), \ - static_cast(lua_tonumber(state, -3)), \ - static_cast(lua_tonumber(state, -4)), \ - static_cast(lua_tonumber(state, -5)), \ - static_cast(lua_tonumber(state, -6)), \ - static_cast(lua_tonumber(state, -7)), \ - static_cast(lua_tonumber(state, -8)), \ - static_cast(lua_tonumber(state, -9)), \ - static_cast(lua_tonumber(state, -10)), \ - static_cast(lua_tonumber(state, -11)), \ - static_cast(lua_tonumber(state, -12))); \ - else \ - return DEFAULT_VALUE;\ -} - -#define DEFAULT_FROM_LUA_LAMBDA_16(TYPE, DEFAULT_VALUE) \ - [](lua_State* state, bool& success) -> TYPE { \ - success = (lua_isnumber(state, -1) == 1) && \ - (lua_isnumber(state, -2) == 1) && \ - (lua_isnumber(state, -3) == 1) && \ - (lua_isnumber(state, -4) == 1) && \ - (lua_isnumber(state, -5) == 1) && \ - (lua_isnumber(state, -6) == 1) && \ - (lua_isnumber(state, -7) == 1) && \ - (lua_isnumber(state, -8) == 1) && \ - (lua_isnumber(state, -9) == 1) && \ - (lua_isnumber(state, -10) == 1) && \ - (lua_isnumber(state, -11) == 1) && \ - (lua_isnumber(state, -12) == 1) && \ - (lua_isnumber(state, -13) == 1) && \ - (lua_isnumber(state, -14) == 1) && \ - (lua_isnumber(state, -15) == 1) && \ - (lua_isnumber(state, -16) == 1); \ - if (success) \ - return TYPE( \ - static_cast(lua_tonumber(state, -1)), \ - static_cast(lua_tonumber(state, -2)), \ - static_cast(lua_tonumber(state, -3)), \ - static_cast(lua_tonumber(state, -4)), \ - static_cast(lua_tonumber(state, -5)), \ - static_cast(lua_tonumber(state, -6)), \ - static_cast(lua_tonumber(state, -7)), \ - static_cast(lua_tonumber(state, -8)), \ - static_cast(lua_tonumber(state, -9)), \ - static_cast(lua_tonumber(state, -10)), \ - static_cast(lua_tonumber(state, -11)), \ - static_cast(lua_tonumber(state, -12)), \ - static_cast(lua_tonumber(state, -13)), \ - static_cast(lua_tonumber(state, -14)), \ - static_cast(lua_tonumber(state, -15)), \ - static_cast(lua_tonumber(state, -16))); \ - else \ - return DEFAULT_VALUE;\ - } +#define DEFAULT_TO_LUA_LAMBDA(__TYPE__) \ + [](lua_State * state, __TYPE__ value) -> bool { \ + lua_newtable(state); \ + int number = 1; \ + for (__TYPE__::size_type i = 0; i < __TYPE__::row_size(); ++i) { \ + for (__TYPE__::size_type j = 0; j < __TYPE__::col_size(); ++j) { \ + lua_pushnumber(state, static_cast(value[i][j])); \ + lua_setfield(state, -2, std::to_string(number).c_str()); \ + ++number; \ + } \ + } \ + return true; \ + } REGISTER_NUMERICALPROPERTY_SOURCE(Mat2Property, glm::mat2x2, glm::mat2x2(0), glm::mat2x2(numeric_limits::lowest()), glm::mat2x2(numeric_limits::max()), glm::mat2x2(0.01f), - DEFAULT_FROM_LUA_LAMBDA_4(glm::mat2x2, glm::mat2x2(0)), - [](lua_State* state, glm::mat2x2 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - return true; - } - ); + DEFAULT_FROM_LUA_LAMBDA(glm::mat2x2), DEFAULT_TO_LUA_LAMBDA(glm::mat2x2)); REGISTER_NUMERICALPROPERTY_SOURCE(Mat2x3Property, glm::mat2x3, glm::mat2x3(0), glm::mat2x3(numeric_limits::lowest()), glm::mat2x3(numeric_limits::max()), glm::mat2x3(0.01f), - DEFAULT_FROM_LUA_LAMBDA_6(glm::mat2x3, glm::mat2x3(0)), - [](lua_State* state, glm::mat2x3 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::mat2x3), DEFAULT_TO_LUA_LAMBDA(glm::mat2x3) ); REGISTER_NUMERICALPROPERTY_SOURCE(Mat2x4Property, glm::mat2x4, glm::mat2x4(0), glm::mat2x4(numeric_limits::lowest()), glm::mat2x4(numeric_limits::max()), glm::mat2x4(0.01f), - DEFAULT_FROM_LUA_LAMBDA_8(glm::mat2x4, glm::mat2x4(0)), - [](lua_State* state, glm::mat2x4 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[0][3])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - lua_pushnumber(state, static_cast(value[1][3])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::mat2x4), DEFAULT_TO_LUA_LAMBDA(glm::mat2x4) ); REGISTER_NUMERICALPROPERTY_SOURCE(Mat3x2Property, glm::mat3x2, glm::mat3x2(0), glm::mat3x2(numeric_limits::lowest()), glm::mat3x2(numeric_limits::max()), glm::mat3x2(0.01f), - DEFAULT_FROM_LUA_LAMBDA_6(glm::mat3x2, glm::mat3x2(0)), - [](lua_State* state, glm::mat3x2 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::mat3x2), DEFAULT_TO_LUA_LAMBDA(glm::mat3x2) ); REGISTER_NUMERICALPROPERTY_SOURCE(Mat3Property, glm::mat3x3, glm::mat3x3(0), glm::mat3x3(numeric_limits::lowest()), glm::mat3x3(numeric_limits::max()), glm::mat3x3(0.01f), - DEFAULT_FROM_LUA_LAMBDA_9(glm::mat3x3, glm::mat3x3(0)), - [](lua_State* state, glm::mat3x3 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - lua_pushnumber(state, static_cast(value[2][2])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::mat3x3), DEFAULT_TO_LUA_LAMBDA(glm::mat3x3) ); REGISTER_NUMERICALPROPERTY_SOURCE(Mat3x4Property, glm::mat3x4, glm::mat3x4(0), glm::mat3x4(numeric_limits::lowest()), glm::mat3x4(numeric_limits::max()), glm::mat3x4(0.01f), - DEFAULT_FROM_LUA_LAMBDA_12(glm::mat3x4, glm::mat3x4(0)), - [](lua_State* state, glm::mat3x4 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[0][3])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - lua_pushnumber(state, static_cast(value[1][3])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - lua_pushnumber(state, static_cast(value[2][2])); - lua_pushnumber(state, static_cast(value[2][3])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::mat3x4), DEFAULT_TO_LUA_LAMBDA(glm::mat3x4) ); REGISTER_NUMERICALPROPERTY_SOURCE(Mat4x2Property, glm::mat4x2, glm::mat4x2(0), glm::mat4x2(numeric_limits::lowest()), glm::mat4x2(numeric_limits::max()), glm::mat4x2(0.01f), - DEFAULT_FROM_LUA_LAMBDA_8(glm::mat4x2, glm::mat4x2(0)), - [](lua_State* state, glm::mat4x2 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - lua_pushnumber(state, static_cast(value[3][0])); - lua_pushnumber(state, static_cast(value[3][1])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::mat4x2), DEFAULT_TO_LUA_LAMBDA(glm::mat4x2) ); REGISTER_NUMERICALPROPERTY_SOURCE(Mat4x3Property, glm::mat4x3, glm::mat4x3(0), glm::mat4x3(numeric_limits::lowest()), glm::mat4x3(numeric_limits::max()), glm::mat4x3(0.01f), - DEFAULT_FROM_LUA_LAMBDA_12(glm::mat4x3, glm::mat4x3(0)), - [](lua_State* state, glm::mat4x3 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - lua_pushnumber(state, static_cast(value[2][2])); - lua_pushnumber(state, static_cast(value[3][0])); - lua_pushnumber(state, static_cast(value[3][1])); - lua_pushnumber(state, static_cast(value[3][2])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::mat4x3), DEFAULT_TO_LUA_LAMBDA(glm::mat4x3) ); REGISTER_NUMERICALPROPERTY_SOURCE(Mat4Property, glm::mat4x4, glm::mat4x4(0), glm::mat4x4(numeric_limits::lowest()), glm::mat4x4(numeric_limits::max()), glm::mat4x4(0.01f), - DEFAULT_FROM_LUA_LAMBDA_16(glm::mat4x4, glm::mat4x4(0)), - [](lua_State* state, glm::mat4x4 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[0][3])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - lua_pushnumber(state, static_cast(value[1][3])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - lua_pushnumber(state, static_cast(value[2][2])); - lua_pushnumber(state, static_cast(value[2][3])); - lua_pushnumber(state, static_cast(value[3][0])); - lua_pushnumber(state, static_cast(value[3][1])); - lua_pushnumber(state, static_cast(value[3][2])); - lua_pushnumber(state, static_cast(value[3][3])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::mat4x4), DEFAULT_TO_LUA_LAMBDA(glm::mat4x4) ); REGISTER_NUMERICALPROPERTY_SOURCE(DMat2Property, glm::dmat2x2, glm::dmat2x2(0), glm::dmat2x2(numeric_limits::lowest()), glm::dmat2x2(numeric_limits::max()), glm::dmat2x2(0.01), - DEFAULT_FROM_LUA_LAMBDA_4(glm::dmat2x2, glm::dmat2x2(0)), - [](lua_State* state, glm::dmat2x2 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x2), DEFAULT_TO_LUA_LAMBDA(glm::dmat2x2) ); REGISTER_NUMERICALPROPERTY_SOURCE(DMat2x3Property, glm::dmat2x3, glm::dmat2x3(0), glm::dmat2x3(numeric_limits::lowest()), glm::dmat2x3(numeric_limits::max()), glm::dmat2x3(0.01), - DEFAULT_FROM_LUA_LAMBDA_6(glm::dmat2x3, glm::dmat2x3(0)), - [](lua_State* state, glm::dmat2x3 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x3), DEFAULT_TO_LUA_LAMBDA(glm::dmat2x3) ); REGISTER_NUMERICALPROPERTY_SOURCE(DMat2x4Property, glm::dmat2x4, glm::dmat2x4(0), glm::dmat2x4(numeric_limits::lowest()), glm::dmat2x4(numeric_limits::max()), glm::dmat2x4(0.01), - DEFAULT_FROM_LUA_LAMBDA_8(glm::dmat2x4, glm::dmat2x4(0)), - [](lua_State* state, glm::dmat2x4 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[0][3])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - lua_pushnumber(state, static_cast(value[1][3])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x4), DEFAULT_TO_LUA_LAMBDA(glm::dmat2x4) ); REGISTER_NUMERICALPROPERTY_SOURCE(DMat3x2Property, glm::dmat3x2, glm::dmat3x2(0), glm::dmat3x2(numeric_limits::lowest()), glm::dmat3x2(numeric_limits::max()), glm::dmat3x2(0.01), - DEFAULT_FROM_LUA_LAMBDA_6(glm::dmat3x2, glm::dmat3x2(0)), - [](lua_State* state, glm::dmat3x2 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x2), DEFAULT_TO_LUA_LAMBDA(glm::dmat3x2) ); REGISTER_NUMERICALPROPERTY_SOURCE(DMat3Property, glm::dmat3x3, glm::dmat3x3(0), glm::dmat3x3(numeric_limits::lowest()), glm::dmat3x3(numeric_limits::max()), glm::dmat3x3(0.01), - DEFAULT_FROM_LUA_LAMBDA_9(glm::dmat3x3, glm::dmat3x3(0)), - [](lua_State* state, glm::dmat3x3 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - lua_pushnumber(state, static_cast(value[2][2])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x3), DEFAULT_TO_LUA_LAMBDA(glm::dmat3x3) ); REGISTER_NUMERICALPROPERTY_SOURCE(DMat3x4Property, glm::dmat3x4, glm::dmat3x4(0), glm::dmat3x4(numeric_limits::lowest()), glm::dmat3x4(numeric_limits::max()), glm::dmat3x4(0.01), - DEFAULT_FROM_LUA_LAMBDA_12(glm::dmat3x4, glm::dmat3x4(0)), - [](lua_State* state, glm::dmat3x4 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[0][3])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - lua_pushnumber(state, static_cast(value[1][3])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - lua_pushnumber(state, static_cast(value[2][2])); - lua_pushnumber(state, static_cast(value[2][3])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x4), DEFAULT_TO_LUA_LAMBDA(glm::dmat3x4) ); REGISTER_NUMERICALPROPERTY_SOURCE(DMat4x2Property, glm::dmat4x2, glm::dmat4x2(0), glm::dmat4x2(numeric_limits::lowest()), glm::dmat4x2(numeric_limits::max()), glm::dmat4x2(0.01), - DEFAULT_FROM_LUA_LAMBDA_8(glm::dmat4x2, glm::dmat4x2(0)), - [](lua_State* state, glm::dmat4x2 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - lua_pushnumber(state, static_cast(value[3][0])); - lua_pushnumber(state, static_cast(value[3][1])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x2), DEFAULT_TO_LUA_LAMBDA(glm::dmat4x2) ); REGISTER_NUMERICALPROPERTY_SOURCE(DMat4x3Property, glm::dmat4x3, glm::dmat4x3(0), glm::dmat4x3(numeric_limits::lowest()), glm::dmat4x3(numeric_limits::max()), glm::dmat4x3(0.01), - DEFAULT_FROM_LUA_LAMBDA_12(glm::dmat4x3, glm::dmat4x3(0)), - [](lua_State* state, glm::dmat4x3 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - lua_pushnumber(state, static_cast(value[2][2])); - lua_pushnumber(state, static_cast(value[3][0])); - lua_pushnumber(state, static_cast(value[3][1])); - lua_pushnumber(state, static_cast(value[3][2])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x3), DEFAULT_TO_LUA_LAMBDA(glm::dmat4x3) ); REGISTER_NUMERICALPROPERTY_SOURCE(DMat4Property, glm::dmat4x4, glm::dmat4x4(0), glm::dmat4x4(numeric_limits::lowest()), glm::dmat4x4(numeric_limits::max()), glm::dmat4x4(0.01), - DEFAULT_FROM_LUA_LAMBDA_16(glm::dmat4x4, glm::dmat4x4(0)), - [](lua_State* state, glm::dmat4x4 value) -> bool { - lua_pushnumber(state, static_cast(value[0][0])); - lua_pushnumber(state, static_cast(value[0][1])); - lua_pushnumber(state, static_cast(value[0][2])); - lua_pushnumber(state, static_cast(value[0][3])); - lua_pushnumber(state, static_cast(value[1][0])); - lua_pushnumber(state, static_cast(value[1][1])); - lua_pushnumber(state, static_cast(value[1][2])); - lua_pushnumber(state, static_cast(value[1][3])); - lua_pushnumber(state, static_cast(value[2][0])); - lua_pushnumber(state, static_cast(value[2][1])); - lua_pushnumber(state, static_cast(value[2][2])); - lua_pushnumber(state, static_cast(value[2][3])); - lua_pushnumber(state, static_cast(value[3][0])); - lua_pushnumber(state, static_cast(value[3][1])); - lua_pushnumber(state, static_cast(value[3][2])); - lua_pushnumber(state, static_cast(value[3][3])); - return true; - } + DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x4), DEFAULT_TO_LUA_LAMBDA(glm::dmat4x4) ); } // namespace properties From dcfcc00092e9d46c4bd1d7203c5c93aff6c18626 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 3 Sep 2014 00:18:57 +0200 Subject: [PATCH 066/113] Fixed to-Lua and from-Lua functions for all properties Corrected serialization of Vectorproperties into tables --- .../properties/numericalproperty.inl | 4 +- src/properties/matrixproperty.cpp | 166 ++++++----- src/properties/scalarproperty.cpp | 115 +++++--- src/properties/vectorproperty.cpp | 266 +++++++----------- 4 files changed, 266 insertions(+), 285 deletions(-) diff --git a/include/openspace/properties/numericalproperty.inl b/include/openspace/properties/numericalproperty.inl index 34f73111fd..e46ca0f0ec 100644 --- a/include/openspace/properties/numericalproperty.inl +++ b/include/openspace/properties/numericalproperty.inl @@ -66,7 +66,7 @@ namespace properties { #define REGISTER_NUMERICALPROPERTY_SOURCE(CLASS_NAME, TYPE, DEFAULT_VALUE, \ DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, \ DEFAULT_STEPPING, FROM_LUA_LAMBDA_EXPRESSION, \ - TO_LUA_LAMBDA_EXPRESSION) \ + TO_LUA_LAMBDA_EXPRESSION, LUA_TYPE) \ template <> \ std::string PropertyDelegate>::className() \ { \ @@ -134,7 +134,7 @@ namespace properties { template <> \ int PropertyDelegate>::typeLua() \ { \ - return LUA_TNUMBER; \ + return LUA_TYPE; \ } \ template <> \ int PropertyDelegate>::typeLua() \ diff --git a/src/properties/matrixproperty.cpp b/src/properties/matrixproperty.cpp index ed5c1d0a0d..e6cd6a8974 100644 --- a/src/properties/matrixproperty.cpp +++ b/src/properties/matrixproperty.cpp @@ -49,6 +49,7 @@ namespace properties { } \ } \ } \ + success = true; \ return result; \ } @@ -67,111 +68,130 @@ namespace properties { } REGISTER_NUMERICALPROPERTY_SOURCE(Mat2Property, glm::mat2x2, glm::mat2x2(0), - glm::mat2x2(numeric_limits::lowest()), - glm::mat2x2(numeric_limits::max()), glm::mat2x2(0.01f), - DEFAULT_FROM_LUA_LAMBDA(glm::mat2x2), DEFAULT_TO_LUA_LAMBDA(glm::mat2x2)); + glm::mat2x2(numeric_limits::lowest()), + glm::mat2x2(numeric_limits::max()), + glm::mat2x2(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::mat2x2), + DEFAULT_TO_LUA_LAMBDA(glm::mat2x2), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(Mat2x3Property, glm::mat2x3, glm::mat2x3(0), - glm::mat2x3(numeric_limits::lowest()), - glm::mat2x3(numeric_limits::max()), glm::mat2x3(0.01f), - DEFAULT_FROM_LUA_LAMBDA(glm::mat2x3), DEFAULT_TO_LUA_LAMBDA(glm::mat2x3) - ); + glm::mat2x3(numeric_limits::lowest()), + glm::mat2x3(numeric_limits::max()), + glm::mat2x3(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::mat2x3), + DEFAULT_TO_LUA_LAMBDA(glm::mat2x3), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(Mat2x4Property, glm::mat2x4, glm::mat2x4(0), - glm::mat2x4(numeric_limits::lowest()), - glm::mat2x4(numeric_limits::max()), glm::mat2x4(0.01f), - DEFAULT_FROM_LUA_LAMBDA(glm::mat2x4), DEFAULT_TO_LUA_LAMBDA(glm::mat2x4) - ); + glm::mat2x4(numeric_limits::lowest()), + glm::mat2x4(numeric_limits::max()), + glm::mat2x4(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::mat2x4), + DEFAULT_TO_LUA_LAMBDA(glm::mat2x4), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(Mat3x2Property, glm::mat3x2, glm::mat3x2(0), - glm::mat3x2(numeric_limits::lowest()), - glm::mat3x2(numeric_limits::max()), glm::mat3x2(0.01f), - DEFAULT_FROM_LUA_LAMBDA(glm::mat3x2), DEFAULT_TO_LUA_LAMBDA(glm::mat3x2) - ); + glm::mat3x2(numeric_limits::lowest()), + glm::mat3x2(numeric_limits::max()), + glm::mat3x2(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::mat3x2), + DEFAULT_TO_LUA_LAMBDA(glm::mat3x2), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(Mat3Property, glm::mat3x3, glm::mat3x3(0), - glm::mat3x3(numeric_limits::lowest()), - glm::mat3x3(numeric_limits::max()), glm::mat3x3(0.01f), - DEFAULT_FROM_LUA_LAMBDA(glm::mat3x3), DEFAULT_TO_LUA_LAMBDA(glm::mat3x3) - ); + glm::mat3x3(numeric_limits::lowest()), + glm::mat3x3(numeric_limits::max()), + glm::mat3x3(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::mat3x3), + DEFAULT_TO_LUA_LAMBDA(glm::mat3x3), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(Mat3x4Property, glm::mat3x4, glm::mat3x4(0), - glm::mat3x4(numeric_limits::lowest()), - glm::mat3x4(numeric_limits::max()), glm::mat3x4(0.01f), - DEFAULT_FROM_LUA_LAMBDA(glm::mat3x4), DEFAULT_TO_LUA_LAMBDA(glm::mat3x4) - ); + glm::mat3x4(numeric_limits::lowest()), + glm::mat3x4(numeric_limits::max()), + glm::mat3x4(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::mat3x4), + DEFAULT_TO_LUA_LAMBDA(glm::mat3x4), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(Mat4x2Property, glm::mat4x2, glm::mat4x2(0), - glm::mat4x2(numeric_limits::lowest()), - glm::mat4x2(numeric_limits::max()), glm::mat4x2(0.01f), - DEFAULT_FROM_LUA_LAMBDA(glm::mat4x2), DEFAULT_TO_LUA_LAMBDA(glm::mat4x2) - ); + glm::mat4x2(numeric_limits::lowest()), + glm::mat4x2(numeric_limits::max()), + glm::mat4x2(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::mat4x2), + DEFAULT_TO_LUA_LAMBDA(glm::mat4x2), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(Mat4x3Property, glm::mat4x3, glm::mat4x3(0), - glm::mat4x3(numeric_limits::lowest()), - glm::mat4x3(numeric_limits::max()), glm::mat4x3(0.01f), - DEFAULT_FROM_LUA_LAMBDA(glm::mat4x3), DEFAULT_TO_LUA_LAMBDA(glm::mat4x3) - ); + glm::mat4x3(numeric_limits::lowest()), + glm::mat4x3(numeric_limits::max()), + glm::mat4x3(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::mat4x3), + DEFAULT_TO_LUA_LAMBDA(glm::mat4x3), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(Mat4Property, glm::mat4x4, glm::mat4x4(0), - glm::mat4x4(numeric_limits::lowest()), - glm::mat4x4(numeric_limits::max()), glm::mat4x4(0.01f), - DEFAULT_FROM_LUA_LAMBDA(glm::mat4x4), DEFAULT_TO_LUA_LAMBDA(glm::mat4x4) - ); + glm::mat4x4(numeric_limits::lowest()), + glm::mat4x4(numeric_limits::max()), + glm::mat4x4(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::mat4x4), + DEFAULT_TO_LUA_LAMBDA(glm::mat4x4), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DMat2Property, glm::dmat2x2, glm::dmat2x2(0), - glm::dmat2x2(numeric_limits::lowest()), - glm::dmat2x2(numeric_limits::max()), glm::dmat2x2(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x2), DEFAULT_TO_LUA_LAMBDA(glm::dmat2x2) - ); + glm::dmat2x2(numeric_limits::lowest()), + glm::dmat2x2(numeric_limits::max()), + glm::dmat2x2(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x2), + DEFAULT_TO_LUA_LAMBDA(glm::dmat2x2), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DMat2x3Property, glm::dmat2x3, glm::dmat2x3(0), - glm::dmat2x3(numeric_limits::lowest()), - glm::dmat2x3(numeric_limits::max()), glm::dmat2x3(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x3), DEFAULT_TO_LUA_LAMBDA(glm::dmat2x3) - ); + glm::dmat2x3(numeric_limits::lowest()), + glm::dmat2x3(numeric_limits::max()), + glm::dmat2x3(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x3), + DEFAULT_TO_LUA_LAMBDA(glm::dmat2x3), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DMat2x4Property, glm::dmat2x4, glm::dmat2x4(0), - glm::dmat2x4(numeric_limits::lowest()), - glm::dmat2x4(numeric_limits::max()), glm::dmat2x4(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x4), DEFAULT_TO_LUA_LAMBDA(glm::dmat2x4) - ); + glm::dmat2x4(numeric_limits::lowest()), + glm::dmat2x4(numeric_limits::max()), + glm::dmat2x4(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dmat2x4), + DEFAULT_TO_LUA_LAMBDA(glm::dmat2x4), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DMat3x2Property, glm::dmat3x2, glm::dmat3x2(0), - glm::dmat3x2(numeric_limits::lowest()), - glm::dmat3x2(numeric_limits::max()), glm::dmat3x2(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x2), DEFAULT_TO_LUA_LAMBDA(glm::dmat3x2) - ); + glm::dmat3x2(numeric_limits::lowest()), + glm::dmat3x2(numeric_limits::max()), + glm::dmat3x2(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x2), + DEFAULT_TO_LUA_LAMBDA(glm::dmat3x2), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DMat3Property, glm::dmat3x3, glm::dmat3x3(0), - glm::dmat3x3(numeric_limits::lowest()), - glm::dmat3x3(numeric_limits::max()), glm::dmat3x3(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x3), DEFAULT_TO_LUA_LAMBDA(glm::dmat3x3) -); + glm::dmat3x3(numeric_limits::lowest()), + glm::dmat3x3(numeric_limits::max()), + glm::dmat3x3(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x3), + DEFAULT_TO_LUA_LAMBDA(glm::dmat3x3), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DMat3x4Property, glm::dmat3x4, glm::dmat3x4(0), - glm::dmat3x4(numeric_limits::lowest()), - glm::dmat3x4(numeric_limits::max()), glm::dmat3x4(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x4), DEFAULT_TO_LUA_LAMBDA(glm::dmat3x4) - ); + glm::dmat3x4(numeric_limits::lowest()), + glm::dmat3x4(numeric_limits::max()), + glm::dmat3x4(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dmat3x4), + DEFAULT_TO_LUA_LAMBDA(glm::dmat3x4), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DMat4x2Property, glm::dmat4x2, glm::dmat4x2(0), - glm::dmat4x2(numeric_limits::lowest()), - glm::dmat4x2(numeric_limits::max()), glm::dmat4x2(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x2), DEFAULT_TO_LUA_LAMBDA(glm::dmat4x2) - ); + glm::dmat4x2(numeric_limits::lowest()), + glm::dmat4x2(numeric_limits::max()), + glm::dmat4x2(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x2), + DEFAULT_TO_LUA_LAMBDA(glm::dmat4x2), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DMat4x3Property, glm::dmat4x3, glm::dmat4x3(0), - glm::dmat4x3(numeric_limits::lowest()), - glm::dmat4x3(numeric_limits::max()), glm::dmat4x3(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x3), DEFAULT_TO_LUA_LAMBDA(glm::dmat4x3) - ); + glm::dmat4x3(numeric_limits::lowest()), + glm::dmat4x3(numeric_limits::max()), + glm::dmat4x3(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x3), + DEFAULT_TO_LUA_LAMBDA(glm::dmat4x3), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DMat4Property, glm::dmat4x4, glm::dmat4x4(0), - glm::dmat4x4(numeric_limits::lowest()), - glm::dmat4x4(numeric_limits::max()), glm::dmat4x4(0.01), - DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x4), DEFAULT_TO_LUA_LAMBDA(glm::dmat4x4) - ); + glm::dmat4x4(numeric_limits::lowest()), + glm::dmat4x4(numeric_limits::max()), + glm::dmat4x4(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dmat4x4), + DEFAULT_TO_LUA_LAMBDA(glm::dmat4x4), LUA_TTABLE); -} // namespace properties -} // namespace openspace +} // namespace properties +} // namespace openspace diff --git a/src/properties/scalarproperty.cpp b/src/properties/scalarproperty.cpp index 01ba23820f..6d32284c78 100644 --- a/src/properties/scalarproperty.cpp +++ b/src/properties/scalarproperty.cpp @@ -67,80 +67,103 @@ REGISTER_TEMPLATEPROPERTY_SOURCE(BoolProperty, bool, false, ); REGISTER_NUMERICALPROPERTY_SOURCE(CharProperty, char, char(0), - numeric_limits::lowest(), numeric_limits::max(), char(1), - DEFAULT_FROM_LUA_LAMBDA(char, char(0)), DEFAULT_TO_LUA_LAMBDA(char)); + numeric_limits::lowest(), + numeric_limits::max(), char(1), + DEFAULT_FROM_LUA_LAMBDA(char, char(0)), + DEFAULT_TO_LUA_LAMBDA(char), LUA_TNUMBER); -//REGISTER_NUMERICALPROPERTY_SOURCE(Char16Property, char16_t, char16_t(0), +// REGISTER_NUMERICALPROPERTY_SOURCE(Char16Property, char16_t, char16_t(0), // numeric_limits::lowest(), numeric_limits::max(), char16_t(1)); -//REGISTER_NUMERICALPROPERTY_SOURCE(Char32Property, char32_t, char32_t(0), +// REGISTER_NUMERICALPROPERTY_SOURCE(Char32Property, char32_t, char32_t(0), // numeric_limits::lowest(), numeric_limits::max(), char32_t(1)); REGISTER_NUMERICALPROPERTY_SOURCE(WCharProperty, wchar_t, wchar_t(0), - numeric_limits::lowest(), numeric_limits::max(), wchar_t(1), - DEFAULT_FROM_LUA_LAMBDA(wchar_t, wchar_t(0)), DEFAULT_TO_LUA_LAMBDA(wchar_t)); + numeric_limits::lowest(), + numeric_limits::max(), wchar_t(1), + DEFAULT_FROM_LUA_LAMBDA(wchar_t, wchar_t(0)), + DEFAULT_TO_LUA_LAMBDA(wchar_t), LUA_TNUMBER); REGISTER_NUMERICALPROPERTY_SOURCE(SignedCharProperty, signed char, (signed char)(0), - numeric_limits::lowest(), numeric_limits::max(), - (signed char)0, DEFAULT_FROM_LUA_LAMBDA(signed char, (signed char)(0)), - DEFAULT_TO_LUA_LAMBDA(signed char)); + numeric_limits::lowest(), + numeric_limits::max(), (signed char)0, + DEFAULT_FROM_LUA_LAMBDA(signed char, (signed char)(0)), + DEFAULT_TO_LUA_LAMBDA(signed char), LUA_TNUMBER); REGISTER_NUMERICALPROPERTY_SOURCE(UCharProperty, unsigned char, (unsigned char)0, - numeric_limits::lowest(), numeric_limits::max(), - (unsigned char)1, DEFAULT_FROM_LUA_LAMBDA(unsigned char, (unsigned char)(0)), - DEFAULT_TO_LUA_LAMBDA(unsigned char)); + numeric_limits::lowest(), + numeric_limits::max(), (unsigned char)1, + DEFAULT_FROM_LUA_LAMBDA(unsigned char, + (unsigned char)(0)), + DEFAULT_TO_LUA_LAMBDA(unsigned char), LUA_TNUMBER); REGISTER_NUMERICALPROPERTY_SOURCE(ShortProperty, short, short(0), - numeric_limits::lowest(), numeric_limits::max(), short(1), - DEFAULT_FROM_LUA_LAMBDA(short, short(0)), DEFAULT_TO_LUA_LAMBDA(short)); + numeric_limits::lowest(), + numeric_limits::max(), short(1), + DEFAULT_FROM_LUA_LAMBDA(short, short(0)), + DEFAULT_TO_LUA_LAMBDA(short), LUA_TNUMBER); -REGISTER_NUMERICALPROPERTY_SOURCE(UShortProperty, unsigned short, (unsigned short)(0), - numeric_limits::lowest(), numeric_limits::max(), - (unsigned short)1, DEFAULT_FROM_LUA_LAMBDA(unsigned short, (unsigned short)(0)), - DEFAULT_TO_LUA_LAMBDA(unsigned short)); +REGISTER_NUMERICALPROPERTY_SOURCE( + UShortProperty, unsigned short, (unsigned short)(0), + numeric_limits::lowest(), numeric_limits::max(), + (unsigned short)1, DEFAULT_FROM_LUA_LAMBDA(unsigned short, (unsigned short)(0)), + DEFAULT_TO_LUA_LAMBDA(unsigned short), LUA_TNUMBER); -REGISTER_NUMERICALPROPERTY_SOURCE(IntProperty, int, int(0), - numeric_limits::lowest(), numeric_limits::max(), int(1), - DEFAULT_FROM_LUA_LAMBDA(int, int(0)), DEFAULT_TO_LUA_LAMBDA(int)); +REGISTER_NUMERICALPROPERTY_SOURCE(IntProperty, int, int(0), numeric_limits::lowest(), + numeric_limits::max(), int(1), + DEFAULT_FROM_LUA_LAMBDA(int, int(0)), + DEFAULT_TO_LUA_LAMBDA(int), LUA_TNUMBER); REGISTER_NUMERICALPROPERTY_SOURCE(UIntProperty, unsigned int, (unsigned int)0, - numeric_limits::lowest(), numeric_limits::max(), - (unsigned int)1, DEFAULT_FROM_LUA_LAMBDA(unsigned int, (unsigned int)(0)), - DEFAULT_TO_LUA_LAMBDA(unsigned int)); + numeric_limits::lowest(), + numeric_limits::max(), (unsigned int)1, + DEFAULT_FROM_LUA_LAMBDA(unsigned int, + (unsigned int)(0)), + DEFAULT_TO_LUA_LAMBDA(unsigned int), LUA_TNUMBER); REGISTER_NUMERICALPROPERTY_SOURCE(LongProperty, long, long(0), - numeric_limits::lowest(), numeric_limits::max(), long(1), - DEFAULT_FROM_LUA_LAMBDA(long, long(0)), DEFAULT_TO_LUA_LAMBDA(long)); + numeric_limits::lowest(), + numeric_limits::max(), long(1), + DEFAULT_FROM_LUA_LAMBDA(long, long(0)), + DEFAULT_TO_LUA_LAMBDA(long), LUA_TNUMBER); REGISTER_NUMERICALPROPERTY_SOURCE(ULongProperty, unsigned long, (unsigned long)0, - numeric_limits::lowest(), numeric_limits::max(), - (unsigned long)1, DEFAULT_FROM_LUA_LAMBDA(unsigned long, (unsigned long)(0)), - DEFAULT_TO_LUA_LAMBDA(unsigned long)); + numeric_limits::lowest(), + numeric_limits::max(), (unsigned long)1, + DEFAULT_FROM_LUA_LAMBDA(unsigned long, + (unsigned long)(0)), + DEFAULT_TO_LUA_LAMBDA(unsigned long), LUA_TNUMBER); REGISTER_NUMERICALPROPERTY_SOURCE(LongLongProperty, long long, (long long)0, - numeric_limits::lowest(), numeric_limits::max(), (long long)1, - DEFAULT_FROM_LUA_LAMBDA(long long, (long long)(0)), - DEFAULT_TO_LUA_LAMBDA(long long)); + numeric_limits::lowest(), + numeric_limits::max(), (long long)1, + DEFAULT_FROM_LUA_LAMBDA(long long, (long long)(0)), + DEFAULT_TO_LUA_LAMBDA(long long), LUA_TNUMBER); -REGISTER_NUMERICALPROPERTY_SOURCE(ULongLongProperty, unsigned long long, - (unsigned long long)1, numeric_limits::lowest(), - numeric_limits::max(), (unsigned long long)1, - DEFAULT_FROM_LUA_LAMBDA(unsigned long long, (unsigned long long)(0)), - DEFAULT_TO_LUA_LAMBDA(unsigned long long)); +REGISTER_NUMERICALPROPERTY_SOURCE( + ULongLongProperty, unsigned long long, (unsigned long long)1, + numeric_limits::lowest(), + numeric_limits::max(), (unsigned long long)1, + DEFAULT_FROM_LUA_LAMBDA(unsigned long long, (unsigned long long)(0)), + DEFAULT_TO_LUA_LAMBDA(unsigned long long), LUA_TNUMBER); REGISTER_NUMERICALPROPERTY_SOURCE(FloatProperty, float, 0.f, - numeric_limits::lowest(), numeric_limits::max(), 0.01f, - DEFAULT_FROM_LUA_LAMBDA(float, float(0)), DEFAULT_TO_LUA_LAMBDA(float)); + numeric_limits::lowest(), + numeric_limits::max(), 0.01f, + DEFAULT_FROM_LUA_LAMBDA(float, float(0)), + DEFAULT_TO_LUA_LAMBDA(float), LUA_TNUMBER); REGISTER_NUMERICALPROPERTY_SOURCE(DoubleProperty, double, 0.0, - numeric_limits::lowest(), numeric_limits::max(), 0.01, - DEFAULT_FROM_LUA_LAMBDA(double, double(0)), DEFAULT_TO_LUA_LAMBDA(double)); + numeric_limits::lowest(), + numeric_limits::max(), 0.01, + DEFAULT_FROM_LUA_LAMBDA(double, double(0)), + DEFAULT_TO_LUA_LAMBDA(double), LUA_TNUMBER); REGISTER_NUMERICALPROPERTY_SOURCE(LongDoubleProperty, long double, (long double)0, - numeric_limits::lowest(), numeric_limits::max(), - (long double)0.01f, - DEFAULT_FROM_LUA_LAMBDA(long double, (long double)(0)), - DEFAULT_TO_LUA_LAMBDA(long double)); + numeric_limits::lowest(), + numeric_limits::max(), (long double)0.01f, + DEFAULT_FROM_LUA_LAMBDA(long double, (long double)(0)), + DEFAULT_TO_LUA_LAMBDA(long double), LUA_TNUMBER); -} // namespace properties +} // namespace properties } // namespace openspace diff --git a/src/properties/vectorproperty.cpp b/src/properties/vectorproperty.cpp index ecd2f01f16..e870f23f12 100644 --- a/src/properties/vectorproperty.cpp +++ b/src/properties/vectorproperty.cpp @@ -35,200 +35,138 @@ using std::numeric_limits; namespace openspace { namespace properties { -#define DEFAULT_FROM_LUA_LAMBDA_2(TYPE, DEFAULT_VALUE) \ - [](lua_State* state, bool& success) -> TYPE { \ - success = (lua_isnumber(state, -1) == 1) && (lua_isnumber(state, -2) == 1); \ - if (success) \ - return TYPE( \ - static_cast(lua_tonumber(state, -1)), \ - static_cast(lua_tonumber(state, -2))); \ - else \ - return DEFAULT_VALUE; \ - } +#define DEFAULT_FROM_LUA_LAMBDA(__TYPE__, __CONVFUNC__, __TESTFUNC__) \ + [](lua_State * state, bool& success) -> __TYPE__ { \ + __TYPE__ result; \ + int number = 1; \ + for (__TYPE__::size_type i = 0; i < result.length(); ++i) { \ + lua_getfield(state, -1, std::to_string(number).c_str()); \ + if (__TESTFUNC__(state, -1) != 1) { \ + success = false; \ + return __TYPE__(0); \ + } else { \ + result[i] = static_cast<__TYPE__::value_type>(__CONVFUNC__(state, -1)); \ + lua_pop(state, 1); \ + ++number; \ + } \ + } \ + success = true; \ + return result; \ + } -#define DEFAULT_FROM_LUA_LAMBDA_3(TYPE, DEFAULT_VALUE) \ - [](lua_State* state, bool& success) -> TYPE { \ - success = (lua_isnumber(state, -1) == 1) && \ - (lua_isnumber(state, -2) == 1) && \ - (lua_isnumber(state, -3) == 1); \ - if (success) \ - return TYPE( \ - static_cast(lua_tonumber(state, -1)), \ - static_cast(lua_tonumber(state, -2)), \ - static_cast(lua_tonumber(state, -3))); \ - else \ - return DEFAULT_VALUE; \ -} - -#define DEFAULT_FROM_LUA_LAMBDA_4(TYPE, DEFAULT_VALUE) \ - [](lua_State* state, bool& success) -> TYPE { \ - success = (lua_isnumber(state, -1) == 1) && \ - (lua_isnumber(state, -2) == 1) && \ - (lua_isnumber(state, -3) == 1) && \ - (lua_isnumber(state, -4) == 1); \ - if (success) \ - return TYPE( \ - static_cast(lua_tonumber(state, -1)), \ - static_cast(lua_tonumber(state, -2)), \ - static_cast(lua_tonumber(state, -3)), \ - static_cast(lua_tonumber(state, -4))); \ - else \ - return DEFAULT_VALUE; \ -} - -#define DEFAULT_TO_LUA_LAMBDA_2(TYPE) \ - [](lua_State* state, TYPE value) -> bool { \ - lua_pushnumber(state, static_cast(value.x)); \ - lua_pushnumber(state, static_cast(value.y)); \ +#define DEFAULT_TO_LUA_LAMBDA(__TYPE__) \ + [](lua_State * state, __TYPE__ value) -> bool { \ + lua_newtable(state); \ + int number = 1; \ + for (__TYPE__::size_type i = 0; i < value.length(); ++i) { \ + lua_pushnumber(state, static_cast(value[i])); \ + lua_setfield(state, -2, std::to_string(number).c_str()); \ + ++number; \ + } \ return true; \ } -#define DEFAULT_TO_LUA_LAMBDA_3(TYPE) \ - [](lua_State* state, TYPE value) -> bool { \ - lua_pushnumber(state, static_cast(value.x)); \ - lua_pushnumber(state, static_cast(value.y)); \ - lua_pushnumber(state, static_cast(value.z)); \ - return true; \ - \ -} - -#define DEFAULT_TO_LUA_LAMBDA_4(TYPE) \ - [](lua_State* state, TYPE value) -> bool { \ - lua_pushnumber(state, static_cast(value.x)); \ - lua_pushnumber(state, static_cast(value.y)); \ - lua_pushnumber(state, static_cast(value.z)); \ - lua_pushnumber(state, static_cast(value.w)); \ - return true; \ - \ -} - REGISTER_TEMPLATEPROPERTY_SOURCE(BVec2Property, glm::bvec2, glm::bvec2(false), - [](lua_State* state, bool& success) -> glm::bvec2 { - success = (lua_isboolean(state, -1) == 1) && (lua_isboolean(state, -2) == 1); - if (success) - return glm::bvec2(lua_toboolean(state, -1), lua_toboolean(state, -2)); - else - return glm::bvec2(false); - }, - [](lua_State* state, glm::bvec2 value) -> bool { - lua_pushboolean(state, value.x); - lua_pushboolean(state, value.y); - return true; - }, - LUA_TTABLE - ); + DEFAULT_FROM_LUA_LAMBDA(glm::bvec2, lua_toboolean, + lua_isboolean), + DEFAULT_TO_LUA_LAMBDA(glm::bvec2), LUA_TTABLE); REGISTER_TEMPLATEPROPERTY_SOURCE(BVec3Property, glm::bvec3, glm::bvec3(false), - [](lua_State* state, bool& success) -> glm::bvec3 { - success = (lua_isboolean(state, -1) == 1) && - (lua_isboolean(state, -2) == 1) && - (lua_isboolean(state, -3) == 1); - if (success) - return glm::bvec3(lua_toboolean(state, -1), - lua_toboolean(state, -2), - lua_toboolean(state, -3)); - else - return glm::bvec3(false); - }, - [](lua_State* state, glm::bvec3 value) -> bool { - lua_pushboolean(state, value.x); - lua_pushboolean(state, value.y); - lua_pushboolean(state, value.z); - return true; - }, - LUA_TTABLE - ); + DEFAULT_FROM_LUA_LAMBDA(glm::bvec3, lua_toboolean, + lua_isboolean), + DEFAULT_TO_LUA_LAMBDA(glm::bvec3), LUA_TTABLE); REGISTER_TEMPLATEPROPERTY_SOURCE(BVec4Property, glm::bvec4, glm::bvec4(false), - [](lua_State* state, bool& success) -> glm::bvec4 { - success = (lua_isboolean(state, -1) == 1) && - (lua_isboolean(state, -2) == 1) && - (lua_isboolean(state, -3) == 1) && - (lua_isboolean(state, -4) == 1); - if (success) - return glm::bvec4(lua_toboolean(state, -1), - lua_toboolean(state, -2), - lua_toboolean(state, -3), - lua_toboolean(state, -4)); - else - return glm::bvec4(false); - }, - [](lua_State* state, glm::bvec4 value) -> bool { - lua_pushboolean(state, value.x); - lua_pushboolean(state, value.y); - lua_pushboolean(state, value.z); - lua_pushboolean(state, value.w); - return true; - }, - LUA_TTABLE - ); + DEFAULT_FROM_LUA_LAMBDA(glm::bvec4, lua_toboolean, + lua_isboolean), + DEFAULT_TO_LUA_LAMBDA(glm::bvec4), LUA_TTABLE); -REGISTER_NUMERICALPROPERTY_SOURCE(Vec2Property, glm::vec2, glm::vec2(0), - glm::vec2(numeric_limits::lowest()), glm::vec2(numeric_limits::max()), - glm::vec2(0.01f), DEFAULT_FROM_LUA_LAMBDA_2(glm::vec2, glm::vec2(0)), - DEFAULT_TO_LUA_LAMBDA_2(glm::vec2)); // , LUA_TTABLE +REGISTER_NUMERICALPROPERTY_SOURCE( + Vec2Property, glm::vec2, glm::vec2(0), glm::vec2(numeric_limits::lowest()), + glm::vec2(numeric_limits::max()), glm::vec2(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::vec2, lua_tonumber, lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::vec2), LUA_TTABLE); -REGISTER_NUMERICALPROPERTY_SOURCE(Vec3Property, glm::vec3, glm::vec3(0), - glm::vec3(numeric_limits::lowest()), glm::vec3(numeric_limits::max()), - glm::vec3(0.01f), DEFAULT_FROM_LUA_LAMBDA_3(glm::vec3, glm::vec3(0)), - DEFAULT_TO_LUA_LAMBDA_3(glm::vec3)); +REGISTER_NUMERICALPROPERTY_SOURCE( + Vec3Property, glm::vec3, glm::vec3(0), glm::vec3(numeric_limits::lowest()), + glm::vec3(numeric_limits::max()), glm::vec3(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::vec3, lua_tonumber, lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::vec3), LUA_TTABLE); -REGISTER_NUMERICALPROPERTY_SOURCE(Vec4Property, glm::vec4, glm::vec4(0), - glm::vec4(numeric_limits::lowest()), glm::vec4(numeric_limits::max()), - glm::vec4(0.01f), DEFAULT_FROM_LUA_LAMBDA_4(glm::vec4, glm::vec4(0)), - DEFAULT_TO_LUA_LAMBDA_4(glm::vec4)); +REGISTER_NUMERICALPROPERTY_SOURCE( + Vec4Property, glm::vec4, glm::vec4(0), glm::vec4(numeric_limits::lowest()), + glm::vec4(numeric_limits::max()), glm::vec4(0.01f), + DEFAULT_FROM_LUA_LAMBDA(glm::vec4, lua_tonumber, lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::vec4), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DVec2Property, glm::dvec2, glm::dvec2(0), - glm::dvec2(numeric_limits::lowest()), - glm::dvec2(numeric_limits::max()), glm::dvec2(0.01), - DEFAULT_FROM_LUA_LAMBDA_2(glm::dvec2, glm::dvec2(0)), - DEFAULT_TO_LUA_LAMBDA_2(glm::dvec2)); + glm::dvec2(numeric_limits::lowest()), + glm::dvec2(numeric_limits::max()), + glm::dvec2(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dvec2, lua_tonumber, + lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::dvec2), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DVec3Property, glm::dvec3, glm::dvec3(0), - glm::dvec3(numeric_limits::lowest()), - glm::dvec3(numeric_limits::max()), glm::dvec3(0.01), - DEFAULT_FROM_LUA_LAMBDA_3(glm::dvec3, glm::dvec3(0)), - DEFAULT_TO_LUA_LAMBDA_3(glm::dvec3)); + glm::dvec3(numeric_limits::lowest()), + glm::dvec3(numeric_limits::max()), + glm::dvec3(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dvec3, lua_tonumber, + lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::dvec3), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(DVec4Property, glm::dvec4, glm::dvec4(0), - glm::dvec4(numeric_limits::lowest()), - glm::dvec4(numeric_limits::max()), glm::dvec4(0.01), - DEFAULT_FROM_LUA_LAMBDA_4(glm::dvec4, glm::dvec4(0)), - DEFAULT_TO_LUA_LAMBDA_4(glm::dvec4)); + glm::dvec4(numeric_limits::lowest()), + glm::dvec4(numeric_limits::max()), + glm::dvec4(0.01), + DEFAULT_FROM_LUA_LAMBDA(glm::dvec4, lua_tonumber, + lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::dvec4), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(IVec2Property, glm::ivec2, glm::ivec2(0), - glm::ivec2(numeric_limits::lowest()), glm::ivec2(numeric_limits::max()), - glm::ivec2(1), DEFAULT_FROM_LUA_LAMBDA_2(glm::ivec2, glm::ivec2(0)), - DEFAULT_TO_LUA_LAMBDA_2(glm::ivec2)); + glm::ivec2(numeric_limits::lowest()), + glm::ivec2(numeric_limits::max()), glm::ivec2(1), + DEFAULT_FROM_LUA_LAMBDA(glm::ivec2, lua_tonumber, + lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::ivec2), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(IVec3Property, glm::ivec3, glm::ivec3(0), - glm::ivec3(numeric_limits::lowest()), glm::ivec3(numeric_limits::max()), - glm::ivec3(1), DEFAULT_FROM_LUA_LAMBDA_3(glm::ivec3, glm::ivec3(0)), - DEFAULT_TO_LUA_LAMBDA_3(glm::ivec3)); + glm::ivec3(numeric_limits::lowest()), + glm::ivec3(numeric_limits::max()), glm::ivec3(1), + DEFAULT_FROM_LUA_LAMBDA(glm::ivec3, lua_tonumber, + lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::ivec3), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(IVec4Property, glm::ivec4, glm::ivec4(0), - glm::ivec4(numeric_limits::lowest()), glm::ivec4(numeric_limits::max()), - glm::ivec4(1), DEFAULT_FROM_LUA_LAMBDA_4(glm::ivec4, glm::ivec4(0)), - DEFAULT_TO_LUA_LAMBDA_4(glm::ivec4)); + glm::ivec4(numeric_limits::lowest()), + glm::ivec4(numeric_limits::max()), glm::ivec4(1), + DEFAULT_FROM_LUA_LAMBDA(glm::ivec4, lua_tonumber, + lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::ivec4), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(UVec2Property, glm::uvec2, glm::uvec2(0), - glm::uvec2(numeric_limits::lowest()), - glm::uvec2(numeric_limits::max()), glm::uvec2(1), - DEFAULT_FROM_LUA_LAMBDA_2(glm::uvec2, glm::uvec2(0)), - DEFAULT_TO_LUA_LAMBDA_2(glm::uvec2)); + glm::uvec2(numeric_limits::lowest()), + glm::uvec2(numeric_limits::max()), + glm::uvec2(1), + DEFAULT_FROM_LUA_LAMBDA(glm::uvec2, lua_tonumber, + lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::uvec2), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(UVec3Property, glm::uvec3, glm::uvec3(0), - glm::uvec3(numeric_limits::lowest()), - glm::uvec3(numeric_limits::max()), glm::uvec3(1), - DEFAULT_FROM_LUA_LAMBDA_3(glm::uvec3, glm::uvec3(0)), - DEFAULT_TO_LUA_LAMBDA_3(glm::uvec3)); + glm::uvec3(numeric_limits::lowest()), + glm::uvec3(numeric_limits::max()), + glm::uvec3(1), + DEFAULT_FROM_LUA_LAMBDA(glm::uvec3, lua_tonumber, + lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::uvec3), LUA_TTABLE); REGISTER_NUMERICALPROPERTY_SOURCE(UVec4Property, glm::uvec4, glm::uvec4(0), - glm::uvec4(numeric_limits::lowest()), - glm::uvec4(numeric_limits::max()), glm::uvec4(1), - DEFAULT_FROM_LUA_LAMBDA_4(glm::uvec4, glm::uvec4(0)), - DEFAULT_TO_LUA_LAMBDA_4(glm::uvec4)); - + glm::uvec4(numeric_limits::lowest()), + glm::uvec4(numeric_limits::max()), + glm::uvec4(1), + DEFAULT_FROM_LUA_LAMBDA(glm::uvec4, lua_tonumber, + lua_isnumber), + DEFAULT_TO_LUA_LAMBDA(glm::uvec4), LUA_TTABLE); } // namespace properties } // namespace openspace From d8fb5392455dfb62e1f2d1bbd5e47a53b4d01564 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 3 Sep 2014 00:24:08 +0200 Subject: [PATCH 067/113] Fixed warning --- src/properties/vectorproperty.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/properties/vectorproperty.cpp b/src/properties/vectorproperty.cpp index e870f23f12..f05299cb37 100644 --- a/src/properties/vectorproperty.cpp +++ b/src/properties/vectorproperty.cpp @@ -41,13 +41,13 @@ namespace properties { int number = 1; \ for (__TYPE__::size_type i = 0; i < result.length(); ++i) { \ lua_getfield(state, -1, std::to_string(number).c_str()); \ - if (__TESTFUNC__(state, -1) != 1) { \ + if (__TESTFUNC__(state, -1) != 1) { \ success = false; \ return __TYPE__(0); \ } else { \ - result[i] = static_cast<__TYPE__::value_type>(__CONVFUNC__(state, -1)); \ - lua_pop(state, 1); \ - ++number; \ + result[i] = static_cast<__TYPE__::value_type>(__CONVFUNC__(state, -1)); \ + lua_pop(state, 1); \ + ++number; \ } \ } \ success = true; \ @@ -66,6 +66,13 @@ namespace properties { return true; \ } + +// Forcing value from int to bool is acceptable here (line 48) +#ifdef WIN32 +#pragma warning(disable : 4800) +#endif + + REGISTER_TEMPLATEPROPERTY_SOURCE(BVec2Property, glm::bvec2, glm::bvec2(false), DEFAULT_FROM_LUA_LAMBDA(glm::bvec2, lua_toboolean, lua_isboolean), @@ -81,6 +88,11 @@ REGISTER_TEMPLATEPROPERTY_SOURCE(BVec4Property, glm::bvec4, glm::bvec4(false), lua_isboolean), DEFAULT_TO_LUA_LAMBDA(glm::bvec4), LUA_TTABLE); +#ifdef WIN32 +#pragma warning(default : 4800) +#endif + + REGISTER_NUMERICALPROPERTY_SOURCE( Vec2Property, glm::vec2, glm::vec2(0), glm::vec2(numeric_limits::lowest()), glm::vec2(numeric_limits::max()), glm::vec2(0.01f), From cd29bbee70d427619a8c77c988487cd68b030ab1 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 3 Sep 2014 13:14:25 +0200 Subject: [PATCH 068/113] Added more conversion tests --- .../openspace/tests/test_luaconversions.inl | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/include/openspace/tests/test_luaconversions.inl b/include/openspace/tests/test_luaconversions.inl index 8477615f07..e58f314593 100644 --- a/include/openspace/tests/test_luaconversions.inl +++ b/include/openspace/tests/test_luaconversions.inl @@ -29,6 +29,7 @@ #include #include #include +#include class LuaConversionTest : public testing::Test { protected: @@ -55,6 +56,21 @@ TEST_F(LuaConversionTest, LuaExecution) { EXPECT_EQ(status, LUA_OK); } +#define CONVERSION_TEST_TEMPLATE(__NAME__, __TYPE__, __VALUE__) \ + TEST_F(LuaConversionTest, __NAME__) \ + { \ + using namespace openspace::properties; \ + bool success \ + = PropertyDelegate>::toLuaValue<__TYPE__>( \ + state, __VALUE__); \ + EXPECT_TRUE(success) << "toLuaValue"; \ + __TYPE__ value = __TYPE__(0); \ + value = PropertyDelegate>::fromLuaValue<__TYPE__>( \ + state, success); \ + EXPECT_TRUE(success) << "fromLuaValue"; \ + EXPECT_EQ(value, __VALUE__) << "fromLuaValue"; \ + } + #define CONVERSION_TEST_NUMERICAL(__NAME__, __TYPE__, __VALUE__) \ TEST_F(LuaConversionTest, __NAME__) \ { \ @@ -63,13 +79,15 @@ TEST_F(LuaConversionTest, LuaExecution) { = PropertyDelegate>::toLuaValue<__TYPE__>( \ state, __VALUE__); \ EXPECT_TRUE(success) << "toLuaValue"; \ - __TYPE__ value \ - = PropertyDelegate>::fromLuaValue<__TYPE__>( \ - state, success); \ + __TYPE__ value = __TYPE__(0); \ + value = PropertyDelegate>::fromLuaValue<__TYPE__>( \ + state, success); \ EXPECT_TRUE(success) << "fromLuaValue"; \ EXPECT_EQ(value, __VALUE__) << "fromLuaValue"; \ } +CONVERSION_TEST_TEMPLATE(Bool, bool, true); + CONVERSION_TEST_NUMERICAL(Char, char, 1); CONVERSION_TEST_NUMERICAL(WChar, wchar_t, 1); CONVERSION_TEST_NUMERICAL(SignedChar, signed char, 1); @@ -117,3 +135,17 @@ CONVERSION_TEST_NUMERICAL(DMat3x4, glm::dmat3x4, glm::dmat3x4(1.f)); CONVERSION_TEST_NUMERICAL(DMat4x2, glm::dmat4x2, glm::dmat4x2(1.f)); CONVERSION_TEST_NUMERICAL(DMat4x3, glm::dmat4x3, glm::dmat4x3(1.f)); CONVERSION_TEST_NUMERICAL(DMat4x4, glm::dmat4x4, glm::dmat4x4(1.f)); + +TEST_F(LuaConversionTest, String) +{ + using namespace openspace::properties; + bool success + = PropertyDelegate>::toLuaValue( + state, "value"); + EXPECT_TRUE(success) << "toLuaValue"; + std::string value = ""; + value = PropertyDelegate>::fromLuaValue( + state, success); + EXPECT_TRUE(success) << "fromLuaValue"; + EXPECT_EQ(value, "value") << "fromLuaValue"; +} \ No newline at end of file From eb7d1aac06d6a27d475f4de235eb7bcb91d661cb Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 7 Sep 2014 15:01:54 +0200 Subject: [PATCH 069/113] Added documentation to Property class Modified callback function mechanism to only allow one call back function to be present --- include/openspace/properties/property.h | 214 ++++++++++++++++-- .../openspace/properties/templateproperty.inl | 2 +- src/properties/property.cpp | 36 +-- 3 files changed, 213 insertions(+), 39 deletions(-) diff --git a/include/openspace/properties/property.h b/include/openspace/properties/property.h index aed1f96afb..93ed912bbd 100644 --- a/include/openspace/properties/property.h +++ b/include/openspace/properties/property.h @@ -39,42 +39,216 @@ namespace properties { class PropertyOwner; +/** + * A property encapsulates a value which should be user-changeable. A property almost + * always belongs to a PropertyOwner who has taken ownership (setPropertyOwner) of the + * Property. Per PropertyOwner, the identifier needs to be unique and can be + * used as a URI. This class is an abstract base class and each subclass (most notable + * TemplateProperty) needs to implement the methods Property::className, Property::get, + * Property::set, Property::type(), Property::getLua, Property::setLua, and + * Property::typeLua to make full use of the infrastructure. + * The most common types can be implemented by creating a specialized instantiation of + * TemplateProperty, which provides default implementations for these methods. + * + * The onChange method can be used by the PropertyOwner to listen to changes that happen + * to the Property. The parameter is a function object that gets called after new value + * has been set. + * The metaData allows the developer to specify additional information about the Property + * which might be used in GUI representations. One example would be a glm::vec4 property, + * (Vec4Property) that can either represent a 4-dimensional position, a powerscaled + * coordinate, a light position, or other things, requiring different GUI representations. + * \see TemplateProperty + * \see PropertyOwner + */ class Property { public: + /** + * The constructor for the property. The identifier needs to be unique + * for each PropertyOwner. The guiName will be stored in the metaData + * to be accessed by the GUI elements using the guiName key. The default + * visibility settings is true, whereas the default read-only state is + * false. + * \param identifier A unique identifier for this property. It has to be unique to the + * PropertyOwner + * \param guiName The human-readable GUI name for this Property + */ Property(std::string identifier, std::string guiName); + + /** + * The destructor taking care of deallocating all unused memory. This method will not + * remove the Property from the PropertyOwner. + */ virtual ~Property(); - //virtual Property* create() const = 0; + /** + * This method returns the class name of the Property. The method is used by the + * TemplateFactory to create new instances of Propertys. The returned value is almost + * always identical to the C++ class name of the derived class. + * \return The class name of the Property + */ virtual std::string className() const = 0; + /** + * This method returns the encapsulated value of the Property to the caller. The type + * that is returned is determined by the type function and is up to the developer of + * the derived class. The default implementation returns an empty boost::any object. + * \return The value that is encapsulated by this Property, or an empty boost::any + * object if the method was not overritten. + */ virtual boost::any get() const; - virtual void set(boost::any value); - virtual const std::type_info& type() const; + /** + * Sets the value encapsulated by this Property to the value passed to + * this function. It is the caller's responsibility to ensure that the type contained + * in value is compatible with the concrete subclass of the Property. The + * method Property::type will return the desired type for the Property. The default + * implementation of this method ignores the input. + * \param value The new value that should be stored in this Property + */ + virtual void set(boost::any value); + + /** + * This method returns the type that is requested by this Property for the set method. + * The default implementation returns the type of void. + * \return The type that is requested by this Property's Property::set method + */ + virtual const std::type_info& type() const; + + /** + * This method encodes the encapsulated value of this Property at the top of the Lua + * stack. The specific details of this serialization is up to the property developer + * as long as the rest of the stack is unchanged. The implementation has to be + * synchronized with the Property::setLua method. The default implementation is a + * no-op. + * \param state The Lua state to which the value will be encoded + * \return true if the encoding succeeded, false otherwise + */ virtual bool getLua(lua_State* state) const; + + /** + * This method sets the value encapsulated by this Property by deserializing the value + * on top of the passed Lua stack. The specific details of the deserialization are up + * to the Property developer, but they must only depend on the top element of the + * stack and must leave all other elements unchanged. The implementation has to be + * synchronized with the Property::getLua method. The default implementation is a + * no-op. + * \param state The Lua state from which the value will be decoded + * \return true if the decoding and setting of the value succeeded, + * false otherwise + */ virtual bool setLua(lua_State* state); + + /** + * Returns the Lua type that will be put onto the stack in the Property::getLua method + * and which will be consumed by the Property::setLua method. The returned value + * can belong to the set of Lua types: LUA_TNONE, LUA_TNIL, + * LUA_TBOOLEAN, LUA_TLIGHTUSERDATA, + * LUA_TNUMBER, LUA_TSTRING, LUA_TTABLE, + * LUA_TFUNCTION, LUA_TUSERDATA, or + * LUA_TTHREAD. The default implementation will return + * LUA_TNONE. + * \return The Lua type that will be consumed or produced by the Property::getLua and + * Property::setLua methods. + */ virtual int typeLua() const; + /** + * This method registers a callback function that will be called every + * time if either Property:set or Property::setLua was called with a value that is + * different from the previously stored value. The callback can be removed my passing + * an empty std::function object. + * \param callback The callback function that is called when the encapsulated type has + * been successfully changed by either the Property::set or Property::setLua methods. + */ virtual void onChange(std::function callback); + /** + * This method returns the unique identifier of this Property. + * \return The unique identifier of this Property + */ const std::string& identifier() const; - const std::string& guiName() const; + /** + * Returns the PropertyOwner of this Property or nullptr, if it does not + * have an owner. + *\ return The Property of this Property + */ PropertyOwner* owner() const; - void setPropertyOwner(PropertyOwner* owner); + /** + * Assigned the Property to a new PropertyOwner. This method does not inform the + * PropertyOwner of this action. + * \param owner The new PropertyOwner for this Property + */ + void setPropertyOwner(PropertyOwner* owner); + + /** + * Returns the human-readable GUI name for this Property that has been set in the + * constructor. This method returns the same value as accessing the metaData object + * and requesting the std::string stored for the guiName + * key. + * \return The human-readable GUI name for this Property + */ + const std::string& guiName() const; + + /** + * Sets the identifier of the group that this Property belongs to. Property groups can + * be used, for example, by GUI application to visually group different properties, + * but it has no impact on the Property itself. The default value for the groupID is + * "". + * \param groupId The group id that this property should belong to + */ void setGroupIdentifier(std::string groupId); + + /** + * Returns the group idenfier that this Property belongs to, or "" if it + * belongs to no group. + * \return The group identifier that this Property belongs to + */ std::string groupIdentifier() const; + /** + * Determines a hint if this Property should be visible, or hidden. Each application + * accessing the properties is free to ignore this hint. It is stored in the metaData + * Dictionary with the key: isVisible. The default value is + * true. + * \param state true if the Property should be visible, + * false otherwise. + */ void setVisible(bool state); - bool isVisible() const; - void setReadOnly(bool state); - bool isReadOnly() const; + /** + * This method determines if this Property should be read-only in external + * applications. This setting is only a hint and does not need to be followed by GUI + * applications and does not have any effect on the Property::set or Property::setLua + * methods. The value is stored in the metaData Dictionary with the key: + * isReadOnly. The default value is false. + * \param state true if the Property should be read only, + * false otherwise + */ + void setReadOnly(bool state); + /** + * This method allows the developer to give hints to the GUI about different + * representations for the GUI. The same Property (for example Vec4Property) can be + * used in different ways, each requiring a different input method. These values are + * stored in the metaData object using the views. prefix in front of the + * option parameter. See Property::ViewOptions for a default list of + * possible options. As these are only hints, the GUI is free to ignore any suggestion + * by the developer. + * \param option The view option that should be modified + * \param value Determines if the view option should be active (true) or + * deactivated (false) + */ void setViewOption(std::string option, bool value = true); - bool viewOption(const std::string& option) const; + /** + * Default view options that can be used in the Property::setViewOption method. The + * values are: Property::ViewOptions::Color = color, + * Property::ViewOptions::LightPosition = lightPosition, + * Property::ViewOptions::PowerScaledScalar = powerScaledScalar, and + * Property::ViewOptions::PowerScaledCoordinate = powerScaledCoordinate. + */ struct ViewOptions { static const std::string Color; static const std::string LightPosition; @@ -82,18 +256,32 @@ public: static const std::string PowerScaledCoordinate; }; + /** + * Returns the metaData that contains all information for external applications to + * correctly display information about the Property. No information that is stored in + * this Dictionary is necessary for the programmatic use of the Property. + * \return The Dictionary containing all meta data information about this Property + */ const ghoul::Dictionary& metaData() const; protected: - void notifyListeners(); + /** + * This method must be called by all subclasses whenever the encapsulated value has + * changed and a potential listener has to be informed. + */ + void notifyListener(); - PropertyOwner* _owner; + /// The PropetyOwner this Property belongs to, or nullptr + PropertyOwner* _owner; + /// The identifier for this Property std::string _identifier; - std::string _guiName; + + /// The Dictionary containing all meta data necessary for external applications ghoul::Dictionary _metaData; - std::vector> _onChangeCallbacks; + /// The callback function that will be invoked whenever the encapsulated value changes + std::function _onChangeCallback; }; } // namespace properties diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index 2db1902329..ae81fd4836 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -133,7 +133,7 @@ template void TemplateProperty::set(boost::any value) { try { _value = boost::any_cast(std::move(value)); - notifyListeners(); + notifyListener(); } catch (boost::bad_any_cast&) { LERRORC("TemplateProperty", "Illegal cast from '" << value.type().name() diff --git a/src/properties/property.cpp b/src/properties/property.cpp index 7ea90bcbe7..f00890f9bd 100644 --- a/src/properties/property.cpp +++ b/src/properties/property.cpp @@ -30,9 +30,12 @@ namespace openspace { namespace properties { namespace { + const std::string _metaDataKeyGuiName = "guiName"; const std::string _metaDataKeyGroup = "group"; const std::string _metaDataKeyVisible = "isVisible"; const std::string _metaDataKeyReadOnly = "isReadOnly"; + + const std::string _metaDataKeyViewPrefix = "view."; } const std::string Property::ViewOptions::Color = "color"; @@ -43,9 +46,9 @@ const std::string Property::ViewOptions::PowerScaledScalar = "powerScaledScalar" Property::Property(std::string identifier, std::string guiName) : _identifier(std::move(identifier)) - , _guiName(std::move(guiName)) { setVisible(true); + _metaData.setValue(_metaDataKeyGuiName, std::move(guiName)); } Property::~Property() {} @@ -77,7 +80,9 @@ int Property::typeLua() const { } const std::string& Property::guiName() const { - return _guiName; + std::string result = ""; + _metaData.getValue(_metaDataKeyGuiName, result); + return std::move(result); } void Property::setGroupIdentifier(std::string groupId) { @@ -94,30 +99,12 @@ void Property::setVisible(bool state) { _metaData.setValue(_metaDataKeyVisible, state); } -bool Property::isVisible() const { - bool result = false; - _metaData.getValue(_metaDataKeyVisible, result); - return result; -} - void Property::setReadOnly(bool state) { _metaData.setValue(_metaDataKeyReadOnly, state); } -bool Property::isReadOnly() const { - bool result = false; - _metaData.getValue(_metaDataKeyReadOnly, result); - return result; -} - void Property::setViewOption(std::string option, bool value) { - _metaData.setValue("view." + option, value, true); -} - -bool Property::viewOption(const std::string& option) const { - bool result = false; - _metaData.getValue("view." + option, result); - return result; + _metaData.setValue(_metaDataKeyViewPrefix + option, value, true); } const ghoul::Dictionary& Property::metaData() const { @@ -125,7 +112,7 @@ const ghoul::Dictionary& Property::metaData() const { } void Property::onChange(std::function callback) { - _onChangeCallbacks.push_back(std::move(callback)); + _onChangeCallback = std::move(callback); } @@ -139,9 +126,8 @@ void Property::setPropertyOwner(PropertyOwner* owner) _owner = owner; } -void Property::notifyListeners() { - for (std::function& f : _onChangeCallbacks) - f(); +void Property::notifyListener() { + _onChangeCallback(); } } // namespace properties From 659b4ff3b8c458f26a6743351f8c3d7edf8998a3 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 7 Sep 2014 15:54:17 +0200 Subject: [PATCH 070/113] Added documentation to PropertyOwner --- include/openspace/properties/property.h | 2 +- include/openspace/properties/propertyowner.h | 140 ++++++++++++++++++- src/properties/propertyowner.cpp | 12 +- 3 files changed, 148 insertions(+), 6 deletions(-) diff --git a/include/openspace/properties/property.h b/include/openspace/properties/property.h index 93ed912bbd..9b042bbed7 100644 --- a/include/openspace/properties/property.h +++ b/include/openspace/properties/property.h @@ -69,7 +69,7 @@ public: * visibility settings is true, whereas the default read-only state is * false. * \param identifier A unique identifier for this property. It has to be unique to the - * PropertyOwner + * PropertyOwner and cannot contain any .s * \param guiName The human-readable GUI name for this Property */ Property(std::string identifier, std::string guiName); diff --git a/include/openspace/properties/propertyowner.h b/include/openspace/properties/propertyowner.h index 6dfaf7c1af..98be6bd064 100644 --- a/include/openspace/properties/propertyowner.h +++ b/include/openspace/properties/propertyowner.h @@ -33,44 +33,178 @@ namespace openspace { namespace properties { +/** + * A PropertyOwner can own Propertys or other PropertyOwner and provide access to both in + * a unified way. The identifiers and names of Propertys and + * sub-owners must be unique to this PropertyOwner. A Property cannot have the same name + * as a PropertyOwner owned by this PropertyOwner. + * Propertys can be added using the Property::addProperty methods and be removed by the + * Property::removeProperty method. The same holds true for sub-owners + * (Property::addPropertySubOwner, Property::removePropertySubOwner). These methods will + * inform the passed object about the new ownership automatically. + * Stored properties can be accessed using the Property::properties method or the + * Property::property method, providing an URI for the location of the property. If the + * URI contains separators (.), the first name before the separator will be + * used as a subOwner's name and the search will proceed recursively. + */ class PropertyOwner { public: + /// The separator that is used while accessing the properties and/or sub-owners static const char URISeparator = '.'; + /// The constructor initializing the PropertyOwner's name to "" PropertyOwner(); + + /** + * The destructor will remove all Propertys and PropertyOwners it owns along with + * itself. + */ virtual ~PropertyOwner(); + /** + * Sets the name for this PropertyOwner. If the PropertyOwner does not have an owner + * itself, the name must be globally unique. If the PropertyOwner has an owner, the + * name must be unique to the owner (including the owner's properties). No uniqueness + * check will be preformed here, but rather in the PropertyOwner::addProperty and + * PropertyOwner::addPropertySubOwner methods). + * \param name The name of this PropertyOwner. It may not contain any .s + */ void setName(std::string name); - virtual const std::string& name() const; + /** + * Returns the name of this PropertyOwner. + * \return The name of this PropertyOwner + */ + const std::string& name() const; + + /** + * Returns a list of all Propertys directly owned by this PropertyOwner. This list not + * include Propertys owned by other sub-owners. + * \return A list of all Propertys directly owned by this PropertyOwner + */ const std::vector& properties() const; - Property* property(const std::string& id) const; - bool hasProperty(const std::string& id) const; + + /** + * Retrieves a Property identified by URI from this PropertyOwner. If + * id does not contain a . the identifier must refer to a + * Property directly owned by this PropertyOwner. If the identifier contains one or + * more ., the first part of the name will be recursively extracted and + * used as a name for a sub-owner and only the last part of the identifier is + * referring to a Property owned by PropertyOwner named by the second-but-last name. + * \param URI The identifier of the Property that should be extracted. If the Property + * cannot be found, nullptr is returned + */ + Property* property(const std::string& URI) const; + + /** + * This method checks if a Propetry with the provided URI exists in this + * PropertyOwner (or any sub-owner). If the identifier contains one or more + * ., the first part of the name will be recursively extracted and is + * used as a name for a sub-owner and only the last part of the identifier is + * referring to a Property owned by PropertyOwner named by the second-but-last name. + * \return true if the URI refers to a Property; + * false otherwise. + */ + bool hasProperty(const std::string& URI) const; + /** + * Returns a list of all sub-owners this PropertyOwner has. Each name of a sub-owner + * has to be unique with respect to other sub-owners as well as Propertys owned by + * this PropertyOwner. + * \return A list of all sub-owners this PropertyOwner has + */ const std::vector& subOwners() const; + + /** + * This method returns the direct sub-owner of this PropertyOwner with the provided + * name. This means that name cannot contain any + * . as this character is not allowed in PropertyOwner names. If the + * name does not name a valid sub-owner of this PropertyOwner, a + * nullptr will be returned. + * \param name The name of the sub-owner that should be returned + * \return The PropertyOwner with the given name, or nullptr + */ PropertyOwner* subOwner(const std::string& name) const; + + /** + * Returns true if this PropertyOwner owns a sub-owner with the provided + * name>/code>; returns false otherwise. + * \param name The name of the sub-owner that should be looked up + * \return true if this PropertyOwner owns a sub-owner with the provided + * name>/code>; returns false otherwise + */ bool hasSubOwner(const std::string& name) const; + /** + * This method converts a provided groupIDname which can be used by some external application. + * \param groupID The group identifier whose human-readable name should be set + * \param name The human-readable name for the group identifier + */ void setPropertyGroupName(std::string groupID, std::string name); + + /** + * Returns the human-readable name for the groupID for the Propertys of + * this PropertyOwner. + * \param groupID The group identifier whose human-readable name should be returned + * \return The human readable name for the Propertys identified by + * groupID + */ const std::string& propertyGroupName(const std::string& groupID) const; protected: + /** + * Assigns the Property prop to this PropertyOwner. This method will + * check if the name of the Property is unique amongst Propertys and sub-owners in + * this PropertyOwner. This method will also inform the Property about the change in + * ownership by calling the Property::setPropertyOwner method. + * \param prop The Property whose ownership is changed. + */ void addProperty(Property* prop); + + /// \see Property::addProperty(Property*) void addProperty(Property& prop); + /** + * Adds the provided PropertyOwner to the list of sub-owners for this PropertyOwner. + * This means that the name of the owner has to be unique amonst the + * direct Property's as well as other PropertyOwner's that this PropertyOwner owns. + * This uniqueness will be tested in this method. + * \param owner The owner that should be assigned to this PropertyOwner + */ void addPropertySubOwner(PropertyOwner* owner); + + /// \see PropertyOwner::addPropertySubOwner(PropertyOwner*) void addPropertySubOwner(PropertyOwner& owner); + /** + * Removes the Property from this PropertyOwner. Notifies the Property about this + * change by calling the Property::setPropertyOwner method with a nullptr + * as parameter. + * \param prop The Property that should be removed from this PropertyOwner + */ void removeProperty(Property* prop); + + /// \see PropertyOwner::removeProperty(Property*) void removeProperty(Property& prop); + /** + * Removes the sub-owner from this PropertyOwner. + * \param owner The PropertyOwner that should be removed + */ void removePropertySubOwner(PropertyOwner* owner); + + /// \see PropertyOwner::removePropertySubOwner(PropertyOwner*) void removePropertySubOwner(PropertyOwner& owner); private: + /// The name of this PropertyOwner std::string _name; + /// A list of all owned Property's std::vector _properties; + /// A list of all sub-owners std::vector _subOwners; + /// The associations between group identifiers of Property's and human-readable names std::map _groupNames; }; diff --git a/src/properties/propertyowner.cpp b/src/properties/propertyowner.cpp index 9162bd1d2f..4831d64fa3 100644 --- a/src/properties/propertyowner.cpp +++ b/src/properties/propertyowner.cpp @@ -47,11 +47,16 @@ bool subOwnerLess(PropertyOwner* lhs, PropertyOwner* rhs) { PropertyOwner::PropertyOwner() : _name("") { - } PropertyOwner::~PropertyOwner() { + for (Property* p : _properties) + delete p; + _properties.clear(); + for (PropertyOwner* s : _subOwners) + delete s; + _subOwners.clear(); } const std::vector& PropertyOwner::properties() const @@ -63,6 +68,7 @@ Property* PropertyOwner::property(const std::string& id) const { assert(std::is_sorted(_properties.begin(), _properties.end(), propertyLess)); + // As the _properties list is sorted, just finding the lower bound is sufficient std::vector::const_iterator it = std::lower_bound(_properties.begin(), _properties.end(), id, [](Property* prop, const std::string& str) { @@ -110,6 +116,7 @@ const std::vector& PropertyOwner::subOwners() const { PropertyOwner* PropertyOwner::subOwner(const std::string& name) const { assert(std::is_sorted(_subOwners.begin(), _subOwners.end(), subOwnerLess)); + // As the _subOwners list is sorted, getting the lower bound is sufficient std::vector::const_iterator it = std::lower_bound(_subOwners.begin(), _subOwners.end(), name, [](PropertyOwner* owner, const std::string& str) { @@ -151,6 +158,7 @@ void PropertyOwner::addProperty(Property* prop) } // See if we can find the identifier of the property to add in the properties list + // The _properties list is sorted, so getting the lower bound is sufficient std::vector::iterator it = std::lower_bound(_properties.begin(), _properties.end(), prop->identifier(), [](Property* prop, const std::string& str) { @@ -184,7 +192,7 @@ void PropertyOwner::addPropertySubOwner(openspace::properties::PropertyOwner* ow return; } - // See if we can find the name of the propertyowner to add + // See if we can find the name of the propertyowner to add using the lower bound std::vector::iterator it = std::lower_bound(_subOwners.begin(), _subOwners.end(), owner->name(), [](PropertyOwner* owner, const std::string& str) { From aa36f7d7761ee5e6cdbdf560965389d8854f201c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 7 Sep 2014 16:00:48 +0200 Subject: [PATCH 071/113] Added check to test for equal names for Propertys and PropertyOwners --- src/properties/propertyowner.cpp | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/properties/propertyowner.cpp b/src/properties/propertyowner.cpp index 4831d64fa3..2b1986ce1d 100644 --- a/src/properties/propertyowner.cpp +++ b/src/properties/propertyowner.cpp @@ -151,6 +151,7 @@ void PropertyOwner::addProperty(Property* prop) { assert(prop != nullptr); assert(std::is_sorted(_properties.begin(), _properties.end(), propertyLess)); + assert(std::is_sorted(_subOwners.begin(), _subOwners.end(), subOwnerLess)); if (prop->identifier().empty()) { LERROR("No property identifier specified"); @@ -172,9 +173,18 @@ void PropertyOwner::addProperty(Property* prop) << name() << "'"); return; } else { - // Otherwise we have found the correct position to add it in - _properties.insert(it, prop); - prop->setPropertyOwner(this); + // Otherwise we still have to look if there is a PropertyOwner with the same name + const bool hasOwner = hasSubOwner(prop->identifier()); + if (hasOwner) { + LERROR("Property identifier '" << prop->identifier() << "' already names a" + << "registed PropertyOwner"); + return; + } + else { + // now have found the correct position to add it in + _properties.insert(it, prop); + prop->setPropertyOwner(this); + } } } @@ -185,6 +195,7 @@ void PropertyOwner::addProperty(Property& prop) void PropertyOwner::addPropertySubOwner(openspace::properties::PropertyOwner* owner) { assert(owner != nullptr); + assert(std::is_sorted(_properties.begin(), _properties.end(), propertyLess)); assert(std::is_sorted(_subOwners.begin(), _subOwners.end(), subOwnerLess)); if (owner->name().empty()) { @@ -205,8 +216,17 @@ void PropertyOwner::addPropertySubOwner(openspace::properties::PropertyOwner* ow << "' already present in PropertyOwner '" << name() << "'"); return; } else { - // Otherwise we have found the correct position to add it in - _subOwners.insert(it, owner); + // We still need to check if the PropertyOwners name is used in a Property + const bool hasProp = hasProperty(owner->name()); + if (hasProp) { + LERROR("PropertyOwner '" << owner->name() << "'s name already names a " + << "Property"); + return; + } + else { + // Otherwise we have found the correct position to add it in + _subOwners.insert(it, owner); + } } } From 0e12366020acb85eee22925c3cf64b8b2d09b48d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 7 Sep 2014 16:02:20 +0200 Subject: [PATCH 072/113] Added LuaConversions test suite --- src/tests/main.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/tests/main.cpp b/src/tests/main.cpp index e9ba33f120..b65a6237fd 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -33,6 +33,7 @@ #include #include //#include +#include #include #include #include @@ -63,7 +64,7 @@ int main(int argc, char** argv) { } LINFO("Configuration file found: " << FileSys.absolutePath(configurationFilePath)); - LDEBUG("registering base path"); + LDEBUG("Registering base path"); if( ! openspace::OpenSpaceEngine::registerBasePathFromConfigurationFile(configurationFilePath)) { LFATAL("Could not register base path"); assert(false); @@ -78,9 +79,6 @@ int main(int argc, char** argv) { } } - /*openspace::Time::init(); - openspace::Spice::init(); - openspace::Spice::ref().loadDefaultKernels();*/ openspace::FactoryManager::initialize(); testing::InitGoogleTest(&argc, argv); From 56af1981711639473ee9fe689ef880b28eea6aa8 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 7 Sep 2014 16:25:27 +0200 Subject: [PATCH 073/113] Updated openspace-data pointer --- openspace-data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openspace-data b/openspace-data index 6548d06674..b54a762448 160000 --- a/openspace-data +++ b/openspace-data @@ -1 +1 @@ -Subproject commit 6548d06674595fea03588d82d84ba606f4d132f0 +Subproject commit b54a7624481c353afe13090718ab303592f3bb3c From fb24f06e5a206121e5b6b2cd96801b3766867b67 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 7 Sep 2014 16:59:51 +0200 Subject: [PATCH 074/113] Added doxygen files and fixed documentation errors --- doxygen/footer.html | 9 + doxygen/header.html | 50 + doxygen/stylesheet.css | 951 +++++++++++++++++++ ext/ghoul | 2 +- include/openspace/properties/propertyowner.h | 10 +- 5 files changed, 1016 insertions(+), 6 deletions(-) create mode 100644 doxygen/footer.html create mode 100644 doxygen/header.html create mode 100644 doxygen/stylesheet.css diff --git a/doxygen/footer.html b/doxygen/footer.html new file mode 100644 index 0000000000..c0bcf0c02b --- /dev/null +++ b/doxygen/footer.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/doxygen/header.html b/doxygen/header.html new file mode 100644 index 0000000000..0cd76f23cb --- /dev/null +++ b/doxygen/header.html @@ -0,0 +1,50 @@ + + + + + +$projectname: $title +$title + + +$treeview +$search +$mathjax + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
+
$projectname +  $projectnumber +
+
$projectbrief
+
+
$projectbrief
+
$searchbox
+
+ diff --git a/doxygen/stylesheet.css b/doxygen/stylesheet.css new file mode 100644 index 0000000000..dd13046594 --- /dev/null +++ b/doxygen/stylesheet.css @@ -0,0 +1,951 @@ +/* The standard CSS for doxygen */ + +body, table, div, p, dl { + font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; + font-size: 13px; + line-height: 1.3; +} + +/* @group Heading Levels */ + +h1 { + font-size: 150%; +} + +.title { + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2 { + font-size: 120%; +} + +h3 { + font-size: 100%; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd, p.starttd { + margin-top: 2px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBF3F6; + border: 1px solid #A3C6D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D728C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4683A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CC1D4; + color: #ffffff; + border: 1px double #86B3CA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +.fragment { + font-family: monospace, fixed; + font-size: 105%; +} + +pre.fragment { + border: 1px solid #C4DAE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 8px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBF3F6; + font-weight: bold; + border: 1px solid #C4DAE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBF3F6; + border: 1px solid #C4DAE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF4F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3C6D7; +} + +th.dirtab { + background: #EBF3F6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A8AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FBFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memItemLeft, .memItemRight, .memTemplParams { + border-top: 1px solid #C4DAE5; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4683A2; + white-space: nowrap; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4683A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBF3F6; + border: 1px solid #A3C6D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; +} + +.memname { + white-space: nowrap; + font-weight: bold; + margin-left: 6px; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8C9D9; + border-left: 1px solid #A8C9D9; + border-right: 1px solid #A8C9D9; + padding: 6px 0px 6px 0px; + color: #254555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 8px; + border-top-left-radius: 8px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 8px; + -moz-border-radius-topleft: 8px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 8px; + -webkit-border-top-left-radius: 8px; + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2EDF2; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8C9D9; + border-left: 1px solid #A8C9D9; + border-right: 1px solid #A8C9D9; + padding: 2px 5px; + background-color: #FBFCFD; + border-top-width: 0; + /* opera specific markup */ + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 8px; + -moz-border-radius-bottomright: 8px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7FAFB 95%, #EEF4F7); + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 8px; + -webkit-border-bottom-right-radius: 8px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7FAFB), to(#EEF4F7)); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} + +.params, .retval, .exception, .tparams { + border-spacing: 6px 2px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + + + + +/* @end */ + +/* @group Directory (tree) */ + +/* for the tree view */ + +.ftvtree { + font-family: sans-serif; + margin: 0px; +} + +/* these are for tree view when used as main index */ + +.directory { + font-size: 9pt; + font-weight: bold; + margin: 5px; +} + +.directory h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +/* +The following two styles can be used to replace the root node title +with an image of your choice. Simply uncomment the next two styles, +specify the name of your image and be sure to set 'height' to the +proper pixel height of your image. +*/ + +/* +.directory h3.swap { + height: 61px; + background-repeat: no-repeat; + background-image: url("yourimage.gif"); +} +.directory h3.swap span { + display: none; +} +*/ + +.directory > h3 { + margin-top: 0; +} + +.directory p { + margin: 0px; + white-space: nowrap; +} + +.directory div { + display: none; + margin: 0px; +} + +.directory img { + vertical-align: -30%; +} + +/* these are for tree view when not used as main index */ + +.directory-alt { + font-size: 100%; + font-weight: bold; +} + +.directory-alt h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +.directory-alt > h3 { + margin-top: 0; +} + +.directory-alt p { + margin: 0px; + white-space: nowrap; +} + +.directory-alt div { + display: none; + margin: 0px; +} + +.directory-alt img { + vertical-align: -30%; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; +} + +address { + font-style: normal; + color: #2A4F61; +} + +table.doxtable { + border-collapse:collapse; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D5468; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #37677F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; +} + +table.fieldtable { + width: 100%; + margin-bottom: 10px; + border: 1px solid #A8C9D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8C9D9; + border-bottom: 1px solid #A8C9D9; + vertical-align: top; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8C9D9; + width: 100%; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2EDF2; + font-size: 90%; + color: #254555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8C9D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + height:30px; + line-height:30px; + color:#8AB6CC; + border:solid 1px #C2D9E4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#36657C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; +} + +.navpath li.navelem a:hover +{ + color:#68A1BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#36657C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + margin-left: 5px; + font-size: 8pt; + padding-left: 5px; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FBFC; + margin: 0px; + border-bottom: 1px solid #C4DAE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 7px; +} + +dl +{ + padding: 0 0 0 10px; +} + +dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug +{ + border-left:4px solid; + padding: 0 0 0 6px; +} + +dl.note +{ + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + border-color: #00D000; +} + +dl.deprecated +{ + border-color: #505050; +} + +dl.todo +{ + border-color: #00C0E0; +} + +dl.test +{ + border-color: #3030E0; +} + +dl.bug +{ + border-color: #C08050; +} + +#projectlogo +{ + text-align: center; + vertical-align: center; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5394B4; + background-color: #006599; + +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90BACE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#335F75; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } + pre.fragment + { + overflow: visible; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + } +} + diff --git a/ext/ghoul b/ext/ghoul index d44211f170..0b84c2e320 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit d44211f170f2929738eec687ded811a1581014e7 +Subproject commit 0b84c2e320e58a187ed7b45dd5e19d49a6abab23 diff --git a/include/openspace/properties/propertyowner.h b/include/openspace/properties/propertyowner.h index 98be6bd064..7e29af385b 100644 --- a/include/openspace/properties/propertyowner.h +++ b/include/openspace/properties/propertyowner.h @@ -97,7 +97,7 @@ public: Property* property(const std::string& URI) const; /** - * This method checks if a Propetry with the provided URI exists in this + * This method checks if a Property with the provided URI exists in this * PropertyOwner (or any sub-owner). If the identifier contains one or more * ., the first part of the name will be recursively extracted and is * used as a name for a sub-owner and only the last part of the identifier is @@ -109,7 +109,7 @@ public: /** * Returns a list of all sub-owners this PropertyOwner has. Each name of a sub-owner - * has to be unique with respect to other sub-owners as well as Propertys owned by + * has to be unique with respect to other sub-owners as well as Property's owned by * this PropertyOwner. * \return A list of all sub-owners this PropertyOwner has */ @@ -128,15 +128,15 @@ public: /** * Returns true if this PropertyOwner owns a sub-owner with the provided - * name>/code>; returns false otherwise. + * name; returns false otherwise. * \param name The name of the sub-owner that should be looked up * \return true if this PropertyOwner owns a sub-owner with the provided - * name>/code>; returns false otherwise + * name; returns false otherwise */ bool hasSubOwner(const std::string& name) const; /** - * This method converts a provided groupIDgroupID, used by the Propertys, into a * human-readable name which can be used by some external application. * \param groupID The group identifier whose human-readable name should be set * \param name The human-readable name for the group identifier From e16373cfcfe4bc1d119ddc6ef448f821cd9e02b7 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 7 Sep 2014 17:10:33 +0200 Subject: [PATCH 075/113] Fixed a bug that causes the application to crash if no listener is installed for a Property --- src/properties/property.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/properties/property.cpp b/src/properties/property.cpp index f00890f9bd..b225be2861 100644 --- a/src/properties/property.cpp +++ b/src/properties/property.cpp @@ -127,7 +127,8 @@ void Property::setPropertyOwner(PropertyOwner* owner) } void Property::notifyListener() { - _onChangeCallback(); + if (_onChangeCallback) + _onChangeCallback(); } } // namespace properties From 816a3a846f21095d18018018f1cb12fd97a2f2f5 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 7 Sep 2014 17:10:45 +0200 Subject: [PATCH 076/113] Removed a float vs double warning --- src/rendering/renderengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 86691afd84..c56e5c84bd 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -55,7 +55,7 @@ bool RenderEngine::initialize() // init camera and set temporary position and scaling _mainCamera = new Camera(); _mainCamera->setScaling(glm::vec2(1.0, -8.0)); - _mainCamera->setPosition(psc(0.0, 0.0, 1.499823, 11.0)); + _mainCamera->setPosition(psc(0.f, 0.f, 1.499823f, 11.f)); // if master, setup interaction //if (sgct::Engine::instance()->isMaster()) From 351c2353128138c041714aeaaa13b02f35add5a1 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 7 Sep 2014 17:11:12 +0200 Subject: [PATCH 077/113] Added documentation to TemplateProperty Fixed bug where listeners were not notified --- .../openspace/properties/templateproperty.h | 107 +++++++++++++++++- .../openspace/properties/templateproperty.inl | 15 ++- 2 files changed, 117 insertions(+), 5 deletions(-) diff --git a/include/openspace/properties/templateproperty.h b/include/openspace/properties/templateproperty.h index 1906a4299f..494eb46e9e 100644 --- a/include/openspace/properties/templateproperty.h +++ b/include/openspace/properties/templateproperty.h @@ -30,29 +30,134 @@ namespace openspace { namespace properties { +/** + * This concrete subclass of Property handles a single parameter value that is of type + * T. It provides all the necessary methods to automatically access the + * value. One notable instantiation of this class is StringProperty, using + * T = std::string while NumericalProperty is a templated subclass dealing + * with numerical parameter types. + * The accessor operator and assignment operators are overloaded, so that the + * TemplateProperty can be used just in the same way as a regular member variable. In the + * case that these cannot not be used inline, the Property::get method will work. + * The default value for the stored value of this TemplateProperty is retrieved via a call + * to the PropertyDelegate::defaultValue method, providing the template parameter + * T as argument. When a new TemplateProperty is required, that method needs + * to be specialized for the new type or a compile-time error will occur + * (See http://openspace.itn.liu.se/trac/wiki/guides/properties). + * \tparam T The type of value that is stored in this TemplateProperty + * \see Property + * \see NumericalProperty + * \see PropertyDelegate + */ template class TemplateProperty : public Property { public: + /** + * The constructor initializing the TemplateProperty with the provided + * identifier and human-readable guiName. The default value + * for the stored type T is retrieved using the PropertyDelegate's + * PropertyDelegate::defaultValue method, which must be specialized for new types or + * a compile-error will occur. + * \param identifier The identifier that is used for this TemplateProperty + * \param guiName The human-readable GUI name for this TemplateProperty + */ TemplateProperty(std::string identifier, std::string guiName); + + /** + * The constructor initializing the TemplateProperty with the provided + * identifier, human-readable guiName and provided + * value. + */ TemplateProperty(std::string identifier, std::string guiName, T value); + /** + * Returns the class name for this TemplateProperty. The default implementation makes + * a call to the PropertyDelegate::className method with the template parameter + * T as argument. For this to work, that method needs to be specialized + * to return the correct class name for the new template parameter T, or a + * compile-time error will occur. + * \return The class name for the TemplateProperty + */ virtual std::string className() const override; + + /** + * Returns the stored value packed into a boost::any object. + * \return The stored value packed into a boost::any object + */ virtual boost::any get() const override; + + /** + * Sets the value fro the provided boost::any object. If the types + * between T and value disagree, an error is logged and the + * stored value remains unchanged. + */ virtual void set(boost::any value) override; + + /** + * Returns the std::type_info describing the template parameter + * T. It can be used to test against a boost::any value + * before trying to assign it. + * \return The type info object describing the template parameter T + */ virtual const std::type_info& type() const override; + /** + * This method encodes the stored value into a Lua object and pushes that object onto + * the stack. The encoding is performed by calling PropertyDelegate::toLuaValue with + * the template parameter T as an argument. This method has to be + * specialized for each new type, or a compile-time error will occur. + * \param state The Lua state onto which the encoded object will be pushed + * \return true if the encoding succeeded; false otherwise + */ bool getLua(lua_State* state) const override; + + /** + * Sets the value of this TemplateProprty by decoding the object at the top of the Lua + * stack and, if successful, assigning it using the Property::set method. The decoding + * is performed by calling the PropertyDelegate::fromLuaValue with the template + * parameter T as argument. If the decoding is successful, the new value + * is set, otherwise it remains unchanged. + * \param state The Lua state from which the value will be decoded + * \return true if the decoding succeeded; false otherwise + */ bool setLua(lua_State* state) override; + + /// \see Property::typeLua int typeLua() const override; - + /** + * This operator allows the TemplateProperty to be used almost transparently as if it + * was of the type T. It makes assignments such as + * T v = property; possible by allowing implicit casts (even though, + * internally, not casts are performed. This method is next to zero overhead). + */ operator T(); + + /** + * The assignment operator allows the TemplateProperty's value to be set without using + * the TemplateProperty::set method. It will be done internally by thos method and it + * allows assigments such as prop = T(1). + * \param val The value that should be set. + */ TemplateProperty& operator=(T val); + /** + * These method sets the stored value to the provided value val, + * moving it into place. This move only happens if the provided value val + * is different from the stored value, which needs an operator== to exist for the type + * T. If the value are different, the listeners are notified. + * \param val The new value for this TemplateProperty + */ void setValue(T val); + + /** + * Returns the currently stored value. + * \return The currently stored value + */ T value() const; protected: + /// The value that this TemplateProperty currently stores T _value; }; diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index ae81fd4836..68b7104fcf 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -92,7 +92,7 @@ template TemplateProperty::TemplateProperty(std::string identifier, std::string guiName, T value) : Property(std::move(identifier), std::move(guiName)) - , _value(value) { + , _value(std::move(value)) { } template @@ -120,7 +120,11 @@ T openspace::properties::TemplateProperty::value() const template void openspace::properties::TemplateProperty::setValue(T val) { - _value = val; + const bool changed = (val != _value); + if (changed) { + _value = std::move(val); + notifyListener(); + } } @@ -132,8 +136,11 @@ boost::any TemplateProperty::get() const { template void TemplateProperty::set(boost::any value) { try { - _value = boost::any_cast(std::move(value)); - notifyListener(); + T value = boost::any_cast(std::move(value)); + if (value != _value) { + _value = std::move(value); + notifyListener(); + } } catch (boost::bad_any_cast&) { LERRORC("TemplateProperty", "Illegal cast from '" << value.type().name() From e5b61492e9ab3a448ab8af2479eab0887041d13a Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 7 Sep 2014 17:20:04 +0200 Subject: [PATCH 078/113] Fixed documentation in the inlined code of TemplateProperty as well --- .../openspace/properties/templateproperty.inl | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index 68b7104fcf..c957c30e81 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -25,6 +25,16 @@ namespace openspace { namespace properties { +// The following macros can be used to quickly generate the necessary PropertyDelegate +// specializations required by the TemplateProperty class. Use the +// REGISTER_TEMPLATEPROPERTY_HEADER macro in the header file and the +// REGISTER_TEMPLATEPROPERTY_SOURCE macro in the source file of your new specialization of +// a TemplateProperty + + +// CLASS_NAME = The string that the Property::className() should return as well as the +// C++ class name for which a typedef will be created +// TYPE = The template parameter T for which the TemplateProperty is specialized #define REGISTER_TEMPLATEPROPERTY_HEADER(CLASS_NAME, TYPE) \ typedef TemplateProperty CLASS_NAME; \ template <> \ @@ -43,6 +53,21 @@ namespace properties { template <> \ int PropertyDelegate>::typeLua(); +// CLASS_NAME = The string that the Property::className() should return as well as the +// C++ class name for which a typedef will be created +// TYPE = The template parameter T for which the TemplateProperty is specialized +// DEFAULT_VALUE = The value (as type T) which should be used as a default value +// FROM_LUA_LAMBDA_EXPRESSION = A lambda expression receiving a lua_State* as the first +// parameter, a bool& as the second parameter and returning +// a value T. It is used by the fromLua method of +// TemplateProperty. The lambda expression must extract the +// stored value from the lua_State, return the value and +// report success in the second argument +// TO_LUA_LAMBDA_EXPRESSION = A lambda expression receiving a lua_State*, a value T and +// returning a bool. The lambda expression must encode the +// value T onto the lua_State stack and return the success +// LUA_TYPE = The Lua type that will be produced/consumed by the previous +// Lambda expressions #define REGISTER_TEMPLATEPROPERTY_SOURCE(CLASS_NAME, TYPE, DEFAULT_VALUE, \ FROM_LUA_LAMBDA_EXPRESSION, \ TO_LUA_LAMBDA_EXPRESSION, LUA_TYPE) \ @@ -50,8 +75,7 @@ namespace properties { std::string PropertyDelegate>::className() \ { \ return #CLASS_NAME; \ - \ -} \ + } \ template <> \ template <> \ TYPE PropertyDelegate>::defaultValue() \ @@ -84,8 +108,10 @@ namespace properties { template TemplateProperty::TemplateProperty(std::string identifier, std::string guiName) - : TemplateProperty(std::move(identifier), std::move(guiName), - PropertyDelegate>::template defaultValue()) { + : TemplateProperty( + std::move(identifier), std::move(guiName), + PropertyDelegate>::template defaultValue()) +{ } template From cdfde82522278b0e79e4fdfdd3a9a02b2ced5ad2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 7 Sep 2014 17:45:53 +0200 Subject: [PATCH 079/113] Added documentation for the PropertyDelegate class --- .../openspace/properties/propertydelegate.h | 83 +++++++++++++++++++ .../openspace/properties/propertydelegate.inl | 11 +-- 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/include/openspace/properties/propertydelegate.h b/include/openspace/properties/propertydelegate.h index a97ae67cf0..2b6dd07651 100644 --- a/include/openspace/properties/propertydelegate.h +++ b/include/openspace/properties/propertydelegate.h @@ -32,26 +32,109 @@ struct lua_State; namespace openspace { namespace properties { +/** + * The PropertyDelegate class is used by (among others) the TemplateProperty and the + * NumericalProperty classes to outsource the definitions of class names, default values, + * etc. Using the PropertyDelegate, it is possible to create new TemplateProperty types + * without subclassing the TemplateProperty, but rather creating a specialized instance + * of PropertyDelegate. See (http://openspace.itn.liu.se/trac/wiki/guides/properties) for + * more detailed information. + * \see TemplateProperty + * \see NumericalProperty + * \tparam T The full class for which this specialized instance of PropertyDelegate is + * responsible. For example T = TemplateProperty. + */ template class PropertyDelegate { public: + /** + * This method returns the class name for the class T. The default + * implementation will lead to a compile-time error if the class method is not + * specialized. + * \return The class name for the class T + */ static std::string className(); + /** + * This method will return the preferred default value for the class T. + * The default implementation will lead to a compile-time error if the class method is + * not specialized. + * \return The default value that the class T should use + * \tparam U The type by which the class T is specialized. If + * T = TemplateProperty, then U = std::string + */ template static U defaultValue(); + /** + * This method will return the preferred default minimum value for the class + * T. The default implementation will lead to a compile-time error if the + * class method is not specialized. This method is not used in TemplateProperty, but + * only NumericalProperty, so the TemplateProperty does not require this method to be + * specialized. + * \return The default minimum value that the class T should use + * \tparam U The type by which the class T is specialized. If + * T = NumericalProperty, then U = int + */ template static U defaultMinimumValue(); + /** + * This method will return the preferred default maximum value for the class + * T. The default implementation will lead to a compile-time error if the + * class method is not specialized. This method is not used in TemplateProperty, but + * only NumericalProperty, so the TemplateProperty does not require this method to be + * specialized. + * \return The default maximum value that the class T should use + * \tparam U The type by which the class T is specialized. If + * T = NumericalProperty, then U = int + */ template static U defaultMaximumValue(); + /** + * This method converts the top value from the Lua stack into a value of type + * U and reports the success back to the caller. The default + * implementation will lead to a compile-time error if the class method is not + * specialized. + * \param state The Lua state from which the value is retrieved + * \param success Will be true if the conversion succeeded; + * false otherwise + * \return The value that was created by converting the top value from the stack + * \tparam U The type by which the class T is specialized. If + * T = TemplateProperty, then U = std::string + */ template static U fromLuaValue(lua_State* state, bool& success); + /** + * This method converts the passed value, encodes it and places it on the + * top value of the Lua stack and returns the success back to the caller. The default + * implementation will lead to a compile-time error if the class method is not + * specialized. + * \param state The Lua state from which the value is retrieved + * \param value The value that will be converted into a Lua object + * \return true if the conversion succeeded; false otherwise + * \tparam U The type by which the class T is specialized. If + * T = TemplateProperty, then U = std::string + */ template static bool toLuaValue(lua_State* state, U value); + /** + * Returns the Lua type that will be put onto the stack in the + * PropertyDelegate::toLuaValue method and which will be consumed by the + * PropertyDelegate::fromLuaValue method. The returned value can belong to the set of + * Lua types: LUA_TNONE, LUA_TNIL, + * LUA_TBOOLEAN, LUA_TLIGHTUSERDATA, + * LUA_TNUMBER, LUA_TSTRING, LUA_TTABLE, + * LUA_TFUNCTION, LUA_TUSERDATA, or + * LUA_TTHREAD. The default implementation will return + * LUA_TNONE. The default implementation will lead to a compile-time + * error if the class method is not specialized. + * \return The Lua type that will be consumed or produced by the + * PropertyDelegate::toLuaValue and PropertyDelegate::fromLuaValue methods. + */ static int typeLua(); }; diff --git a/include/openspace/properties/propertydelegate.inl b/include/openspace/properties/propertydelegate.inl index 7f0f57e344..584f2a3098 100644 --- a/include/openspace/properties/propertydelegate.inl +++ b/include/openspace/properties/propertydelegate.inl @@ -24,22 +24,20 @@ #include -#include - -#include - namespace openspace { namespace properties { template std::string PropertyDelegate::className() { - static_assert(sizeof(T) == 0, "Unimplemented PropertyDelegate::className specialization"); + static_assert(sizeof(T) == 0, + "Unimplemented PropertyDelegate::className specialization"); } template template U PropertyDelegate::defaultValue() { - static_assert(sizeof(T) == 0, "Unimplemented PropertyDelegate::defaultValue specialization"); + static_assert(sizeof(T) == 0, + "Unimplemented PropertyDelegate::defaultValue specialization"); } template @@ -49,7 +47,6 @@ U PropertyDelegate::defaultMinimumValue() { "Unimplemented PropertyDelegate::defaultMinimumValue specialization"); } - template template U PropertyDelegate::defaultMaximumValue() { From d659c11365e74d84466a0d267a8e3cfce210b429 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 12 Sep 2014 16:59:29 +0200 Subject: [PATCH 080/113] Make StringProperty a specialization rather than a subclass of TemplateProperty --- include/openspace/properties/stringproperty.h | 30 +-------- src/properties/stringproperty.cpp | 62 +++++-------------- 2 files changed, 15 insertions(+), 77 deletions(-) diff --git a/include/openspace/properties/stringproperty.h b/include/openspace/properties/stringproperty.h index 7fa08b1753..98b9020664 100644 --- a/include/openspace/properties/stringproperty.h +++ b/include/openspace/properties/stringproperty.h @@ -30,35 +30,7 @@ namespace openspace { namespace properties { -class StringProperty : public TemplateProperty { -public: - StringProperty(std::string identifier, std::string guiName); - StringProperty(std::string identifier, std::string guiName, std::string value); - - using TemplateProperty::operator=; -}; - -template <> -std::string PropertyDelegate>::className(); - -template <> -template <> -std::string PropertyDelegate>::defaultValue(); - -template <> -template <> -std::string PropertyDelegate>::fromLuaValue( - lua_State* state, bool& success); - -template <> -template <> -bool PropertyDelegate>::toLuaValue( - lua_State* state, std::string value); - -template <> -int PropertyDelegate>::typeLua(); - - +REGISTER_TEMPLATEPROPERTY_HEADER(StringProperty, std::string); } // namespace properties } // namespace openspace diff --git a/src/properties/stringproperty.cpp b/src/properties/stringproperty.cpp index 1389f2c200..2b5d51d5b6 100644 --- a/src/properties/stringproperty.cpp +++ b/src/properties/stringproperty.cpp @@ -29,54 +29,20 @@ namespace openspace { namespace properties { -StringProperty::StringProperty(std::string identifier, std::string guiName) - : StringProperty( - std::move(identifier), std::move(guiName), - PropertyDelegate>::defaultValue()) -{ -} - -StringProperty::StringProperty(std::string identifier, std::string guiName, - std::string value) - : TemplateProperty(std::move(identifier), std::move(guiName), std::move(value)) -{} - -template <> -std::string PropertyDelegate>::className() { - return "StringProperty"; -} - -template <> -template <> -std::string PropertyDelegate>::defaultValue() { - return ""; -} - -template <> -template <> -std::string PropertyDelegate>::fromLuaValue( - lua_State* state, bool& success) -{ - success = lua_isstring(state, -1) == 1; - if (success) - return lua_tostring(state, -1); - else - return ""; -} - -template <> -template <> -bool PropertyDelegate>::toLuaValue( - lua_State* state, std::string value) -{ - lua_pushstring(state, value.c_str()); - return true; -} - -template <> -int PropertyDelegate>::typeLua() { - return LUA_TSTRING; -} +REGISTER_TEMPLATEPROPERTY_SOURCE(StringProperty, std::string, "", +[](lua_State* state, bool& success) -> std::string { + success = lua_isstring(state, -1) == 1; + if (success) + return lua_tostring(state, -1); + else + return ""; + }, +[](lua_State* state, std::string value) -> bool { + lua_pushstring(state, value.c_str()); + return true; + }, +LUA_TSTRING +); } // namespace properties } // namespace openspace From e13eafdbdef3691c229fc2d80add5855f27f6f9c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 13 Sep 2014 10:33:16 +0200 Subject: [PATCH 081/113] Added more comments to main.cpp --- src/main.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d2e0bd86f1..9a69b4328b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,7 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ - // open space includes #include #include @@ -47,6 +46,10 @@ void mainEncodeFun(); void mainDecodeFun(); void mainExternalControlCallback(const char * receivedChars, int size, int clientId); +namespace { + const std::string _loggerCat = "main"; +} + int main(int argc, char** argv) { // create the OpenSpace engine and get arguments for the sgct engine @@ -57,19 +60,16 @@ int main(int argc, char** argv) // create sgct engine c arguments int newArgc = static_cast(sgctArguments.size()); - char** newArgv = new char* [newArgc]; - for (int i = 0; i < newArgc; ++i) { - // newArgv[i] = new char[sgctArguments.at(i).length()]; - // std::strcpy(newArgv[i], sgctArguments.at(i).c_str()); + char** newArgv = new char*[newArgc]; + for (int i = 0; i < newArgc; ++i) newArgv[i] = const_cast(sgctArguments.at(i).c_str()); - } + LDEBUG("Creating SGCT Engine"); _sgctEngine = new sgct::Engine(newArgc, newArgv); // deallocate sgct c arguments - for (int i = 0; i < newArgc; ++i) { - // delete newArgv[i]; - } + for (int i = 0; i < newArgc; ++i) + delete newArgv[i]; delete[] newArgv; // Bind functions @@ -90,10 +90,14 @@ int main(int argc, char** argv) sgct::SharedData::instance()->setDecodeFunction(mainDecodeFun); // init the interface which will handle callbacks from an external gui + LDEBUG("Creating Interface module"); _interface = new openspace::Interface(&OsEng); // try to open a window - if (!_sgctEngine->init(sgct::Engine::OpenGL_4_0_Core_Profile)) { + LDEBUG("Initialize SGCT Engine"); + const bool initSuccess = _sgctEngine->init(sgct::Engine::OpenGL_4_0_Core_Profile); + if (!initSuccess) { + LFATAL("Initializing failed"); // could not open a window, deallocates and exits delete _sgctEngine; openspace::OpenSpaceEngine::destroy(); @@ -101,9 +105,14 @@ int main(int argc, char** argv) } // Main loop + LDEBUG("Starting rendering loop"); _sgctEngine->render(); + LDEBUG("Destroying OpenSpaceEngine"); + openspace::OpenSpaceEngine::destroy(); + // Clean up (de-allocate) + LDEBUG("Destroying SGCT Engine"); delete _sgctEngine; // Exit program From 4b8a17386f71d9839ca65e22fb2044a9427f4259 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 13 Sep 2014 10:52:04 +0200 Subject: [PATCH 082/113] Updated ghoul version --- ext/ghoul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ghoul b/ext/ghoul index 0b84c2e320..6de5adc0c5 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 0b84c2e320e58a187ed7b45dd5e19d49a6abab23 +Subproject commit 6de5adc0c56dcb1069ff08e353d2e20ab2befcf7 From ce10dea96e319b49f1fb2b04ac88badcaa69120b Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 13 Sep 2014 11:45:49 +0200 Subject: [PATCH 083/113] Fixed compile errors, probably finished merge --- include/openspace/engine/openspaceengine.h | 20 +++++++++-- shaders/ABuffer/abufferResolveFragment.glsl | 4 +++ src/engine/openspaceengine.cpp | 38 ++++++++++----------- src/scenegraph/scenegraph.cpp | 18 +++++----- src/scenegraph/scenegraphnode.cpp | 4 ++- src/util/shadercreator.cpp | 17 +++++---- 6 files changed, 62 insertions(+), 39 deletions(-) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index dae55381ab..c3c3c0022e 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -46,13 +46,22 @@ // #define OPENSPACE_VIDEO_EXPORT +namespace ghoul { + namespace cmdparser { + class CommandlineParser; + class CommandlineCommand; + } +} + namespace openspace { -class ScriptEngine; +namespace scripting { + class ScriptEngine; +} class OpenSpaceEngine { public: - static void create(int argc, char** argv, std::vector& sgctArguments); + static bool create(int argc, char** argv, std::vector& sgctArguments); static void destroy(); static OpenSpaceEngine& ref(); @@ -67,6 +76,7 @@ public: ghoul::opencl::CLContext& clContext(); InteractionHandler& interactionHandler(); RenderEngine& renderEngine(); + scripting::ScriptEngine& scriptEngine(); ShaderCreator& shaderBuilder(); // SGCT callbacks @@ -84,14 +94,18 @@ public: void decode(); private: - OpenSpaceEngine(); + OpenSpaceEngine(std::string programName); ~OpenSpaceEngine(); + bool gatherCommandlineArguments(); + static OpenSpaceEngine* _engine; ghoul::Dictionary* _configurationManager; InteractionHandler* _interactionHandler; RenderEngine* _renderEngine; + scripting::ScriptEngine* _scriptEngine; + ghoul::cmdparser::CommandlineParser* _commandlineParser; #ifdef OPENSPACE_VIDEO_EXPORT bool _doVideoExport; #endif diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index 6c3245cdff..c076cad685 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -137,6 +137,7 @@ void blendStep(inout vec4 dst, in vec4 src, in float stepSize) { } float volumeRaycastingDistance(in int id, in ABufferStruct_t startFrag, in ABufferStruct_t endFrag) { +#if MAX_VOLUMES > 0 #if ZTYPE == ZDEPTH const float S1 = volume_zlength[id].x; const float S2 = volume_zlength[id].y; @@ -155,6 +156,9 @@ float volumeRaycastingDistance(in int id, in ABufferStruct_t startFrag, in ABuff // const float z2 = _z_(endFrag); return (dist / L) * volume_length[id]; #endif +#else + return 0.f; +#endif } vec4 calculate_final_color(uint frag_count) { diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 3ef492befe..595ec959ca 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -155,29 +156,28 @@ bool OpenSpaceEngine::registerBasePathFromConfigurationFile(const std::string& f bool OpenSpaceEngine::findConfiguration(std::string& filename) { - return FileSys.fileExists(filename); - std::string currentDirectory = FileSys.absolutePath(FileSys.currentDirectory()); - size_t occurrences = std::count(currentDirectory.begin(), currentDirectory.end(), - ghoul::filesystem::FileSystem::PathSeparator); + //return FileSys.fileExists(filename); + std::string currentDirectory = FileSys.absolutePath(FileSys.currentDirectory()); + size_t occurrences = std::count(currentDirectory.begin(), currentDirectory.end(), + ghoul::filesystem::FileSystem::PathSeparator); - std::string cfgname = _configurationFile; + std::string cfgname = _configurationFile; - bool cfgFileFound = false; - for (size_t i = 0; i < occurrences; ++i) { - if (i > 0) - cfgname = "../" + cfgname; - if (FileSys.fileExists(cfgname)) { - cfgFileFound = true; - break; - } + bool cfgFileFound = false; + for (size_t i = 0; i < occurrences; ++i) { + if (i > 0) + cfgname = "../" + cfgname; + if (FileSys.fileExists(cfgname)) { + cfgFileFound = true; + break; } - if (!cfgFileFound) - return false; - - filename = cfgname; - - return true; } + if (!cfgFileFound) + return false; + + filename = cfgname; + + return true; } bool OpenSpaceEngine::create(int argc, char** argv, diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 9108e7bc28..b2ac485212 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -50,18 +50,18 @@ #include #include - #include + //#include namespace { const std::string _loggerCat = "SceneGraph"; const std::string _moduleExtension = ".mod"; -{ - LDEBUGC("Tree", pre << node->name()); - const std::vector& children = node->children(); - for (openspace::SceneGraphNode* child : children) - printTree(child, pre + " "); -} - +//{ +// LDEBUGC("Tree", pre << node->name()); +// const std::vector& children = node->children(); +// for (openspace::SceneGraphNode* child : children) +// printTree(child, pre + " "); +//} +// } namespace openspace { @@ -374,7 +374,7 @@ void SceneGraph::loadModule(const std::string& modulePath) } // Print the tree - printTree(_root); + //printTree(_root); } void SceneGraph::printChildren() const diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 0ce7b0f9e6..5e349c782c 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -42,6 +42,8 @@ #include +#include + namespace { const std::string _loggerCat = "SceneGraphNode"; } @@ -347,7 +349,7 @@ PowerScaledScalar SceneGraphNode::calculateBoundingSphere() } - LWARNING(_nodeName << ": " << _boundingSphere); + LWARNING(name() << ": " << _boundingSphere); return _boundingSphere; } diff --git a/src/util/shadercreator.cpp b/src/util/shadercreator.cpp index b4b1b0d930..a70c9032a4 100644 --- a/src/util/shadercreator.cpp +++ b/src/util/shadercreator.cpp @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include // #include @@ -143,15 +143,18 @@ std::string ShaderCreator::_loadSource(const std::string& filename, unsigned int return contents; } - boost::regex e1(R"(^\s*#include \"(.+)\"\s*)"); - boost::regex e2(R"(^\s*#include <(.+)>\s*)"); + std::regex e1(R"(^\s*#include \"(.+)\"\s*)"); + std::regex e2(R"(^\s*#include <(.+)>\s*)"); while(std::getline(f, line)) { - boost::smatch m; - if(boost::regex_search(line, m, e1)) { + std::smatch m; + if(std::regex_search(line, m, e1)) { + using namespace ghoul::filesystem; std::string includeFilename = m[1]; - includeFilename = filename.substr(0, filename.find_last_of("/")+1) + includeFilename; + File f(filename); + includeFilename = f.directoryName() + FileSystem::PathSeparator + includeFilename; + //includeFilename = filename.substr(0, filename.find_last_of("/")+1) + includeFilename; line = _loadSource(includeFilename, depth + 1); - } else if(boost::regex_search(line, m, e2)) { + } else if(std::regex_search(line, m, e2)) { std::string includeFilename = m[1]; line = _loadSource(absPath(includeFilename), depth + 1); } From 1101b656b82dd2274b02e2dd576b957b8a936c1f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 13 Sep 2014 12:10:55 +0200 Subject: [PATCH 084/113] Added missing change for the merge --- src/interaction/interactionhandler.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index ef241cc0bb..2d09ab1b3a 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -173,10 +173,7 @@ void InteractionHandler::distance(const PowerScaledScalar &distance) { lockControls(); psc relative = camera_->position(); - psc origin; - if(node_) { - origin = node_->worldPosition(); - } + const psc origin = (node_) ? node_->worldPosition() : psc(); psc relative_origin_coordinate = relative - origin; const glm::vec3 dir(relative_origin_coordinate.direction()); From b6246f653892d4814ddf8ee57b47b2db32c85b79 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 13 Sep 2014 18:02:39 +0200 Subject: [PATCH 085/113] Renamed methods in SpiceManager Started change of Time class --- include/openspace/tests/test_spicemanager.inl | 2 +- include/openspace/util/spicemanager.h | 14 ++- include/openspace/util/time.h | 64 +++++++--- src/engine/openspaceengine.cpp | 9 +- src/rendering/renderengine.cpp | 20 +++ src/util/spice.cpp | 6 +- src/util/spicemanager.cpp | 22 +++- src/util/time.cpp | 114 +++++++++++++----- 8 files changed, 194 insertions(+), 57 deletions(-) diff --git a/include/openspace/tests/test_spicemanager.inl b/include/openspace/tests/test_spicemanager.inl index e46e72d2a5..a1dbb8b9ed 100644 --- a/include/openspace/tests/test_spicemanager.inl +++ b/include/openspace/tests/test_spicemanager.inl @@ -226,7 +226,7 @@ TEST_F(SpiceManagerTest, stringToEphemerisTime){ char *date = "Thu Mar 20 12:53:29 PST 1997"; str2et_c(date, &control_ephemerisTime); - ephemerisTime = openspace::SpiceManager::ref().stringToEphemerisTime(date); + ephemerisTime = openspace::SpiceManager::ref().convertStringToTdbSeconds(date); EXPECT_EQ(ephemerisTime, control_ephemerisTime) << "Ephemeries times differ / not found"; unload_c(LSK.c_str()); diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 328021bb3c..695dcd9dd1 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -119,7 +119,19 @@ public: * \param epochString, A string representing an epoch. * \return Corresponding ephemeris time, equivalent value in seconds past J2000, TDB. */ - double stringToEphemerisTime(const std::string& epochString) const; + double convertStringToTdbSeconds(const std::string& epochString) const; + + /** + * Convert the number of TDB seconds past the J2000 epoch into a human readable + * string representation. Fur further details, please refer to 'timout_c' in SPICE + * Documentation + * + * \param seconds The number of seconds that have passed since the J2000 epoch + * \param format The output format of the string + * (see ftp://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html) + * \return The formatted date string + */ + std::string convertTdbSecondsToString(double seconds, const std::string& format) const; // Computing Positions of Spacecraft and Natural Bodies(SPK) ---------------------------- // diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 84303a136c..220f599ad1 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -1,31 +1,63 @@ -#ifndef ENGINETIME_H -#define ENGINETIME_H +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ -namespace openspace -{ +#ifndef __TIME_H__ +#define __TIME_H__ + +#include + +namespace openspace { class Time { public: - virtual ~Time(); - - static void init(); - static void deinit(); + static bool initialize(); + static void deinitialize(); static Time& ref(); static bool isInitialized(); + + double advanceTime(double tickTime); + + void setTime(double value); + double currentTime() const; + void setTimeUTC(std::string time); + std::string currentTimeUTC() const; - void setTime(const char* stringTime); - double getTime(); + void setDeltaTime(double deltaT); + double deltaTime() const; private: - static Time* this_; - Time(void); - Time(const Time& src); - Time& operator=(const Time& rhs); + Time(); + Time(const Time& src) = delete; + Time& operator=(const Time& rhs) = delete; - double time_; + static Time* _instance; + double _time; + + double _deltaTimePerSecond; }; } // namespace openspace -#endif \ No newline at end of file +#endif // __TIME_H__ diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 595ec959ca..7a0bf258ac 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -92,8 +93,9 @@ OpenSpaceEngine::~OpenSpaceEngine() delete _commandlineParser; _commandlineParser = nullptr; + SpiceManager::deinitialize(); Spice::deinit(); - Time::deinit(); + Time::deinitialize(); DeviceIdentifier::deinit(); FileSystem::deinitialize(); LogManager::deinitialize(); @@ -323,7 +325,8 @@ bool OpenSpaceEngine::initialize() SysCap.logCapabilities(); // initialize OpenSpace helpers - Time::init(); + SpiceManager::initialize(); + Time::initialize(); Spice::init(); Spice::ref().loadDefaultKernels(); FactoryManager::initialize(); @@ -463,6 +466,8 @@ void OpenSpaceEngine::preSynchronization() _interactionHandler->update(dt); _interactionHandler->lockControls(); + + Time::ref().advanceTime(dt); } #ifdef FLARE_ONLY _flare->preSync(); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 9c5524e0f0..85199e29f6 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "sgct.h" @@ -203,6 +204,24 @@ void RenderEngine::render() const psc origin = OsEng.interactionHandler().getOrigin(); const PowerScaledScalar pssl = (position - origin).length(); + const std::string time = Time::ref().currentTimeUTC().c_str(); + LINFO(time); + Freetype::print( + sgct_text::FontManager::instance()->getFont("SGCTFont", FONT_SIZE), + FONT_SIZE, FONT_SIZE * 18, "Date: %s", time.c_str() + ); + Freetype::print( + sgct_text::FontManager::instance()->getFont("SGCTFont", FONT_SIZE), + FONT_SIZE, FONT_SIZE * 16, "Avg. Frametime: %.10f", sgct::Engine::instance()->getAvgDt() + ); + Freetype::print( + sgct_text::FontManager::instance()->getFont("SGCTFont", FONT_SIZE), + FONT_SIZE, FONT_SIZE * 14, "Drawtime: %.10f", sgct::Engine::instance()->getDrawTime() + ); + Freetype::print( + sgct_text::FontManager::instance()->getFont("SGCTFont", FONT_SIZE), + FONT_SIZE, FONT_SIZE * 12, "Frametime: %.10f", sgct::Engine::instance()->getDt() + ); Freetype::print( sgct_text::FontManager::instance()->getFont("SGCTFont", FONT_SIZE), FONT_SIZE, FONT_SIZE * 10, "Origin: (%.5f, %.5f, %.5f, %.5f)", origin[0], @@ -222,6 +241,7 @@ void RenderEngine::render() Freetype::print( sgct_text::FontManager::instance()->getFont("SGCTFont", FONT_SIZE), FONT_SIZE, FONT_SIZE * 2, "Scaling: (%.10f, %.2f)", scaling[0], scaling[1]); + } #endif diff --git a/src/util/spice.cpp b/src/util/spice.cpp index 3be4c9a323..e7f8dc17fc 100644 --- a/src/util/spice.cpp +++ b/src/util/spice.cpp @@ -128,7 +128,7 @@ bool Spice::spk_getPosition(const std::string &target, const std::string &origin assert(this_); assert(Time::ref().isInitialized()); - SpiceDouble et = Time::ref().getTime(); + SpiceDouble et = Time::ref().currentTime(); SpiceDouble lt; spkpos_c(target.c_str(), et, "J2000", "LT+S", origin.c_str(), state, <); int failed = failed_c(); @@ -143,7 +143,7 @@ void Spice::spk_getPosition(int target, int origin, double state[3]) { assert(this_); assert(Time::ref().isInitialized()); - SpiceDouble et = Time::ref().getTime(); + SpiceDouble et = Time::ref().currentTime(); SpiceDouble lt; spkezp_c (target, et, "J2000", "NONE", origin, state, <); } @@ -156,7 +156,7 @@ bool Spice::spk_getOrientation(const std::string &target, double state[3][3]) { // ghoul logging std::string _loggerCat = "Spice::spk_getOrientation"; - SpiceDouble et = Time::ref().getTime(); + SpiceDouble et = Time::ref().currentTime(); std::string newname = "IAU_"; newname += target; pxform_c ( "J2000", newname.c_str(), et, state ); diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 9ab3bb44ed..a6a70c8801 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -207,12 +207,32 @@ bool SpiceManager::getValueFromID(const std::string& bodyname, return true; } -double SpiceManager::stringToEphemerisTime(const std::string& epochString) const{ +double SpiceManager::convertStringToTdbSeconds(const std::string& epochString) const{ double et; str2et_c(epochString.c_str(), &et); return et; } +std::string SpiceManager::convertTdbSecondsToString(double seconds, + const std::string& format) const +{ + const int bufferSize = 128; + SpiceChar buffer[bufferSize]; + timout_c(seconds, format.c_str(), bufferSize - 1, buffer); + + int failed = failed_c(); + if (failed) { + char msg[1024]; + getmsg_c("LONG", 1024, msg); + //LERROR("Error retrieving position of target '" + target + "'"); + LERROR("Spice reported: " + std::string(msg)); + reset_c(); + return ""; + } + + return std::string(buffer); +} + bool SpiceManager::getTargetPosition(const std::string& target, double ephemerisTime, const std::string& referenceFrame, diff --git a/src/util/time.cpp b/src/util/time.cpp index d515affa5a..e4a6e9af4c 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -1,62 +1,110 @@ +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ -// open space includes #include -#include -// std includes +#include +#include + +#include + #include -// spice includes -#include "SpiceUsr.h" -#include +namespace { + const std::string _loggerCat = "Time"; +} namespace openspace { -Time* Time::this_ = nullptr; - -Time::Time() { - time_ = 0.0; +Time* Time::_instance = nullptr; +Time::Time() + : _time(-1.0) + , _deltaTimePerSecond(1.0) +{ + SpiceManager::ref().loadKernel(absPath("${OPENSPACE_DATA}/spice/naif0010.tls"), "leap"); // load spice time kernel - furnsh_c (absPath("${OPENSPACE_DATA}/spice/naif0010.tls").c_str()); + //furnsh_c (absPath("${OPENSPACE_DATA}/spice/naif0010.tls").c_str()); // convert UTC to ET - str2et_c ( "2006 JAN 31 01:00", &time_ ); + //str2et_c ( "2006 JAN 31 01:00", &_time ); } -Time::~Time() { - +bool Time::initialize() { + assert( _instance == nullptr); + _instance = new Time(); + return true; } -void Time::init() { - assert( this_ == nullptr); - this_ = new Time(); -} - -void Time::deinit() { - assert(this_); - delete this_; - this_ = nullptr; +void Time::deinitialize() { + assert(_instance); + delete _instance; + _instance = nullptr; } Time& Time::ref() { - assert(this_); - return *this_; + assert(_instance); + return *_instance; } bool Time::isInitialized() { - return this_ != nullptr; + return _instance != nullptr; } -void Time::setTime(const char* stringTime) { - assert(this_); - // convert UTC to ET - str2et_c ( stringTime, &time_ ); +//void Time::setTime(const char* stringTime) { +// assert(_instance); +// // convert UTC to ET +// //str2et_c ( stringTime, &_time ); +//} + +void Time::setTime(double value) { + _time = std::move(value); } -double Time::getTime() { - assert(this_); - return time_; +double Time::currentTime() const { + assert(_instance); + return _time; +} + +double Time::advanceTime(double tickTime) { + return _time += _deltaTimePerSecond * tickTime; +} + +void Time::setDeltaTime(double deltaT) { + _deltaTimePerSecond = std::move(deltaT); +} + +double Time::deltaTime() const { + return _deltaTimePerSecond; +} + +void Time::setTimeUTC(std::string time) { + _time = SpiceManager::ref().convertStringToTdbSeconds(std::move(time)); +} + +std::string Time::currentTimeUTC() const { + return SpiceManager::ref().convertTdbSecondsToString(_time, "MON DD,YYYY HR:MN:SC.#### (TDB) ::TDB"); } } // namespace openspace From 3afa0ecaa17977ce9ccb7ad10cfce29405f7f328 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 13 Sep 2014 18:25:14 +0200 Subject: [PATCH 086/113] Added support for scripting --- include/openspace/util/time.h | 4 ++++ scripts/default_startup.lua | 4 +++- src/engine/openspaceengine.cpp | 23 +++++++++++-------- src/util/time.cpp | 40 ++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 220f599ad1..1ab38ce6bf 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -25,6 +25,8 @@ #ifndef __TIME_H__ #define __TIME_H__ +#include + #include namespace openspace { @@ -46,6 +48,8 @@ public: void setDeltaTime(double deltaT); double deltaTime() const; + static scripting::ScriptEngine::LuaLibrary luaLibrary(); + private: Time(); Time(const Time& src) = delete; diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index 9acbddfa87..92698abacc 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -1 +1,3 @@ ---openspace.setPropertyValue('Earth.renderable.colorTexture', '${OPENSPACE_DATA}/modules/mars/textures/mars.png') \ No newline at end of file +--openspace.setPropertyValue('Earth.renderable.colorTexture', '${OPENSPACE_DATA}/modules/mars/textures/mars.png') +openspace.setTime(1000000) +openspace.setDeltaTime(100) \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 7a0bf258ac..aa019039a8 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -110,8 +110,10 @@ OpenSpaceEngine& OpenSpaceEngine::ref() bool OpenSpaceEngine::gatherCommandlineArguments() { // TODO: Get commandline arguments from all modules - - CommandlineCommand* configurationFileCommand = new SingleCommand(&commandlineArgumentPlaceholders.configurationName, "-config", "-c", "Provides the path to the OpenSpace configuration file"); + + CommandlineCommand* configurationFileCommand = new SingleCommand( + &commandlineArgumentPlaceholders.configurationName, "-config", "-c", + "Provides the path to the OpenSpace configuration file"); _commandlineParser->addCommand(configurationFileCommand); return true; @@ -313,9 +315,6 @@ bool OpenSpaceEngine::initialize() // registerFilePaths(); _context.createContextFromGLContext(); - // initialize the configurationmanager with the default configuration - //_configurationManager->loadConfiguration(absPath("${SCRIPTS}/DefaultConfig.lua")); - // Detect and log OpenCL and OpenGL versions and available devices ghoul::systemcapabilities::SystemCapabilities::initialize(); SysCap.addComponent(new ghoul::systemcapabilities::CPUCapabilitiesComponent); @@ -324,6 +323,7 @@ bool OpenSpaceEngine::initialize() SysCap.detectCapabilities(); SysCap.logCapabilities(); + // initialize OpenSpace helpers SpiceManager::initialize(); Time::initialize(); @@ -331,11 +331,16 @@ bool OpenSpaceEngine::initialize() Spice::ref().loadDefaultKernels(); FactoryManager::initialize(); + scriptEngine().initialize(); -// scriptEngine().addLibrary(ScriptEngine::LuaLibrary()); - -// _engine->scriptEngine().runScript("return mylib.mysin(4)"); - + + // Register Lua script functions + scriptEngine().addLibrary(Time::luaLibrary()); + + //scripting::ScriptEngine::LuaLibrary timeLibrary = { + // "time", + //} + // Load scenegraph SceneGraph* sceneGraph = new SceneGraph; diff --git a/src/util/time.cpp b/src/util/time.cpp index e4a6e9af4c..01bc1c0837 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -33,6 +33,33 @@ namespace { const std::string _loggerCat = "Time"; + + int time_setDeltaTime(lua_State* L) { + const std::string _loggerCat = "time_setDeltaTime"; + double value = luaL_checknumber(L, -1); + openspace::Time::ref().setDeltaTime(value); + return 0; + } + + int time_deltaTime(lua_State* L) { + const std::string _loggerCat = "time_deltaTime"; + lua_pushnumber(L, openspace::Time::ref().deltaTime()); + return 1; + } + + int time_setTime(lua_State* L) { + const std::string _loggerCat = "time_setTime"; + double value = luaL_checknumber(L, -1); + openspace::Time::ref().setTime(value); + return 0; + } + + int time_currentTime(lua_State* L) { + const std::string _loggerCat = "time_time"; + lua_pushnumber(L, openspace::Time::ref().currentTime()); + return 1; + } + } namespace openspace { @@ -107,4 +134,17 @@ std::string Time::currentTimeUTC() const { return SpiceManager::ref().convertTdbSecondsToString(_time, "MON DD,YYYY HR:MN:SC.#### (TDB) ::TDB"); } +scripting::ScriptEngine::LuaLibrary Time::luaLibrary() { + scripting::ScriptEngine::LuaLibrary timeLibrary = { + "", + { + {"setDeltaTime", &time_setDeltaTime}, + {"deltaTime", &time_deltaTime}, + {"setTime", &time_setTime}, + {"currentTime", &time_currentTime} + } + }; + return std::move(timeLibrary); +} + } // namespace openspace From 0eeeb8efd6a12c1bef8331d375094f768a4f0ea2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 13 Sep 2014 19:25:33 +0200 Subject: [PATCH 087/113] More work on fixing script access to time --- ext/ghoul | 2 +- scripts/default_startup.lua | 4 ++-- src/engine/openspaceengine.cpp | 5 ----- src/rendering/renderengine.cpp | 1 - src/scripting/scriptengine.cpp | 39 ++++++++++++++++++++++++++++------ src/util/time.cpp | 2 +- 6 files changed, 36 insertions(+), 17 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 6de5adc0c5..7906906863 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 6de5adc0c56dcb1069ff08e353d2e20ab2befcf7 +Subproject commit 79069068634b5a582d7fed49eb857dcc490471d3 diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index 92698abacc..e064f06acd 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -1,3 +1,3 @@ --openspace.setPropertyValue('Earth.renderable.colorTexture', '${OPENSPACE_DATA}/modules/mars/textures/mars.png') -openspace.setTime(1000000) -openspace.setDeltaTime(100) \ No newline at end of file +openspace.time.setTime(1000000) +openspace.time.setDeltaTime(100) \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index aa019039a8..01ec011aa2 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -337,11 +337,6 @@ bool OpenSpaceEngine::initialize() // Register Lua script functions scriptEngine().addLibrary(Time::luaLibrary()); - //scripting::ScriptEngine::LuaLibrary timeLibrary = { - // "time", - //} - - // Load scenegraph SceneGraph* sceneGraph = new SceneGraph; _renderEngine->setSceneGraph(sceneGraph); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 85199e29f6..d86928517d 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -205,7 +205,6 @@ void RenderEngine::render() const PowerScaledScalar pssl = (position - origin).length(); const std::string time = Time::ref().currentTimeUTC().c_str(); - LINFO(time); Freetype::print( sgct_text::FontManager::instance()->getFont("SGCTFont", FONT_SIZE), FONT_SIZE, FONT_SIZE * 18, "Date: %s", time.c_str() diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 6d90fdb3da..1799dd55e7 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -30,6 +30,7 @@ #include #include +#include #include namespace openspace { @@ -88,22 +89,34 @@ bool ScriptEngine::addLibrary(const ScriptEngine::LuaLibrary& library) { return false; } + //ghoul::lua::logStack(_state); lua_getglobal(_state, _openspaceLibraryName.c_str()); + //ghoul::lua::logStack(_state); if (library.name.empty()) { + //ghoul::lua::logStack(_state); addLibraryFunctions(library, true); + //ghoul::lua::logStack(_state); + lua_pop(_state, 1); + //ghoul::lua::logStack(_state); } else { const bool allowed = isLibraryNameAllowed(library.name); if (!allowed) return false; + //ghoul::lua::logStack(_state); + lua_pushstring(_state, library.name.c_str()); + //ghoul::lua::logStack(_state); lua_newtable(_state); + //ghoul::lua::logStack(_state); addLibraryFunctions(library, false); lua_settable(_state, _setTableOffset); - + //ghoul::lua::logStack(_state); + _registeredLibraries.insert(ghoul::hashCRC32(library.name)); } + return true; } @@ -199,8 +212,8 @@ bool ScriptEngine::isLibraryNameAllowed(const std::string& name) LERROR("Library name '" << name << "' specifies a thread"); break; } - - lua_pop(_state, 1); + + lua_pop(_state, 2); return result; } @@ -208,16 +221,23 @@ void ScriptEngine::addLibraryFunctions(const LuaLibrary& library, bool replace) { for (std::pair p : library.functions) { if (!replace) { + ghoul::lua::logStack(_state); lua_getfield(_state, -1, p.first.c_str()); + ghoul::lua::logStack(_state); const bool isNil = lua_isnil(_state, -1); if (!isNil) { LERROR("Function name '" << p.first << "' was already assigned"); return; } + lua_pop(_state, 1); } + //ghoul::lua::logStack(_state); lua_pushstring(_state, p.first.c_str()); + //ghoul::lua::logStack(_state); lua_pushcfunction(_state, p.second); + //ghoul::lua::logStack(_state); lua_settable(_state, _setTableOffset); + //ghoul::lua::logStack(_state); } } @@ -236,10 +256,15 @@ void ScriptEngine::addBaseLibrary() { } void ScriptEngine::remapPrintFunction() { - lua_getglobal(_state, _luaGlobalNamespace.c_str()); - lua_pushstring(_state, _printFunctionName.c_str()); - lua_pushcfunction(_state, _printFunctionReplacement); - lua_settable(_state, _setTableOffset); + //ghoul::lua::logStack(_state); + // lua_getglobal(_state, _luaGlobalNamespace.c_str()); + //ghoul::lua::logStack(_state); + // lua_pushstring(_state, _printFunctionName.c_str()); + //ghoul::lua::logStack(_state); + // lua_pushcfunction(_state, _printFunctionReplacement); + //ghoul::lua::logStack(_state); + // lua_settable(_state, _setTableOffset); + //ghoul::lua::logStack(_state); } } // namespace scripting diff --git a/src/util/time.cpp b/src/util/time.cpp index 01bc1c0837..441586d77b 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -136,7 +136,7 @@ std::string Time::currentTimeUTC() const { scripting::ScriptEngine::LuaLibrary Time::luaLibrary() { scripting::ScriptEngine::LuaLibrary timeLibrary = { - "", + "time", { {"setDeltaTime", &time_setDeltaTime}, {"deltaTime", &time_deltaTime}, From 9b2a04a8c4730ebea879c17c884c38327436bb20 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 14 Sep 2014 15:51:46 +0200 Subject: [PATCH 088/113] More work on Time class Fixed bool -> int conversion in SpiceManager --- include/openspace/scripting/scriptengine.h | 11 +- include/openspace/util/constants.h | 1 + include/openspace/util/time.h | 2 +- openspace.cfg | 1 + src/scripting/scriptengine.cpp | 39 ++++--- src/util/spicemanager.cpp | 2 +- src/util/time.cpp | 128 ++++++++++++++++----- 7 files changed, 138 insertions(+), 46 deletions(-) diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index 83c3795b18..186c986d5b 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -34,8 +34,15 @@ namespace scripting { class ScriptEngine { public: struct LuaLibrary { + struct Function { + std::string name; + lua_CFunction function; + std::string helpText; + }; std::string name; - std::vector> functions; + std::vector functions; + + bool operator<(const LuaLibrary& rhs) const; }; ScriptEngine(); @@ -57,7 +64,7 @@ private: void remapPrintFunction(); lua_State* _state; - std::set _registeredLibraries; + std::set _registeredLibraries; }; } // namespace scripting diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index 2fde16e5f5..6b16882f15 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -35,6 +35,7 @@ namespace openspaceengine { const std::string keyConfigSgct = "SGCTConfig"; const std::string keyConfigScene = "Scene"; const std::string keyStartupScript = "StartupScripts"; + const std::string keyConfigTimekernel = "SpiceTimeKernel"; } // namespace openspaceengine namespace scenegraph { diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 1ab38ce6bf..5972bf5b63 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -42,7 +42,7 @@ public: void setTime(double value); double currentTime() const; - void setTimeUTC(std::string time); + void setTime(std::string time); std::string currentTimeUTC() const; void setDeltaTime(double deltaT); diff --git a/openspace.cfg b/openspace.cfg index 65ebf301ab..96a75211ea 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -14,6 +14,7 @@ return { --SGCTConfig = "${SGCT}/two_nodes.xml", --SGCTConfig = "${SGCT}/single_sbs_stereo.xml", Scene = "${SCENEPATH}/default.scene", + SpiceTimeKernel = "${OPENSPACE_DATA}/spice/naif0010.tls", StartupScripts = { "${SCRIPTS}/default_startup.lua" } diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 1799dd55e7..1810def1a4 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -28,7 +28,6 @@ #include #include -#include #include #include @@ -45,6 +44,11 @@ namespace { const lua_CFunction _printFunctionReplacement = printInfo; const int _setTableOffset = -3; // -1 (top) -1 (first argument) -1 (second argument) + +} + +bool ScriptEngine::LuaLibrary::operator<(const LuaLibrary& rhs) const { + return name < rhs.name; } ScriptEngine::ScriptEngine() @@ -114,7 +118,7 @@ bool ScriptEngine::addLibrary(const ScriptEngine::LuaLibrary& library) { lua_settable(_state, _setTableOffset); //ghoul::lua::logStack(_state); - _registeredLibraries.insert(ghoul::hashCRC32(library.name)); + _registeredLibraries.insert(library); } return true; @@ -163,8 +167,10 @@ bool ScriptEngine::runScriptFile(const std::string& filename) { bool ScriptEngine::hasLibrary(const std::string& name) { - const unsigned int hash = ghoul::hashCRC32(name); - return (_registeredLibraries.find(hash) != _registeredLibraries.end()); + for (auto it = _registeredLibraries.begin(); it != _registeredLibraries.end(); ++it) + if (it->name == name) + return true; + return false; } bool ScriptEngine::isLibraryNameAllowed(const std::string& name) @@ -219,22 +225,22 @@ bool ScriptEngine::isLibraryNameAllowed(const std::string& name) void ScriptEngine::addLibraryFunctions(const LuaLibrary& library, bool replace) { - for (std::pair p : library.functions) { + for (LuaLibrary::Function p : library.functions) { if (!replace) { ghoul::lua::logStack(_state); - lua_getfield(_state, -1, p.first.c_str()); + lua_getfield(_state, -1, p.name.c_str()); ghoul::lua::logStack(_state); const bool isNil = lua_isnil(_state, -1); if (!isNil) { - LERROR("Function name '" << p.first << "' was already assigned"); + LERROR("Function name '" << p.name << "' was already assigned"); return; } lua_pop(_state, 1); } //ghoul::lua::logStack(_state); - lua_pushstring(_state, p.first.c_str()); + lua_pushstring(_state, p.name.c_str()); //ghoul::lua::logStack(_state); - lua_pushcfunction(_state, p.second); + lua_pushcfunction(_state, p.function); //ghoul::lua::logStack(_state); lua_settable(_state, _setTableOffset); //ghoul::lua::logStack(_state); @@ -245,11 +251,16 @@ void ScriptEngine::addBaseLibrary() { LuaLibrary lib = { "", { - { "printDebug", &printDebug }, - { "printInfo", &printInfo }, - { "printWarning", &printWarning }, - { "printError", &printError }, - { "printFatal", &printFatal } + { "printDebug", &printDebug, "printDebug(*): Logs the passed value to the " + "installed LogManager with a LogLevel of 'Debug'" }, + { "printInfo", &printInfo, "printInfo(*): Logs the passed value to the " + "installed LogManager with a LogLevel of 'Info'" }, + { "printWarning", &printWarning, "printWarning(*): Logs the passed value to " + "the installed LogManager with a LogLevel of 'Warning'" }, + { "printError", &printError, "printError(*): Logs the passed value to the " + "installed LogManager with a LogLevel of 'Error'" }, + { "printFatal", &printFatal, "printFatal(*): Logs the passed value to the " + "installed LogManager with a LogLevel of 'Fatal'" } } }; addLibrary(lib); diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index a6a70c8801..20b440c4c5 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -68,7 +68,7 @@ int SpiceManager::loadKernel(const std::string& fullPath, const std::string& sho std::string currentDirectory = FileSys.currentDirectory(); std::string::size_type last = fullPath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator); if (last == std::string::npos) - return false; + return 0; std::string kernelDir = fullPath.substr(0, last); FileSys.setCurrentDirectory(kernelDir); furnsh_c(fullPath.c_str()); diff --git a/src/util/time.cpp b/src/util/time.cpp index 441586d77b..a1c6a2ed91 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -24,42 +24,86 @@ #include +#include #include +#include #include #include #include +#include namespace { const std::string _loggerCat = "Time"; + //tag_error(L, narg, LUA_TNUMBER); + int time_setDeltaTime(lua_State* L) { - const std::string _loggerCat = "time_setDeltaTime"; - double value = luaL_checknumber(L, -1); - openspace::Time::ref().setDeltaTime(value); - return 0; + const bool isFunction = (lua_isfunction(L, -1) != 0); + if (isFunction) { + // If the top of the stack is a function, it is ourself + const char* msg = lua_pushfstring(L, "method called without argument"); + return luaL_error(L, "bad argument (%s)", msg); + } + + const bool isNumber = (lua_isnumber(L, -1) != 0); + if (isNumber) { + double value = lua_tonumber(L, -1); + openspace::Time::ref().setDeltaTime(value); + return 0; + } + else { + const char* msg = lua_pushfstring(L, "%s expected, got %s", + lua_typename(L, LUA_TNUMBER), luaL_typename(L, -1)); + return luaL_error(L, "bad argument #%d (%s)", 1, msg); + } + } int time_deltaTime(lua_State* L) { - const std::string _loggerCat = "time_deltaTime"; lua_pushnumber(L, openspace::Time::ref().deltaTime()); return 1; } int time_setTime(lua_State* L) { - const std::string _loggerCat = "time_setTime"; - double value = luaL_checknumber(L, -1); - openspace::Time::ref().setTime(value); + const bool isFunction = (lua_isfunction(L, -1) != 0); + if (isFunction) { + // If the top of the stack is a function, it is ourself + const char* msg = lua_pushfstring(L, "method called without argument"); + return luaL_error(L, "bad argument (%s)", 1, msg); + } + + const bool isNumber = (lua_isnumber(L, -1) != 0); + const bool isString = (lua_isstring(L, -1) != 0); + if (!isNumber && !isString) { + const char* msg = lua_pushfstring(L, "%s or %s expected, got %s", + lua_typename(L, LUA_TNUMBER), + lua_typename(L, LUA_TSTRING), luaL_typename(L, -1)); + return luaL_error(L, "bad argument #%d (%s)", 1, msg); + } + if (isNumber) { + double value = lua_tonumber(L, -1); + openspace::Time::ref().setTime(value); + return 0; + } + if (isString) { + const char* time = lua_tostring(L, -1); + openspace::Time::ref().setTime(time); + return 0; + } return 0; } int time_currentTime(lua_State* L) { - const std::string _loggerCat = "time_time"; lua_pushnumber(L, openspace::Time::ref().currentTime()); return 1; } + int time_currentTimeUTC(lua_State* L) { + lua_pushstring(L, openspace::Time::ref().currentTimeUTC().c_str()); + return 1; + } } namespace openspace { @@ -70,17 +114,23 @@ Time::Time() : _time(-1.0) , _deltaTimePerSecond(1.0) { - SpiceManager::ref().loadKernel(absPath("${OPENSPACE_DATA}/spice/naif0010.tls"), "leap"); - // load spice time kernel - //furnsh_c (absPath("${OPENSPACE_DATA}/spice/naif0010.tls").c_str()); - - // convert UTC to ET - //str2et_c ( "2006 JAN 31 01:00", &_time ); } bool Time::initialize() { assert( _instance == nullptr); _instance = new Time(); + + using constants::openspaceengine::keyConfigTimekernel; + if (OsEng.configurationManager().hasKeyAndValue(keyConfigTimekernel)) { + std::string value; + OsEng.configurationManager().getValue(keyConfigTimekernel, value); + const int success = SpiceManager::ref().loadKernel(absPath(value), "TimeKernel"); + if (success == 0) { + LERROR("Error loading SPICE time kernel '" << value << "'"); + return false; + } + } + return true; } @@ -96,15 +146,9 @@ Time& Time::ref() { } bool Time::isInitialized() { - return _instance != nullptr; + return (_instance != nullptr); } -//void Time::setTime(const char* stringTime) { -// assert(_instance); -// // convert UTC to ET -// //str2et_c ( stringTime, &_time ); -//} - void Time::setTime(double value) { _time = std::move(value); } @@ -126,22 +170,50 @@ double Time::deltaTime() const { return _deltaTimePerSecond; } -void Time::setTimeUTC(std::string time) { +void Time::setTime(std::string time) { _time = SpiceManager::ref().convertStringToTdbSeconds(std::move(time)); } std::string Time::currentTimeUTC() const { - return SpiceManager::ref().convertTdbSecondsToString(_time, "MON DD,YYYY HR:MN:SC.#### (TDB) ::TDB"); + return SpiceManager::ref().convertTdbSecondsToString(_time, "YYYY-MM-DDTHR:MN:SC.#####"); } scripting::ScriptEngine::LuaLibrary Time::luaLibrary() { scripting::ScriptEngine::LuaLibrary timeLibrary = { "time", { - {"setDeltaTime", &time_setDeltaTime}, - {"deltaTime", &time_deltaTime}, - {"setTime", &time_setTime}, - {"currentTime", &time_currentTime} + { + "setDeltaTime", + &time_setDeltaTime, + "setDeltaTime(number): Sets the amount of simulation time that happens " + "in one second of real time" + }, + { + "deltaTime", + &time_deltaTime, + "deltaTime: Returns the amount of simulated time that passes in one " + "second of real time" + }, + { + "setTime", + &time_setTime, + "setTime({number, string}): Sets the current simulation time to the " + "specified value. If the parameter is a number, the value is the number " + "of seconds past the J2000 epoch. If it is a string, it has to be a " + "valid ISO 8601 date string (YYYY-MM-DDTHH:MN:SS)" + }, + { + "currentTime", + &time_currentTime, + "currentTime(): Returns the current time as the number of seconds since " + "the J2000 epoch" + }, + { + "currentTimeUTC", + &time_currentTimeUTC, + "currentTimeUTC: Returns the current time as an ISO 8601 date string " + "(YYYY-MM-DDTHH:MN:SS" + } } }; return std::move(timeLibrary); From f0dfd0fa043072f95b9a721ff144b558e6cc0e03 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 14 Sep 2014 17:36:10 +0200 Subject: [PATCH 089/113] Added documentation for Time class --- include/openspace/scripting/scriptengine.h | 4 + include/openspace/util/time.h | 117 +++++++++++- src/engine/openspaceengine.cpp | 7 +- src/util/time.cpp | 197 ++++++++++++--------- 4 files changed, 232 insertions(+), 93 deletions(-) diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index 186c986d5b..648bc0ca12 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -28,6 +28,10 @@ #include #include +/** + * \defgroup LuaScripts Lua Scripts + */ + namespace openspace { namespace scripting { diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 5972bf5b63..2e1b48c6c4 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -26,42 +26,141 @@ #define __TIME_H__ #include - #include namespace openspace { +/** + * This singleton class represents the current simulation time in OpenSpace. It + * internally stores the time and provides methods to set the time directly + * (setTime(double), setTime(std::string)) using a double value using the + * number of seconds passed since the J2000 epoch or a string that denotes + * a valid date string in accordance to the Spice library + * (http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html). The time can + * be retrieved as the number of seconds since the J2000 epoch with currentTime() or as a + * UTC string following ISO 8601 with the method currentTimeUTC(). + * + * In addition to the time itself, it also stores a delta time value. This value denotes + * the number of seconds that pass for each real-time second. This value is set with + * setDeltaTime(double), retrieved with deltaTime() and solely used in the + * advanceTime(double), which takes a tickTime parameter. The value of the + * parameter is dependent on the usage of the class and must be equal to the real-world + * time that has passed since the last call to the method. For example, if the + * advanceTime(double) method is called each frame, the tickTime has to be + * equal to the frame time. + */ class Time { public: - static bool initialize(); + /** + * Initializes the Time singleton and loads an LSK spice kernel with the provided + * name. + * \param lskKernel The name of the kernel that should be loaded during the + * initialization. If the parameter is empty, no kernel will be loaded + * \return true if the initialization succeeded, false + * otherwise + */ + static bool initialize(const std::string& lskKernel = ""); + + /** + * Deinitializes the Time singleton. This method will not unload the kernel that was + * possibly loaded during the initialize method. + */ static void deinitialize(); + + /** + * Returns the reference to the Time singleton object. + * \return The reference to the Time singleton object + */ static Time& ref(); + + /** + * Returns true if the singleton has been successfully initialized, + * false otherwise + * \return true if the singleton has been successfully initialized, + * false otherwise + */ static bool isInitialized(); - double advanceTime(double tickTime); - + /** + * Sets the current time to the specified value in seconds past the J2000 epoch. This + * value can be negative to represent dates before the epoch. + * \param The number of seconds after the J2000 epoch + */ void setTime(double value); - double currentTime() const; + + /** + * Sets the current time to the specified value given as a Spice compliant string as + * described in the Spice documentation + * (http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html) + * \param time The time to be set as a date string + */ void setTime(std::string time); + + /** + * Returns the current time as the number of seconds past the J2000 epoch. If the + * current time is a date before that epoch, the returned value will be negative. + * \return The current time as the number of seconds past the J2000 epoch + */ + double currentTime() const; + + /** + * Returns the current time as a formatted date string compliant with ISO 8601 and + * thus also compliant with the Spice library. + * \return The current time as a formatted date string + */ std::string currentTimeUTC() const; + /** + * Sets the delta time value that is the number of seconds that should pass for each + * real-time second. This value is used in the advanceTime(double) method to easily + * advance the simulation time. + * \param deltaT The number of seconds that should pass for each real-time second + */ void setDeltaTime(double deltaT); + + /** + * Returns the delta time, that is the number of seconds that pass in the simulation + * for each real-time second + * \return The number of seconds that pass for each real-time second + */ double deltaTime() const; + /** + * Advances the simulation time using the deltaTime() and the tickTime. + * The deltaTime() is the number of simulation seconds that pass for each real-time + * second. tickTime is the number of real-time seconds that passed since + * the last call to this method. If this method is called in the render loop, the + * tickTime should be equivalent to the frame time. + * \param tickTime The number of real-time seconds that passed since the last call + * to this method + * \return The new time value after advancing the time + */ + double advanceTime(double tickTime); + + /** + * Returns the Lua library that contains all Lua functions available to change the + * current time, retrieve the current time etc. The functions contained are + * - time_setDeltaTime + * - time_deltaTime + * - time_currentTime + * - time_currentTimeUTC + * \return The Lua library that contains all Lua functions available to change the + * Time singleton + */ static scripting::ScriptEngine::LuaLibrary luaLibrary(); private: + /// Creates the time object. Only used in the initialize() method Time(); Time(const Time& src) = delete; Time& operator=(const Time& rhs) = delete; - static Time* _instance; - double _time; + static Time* _instance; ///< The singleton instance + double _time; ///< The time stored as the number of seconds past the J2000 epoch - double _deltaTimePerSecond; + double _deltaTimePerSecond; ///< The delta time that is used to advance the time }; - } // namespace openspace #endif // __TIME_H__ diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 01ec011aa2..f30dd8d8c1 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -323,10 +323,15 @@ bool OpenSpaceEngine::initialize() SysCap.detectCapabilities(); SysCap.logCapabilities(); + std::string timeKernel = ""; + using constants::openspaceengine::keyConfigTimekernel; + if (OsEng.configurationManager().hasKeyAndValue(keyConfigTimekernel)) { + OsEng.configurationManager().getValue(keyConfigTimekernel, timeKernel); + } // initialize OpenSpace helpers SpiceManager::initialize(); - Time::initialize(); + Time::initialize(timeKernel); Spice::init(); Spice::ref().loadDefaultKernels(); FactoryManager::initialize(); diff --git a/src/util/time.cpp b/src/util/time.cpp index a1c6a2ed91..854b38d70c 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -36,78 +36,112 @@ namespace { const std::string _loggerCat = "Time"; - - //tag_error(L, narg, LUA_TNUMBER); - - int time_setDeltaTime(lua_State* L) { - const bool isFunction = (lua_isfunction(L, -1) != 0); - if (isFunction) { - // If the top of the stack is a function, it is ourself - const char* msg = lua_pushfstring(L, "method called without argument"); - return luaL_error(L, "bad argument (%s)", msg); - } - - const bool isNumber = (lua_isnumber(L, -1) != 0); - if (isNumber) { - double value = lua_tonumber(L, -1); - openspace::Time::ref().setDeltaTime(value); - return 0; - } - else { - const char* msg = lua_pushfstring(L, "%s expected, got %s", - lua_typename(L, LUA_TNUMBER), luaL_typename(L, -1)); - return luaL_error(L, "bad argument #%d (%s)", 1, msg); - } - - } - - int time_deltaTime(lua_State* L) { - lua_pushnumber(L, openspace::Time::ref().deltaTime()); - return 1; - } - - int time_setTime(lua_State* L) { - const bool isFunction = (lua_isfunction(L, -1) != 0); - if (isFunction) { - // If the top of the stack is a function, it is ourself - const char* msg = lua_pushfstring(L, "method called without argument"); - return luaL_error(L, "bad argument (%s)", 1, msg); - } - - const bool isNumber = (lua_isnumber(L, -1) != 0); - const bool isString = (lua_isstring(L, -1) != 0); - if (!isNumber && !isString) { - const char* msg = lua_pushfstring(L, "%s or %s expected, got %s", - lua_typename(L, LUA_TNUMBER), - lua_typename(L, LUA_TSTRING), luaL_typename(L, -1)); - return luaL_error(L, "bad argument #%d (%s)", 1, msg); - } - if (isNumber) { - double value = lua_tonumber(L, -1); - openspace::Time::ref().setTime(value); - return 0; - } - if (isString) { - const char* time = lua_tostring(L, -1); - openspace::Time::ref().setTime(time); - return 0; - } - return 0; - } - - int time_currentTime(lua_State* L) { - lua_pushnumber(L, openspace::Time::ref().currentTime()); - return 1; - } - - int time_currentTimeUTC(lua_State* L) { - lua_pushstring(L, openspace::Time::ref().currentTimeUTC().c_str()); - return 1; - } } namespace openspace { +namespace luascriptfunctions { + +/** + * \ingroup LuaScripts + * setDeltaTime(number): + * Sets the delta time by calling the Time::setDeltaTime method + */ +int time_setDeltaTime(lua_State* L) { + const bool isFunction = (lua_isfunction(L, -1) != 0); + if (isFunction) { + // If the top of the stack is a function, it is ourself + const char* msg = lua_pushfstring(L, "method called without argument"); + return luaL_error(L, "bad argument (%s)", msg); + } + + const bool isNumber = (lua_isnumber(L, -1) != 0); + if (isNumber) { + double value = lua_tonumber(L, -1); + openspace::Time::ref().setDeltaTime(value); + return 0; + } + else { + const char* msg = lua_pushfstring(L, "%s expected, got %s", + lua_typename(L, LUA_TNUMBER), luaL_typename(L, -1)); + return luaL_error(L, "bad argument #%d (%s)", 1, msg); + } + +} + +/** + * \ingroup LuaScripts + * deltaTime(): + * Returns the delta time by calling the Time::deltaTime method + */ +int time_deltaTime(lua_State* L) { + lua_pushnumber(L, openspace::Time::ref().deltaTime()); + return 1; +} + +/** + * \ingroup LuaScripts + * setTime({number, string}): + * Sets the simulation time to the passed value. If the parameter is a number, it is + * interpreted as the number of seconds past the J2000 epoch and the + * Time::setTime(double) method is called. If the parameter is a string, it is + * interpreted as a structured date string and the Time::setTime(std::string) method + * is called + */ +int time_setTime(lua_State* L) { + const bool isFunction = (lua_isfunction(L, -1) != 0); + if (isFunction) { + // If the top of the stack is a function, it is ourself + const char* msg = lua_pushfstring(L, "method called without argument"); + return luaL_error(L, "bad argument (%s)", 1, msg); + } + + const bool isNumber = (lua_isnumber(L, -1) != 0); + const bool isString = (lua_isstring(L, -1) != 0); + if (!isNumber && !isString) { + const char* msg = lua_pushfstring(L, "%s or %s expected, got %s", + lua_typename(L, LUA_TNUMBER), + lua_typename(L, LUA_TSTRING), luaL_typename(L, -1)); + return luaL_error(L, "bad argument #%d (%s)", 1, msg); + } + if (isNumber) { + double value = lua_tonumber(L, -1); + openspace::Time::ref().setTime(value); + return 0; + } + if (isString) { + const char* time = lua_tostring(L, -1); + openspace::Time::ref().setTime(time); + return 0; + } + return 0; +} + +/** + * \ingroup LuaScripts + * currentTime(): + * Returns the current simulation time as the number of seconds past the J2000 epoch. + * It is returned by calling the Time::currentTime method. + */ +int time_currentTime(lua_State* L) { + lua_pushnumber(L, openspace::Time::ref().currentTime()); + return 1; +} + +/** + * \ingroup LuaScripts + * currentTimeUTC(): + * Returns the current simulation time as a structured ISO 8601 string using the UTC + * timezone by calling the Time::currentTimeUTC method + */ +int time_currentTimeUTC(lua_State* L) { + lua_pushstring(L, openspace::Time::ref().currentTimeUTC().c_str()); + return 1; +} + +} // namespace luascripts + + Time* Time::_instance = nullptr; Time::Time() @@ -116,21 +150,18 @@ Time::Time() { } -bool Time::initialize() { +bool Time::initialize(const std::string& lskKernel) { assert( _instance == nullptr); - _instance = new Time(); - using constants::openspaceengine::keyConfigTimekernel; - if (OsEng.configurationManager().hasKeyAndValue(keyConfigTimekernel)) { - std::string value; - OsEng.configurationManager().getValue(keyConfigTimekernel, value); - const int success = SpiceManager::ref().loadKernel(absPath(value), "TimeKernel"); + if (!lskKernel.empty()) { + const int success = SpiceManager::ref().loadKernel( + absPath(lskKernel), "TimeKernel"); if (success == 0) { - LERROR("Error loading SPICE time kernel '" << value << "'"); - return false; + LERROR("Error loading SPICE time kernel '" << lskKernel << "'"); + return false; } } - + _instance = new Time(); return true; } @@ -184,19 +215,19 @@ scripting::ScriptEngine::LuaLibrary Time::luaLibrary() { { { "setDeltaTime", - &time_setDeltaTime, + &luascriptfunctions::time_setDeltaTime, "setDeltaTime(number): Sets the amount of simulation time that happens " "in one second of real time" }, { "deltaTime", - &time_deltaTime, + &luascriptfunctions::time_deltaTime, "deltaTime: Returns the amount of simulated time that passes in one " "second of real time" }, { "setTime", - &time_setTime, + &luascriptfunctions::time_setTime, "setTime({number, string}): Sets the current simulation time to the " "specified value. If the parameter is a number, the value is the number " "of seconds past the J2000 epoch. If it is a string, it has to be a " @@ -204,13 +235,13 @@ scripting::ScriptEngine::LuaLibrary Time::luaLibrary() { }, { "currentTime", - &time_currentTime, + &luascriptfunctions::time_currentTime, "currentTime(): Returns the current time as the number of seconds since " "the J2000 epoch" }, { "currentTimeUTC", - &time_currentTimeUTC, + &luascriptfunctions::time_currentTimeUTC, "currentTimeUTC: Returns the current time as an ISO 8601 date string " "(YYYY-MM-DDTHH:MN:SS" } From 3d62caae46fbbbf93fb43e53341bc62207137590 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 14 Sep 2014 17:40:19 +0200 Subject: [PATCH 090/113] Added missing documentation --- include/openspace/util/time.h | 9 +++++---- src/util/time.cpp | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 2e1b48c6c4..2db604e328 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -140,10 +140,11 @@ public: /** * Returns the Lua library that contains all Lua functions available to change the * current time, retrieve the current time etc. The functions contained are - * - time_setDeltaTime - * - time_deltaTime - * - time_currentTime - * - time_currentTimeUTC + * - openspace::luascriptfunctions::time_setDeltaTime + * - openspace::luascriptfunctions::time_deltaTime + * - openspace::luascriptfunctions::time_setTime + * - openspace::luascriptfunctions::time_currentTime + * - openspace::luascriptfunctions::time_currentTimeUTC * \return The Lua library that contains all Lua functions available to change the * Time singleton */ diff --git a/src/util/time.cpp b/src/util/time.cpp index 854b38d70c..dad1f20f43 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -139,7 +139,7 @@ int time_currentTimeUTC(lua_State* L) { return 1; } -} // namespace luascripts +} // namespace luascriptfunctions Time* Time::_instance = nullptr; From 66722e83a611da15269e8a181c4d5ea943722900 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 14 Sep 2014 18:36:33 +0200 Subject: [PATCH 091/113] Cleaned up script functionality in SceneGraph Removed scriptfunctions.h and cpp as the functions have moved into other classes --- include/openspace/scenegraph/scenegraph.h | 15 +- include/openspace/scripting/scriptfunctions.h | 48 ----- scripts/default_startup.lua | 6 +- src/engine/openspaceengine.cpp | 2 + src/scenegraph/scenegraph.cpp | 171 ++++++++++++--- src/scripting/scriptengine.cpp | 137 ++++++++++-- src/scripting/scriptfunctions.cpp | 195 ------------------ 7 files changed, 284 insertions(+), 290 deletions(-) delete mode 100644 include/openspace/scripting/scriptfunctions.h delete mode 100644 src/scripting/scriptfunctions.cpp diff --git a/include/openspace/scenegraph/scenegraph.h b/include/openspace/scenegraph/scenegraph.h index b41cd79532..59e6e2b08e 100644 --- a/include/openspace/scenegraph/scenegraph.h +++ b/include/openspace/scenegraph/scenegraph.h @@ -31,12 +31,15 @@ #include +#include + // ghoul includes #include #include namespace openspace { + class SceneGraphNode; class SceneGraph { @@ -94,9 +97,17 @@ public: */ SceneGraphNode* sceneGraphNode(const std::string& name) const; + /** + * Returns the Lua library that contains all Lua functions available to change the + * scene graph. The functions contained are + * - openspace::luascriptfunctions::property_setValue + * - openspace::luascriptfunctions::property_getValue + * \return The Lua library that contains all Lua functions available to change the + * scene graph + */ + static scripting::ScriptEngine::LuaLibrary luaLibrary(); + private: - bool registerScriptFunctions(); - std::string _focus, _position; // actual scenegraph diff --git a/include/openspace/scripting/scriptfunctions.h b/include/openspace/scripting/scriptfunctions.h deleted file mode 100644 index a590cca1d0..0000000000 --- a/include/openspace/scripting/scriptfunctions.h +++ /dev/null @@ -1,48 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __SCRIPTFUNCTIONS_H__ -#define __SCRIPTFUNCTIONS_H__ - -struct lua_State; - -namespace openspace { -namespace scripting { - -// Helper functions -int printDebug(lua_State* L); -int printInfo(lua_State* L); -int printWarning(lua_State* L); -int printError(lua_State* L); -int printFatal(lua_State* L); - -// Properties - -int property_setValue(lua_State* L); -int property_getValue(lua_State* L); - -} // namespace scripting -} // namespace openspace - -#endif // __SCRIPTFUNCTIONS_H__ diff --git a/scripts/default_startup.lua b/scripts/default_startup.lua index e064f06acd..f3d66d3ddc 100644 --- a/scripts/default_startup.lua +++ b/scripts/default_startup.lua @@ -1,3 +1,5 @@ --openspace.setPropertyValue('Earth.renderable.colorTexture', '${OPENSPACE_DATA}/modules/mars/textures/mars.png') -openspace.time.setTime(1000000) -openspace.time.setDeltaTime(100) \ No newline at end of file +openspace.time.setTime("2000-01-01T00:00:00") +openspace.time.setDeltaTime(0.0) + +print(openspace.time.currentTimeUTC()) diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index f30dd8d8c1..7bf0f04ceb 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -340,6 +340,8 @@ bool OpenSpaceEngine::initialize() scriptEngine().initialize(); // Register Lua script functions + LDEBUG("Registering Lua libraries"); + scriptEngine().addLibrary(SceneGraph::luaLibrary()); scriptEngine().addLibrary(Time::luaLibrary()); // Load scenegraph diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index b2ac485212..a6ac8cf10e 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -28,10 +28,10 @@ #include #include #include -#include #include #include #include +#include // ghoul includes #include "ghoul/opengl/programobject.h" @@ -55,17 +55,127 @@ namespace { const std::string _loggerCat = "SceneGraph"; const std::string _moduleExtension = ".mod"; -//{ -// LDEBUGC("Tree", pre << node->name()); -// const std::vector& children = node->children(); -// for (openspace::SceneGraphNode* child : children) -// printTree(child, pre + " "); -//} -// } namespace openspace { +namespace luascriptfunctions { + +/** + * \ingroup LuaScripts + * setPropertyValue(string, *): + * Sets the property identified by the URI in the first argument to the value passed to + * the second argument. The type of the second argument is arbitrary, but it must agree + * with the type the denoted Property expects + */ +int property_setValue(lua_State* L) { + using ghoul::lua::luaTypeToString; + const std::string _loggerCat = "property_setValue"; + + // TODO Check for argument number (ab) + std::string uri = luaL_checkstring(L, -2); + const int type = lua_type(L, -1); + // boost::any propertyValue; + // switch (type) { + // case LUA_TNONE: + // case LUA_TLIGHTUSERDATA: + // case LUA_TFUNCTION: + // case LUA_TUSERDATA: + // case LUA_TTHREAD: + // LERROR("Function parameter was of type '" << luaTypeToString(type) << "'"); + // return 0; + // case LUA_TNIL: + // propertyValue = 0; + // break; + // case LUA_TBOOLEAN: + // propertyValue = lua_toboolean(L, -1); + // break; + // case LUA_TNUMBER: + // propertyValue = lua_tonumber(L, -1); + // break; + // case LUA_TSTRING: + // propertyValue = std::string(lua_tostring(L, -1)); + // break; + //case LUA_TTABLE: { + // ghoul::Dictionary d; + // ghoul::lua::populateDictionary(L, d); + // propertyValue = d; + // break; + //} + // } + + openspace::properties::Property* prop = property(uri); + if (!prop) { + LERROR("Property with uri '" << uri << "' could not be found"); + return 0; + } + + //if (propertyValue.type() != prop->type()) { + if (type != prop->typeLua()) + LERROR("Property '" << uri << "' does not accept input of type '" + << luaTypeToString(type) << "'. Requested type: '" + << luaTypeToString(prop->typeLua()) << "'"); + else + prop->setLua(L); + //prop->set(propertyValue); + + return 0; +} + +/** + * \ingroup LuaScripts + * getPropertyValue(string): + * Returns the value of the property identified by the passed URI as a Lua object that can + * be passed to the setPropertyValue method. + */ +int property_getValue(lua_State* L) { + const std::string _loggerCat = "property_getValue"; + + // TODO Check for argument number (ab) + std::string uri = luaL_checkstring(L, -1); + + openspace::properties::Property* prop = property(uri); + if (!prop) { + LERROR("Property with uri '" << uri << "' could not be found"); + lua_pushnil(L); + } + else { + prop->getLua(L); + + //switch (type) { + // case LUA_TNONE: + // case LUA_TLIGHTUSERDATA: + // case LUA_TFUNCTION: + // case LUA_TUSERDATA: + // case LUA_TTHREAD: + // LERROR("Function parameter was of type '" << luaTypeToString(type) + // << "'"); + // return 0; + // case LUA_TNIL: + // propertyValue = 0; + // break; + // case LUA_TBOOLEAN: + // propertyValue = lua_toboolean(L, -1); + // break; + // case LUA_TNUMBER: + // propertyValue = lua_tonumber(L, -1); + // break; + // case LUA_TSTRING: + // propertyValue = std::string(lua_tostring(L, -1)); + // break; + // case LUA_TTABLE: { + // ghoul::Dictionary d; + // ghoul::lua::populateDictionary(L, d); + // propertyValue = d; + // break; + // } + //} + } + return 1; +} + +} // namespace luascriptfunctions + SceneGraph::SceneGraph() : _focus(SceneGraphNode::RootNodeName) , _position(SceneGraphNode::RootNodeName) @@ -82,10 +192,6 @@ bool SceneGraph::initialize() { LDEBUG("Initializing SceneGraph"); - const bool scriptSuccess = registerScriptFunctions(); - if (!scriptSuccess) - return false; - LDEBUG("Creating ProgramObjects"); using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; @@ -387,24 +493,6 @@ SceneGraphNode* SceneGraph::root() const return _root; } -bool SceneGraph::registerScriptFunctions() -{ - LDEBUG("Registering Script Functions"); - - using namespace scripting; - - ScriptEngine::LuaLibrary sceneGraphLibrary = { - "", - { - { "setPropertyValue", &property_setValue}, - { "getPropertyValue", &property_getValue} - } - }; - - OsEng.scriptEngine().addLibrary(sceneGraphLibrary); - return true; -} - SceneGraphNode* SceneGraph::sceneGraphNode(const std::string& name) const { auto it = _allNodes.find(name); if (it == _allNodes.end()) @@ -413,4 +501,27 @@ SceneGraphNode* SceneGraph::sceneGraphNode(const std::string& name) const { return it->second; } +scripting::ScriptEngine::LuaLibrary SceneGraph::luaLibrary() { + scripting::ScriptEngine::LuaLibrary sceneGraphLibrary = { + "", + { + { + "setPropertyValue", + &luascriptfunctions::property_setValue, + "setPropertyValue(string, *): Sets a property identified by the URI in " + "the first argument. The second argument can be any type, but it has to " + " agree with the type that the property expects" + }, + { + "getPropertyValue", + &luascriptfunctions::property_getValue, + "getPropertyValue(string): Returns the value the property, identified by " + "the provided URI, has" + } + } + }; + + return std::move(sceneGraphLibrary); +} + } // namespace openspace diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 1810def1a4..b42fd198a2 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -24,8 +24,6 @@ #include -#include - #include #include @@ -33,6 +31,99 @@ #include namespace openspace { + +namespace luascriptfunctions { + + void printInternal(ghoul::logging::LogManager::LogLevel level, lua_State* L) { + using ghoul::lua::luaTypeToString; + const std::string _loggerCat = "print"; + + const int type = lua_type(L, -1); + switch (type) { + case LUA_TNONE: + case LUA_TLIGHTUSERDATA: + case LUA_TTABLE: + case LUA_TFUNCTION: + case LUA_TUSERDATA: + case LUA_TTHREAD: + LOG(level, "Function parameter was of type '" << + luaTypeToString(type) << "'"); + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + LOG(level, lua_toboolean(L, -1)); + break; + case LUA_TNUMBER: + LOG(level, lua_tonumber(L, -1)); + break; + case LUA_TSTRING: + LOG(level, lua_tostring(L, -1)); + break; + } + } + + /** + * \ingroup LuaScripts + * printDebug(*): + * Logs the passed value to the installed LogManager with a LogLevel of 'Debug'. + * For Boolean, numbers, and strings, the internal values are printed, for all other + * types, the type is printed instead + */ + int printDebug(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Debug, L); + return 0; + } + + /** + * \ingroup LuaScripts + * printInfo(*): + * Logs the passed value to the installed LogManager with a LogLevel of 'Info'. + * For Boolean, numbers, and strings, the internal values are printed, for all other + * types, the type is printed instead + */ + int printInfo(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Info, L); + return 0; + } + + /** + * \ingroup LuaScripts + * printWarning(*): + * Logs the passed value to the installed LogManager with a LogLevel of 'Warning'. + * For Boolean, numbers, and strings, the internal values are printed, for all other + * types, the type is printed instead + */ + int printWarning(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Warning, L); + return 0; + } + + /** + * \ingroup LuaScripts + * printError(*): + * Logs the passed value to the installed LogManager with a LogLevel of 'Error'. + * For Boolean, numbers, and strings, the internal values are printed, for all other + * types, the type is printed instead + */ + int printError(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Error, L); + return 0; + } + + /** + * \ingroup LuaScripts + * printFatal(*): + * Logs the passed value to the installed LogManager with a LogLevel of 'Fatal'. + * For Boolean, numbers, and strings, the internal values are printed, for all other + * types, the type is printed instead + */ + int printFatal(lua_State* L) { + printInternal(ghoul::logging::LogManager::LogLevel::Fatal, L); + return 0; + } + +} // namespace luascriptfunctions + namespace scripting { namespace { @@ -41,7 +132,7 @@ namespace { const std::string _openspaceLibraryName = "openspace"; const std::string _luaGlobalNamespace = "_G"; const std::string _printFunctionName = "print"; - const lua_CFunction _printFunctionReplacement = printInfo; + const lua_CFunction _printFunctionReplacement = luascriptfunctions::printInfo; const int _setTableOffset = -3; // -1 (top) -1 (first argument) -1 (second argument) @@ -251,16 +342,36 @@ void ScriptEngine::addBaseLibrary() { LuaLibrary lib = { "", { - { "printDebug", &printDebug, "printDebug(*): Logs the passed value to the " - "installed LogManager with a LogLevel of 'Debug'" }, - { "printInfo", &printInfo, "printInfo(*): Logs the passed value to the " - "installed LogManager with a LogLevel of 'Info'" }, - { "printWarning", &printWarning, "printWarning(*): Logs the passed value to " - "the installed LogManager with a LogLevel of 'Warning'" }, - { "printError", &printError, "printError(*): Logs the passed value to the " - "installed LogManager with a LogLevel of 'Error'" }, - { "printFatal", &printFatal, "printFatal(*): Logs the passed value to the " - "installed LogManager with a LogLevel of 'Fatal'" } + { + "printDebug", + &luascriptfunctions::printDebug, + "printDebug(*): Logs the passed value to the installed LogManager with a " + "LogLevel of 'Debug'" + }, + { + "printInfo", + &luascriptfunctions::printInfo, + "printInfo(*): Logs the passed value to the installed LogManager with a " + " LogLevel of 'Info'" + }, + { + "printWarning", + &luascriptfunctions::printWarning, + "printWarning(*): Logs the passed value to the installed LogManager with " + "a LogLevel of 'Warning'" + }, + { + "printError", + &luascriptfunctions::printError, + "printError(*): Logs the passed value to the installed LogManager with a " + "LogLevel of 'Error'" + }, + { + "printFatal", + &luascriptfunctions::printFatal, + "printFatal(*): Logs the passed value to the installed LogManager with a " + "LogLevel of 'Fatal'" + } } }; addLibrary(lib); diff --git a/src/scripting/scriptfunctions.cpp b/src/scripting/scriptfunctions.cpp deleted file mode 100644 index cf7279f20d..0000000000 --- a/src/scripting/scriptfunctions.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#include - -#include -#include - -#include -#include -#include - -namespace openspace { -namespace scripting { - -using namespace openspace::properties; - -void printInternal(ghoul::logging::LogManager::LogLevel level, lua_State* L) { - using ghoul::lua::luaTypeToString; - const std::string _loggerCat = "print"; - - const int type = lua_type(L, -1); - switch (type) { - case LUA_TNONE: - case LUA_TLIGHTUSERDATA: - case LUA_TTABLE: - case LUA_TFUNCTION: - case LUA_TUSERDATA: - case LUA_TTHREAD: - LOG(level, "Function parameter was of type '" << - luaTypeToString(type) << "'"); - case LUA_TNIL: - break; - case LUA_TBOOLEAN: - LOG(level, lua_toboolean(L, -1)); - break; - case LUA_TNUMBER: - LOG(level, lua_tonumber(L, -1)); - break; - case LUA_TSTRING: - LOG(level, lua_tostring(L, -1)); - break; - } -} - -int printDebug(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Debug, L); - return 0; -} - -int printInfo(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Info, L); - return 0; -} - -int printWarning(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Warning, L); - return 0; -} - -int printError(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Error, L); - return 0; -} - -int printFatal(lua_State* L) { - printInternal(ghoul::logging::LogManager::LogLevel::Fatal, L); - return 0; -} - - -int property_setValue(lua_State* L) -{ - using ghoul::lua::luaTypeToString; - const std::string _loggerCat = "property_setValue"; - - // TODO Check for argument number (ab) - std::string uri = luaL_checkstring(L, -2); - const int type = lua_type(L, -1); - // boost::any propertyValue; - // switch (type) { - // case LUA_TNONE: - // case LUA_TLIGHTUSERDATA: - // case LUA_TFUNCTION: - // case LUA_TUSERDATA: - // case LUA_TTHREAD: - // LERROR("Function parameter was of type '" << luaTypeToString(type) << "'"); - // return 0; - // case LUA_TNIL: - // propertyValue = 0; - // break; - // case LUA_TBOOLEAN: - // propertyValue = lua_toboolean(L, -1); - // break; - // case LUA_TNUMBER: - // propertyValue = lua_tonumber(L, -1); - // break; - // case LUA_TSTRING: - // propertyValue = std::string(lua_tostring(L, -1)); - // break; - //case LUA_TTABLE: { - // ghoul::Dictionary d; - // ghoul::lua::populateDictionary(L, d); - // propertyValue = d; - // break; - //} - // } - - Property* prop = property(uri); - if (!prop) { - LERROR("Property with uri '" << uri << "' could not be found"); - return 0; - } - - //if (propertyValue.type() != prop->type()) { - if (type != prop->typeLua()) - LERROR("Property '" << uri << "' does not accept input of type '" - << luaTypeToString(type) << "'. Requested type: '" - << luaTypeToString(prop->typeLua()) << "'"); - else - prop->setLua(L); - //prop->set(propertyValue); - - return 0; -} - -int property_getValue(lua_State* L) { - const std::string _loggerCat = "property_getValue"; - - // TODO Check for argument number (ab) - std::string uri = luaL_checkstring(L, -1); - - Property* prop = property(uri); - if (!prop) { - LERROR("Property with uri '" << uri << "' could not be found"); - lua_pushnil(L); - } - else { - prop->getLua(L); - - //switch (type) { - // case LUA_TNONE: - // case LUA_TLIGHTUSERDATA: - // case LUA_TFUNCTION: - // case LUA_TUSERDATA: - // case LUA_TTHREAD: - // LERROR("Function parameter was of type '" << luaTypeToString(type) - // << "'"); - // return 0; - // case LUA_TNIL: - // propertyValue = 0; - // break; - // case LUA_TBOOLEAN: - // propertyValue = lua_toboolean(L, -1); - // break; - // case LUA_TNUMBER: - // propertyValue = lua_tonumber(L, -1); - // break; - // case LUA_TSTRING: - // propertyValue = std::string(lua_tostring(L, -1)); - // break; - // case LUA_TTABLE: { - // ghoul::Dictionary d; - // ghoul::lua::populateDictionary(L, d); - // propertyValue = d; - // break; - // } - //} -} - return 1; -} - -} // namespace scripting -} // namespace openspace From c48b35a7ce6ade04cf95c1a7fa868638e60f6e35 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 14 Sep 2014 18:37:30 +0200 Subject: [PATCH 092/113] Added Doxygen configuration file --- .gitignore | 1 - Doxyfile | 452 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 Doxyfile diff --git a/.gitignore b/.gitignore index eb0db62a4f..ce9b9d5a70 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,3 @@ install_manifest.txt # Doxygen stuff html/ latex/ -Doxyfile diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000000..df1e74bf65 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,452 @@ +# Doxyfile 1.7.6.1 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = OpenSpace +PROJECT_NUMBER = +PROJECT_LOGO = +OUTPUT_DIRECTORY = doc/ +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = YES +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = +BUILTIN_STL_SUPPORT = NO + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = YES +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 1 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = YES +SHOW_INCLUDE_FILES = YES +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = NO +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = YES +SORT_MEMBERS_CTORS_1ST = YES +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = NO +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = NO +SHOW_FILES = NO +SHOW_NAMESPACES = YES +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +QUIET = YES +WARNINGS = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = YES +WARN_FORMAT = "$file:$line: $text" + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +INPUT = src \ + include + +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.cpp \ + *.h \ + *.inl + +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = /ext/* bin/* build/* config/* gui/* kernels/* openspace-data/* scripts/* shaders/* +EXCLUDE_SYMBOLS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 4 +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = doxygen/header.html +HTML_FOOTER = doxygen/footer.html +HTML_STYLESHEET = doxygen/stylesheet.css +#HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 200 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = NO +HTML_DYNAMIC_SECTIONS = NO +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = +DOCSET_BUNDLE_ID = +DOCSET_PUBLISHER_ID = +DOCSET_PUBLISHER_NAME = +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = YES +GENERATE_TREEVIEW = YES +ENUM_VALUES_PER_LINE = 6 +TREEVIEW_WIDTH = 300 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_RELPATH = http://www.mathjax.org/mathjax +MATHJAX_EXTENSIONS = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = YES +SKIP_FUNCTION_MACROS = NO + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES From d8c41c7d4f62c3eb3ac463ef45505fff01578475 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 14 Sep 2014 23:35:14 +0200 Subject: [PATCH 093/113] Remove warnings and errors in Jenkin's gcc --- include/openspace/properties/templateproperty.inl | 6 +++--- include/openspace/tests/test_spicemanager.inl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index c957c30e81..ba99d6fde6 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -183,7 +183,7 @@ template bool TemplateProperty::setLua(lua_State* state) { bool success; - T value = PropertyDelegate>::fromLuaValue(state, success); + T value = PropertyDelegate>::fromLuaValue(state, success); if (success) set(value); return success; @@ -192,13 +192,13 @@ bool TemplateProperty::setLua(lua_State* state) template bool TemplateProperty::getLua(lua_State* state) const { - bool success = PropertyDelegate>::toLuaValue(state, _value); + bool success = PropertyDelegate>::toLuaValue(state, _value); return success; } template int TemplateProperty::typeLua() const { - return PropertyDelegate>::typeLua(); + return PropertyDelegate>::typeLua(); } } // namespace properties diff --git a/include/openspace/tests/test_spicemanager.inl b/include/openspace/tests/test_spicemanager.inl index e46e72d2a5..bcb656480a 100644 --- a/include/openspace/tests/test_spicemanager.inl +++ b/include/openspace/tests/test_spicemanager.inl @@ -223,7 +223,7 @@ TEST_F(SpiceManagerTest, stringToEphemerisTime){ double ephemerisTime; double control_ephemerisTime; - char *date = "Thu Mar 20 12:53:29 PST 1997"; + char date[SRCLEN] = "Thu Mar 20 12:53:29 PST 1997"; str2et_c(date, &control_ephemerisTime); ephemerisTime = openspace::SpiceManager::ref().stringToEphemerisTime(date); From 1f7f4016ae4b560b5ddd974b9ebad087b36fb1df Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 14 Sep 2014 23:40:48 +0200 Subject: [PATCH 094/113] More compile fixes for Jenkins --- include/openspace/properties/numericalproperty.inl | 4 ++-- include/openspace/properties/templateproperty.inl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/openspace/properties/numericalproperty.inl b/include/openspace/properties/numericalproperty.inl index e46ca0f0ec..11f116cb53 100644 --- a/include/openspace/properties/numericalproperty.inl +++ b/include/openspace/properties/numericalproperty.inl @@ -181,7 +181,7 @@ template bool NumericalProperty::setLua(lua_State* state) { bool success; - T value = PropertyDelegate>::fromLuaValue(state, success); + T value = PropertyDelegate>::template fromLuaValue(state, success); if (success) set(value); return success; @@ -190,7 +190,7 @@ bool NumericalProperty::setLua(lua_State* state) template bool NumericalProperty::getLua(lua_State* state) const { - bool success = PropertyDelegate>::toLuaValue(state, TemplateProperty::_value); + bool success = PropertyDelegate>::template toLuaValue(state, TemplateProperty::_value); return success; } diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index ba99d6fde6..d2c333abcd 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -183,7 +183,7 @@ template bool TemplateProperty::setLua(lua_State* state) { bool success; - T value = PropertyDelegate>::fromLuaValue(state, success); + T value = PropertyDelegate>::template fromLuaValue(state, success); if (success) set(value); return success; @@ -192,13 +192,13 @@ bool TemplateProperty::setLua(lua_State* state) template bool TemplateProperty::getLua(lua_State* state) const { - bool success = PropertyDelegate>::toLuaValue(state, _value); + bool success = PropertyDelegate>::template toLuaValue(state, _value); return success; } template int TemplateProperty::typeLua() const { - return PropertyDelegate>::typeLua(); + return PropertyDelegate>::typeLua(); } } // namespace properties From b30de7726eb0e41c47354da83835ef602db7db37 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 14 Sep 2014 23:46:02 +0200 Subject: [PATCH 095/113] More compile fixes for Jenkins --- include/openspace/properties/numericalproperty.inl | 2 +- include/openspace/tests/test_luaconversions.inl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/openspace/properties/numericalproperty.inl b/include/openspace/properties/numericalproperty.inl index 11f116cb53..233688320a 100644 --- a/include/openspace/properties/numericalproperty.inl +++ b/include/openspace/properties/numericalproperty.inl @@ -183,7 +183,7 @@ bool NumericalProperty::setLua(lua_State* state) bool success; T value = PropertyDelegate>::template fromLuaValue(state, success); if (success) - set(value); + setValue(value); return success; } diff --git a/include/openspace/tests/test_luaconversions.inl b/include/openspace/tests/test_luaconversions.inl index e58f314593..53cbd368f5 100644 --- a/include/openspace/tests/test_luaconversions.inl +++ b/include/openspace/tests/test_luaconversions.inl @@ -64,7 +64,7 @@ TEST_F(LuaConversionTest, LuaExecution) { = PropertyDelegate>::toLuaValue<__TYPE__>( \ state, __VALUE__); \ EXPECT_TRUE(success) << "toLuaValue"; \ - __TYPE__ value = __TYPE__(0); \ + __TYPE__ value = (__TYPE__)(0); \ value = PropertyDelegate>::fromLuaValue<__TYPE__>( \ state, success); \ EXPECT_TRUE(success) << "fromLuaValue"; \ @@ -79,7 +79,7 @@ TEST_F(LuaConversionTest, LuaExecution) { = PropertyDelegate>::toLuaValue<__TYPE__>( \ state, __VALUE__); \ EXPECT_TRUE(success) << "toLuaValue"; \ - __TYPE__ value = __TYPE__(0); \ + __TYPE__ value = (__TYPE__)(0); \ value = PropertyDelegate>::fromLuaValue<__TYPE__>( \ state, success); \ EXPECT_TRUE(success) << "fromLuaValue"; \ From 50494cffdd9c96907ef37c606ac9cca9365fe6a1 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 14 Sep 2014 23:49:38 +0200 Subject: [PATCH 096/113] More compile fixes for Jenkins --- include/openspace/properties/numericalproperty.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/openspace/properties/numericalproperty.inl b/include/openspace/properties/numericalproperty.inl index 233688320a..30ee9ea0d3 100644 --- a/include/openspace/properties/numericalproperty.inl +++ b/include/openspace/properties/numericalproperty.inl @@ -183,7 +183,7 @@ bool NumericalProperty::setLua(lua_State* state) bool success; T value = PropertyDelegate>::template fromLuaValue(state, success); if (success) - setValue(value); + TemplateProperty::setValue(value); return success; } From 3ae37d099187f85232df1cb1791e26c743ce7e84 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 14 Sep 2014 23:53:41 +0200 Subject: [PATCH 097/113] More compile fixes for Jenkins --- src/util/spicemanager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 9ab3bb44ed..85a599525b 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -21,9 +21,11 @@ * 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 #ifdef WIN32 #include From 7f8b7950af90834314a1117a66c7fd47af59c2ad Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 15 Sep 2014 17:59:06 +0200 Subject: [PATCH 098/113] Deliberately break to check email from Jenkins --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index d4b5d26af7..89aa3490f3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,7 +116,7 @@ int main(int argc, char** argv) delete _sgctEngine; // Exit program - exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS);s } void mainExternalControlCallback(const char* receivedChars, int size, int clientId) From c7c7fa44133127ac1d98bc498a5339cf9056c2be Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 15 Sep 2014 18:02:57 +0200 Subject: [PATCH 099/113] Fix the build again --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 89aa3490f3..d4b5d26af7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,7 +116,7 @@ int main(int argc, char** argv) delete _sgctEngine; // Exit program - exit(EXIT_SUCCESS);s + exit(EXIT_SUCCESS); } void mainExternalControlCallback(const char* receivedChars, int size, int clientId) From 954b2d07e9d53fa8256546beab2f775ef5038f7e Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 15 Sep 2014 18:31:27 +0200 Subject: [PATCH 100/113] A change to check the build system --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index d4b5d26af7..b5ca354f46 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,7 +116,7 @@ int main(int argc, char** argv) delete _sgctEngine; // Exit program - exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); } void mainExternalControlCallback(const char* receivedChars, int size, int clientId) From 8e1135cf274574fa503891907f5d49a3d464d866 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 15 Sep 2014 18:32:22 +0200 Subject: [PATCH 101/113] Update post-receive hook --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index b5ca354f46..d4b5d26af7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,7 +116,7 @@ int main(int argc, char** argv) delete _sgctEngine; // Exit program - exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); } void mainExternalControlCallback(const char* receivedChars, int size, int clientId) From 03e25f69d59e59d77e0b45bb0622a73ee05c4903 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 15 Sep 2014 18:52:43 +0200 Subject: [PATCH 102/113] Update post-receive hook --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index d4b5d26af7..b5ca354f46 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,7 +116,7 @@ int main(int argc, char** argv) delete _sgctEngine; // Exit program - exit(EXIT_SUCCESS); + exit(EXIT_SUCCESS); } void mainExternalControlCallback(const char* receivedChars, int size, int clientId) From 8ec9bc6705bfafff63783ab4b6ae41755aa7c1b1 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 17 Sep 2014 01:10:52 +0200 Subject: [PATCH 103/113] Cleaned up main.cpp Added functionality to send Lua scripts over the network --- include/openspace/engine/openspaceengine.h | 1 + src/engine/openspaceengine.cpp | 20 ++++++++++++ src/main.cpp | 38 +++++++++------------- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index c3c3c0022e..80ea8a7626 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -89,6 +89,7 @@ public: void mouseButtonCallback(int key, int action); void mousePositionCallback(int x, int y); void mouseScrollWheelCallback(int pos); + void externalControlCallback(const char* receivedChars, int size, int clientId); void encode(); void decode(); diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 7bf0f04ceb..b1571563fe 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -585,4 +585,24 @@ void OpenSpaceEngine::decode() #endif } +void OpenSpaceEngine::externalControlCallback(const char* receivedChars, + int size, int clientId) +{ + if (size == 0) + return; + + // The first byte determines the type of message + const char type = receivedChars[0]; + switch (type) { + case '0': // LuaScript + { + std::string script = std::string(receivedChars + 1); + LINFO("Received Lua Script: '" << script << "'"); + _scriptEngine->runScript(script); + } + } + + +} + } // namespace openspace diff --git a/src/main.cpp b/src/main.cpp index b5ca354f46..0808327683 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,20 +24,18 @@ // open space includes #include -#include // sgct includes #include sgct::Engine* _sgctEngine; -openspace::Interface* _interface; // function pointer declarations -void mainInitFunc(void); -void mainPreSyncFunc(void); -void mainPostSyncPreDrawFunc(void); -void mainRenderFunc(void); -void mainPostDrawFunc(void); +void mainInitFunc(); +void mainPreSyncFunc(); +void mainPostSyncPreDrawFunc(); +void mainRenderFunc(); +void mainPostDrawFunc(); void mainKeyboardCallback(int key, int action); void mainMouseButtonCallback(int key, int action); void mainMousePosCallback(double x, double y); @@ -89,10 +87,6 @@ int main(int argc, char** argv) sgct::SharedData::instance()->setEncodeFunction(mainEncodeFun); sgct::SharedData::instance()->setDecodeFunction(mainDecodeFun); - // init the interface which will handle callbacks from an external gui - LDEBUG("Creating Interface module"); - _interface = new openspace::Interface(&OsEng); - // try to open a window LDEBUG("Initialize SGCT Engine"); const bool initSuccess = _sgctEngine->init(sgct::Engine::OpenGL_4_0_Core_Profile); @@ -119,38 +113,38 @@ int main(int argc, char** argv) exit(EXIT_SUCCESS); } -void mainExternalControlCallback(const char* receivedChars, int size, int clientId) -{ - if (_sgctEngine->isMaster()) - _interface->callback(receivedChars); -} - -void mainInitFunc(void) +void mainInitFunc() { OsEng.initialize(); OsEng.initializeGL(); } -void mainPreSyncFunc(void) +void mainPreSyncFunc() { OsEng.preSynchronization(); } -void mainPostSyncPreDrawFunc(void) +void mainPostSyncPreDrawFunc() { OsEng.postSynchronizationPreDraw(); } -void mainRenderFunc(void) +void mainRenderFunc() { OsEng.render(); } -void mainPostDrawFunc(void) +void mainPostDrawFunc() { OsEng.postDraw(); } +void mainExternalControlCallback(const char* receivedChars, int size, int clientId) +{ + if (_sgctEngine->isMaster()) + OsEng.externalControlCallback(receivedChars, size, clientId); +} + void mainKeyboardCallback(int key, int action) { if (_sgctEngine->isMaster()) From 7fd3519d10eb63e16b120a8da30b6e52c2ad8514 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 17 Sep 2014 01:11:12 +0200 Subject: [PATCH 104/113] Make the single.xml SGCT file allow external commands --- config/sgct/single.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/sgct/single.xml b/config/sgct/single.xml index eec3b163c1..404e26df2b 100644 --- a/config/sgct/single.xml +++ b/config/sgct/single.xml @@ -1,5 +1,5 @@ - + From 448aa97ce6fe99c109add250d3b819677cc04230 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 17 Sep 2014 01:11:39 +0200 Subject: [PATCH 105/113] Removed old GUI application and added new version --- CMakeLists.txt | 2 + gui/CMakeLists.txt | 7 +- gui/luascriptexternalcontrol/CMakeLists.txt | 22 ++++ gui/luascriptexternalcontrol/main.cpp | 35 +++++++ gui/luascriptexternalcontrol/mainwindow.cpp | 103 ++++++++++++++++++ gui/luascriptexternalcontrol/mainwindow.h | 67 ++++++++++++ gui/src/CMakeLists.txt | 20 ---- gui/src/main.cpp | 12 --- gui/src/mainwindow.cpp | 109 -------------------- gui/src/mainwindow.h | 33 ------ gui/src/mainwindow.ui | 102 ------------------ 11 files changed, 230 insertions(+), 282 deletions(-) create mode 100644 gui/luascriptexternalcontrol/CMakeLists.txt create mode 100644 gui/luascriptexternalcontrol/main.cpp create mode 100644 gui/luascriptexternalcontrol/mainwindow.cpp create mode 100644 gui/luascriptexternalcontrol/mainwindow.h delete mode 100644 gui/src/CMakeLists.txt delete mode 100644 gui/src/main.cpp delete mode 100644 gui/src/mainwindow.cpp delete mode 100644 gui/src/mainwindow.h delete mode 100644 gui/src/mainwindow.ui diff --git a/CMakeLists.txt b/CMakeLists.txt index 3bb7d3ed56..2b247e5159 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,3 +122,5 @@ endif () ######################################################################################### add_subdirectory(src) + +add_subdirectory(gui) \ No newline at end of file diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 7feae25029..e33b8eb266 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -1,8 +1,3 @@ cmake_minimum_required(VERSION 2.8.11) -project(GUI) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${GUI_SOURCE_DIR}/build-debug) - -set(CMAKE_BUILD_TYPE Debug) - -add_subdirectory(src) \ No newline at end of file +add_subdirectory(luascriptexternalcontrol) \ No newline at end of file diff --git a/gui/luascriptexternalcontrol/CMakeLists.txt b/gui/luascriptexternalcontrol/CMakeLists.txt new file mode 100644 index 0000000000..44d82b517d --- /dev/null +++ b/gui/luascriptexternalcontrol/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 2.8.11) + +project(LuascriptExternalControl) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +#set(QT_PATH_OPTION "C:/Qt/5.1.0/5.1.0/msvc2012_64_opengl/lib" CACHE PATH "Path to Qt folder") +#set(QT_PATH_OPTION "C:\\Qt\\Qt5\\5.3\\msvc2013_64_opengl\\lib\\cmake\\Qt5Widgets") +#option(QT_PATH_OPTION "Path to the Qt5 folder" "C:/Qt/5.1.0/5.1.0/msvc2012_64_opengl/lib") +#message("Option: ${QT_PATH_OPTION}") + +#set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH} ${QT_PATH_OPTION}") + +#set(CMAKE_PREFIX_PATH $ENV{QTDIR}) + +#message("Prefix: ${CMAKE_PREFIX_PATH}") + +set(CMAKE_AUTOMOC ON) +find_package(Qt5Widgets) +find_package(Qt5Network) +add_executable(LuascriptExternalControl WIN32 main.cpp mainwindow.cpp) +#qt5_use_modules(LuascriptExternalControl, Widgets) +target_link_libraries(LuascriptExternalControl Qt5::Widgets Qt5::Network) \ No newline at end of file diff --git a/gui/luascriptexternalcontrol/main.cpp b/gui/luascriptexternalcontrol/main.cpp new file mode 100644 index 0000000000..59eb5baf55 --- /dev/null +++ b/gui/luascriptexternalcontrol/main.cpp @@ -0,0 +1,35 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include "mainwindow.h" + +int main(int argc, char** argv) { + QApplication app(argc, argv); + + MainWidget window; + window.show(); + + return app.exec(); +} diff --git a/gui/luascriptexternalcontrol/mainwindow.cpp b/gui/luascriptexternalcontrol/mainwindow.cpp new file mode 100644 index 0000000000..31fb8b31da --- /dev/null +++ b/gui/luascriptexternalcontrol/mainwindow.cpp @@ -0,0 +1,103 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "mainwindow.h" + +#include +#include +#include + +MainWidget::MainWidget() + : _ipAddress(new QLineEdit) + , _command(new QLineEdit) + , _logWindow(new QTextEdit) + , _socket(nullptr) +{ + setWindowTitle("OpenSpace LuaScripting GUI"); + + QGridLayout* layout = new QGridLayout; + _ipAddress->setMinimumWidth(200); + _ipAddress->setText("127.0.0.1"); + layout->addWidget(_ipAddress, 0, 0); + + QPushButton* connectButton = new QPushButton("Connect"); + connect(connectButton, SIGNAL(clicked()), this, SLOT(onConnectButton())); + connectButton->show(); + layout->addWidget(connectButton, 0, 1); + + _command->setMinimumWidth(200); + layout->addWidget(_command, 1, 0); + + QPushButton* sendButton = new QPushButton("Send"); + sendButton->setDefault(true); + connect(sendButton, SIGNAL(clicked()), this, SLOT(sendCommandButton())); + layout->addWidget(sendButton, 1, 1); + + layout->addWidget(_logWindow, 2, 0, 1, 2); + + setLayout(layout); +} + +MainWidget::~MainWidget() { + delete _command; + delete _socket; +} + +void MainWidget::readTcpData() { + QByteArray data = _socket->readAll(); + + if (_logWindow->toPlainText().isEmpty()) + _logWindow->setText(data.data()); + else + _logWindow->setText(_logWindow->toPlainText() + "\n" + data.data()); +} + +void MainWidget::onConnectButton() { + delete _socket; + + _socket = new QTcpSocket(this); + connect( _socket, SIGNAL(readyRead()), SLOT(readTcpData()) ); + _socket->connectToHost(_ipAddress->text(), 20500); + +} + +void MainWidget::sendCommandButton() { + if (!_socket) { + if (_logWindow->toPlainText().isEmpty()) + _logWindow->setText("No connection found"); + else + _logWindow->setText(_logWindow->toPlainText() + "\n" + "No connection found"); + return; + } + + QString command = _command->text(); + + if (_logWindow->toPlainText().isEmpty()) + _logWindow->setText(command); + else + _logWindow->setText(_logWindow->toPlainText() + "\n" + command); + + + _socket->write(("0" + command + "\r\n").toLatin1()); +} diff --git a/gui/luascriptexternalcontrol/mainwindow.h b/gui/luascriptexternalcontrol/mainwindow.h new file mode 100644 index 0000000000..46f3a5892d --- /dev/null +++ b/gui/luascriptexternalcontrol/mainwindow.h @@ -0,0 +1,67 @@ +/***************************************************************************************** + * * + * 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 __MAINWINDOW_H__ +#define __MAINWINDOW_H__ + +#include +#include +#include +#include + +class MainWidget : public QWidget { +Q_OBJECT +public: + MainWidget(); + ~MainWidget(); + +private slots: + void onConnectButton(); + void sendCommandButton(); + void readTcpData(); + +private: + QLineEdit* _ipAddress; + QLineEdit* _command; + QTextEdit* _logWindow; + + QTcpSocket* _socket; + + +// +//private slots: +// void on__connectButton_clicked(); +// void on__statsCheckBox_toggled(bool checked); +// void readTcpData(); +// void on__graphCheckBox_toggled(bool checked); +// void on__renderComboBox_currentIndexChanged(const QString &arg1); +// +//private: +// qint64 sendToSGCT(QByteArray data); +// +// Ui::MainWindow *ui; +// QTcpSocket* _sgctSocket; +}; + +#endif // __MAINWINDOW_H__ diff --git a/gui/src/CMakeLists.txt b/gui/src/CMakeLists.txt deleted file mode 100644 index d145273478..0000000000 --- a/gui/src/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# FIXME: ugly hack for linking qt5 -set (CMAKE_PREFIX_PATH "/home/hhellteg/Qt/5.2.1/gcc_64") - -# Find includes in corresponding build directories -set(CMAKE_INCLUDE_CURRENT_DIR ON) -# Instruct CMake to run moc automatically when needed. -set(CMAKE_AUTOMOC ON) - -# Find the Qt libraries -find_package(Qt5Widgets) -find_package(Qt5Network) - -# Create ui_mainwindow.h file -qt5_wrap_ui(QT_UI_HEADERS mainwindow.ui) - -# Tell CMake to create the executable -add_executable(gui main.cpp mainwindow.cpp ${QT_UI_HEADERS}) - -# Use the needed modules from Qt 5. -target_link_libraries(gui Qt5::Widgets Qt5::Network) \ No newline at end of file diff --git a/gui/src/main.cpp b/gui/src/main.cpp deleted file mode 100644 index 1797005f1d..0000000000 --- a/gui/src/main.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "mainwindow.h" -#include -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - MainWindow w; - w.show(); - - return a.exec(); -} diff --git a/gui/src/mainwindow.cpp b/gui/src/mainwindow.cpp deleted file mode 100644 index 39bc8b0eb4..0000000000 --- a/gui/src/mainwindow.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "mainwindow.h" -#include "ui_mainwindow.h" - -#include - -#include -#include -#include -#include - -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow), - _sgctSocket(NULL) { - ui->setupUi(this); - ui->_hostEdit->setText("127.0.0.1"); - setWindowTitle("OpenSpace Qt GUI"); - ui->_statsCheckBox->setEnabled(false); - ui->_graphCheckBox->setEnabled(false); - ui->_renderComboBox->setEnabled(false); - -// TEST JSON -// QJsonObject json, jsonObj2; -// QJsonArray jsonArr, jsonArr2; -// json["Value 1"] = (QString("Herp")); -// json["Value 2"] = (QString("Derp")); -// jsonArr.push_back(QString("val1")); -// jsonArr.push_back(QString("val2")); -// jsonArr.push_back(QString("val3")); -// jsonArr.push_back(QString("val4")); -// jsonArr.push_back(QString("val5")); -// jsonArr2.push_back(QString("val21")); -// jsonArr2.push_back(QString("val22")); -// jsonArr2.push_back(QString("val23")); -// jsonArr2.push_back(QString("val24")); -// jsonArr2.push_back(QString("val25")); -// jsonObj2["ArrayYo2"] = jsonArr2; -// jsonArr.push_back(jsonObj2); -// json["ArrayYo"] = jsonArr; -// QJsonDocument doc; -// doc.setObject(json); -// std::cout << doc.toJson().data() << std::endl; -// quick_exit(0); -} - -MainWindow::~MainWindow() { - delete ui; -} - -void MainWindow::on__connectButton_clicked() { - _sgctSocket = new QTcpSocket(this); - connect( _sgctSocket, SIGNAL(readyRead()), SLOT(readTcpData()) ); - _sgctSocket->connectToHost(ui->_hostEdit->text(), 20500); - if (_sgctSocket->waitForConnected()) { - ui->_statsCheckBox->setEnabled(true); - ui->_graphCheckBox->setEnabled(true); - ui->_renderComboBox->setEnabled(true); - } else { - std::cout << "Connection failed" << std::endl; - ui->_statsCheckBox->setEnabled(false); - ui->_graphCheckBox->setEnabled(false); - ui->_renderComboBox->setEnabled(false); - } -} - -void MainWindow::on__statsCheckBox_toggled(bool checked) { - QJsonObject json; - QJsonDocument doc; - if (checked) { - json["stats"] = 1; - } else { - json["stats"] = 0; - } - doc.setObject(json); - std::cout << "Bytes sent: " << sendToSGCT(doc.toJson()) << " " << std::flush; -} - -void MainWindow::on__graphCheckBox_toggled(bool checked) { - QJsonObject json; - QJsonDocument doc; - if (checked) { - json["graph"] = 1; - } else { - json["graph"] = 0; - } - doc.setObject(json); - std::cout << "Bytes sent: " << sendToSGCT(doc.toJson()) << " " << std::flush; -} - -void MainWindow::readTcpData() { - QByteArray data = _sgctSocket->readAll(); - std::cout << data.data() << std::flush; -} - -void MainWindow::on__renderComboBox_currentIndexChanged(const QString &arg1){ - QJsonObject json; - QJsonDocument doc; - if (arg1.compare(QString("VolumeRaycaster")) == 0) { - json["renderer"] = QString("volumeraycaster"); - } else if (arg1.compare(QString("Flare")) == 0) { - json["renderer"] = QString("flare"); - } - doc.setObject(json); - std::cout << "Bytes sent: " << sendToSGCT(doc.toJson()) << " " << std::flush; -} - -qint64 MainWindow::sendToSGCT(QByteArray data) { - return _sgctSocket->write(data + "\r\n"); // "\r\n" seperates messages -} diff --git a/gui/src/mainwindow.h b/gui/src/mainwindow.h deleted file mode 100644 index c392d03b48..0000000000 --- a/gui/src/mainwindow.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include -#include - -namespace Ui { -class MainWindow; -} - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - explicit MainWindow(QWidget *parent = 0); - ~MainWindow(); - -private slots: - void on__connectButton_clicked(); - void on__statsCheckBox_toggled(bool checked); - void readTcpData(); - void on__graphCheckBox_toggled(bool checked); - void on__renderComboBox_currentIndexChanged(const QString &arg1); - -private: - qint64 sendToSGCT(QByteArray data); - - Ui::MainWindow *ui; - QTcpSocket* _sgctSocket; -}; - -#endif // MAINWINDOW_H diff --git a/gui/src/mainwindow.ui b/gui/src/mainwindow.ui deleted file mode 100644 index 986a7eb747..0000000000 --- a/gui/src/mainwindow.ui +++ /dev/null @@ -1,102 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 303 - 312 - - - - MainWindow - - - - - - - Graph - - - - - - - - VolumeRaycaster - - - - - Flare - - - - - - - - Connect - - - - - - - Stats - - - - - - - Debug info - - - - - - - Renderer - - - - - - - - - - Host - - - - - - - - - 0 - 0 - 303 - 20 - - - - - - TopToolBarArea - - - false - - - - - - - - From 27901c1629a2ad14689614c54c4d91142821bf29 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Wed, 17 Sep 2014 01:13:17 +0200 Subject: [PATCH 106/113] Make GUI creation optional --- CMakeLists.txt | 2 +- openspace.cfg | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b247e5159..4079e3ab15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,4 +123,4 @@ endif () add_subdirectory(src) -add_subdirectory(gui) \ No newline at end of file +#add_subdirectory(gui) \ No newline at end of file diff --git a/openspace.cfg b/openspace.cfg index 96a75211ea..a476eed479 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -6,8 +6,8 @@ return { SHADERS = "${BASE_PATH}/shaders", OPENSPACE_DATA = "${BASE_PATH}/openspace-data", TESTDIR = "${BASE_PATH}/src/tests", - -- SCENEPATH = "${OPENSPACE_DATA}/scene", - SCENEPATH = "${OPENSPACE_DATA}/ABufferVolumes", + SCENEPATH = "${OPENSPACE_DATA}/scene", + -- SCENEPATH = "${OPENSPACE_DATA}/ABufferVolumes", CONFIG = "${BASE_PATH}/config" }, SGCTConfig = "${SGCT}/single.xml", From 0fbdbb8dabb8e4969649b51455af31f27712fc38 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 18 Sep 2014 08:46:46 +0200 Subject: [PATCH 107/113] Fix a bug in TemplateProperty preventing new bool values to be set Add "isEnabled" flag BoolProperty to all renderables --- gui/luascriptexternalcontrol/CMakeLists.txt | 12 ------------ include/openspace/properties/templateproperty.h | 12 +++++++++++- include/openspace/properties/templateproperty.inl | 15 ++++++++++----- include/openspace/rendering/renderable.h | 10 ++++++++-- src/rendering/renderable.cpp | 9 +++++++-- src/scenegraph/scenegraph.cpp | 1 - src/scenegraph/scenegraphnode.cpp | 3 ++- 7 files changed, 38 insertions(+), 24 deletions(-) diff --git a/gui/luascriptexternalcontrol/CMakeLists.txt b/gui/luascriptexternalcontrol/CMakeLists.txt index 44d82b517d..b4ff6d4784 100644 --- a/gui/luascriptexternalcontrol/CMakeLists.txt +++ b/gui/luascriptexternalcontrol/CMakeLists.txt @@ -3,20 +3,8 @@ cmake_minimum_required(VERSION 2.8.11) project(LuascriptExternalControl) set(CMAKE_INCLUDE_CURRENT_DIR ON) -#set(QT_PATH_OPTION "C:/Qt/5.1.0/5.1.0/msvc2012_64_opengl/lib" CACHE PATH "Path to Qt folder") -#set(QT_PATH_OPTION "C:\\Qt\\Qt5\\5.3\\msvc2013_64_opengl\\lib\\cmake\\Qt5Widgets") -#option(QT_PATH_OPTION "Path to the Qt5 folder" "C:/Qt/5.1.0/5.1.0/msvc2012_64_opengl/lib") -#message("Option: ${QT_PATH_OPTION}") - -#set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH} ${QT_PATH_OPTION}") - -#set(CMAKE_PREFIX_PATH $ENV{QTDIR}) - -#message("Prefix: ${CMAKE_PREFIX_PATH}") - set(CMAKE_AUTOMOC ON) find_package(Qt5Widgets) find_package(Qt5Network) add_executable(LuascriptExternalControl WIN32 main.cpp mainwindow.cpp) -#qt5_use_modules(LuascriptExternalControl, Widgets) target_link_libraries(LuascriptExternalControl Qt5::Widgets Qt5::Network) \ No newline at end of file diff --git a/include/openspace/properties/templateproperty.h b/include/openspace/properties/templateproperty.h index 494eb46e9e..f2e511ab15 100644 --- a/include/openspace/properties/templateproperty.h +++ b/include/openspace/properties/templateproperty.h @@ -130,13 +130,23 @@ public: * was of the type T. It makes assignments such as * T v = property; possible by allowing implicit casts (even though, * internally, not casts are performed. This method is next to zero overhead). + * \return The internal representation of the Property */ operator T(); + /** + * This operator allows the TemplateProperty to be used almost transparently as if it + * was of the type T. It makes assignments such as + * T v = property; possible by allowing implicit casts (even though, + * internally, not casts are performed. This method is next to zero overhead). + * \return The internal representation of the Property + */ + operator T() const; + /** * The assignment operator allows the TemplateProperty's value to be set without using * the TemplateProperty::set method. It will be done internally by thos method and it - * allows assigments such as prop = T(1). + * allows assignments such as prop = T(1). * \param val The value that should be set. */ TemplateProperty& operator=(T val); diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index d2c333abcd..5459d644ef 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -131,6 +131,11 @@ TemplateProperty::operator T() { return _value; } +template +TemplateProperty::operator T() const { + return _value; +} + template TemplateProperty& TemplateProperty::operator=(T val) { setValue(val); @@ -162,9 +167,9 @@ boost::any TemplateProperty::get() const { template void TemplateProperty::set(boost::any value) { try { - T value = boost::any_cast(std::move(value)); - if (value != _value) { - _value = std::move(value); + T v = boost::any_cast(std::move(value)); + if (v != _value) { + _value = std::move(v); notifyListener(); } } @@ -183,9 +188,9 @@ template bool TemplateProperty::setLua(lua_State* state) { bool success; - T value = PropertyDelegate>::template fromLuaValue(state, success); + T thisValue = PropertyDelegate>::template fromLuaValue(state, success); if (success) - set(value); + set(boost::any(thisValue)); return success; } diff --git a/include/openspace/rendering/renderable.h b/include/openspace/rendering/renderable.h index a1959f72aa..91c001e5d7 100644 --- a/include/openspace/rendering/renderable.h +++ b/include/openspace/rendering/renderable.h @@ -25,12 +25,13 @@ #ifndef __RENDERABLE_H__ #define __RENDERABLE_H__ -// open space includes +#include + +#include #include #include #include #include -#include namespace openspace { @@ -51,9 +52,14 @@ public: virtual void render(const Camera* camera, const psc& thisPosition) = 0; virtual void update(); + bool isVisible() const; + protected: std::string findPath(const std::string& path); + private: + properties::BoolProperty _enabled; + PowerScaledScalar boundingSphere_; std::string _relativePath; }; diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index f62e26be7a..a81a6b1b33 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -59,9 +59,8 @@ Renderable* Renderable::createFromDictionary(const ghoul::Dictionary& dictionary } Renderable::Renderable(const ghoul::Dictionary& dictionary) + : _enabled("enabled", "Is Enabled", true) { -// std::string name; -// dictionary.getValue(constants::scenegraphnode::keyName, name); setName("renderable"); // get path if available @@ -70,6 +69,8 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary) dictionary.getValue(constants::scenegraph::keyPathModule, _relativePath); _relativePath += "/"; } + + addProperty(_enabled); } Renderable::~Renderable() @@ -104,4 +105,8 @@ std::string Renderable::findPath(const std::string& path) { return ""; } +bool Renderable::isVisible() const { + return _enabled; +} + } // namespace openspace diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index a6ac8cf10e..750b32f94b 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -110,7 +110,6 @@ int property_setValue(lua_State* L) { return 0; } - //if (propertyValue.type() != prop->type()) { if (type != prop->typeLua()) LERROR("Property '" << uri << "' does not accept input of type '" << luaTypeToString(type) << "'. Requested type: '" diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 5e349c782c..f033942988 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -269,7 +269,8 @@ void SceneGraphNode::render(const Camera* camera, const psc& parentPosition) if (!_boundingSphereVisible) { return; } - if (_renderableVisible && _renderableToggle) { + + if (_renderableVisible && _renderableToggle && _renderable->isVisible()) { // LDEBUG("Render"); _renderable->render(camera, thisPosition); } From 80b73f99100d9ba274f4abf8684380b2b523a9e4 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 18 Sep 2014 17:28:50 +0200 Subject: [PATCH 108/113] Fix for rendering volumes --- src/rendering/renderablevolumegl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index 9e4bca99a0..ce6480c8e8 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -98,6 +98,8 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): if(dictionary.hasKey("BoxScaling.4") && dictionary.getValue("BoxScaling.4", tempValue)) { _w = tempValue; } + else + _w = 0.0; _volumeName = ""; if (dictionary.hasKey("VolumeName")) From bd850d56f5ddceb5adce5d058b72c287ce6f4802 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 18 Sep 2014 20:39:30 +0200 Subject: [PATCH 109/113] Remove renderableToggle as it has been replaced with a property --- include/openspace/scenegraph/scenegraphnode.h | 1 - src/scenegraph/scenegraphnode.cpp | 49 +------------------ 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/include/openspace/scenegraph/scenegraphnode.h b/include/openspace/scenegraph/scenegraphnode.h index 0123e45dad..a7cf2089b7 100644 --- a/include/openspace/scenegraph/scenegraphnode.h +++ b/include/openspace/scenegraph/scenegraphnode.h @@ -91,7 +91,6 @@ private: // renderable Renderable* _renderable; bool _renderableVisible; - bool _renderableToggle; // bounding sphere bool _boundingSphereVisible; diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index f033942988..4c203b8e36 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -86,52 +86,6 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di LDEBUG("Successfully create renderable for '" << result->name() << "'"); } - if (dictionary.hasKey("RenderableToggle")) { - std::string val = ""; - dictionary.getValue("RenderableToggle", val); - - if(val.length() > 0) { - auto func = [result]() { - result->_renderableToggle = ! result->_renderableToggle; - }; - int key = SGCT_KEY_UNKNOWN; - - if(val.length() == 1) { - char c = std::toupper(val[0]); - key = static_cast(c); - } else if (boost::iequals(val, "left")) { - key = SGCT_KEY_LEFT; - } else if (boost::iequals(val, "right")) { - key = SGCT_KEY_RIGHT; - } else if (boost::iequals(val, "up")) { - key = SGCT_KEY_UP; - } else if (boost::iequals(val, "down")) { - key = SGCT_KEY_DOWN; - } else if (boost::iequals(val, "space")) { - key = SGCT_KEY_SPACE; - } else if (boost::iequals(val, "enter")) { - key = SGCT_KEY_ENTER; - } else if (boost::iequals(val, "backspace")) { - key = SGCT_KEY_BACKSPACE; - } else if (boost::iequals(val, "del")) { - key = SGCT_KEY_DEL; - } else if (boost::iequals(val, "delete")) { - key = SGCT_KEY_DELETE; - } else { - // Loop through all F keys - for(int i = 0; i < 25; ++i) { - std::string stringKey = "F" + std::to_string(i+1); - if(boost::iequals(val, stringKey)) { - key = SGCT_KEY_F1 + i; - } - } - } - - if(key != SGCT_KEY_UNKNOWN) - OsEng.interactionHandler().addKeyCallback(key, func); - } - } - if (dictionary.hasKey(keyEphemeris)) { ghoul::Dictionary ephemerisDictionary; dictionary.getValue(keyEphemeris, ephemerisDictionary); @@ -171,7 +125,6 @@ SceneGraphNode::SceneGraphNode() , _ephemeris(new StaticEphemeris) , _renderable(nullptr) , _renderableVisible(false) - , _renderableToggle(true) , _boundingSphereVisible(false) { } @@ -270,7 +223,7 @@ void SceneGraphNode::render(const Camera* camera, const psc& parentPosition) return; } - if (_renderableVisible && _renderableToggle && _renderable->isVisible()) { + if (_renderableVisible && _renderable->isVisible()) { // LDEBUG("Render"); _renderable->render(camera, thisPosition); } From 51be4b1788650b753c8474a4f8f261dfe46ead9b Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 19 Sep 2014 00:29:36 +0200 Subject: [PATCH 110/113] Make use of new Dictionary::getValueSafe method Clean up code in various places --- ext/ghoul | 2 +- src/engine/openspaceengine.cpp | 67 +++++---- src/properties/property.cpp | 14 +- src/rendering/planets/planetgeometry.cpp | 17 +-- src/rendering/planets/renderableplanet.cpp | 16 ++- .../planets/simplespheregeometry.cpp | 49 ++++--- src/rendering/renderable.cpp | 21 +-- src/rendering/renderablefieldlines.cpp | 127 +++++++++++------- src/scenegraph/scenegraphnode.cpp | 2 + 9 files changed, 172 insertions(+), 143 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 7906906863..d0cc759daa 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 79069068634b5a582d7fed49eb857dcc490471d3 +Subproject commit d0cc759daaedbd199b91aad5ce398b58f2084557 diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index b1571563fe..6d0a9d518c 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -160,7 +160,6 @@ bool OpenSpaceEngine::registerBasePathFromConfigurationFile(const std::string& f bool OpenSpaceEngine::findConfiguration(std::string& filename) { - //return FileSys.fileExists(filename); std::string currentDirectory = FileSys.absolutePath(FileSys.currentDirectory()); size_t occurrences = std::count(currentDirectory.begin(), currentDirectory.end(), ghoul::filesystem::FileSystem::PathSeparator); @@ -249,13 +248,10 @@ bool OpenSpaceEngine::create(int argc, char** argv, LDEBUG("Loading configuration from disk"); ghoul::Dictionary& configuration = _engine->configurationManager(); ghoul::lua::loadDictionaryFromFile(configurationFilePath, configuration); - const bool hasKey = configuration.hasKey(constants::openspaceengine::keyPaths); - const bool hasValue = configuration.hasValue(constants::openspaceengine::keyPaths); - if (hasKey && hasValue) { - ghoul::Dictionary pathsDictionary; - configuration.getValue(constants::openspaceengine::keyPaths, pathsDictionary); + ghoul::Dictionary pathsDictionary; + const bool success = configuration.getValueSafe(constants::openspaceengine::keyPaths, pathsDictionary); + if (success) OpenSpaceEngine::registerPathsFromDictionary(pathsDictionary); - } else { LFATAL("Configuration file does not contain paths token '" << constants::openspaceengine::keyPaths << "'"); return false; @@ -264,10 +260,9 @@ bool OpenSpaceEngine::create(int argc, char** argv, // Determining SGCT configuration file LDEBUG("Determining SGCT configuration file"); - std::string sgctConfigurationPath = _sgctDefaultConfigFile; - if (configuration.hasKey(constants::openspaceengine::keyConfigSgct)) - configuration.getValue(constants::openspaceengine::keyConfigSgct, sgctConfigurationPath); - + std::string sgctConfigurationPath = _sgctDefaultConfigFile; + configuration.getValueSafe(constants::openspaceengine::keyConfigSgct, + sgctConfigurationPath); // Prepend the outgoing sgctArguments with the program name // as well as the configuration file that sgct is supposed to use @@ -296,8 +291,8 @@ bool OpenSpaceEngine::initialize() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLFWwindow* win = sgct::Engine::instance()->getActiveWindowPtr()->getWindowHandle(); glfwSwapBuffers(win); - int samples = sqrt(sgct::Engine::instance()->getActiveWindowPtr()->getNumberOfAASamples()); - LDEBUG("samples: " << samples); + //int samples = sqrt(sgct::Engine::instance()->getActiveWindowPtr()->getNumberOfAASamples()); + //LDEBUG("samples: " << samples); int x1, xSize, y1, ySize; sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize); @@ -323,11 +318,8 @@ bool OpenSpaceEngine::initialize() SysCap.detectCapabilities(); SysCap.logCapabilities(); - std::string timeKernel = ""; - using constants::openspaceengine::keyConfigTimekernel; - if (OsEng.configurationManager().hasKeyAndValue(keyConfigTimekernel)) { - OsEng.configurationManager().getValue(keyConfigTimekernel, timeKernel); - } + std::string timeKernel; + OsEng.configurationManager().getValueSafe(constants::openspaceengine::keyConfigTimekernel, timeKernel); // initialize OpenSpace helpers SpiceManager::initialize(); @@ -347,25 +339,27 @@ bool OpenSpaceEngine::initialize() // Load scenegraph SceneGraph* sceneGraph = new SceneGraph; _renderEngine->setSceneGraph(sceneGraph); - if (!OsEng.configurationManager().hasValue( - constants::openspaceengine::keyConfigScene)) { - LFATAL("Configuration needs to point to the scene file"); + + std::string sceneDescriptionPath; + bool success = OsEng.configurationManager().getValueSafe( + constants::openspaceengine::keyConfigScene, sceneDescriptionPath); + if (!success) { + LFATAL("The configuration does not contain a scene file under key '" << + constants::openspaceengine::keyConfigScene << "'"); return false; } - std::string sceneDescriptionPath; - bool success = _configurationManager->getValue( - constants::openspaceengine::keyConfigScene, sceneDescriptionPath); - - if (!FileSys.fileExists(sceneDescriptionPath)) { - LFATAL("Could not find '" << sceneDescriptionPath << "'"); + if (!FileSys.fileExists(sceneDescriptionPath)) { + LFATAL("Could not find scene description '" << sceneDescriptionPath << "'"); return false; } std::string scenePath; - success = _configurationManager->getValue(constants::openspaceengine::keyPathScene, scenePath); + success = _configurationManager->getValueSafe( + constants::openspaceengine::keyPathScene, scenePath); if (!success) { - LFATAL("Could not find SCENEPATH key in configuration file"); + LFATAL("Could not find key '" << constants::openspaceengine::keyPathScene << + "' in configuration file '" << sceneDescriptionPath << "'"); return false; } @@ -385,13 +379,12 @@ bool OpenSpaceEngine::initialize() _engine->_interactionHandler->connectDevices(); // Run start up scripts - using ghoul::Dictionary; - using constants::openspaceengine::keyStartupScript; - const bool hasScript = _engine->configurationManager().hasKeyAndValue(keyStartupScript); - if (hasScript) { - Dictionary scripts; - _engine->configurationManager().getValue(keyStartupScript, scripts); - + //using ghoul::Dictionary; + //using constants::openspaceengine::keyStartupScript; + ghoul::Dictionary scripts; + success = _engine->configurationManager().getValueSafe( + constants::openspaceengine::keyStartupScript, scripts); + if (success) { for (size_t i = 0; i < scripts.size(); ++i) { std::stringstream stream; // Dictionary-size is 0-based; script numbers are 1-based @@ -405,7 +398,7 @@ bool OpenSpaceEngine::initialize() std::string scriptPath; scripts.getValue(key, scriptPath); - const std::string absoluteScriptPath = absPath(scriptPath); + std::string&& absoluteScriptPath = absPath(scriptPath); _engine->scriptEngine().runScriptFile(absoluteScriptPath); } } diff --git a/src/properties/property.cpp b/src/properties/property.cpp index b225be2861..0b5004a281 100644 --- a/src/properties/property.cpp +++ b/src/properties/property.cpp @@ -30,6 +30,7 @@ namespace openspace { namespace properties { namespace { + const std::string _loggerCat = "Property"; const std::string _metaDataKeyGuiName = "guiName"; const std::string _metaDataKeyGroup = "group"; const std::string _metaDataKeyVisible = "isVisible"; @@ -47,6 +48,11 @@ const std::string Property::ViewOptions::PowerScaledScalar = "powerScaledScalar" Property::Property(std::string identifier, std::string guiName) : _identifier(std::move(identifier)) { + if (_identifier.empty()) + LWARNING("Property identifier is empty"); + if (guiName.empty()) + LWARNING("Property GUI name is empty"); + setVisible(true); _metaData.setValue(_metaDataKeyGuiName, std::move(guiName)); } @@ -80,8 +86,8 @@ int Property::typeLua() const { } const std::string& Property::guiName() const { - std::string result = ""; - _metaData.getValue(_metaDataKeyGuiName, result); + std::string result; + _metaData.getValueSafe(_metaDataKeyGuiName, result); return std::move(result); } @@ -90,8 +96,8 @@ void Property::setGroupIdentifier(std::string groupId) { } std::string Property::groupIdentifier() const { - std::string result = ""; - _metaData.getValue(_metaDataKeyGroup, result); + std::string result; + _metaData.getValueSafe(_metaDataKeyGroup, result); return std::move(result); } diff --git a/src/rendering/planets/planetgeometry.cpp b/src/rendering/planets/planetgeometry.cpp index ca6e361414..547984a8fe 100644 --- a/src/rendering/planets/planetgeometry.cpp +++ b/src/rendering/planets/planetgeometry.cpp @@ -36,17 +36,14 @@ namespace planetgeometry { PlanetGeometry* PlanetGeometry::createFromDictionary(const ghoul::Dictionary& dictionary) { - std::string name; - dictionary.getValue(constants::scenegraphnode::keyName, name); - - if (!dictionary.hasValue(constants::planetgeometry::keyType)) { - LERROR("PlanetGeometry for '" << name << "' did not contain a '" - << constants::planetgeometry::keyType << "' key"); + std::string geometryType; + const bool success = dictionary.getValueSafe( + constants::planetgeometry::keyType, geometryType); + if (!success) { + LERROR("PlanetGeometry did not contain a correct value of the key '" + << constants::planetgeometry::keyType << "'"); return nullptr; - } - std::string geometryType; - dictionary.getValue(constants::planetgeometry::keyType, geometryType); - + } ghoul::TemplateFactory* factory = FactoryManager::ref().factory(); diff --git a/src/rendering/planets/renderableplanet.cpp b/src/rendering/planets/renderableplanet.cpp index f6dd119ab2..4f0700a763 100644 --- a/src/rendering/planets/renderableplanet.cpp +++ b/src/rendering/planets/renderableplanet.cpp @@ -47,18 +47,22 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) , _texture(nullptr) , _geometry(nullptr) { + std::string name; + bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); + assert(success); + std::string path; dictionary.getValue(constants::scenegraph::keyPathModule, path); - if (dictionary.hasKey(constants::renderableplanet::keyGeometry)) { - ghoul::Dictionary geometryDictionary; - dictionary.getValue(constants::renderableplanet::keyGeometry, geometryDictionary); + ghoul::Dictionary geometryDictionary; + success = dictionary.getValueSafe( + constants::renderableplanet::keyGeometry, geometryDictionary); + if (success) { + geometryDictionary.setValue(constants::scenegraphnode::keyName, name); geometryDictionary.setValue(constants::scenegraph::keyPathModule, path); - geometryDictionary.setValue(constants::scenegraphnode::keyName, name()); - _geometry = planetgeometry::PlanetGeometry::createFromDictionary(geometryDictionary); - } + } // TODO: textures need to be replaced by a good system similar to the geometry as soon // as the requirements are fixed (ab) diff --git a/src/rendering/planets/simplespheregeometry.cpp b/src/rendering/planets/simplespheregeometry.cpp index 5c544d49fd..e016f37f4c 100644 --- a/src/rendering/planets/simplespheregeometry.cpp +++ b/src/rendering/planets/simplespheregeometry.cpp @@ -47,38 +47,37 @@ SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary) , _segments("segments", "Segments", 20, 1, 1000) , _planet(nullptr) { - if (!dictionary.hasValue(constants::simplespheregeometry::keyRadius)) { - std::string name; - dictionary.getValue(constants::scenegraphnode::keyName, name); - LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '" - << constants::simplespheregeometry::keyRadius - << "'"); - } - else { - glm::vec2 radius; - dictionary.getValue(constants::simplespheregeometry::keyRadius, radius); - _radius = radius; - } + using constants::scenegraphnode::keyName; + using constants::simplespheregeometry::keyRadius; + using constants::simplespheregeometry::keySegments; - if (!dictionary.hasValue(constants::simplespheregeometry::keySegments)) { - std::string name; - dictionary.getValue(constants::scenegraphnode::keyName, name); + // The name is passed down from the SceneGraphNode + std::string name; + bool success = dictionary.getValue(keyName, name); + assert(success); + + glm::vec2 radius; + success = dictionary.getValueSafe(keyRadius, radius); + if (!success) { LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '" - << constants::simplespheregeometry::keySegments - << "'"); - } - else { - float segments; - dictionary.getValue(constants::simplespheregeometry::keySegments, segments); - _segments = static_cast(segments); - } + << keyRadius << "'"); + } + else + _radius = radius; + + int segments; + success = dictionary.getValueSafe(keySegments, segments); + if (!success) { + LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '" + << keySegments << "'"); + } + else + _segments = segments; addProperty(_radius); _radius.onChange(std::bind(&SimpleSphereGeometry::createSphere, this)); addProperty(_segments); _segments.onChange(std::bind(&SimpleSphereGeometry::createSphere, this)); - - //createSphere(); } SimpleSphereGeometry::~SimpleSphereGeometry() diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index a81a6b1b33..7c497be81c 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -37,16 +37,19 @@ namespace openspace { Renderable* Renderable::createFromDictionary(const ghoul::Dictionary& dictionary) { + // The name is passed down from the SceneGraphNode std::string name; - dictionary.getValue(constants::scenegraphnode::keyName, name); + bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); + assert(success); - if (!dictionary.hasValue(constants::renderable::keyType)) { + std::string renderableType; + success = dictionary.getValueSafe(constants::renderable::keyType, renderableType); + if (!success) { LERROR("Renderable '" << name << "' did not have key '" << constants::renderable::keyType << "'"); return nullptr; - } - std::string renderableType; - dictionary.getValue(constants::renderable::keyType, renderableType); + } + ghoul::TemplateFactory* factory = FactoryManager::ref().factory(); Renderable* result = factory->create(renderableType, dictionary); @@ -64,11 +67,9 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary) setName("renderable"); // get path if available - _relativePath = ""; - if(dictionary.hasKey(constants::scenegraph::keyPathModule)) { - dictionary.getValue(constants::scenegraph::keyPathModule, _relativePath); - _relativePath += "/"; - } + const bool success = dictionary.getValueSafe(constants::scenegraph::keyPathModule, _relativePath); + if (success) + _relativePath += ghoul::filesystem::FileSystem::PathSeparator; addProperty(_enabled); } diff --git a/src/rendering/renderablefieldlines.cpp b/src/rendering/renderablefieldlines.cpp index c750ddcd9a..1817400413 100644 --- a/src/rendering/renderablefieldlines.cpp +++ b/src/rendering/renderablefieldlines.cpp @@ -27,70 +27,97 @@ #include #include +#include + namespace { - std::string _loggerCat = "RenderableFieldlines"; + const std::string _loggerCat = "RenderableFieldlines"; + + 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) { +RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) + , _VAO(0) + , _programUpdateOnSave(false) + , _update(false) +{ + std::string name; + bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); + assert(success); - if(dictionary.hasKey("Fieldlines")) { - ghoul::Dictionary fieldlines; - if(dictionary.getValue("Fieldlines", fieldlines)) { - for(auto key: fieldlines.keys()) { - ghoul::Dictionary fieldline; - if(fieldlines.getValue(key, fieldline)) { - if (fieldline.hasKey("File")) { - std::string file = ""; - if (fieldline.getValue("File", file)) { - file = findPath(file); - if (file != "") { + ghoul::Dictionary fieldlines; + success = dictionary.getValueSafe(keyFieldlines, fieldlines); + if (!success) { + LERROR("RenderableFieldlines '" << name << "' did not contain a '" << + keyFieldlines << "' key"); + return; + } + for (const std::string& key : fieldlines.keys()) { + ghoul::Dictionary fieldline; + success = fieldlines.getValueSafe(key, fieldline); - // read hints into dictionary - ghoul::Dictionary hintsDictionary; - if(fieldline.hasKey("Hints")) - fieldline.getValue("Hints", hintsDictionary); + if (!success) { + LERROR("Key '" << key << "' in '" << keyFieldlines << + "' of the RenderableFieldlines '" << name << + "' does not have a table as value"); + continue; + } - _filenames.push_back(file); - _hintsDictionaries.push_back(hintsDictionary); - } else - LERROR("File not found!"); - } - } - } - } + std::string fileName; + fieldline.getValueSafe(keyFilename, fileName); + fileName = findPath(fileName); + if (fileName.empty()) + LERROR("File not found!"); + else { + ghoul::Dictionary hintsDictionary; + fieldline.getValueSafe(keyHints, hintsDictionary); + + _filenames.push_back(fileName); + _hintsDictionaries.push_back(hintsDictionary); } } - std::string vshaderpath = ""; - std::string fshaderpath = ""; - - if (dictionary.hasKey("Shaders")) { - ghoul::Dictionary shaderDictionary; - if(dictionary.getValue("Shaders", shaderDictionary)) { - if (shaderDictionary.hasKey("VertexShader")) - shaderDictionary.getValue("VertexShader", vshaderpath); - - if (shaderDictionary.hasKey("FragmentShader")) - shaderDictionary.getValue("FragmentShader", fshaderpath); - - vshaderpath = findPath(vshaderpath); - fshaderpath = findPath(fshaderpath); - - _vertexSourceFile = new ghoul::filesystem::File(vshaderpath, false); - _fragmentSourceFile = new ghoul::filesystem::File(fshaderpath, false); - - - ShaderCreator sc = OsEng.shaderBuilder(); - _fieldlinesProgram = sc.buildShader("FieldlinesProgram", vshaderpath, fshaderpath); - } + ghoul::Dictionary shaderDictionary; + success = dictionary.getValueSafe(keyShaders, shaderDictionary); + if (!success) { + LERROR("RenderableFieldlines '" << name << "' does not contain a '" << + keyShaders << "' table"); + return; } - if(dictionary.hasKey("UpdateOnSave")) { - dictionary.getValue("UpdateOnSave", _programUpdateOnSave); + std::string vshaderpath; + success = shaderDictionary.getValueSafe(keyVertexShader, vshaderpath); + if (!success) { + LERROR("RenderableFieldlines '" << name << "' does not have a '" << + keyVertexShader << "'"); + return; } + vshaderpath = findPath(vshaderpath); + + std::string fshaderpath; + success = shaderDictionary.getValueSafe(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); + + + ShaderCreator sc = OsEng.shaderBuilder(); + _fieldlinesProgram = sc.buildShader("FieldlinesProgram", vshaderpath, fshaderpath); + + dictionary.getValueSafe("UpdateOnSave", _programUpdateOnSave); setBoundingSphere(PowerScaledScalar::CreatePSS(5)); // FIXME a non-magic number perhaps } diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 4c203b8e36..b096b8a1eb 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -74,6 +74,8 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di if (dictionary.hasValue(keyRenderable)) { ghoul::Dictionary renderableDictionary; dictionary.getValue(keyRenderable, renderableDictionary); + + renderableDictionary.setValue(keyName, name); renderableDictionary.setValue(keyPathModule, path); result->_renderable = Renderable::createFromDictionary(renderableDictionary); From dd629db53d4a65a024c4c8cd742062d002f30f10 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 19 Sep 2014 17:44:33 +0200 Subject: [PATCH 111/113] More code cleanup, force inclusion of swizzling for GLM --- CMakeLists.txt | 1 + .../openspace/rendering/renderablevolumecl.h | 211 ++-- .../rendering/renderablevolumeexpert.h | 237 ++-- .../openspace/rendering/renderablevolumegl.h | 2 - include/openspace/util/constants.h | 10 + src/rendering/planets/renderableplanet.cpp | 8 +- src/rendering/renderablevolumecl.cpp | 803 ++++++------- src/rendering/renderablevolumeexpert.cpp | 1067 +++++++++-------- src/rendering/renderablevolumegl.cpp | 121 +- src/scripting/scriptengine.cpp | 4 +- src/util/factorymanager.cpp | 5 - 11 files changed, 1241 insertions(+), 1228 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4079e3ab15..ff62ae9684 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,7 @@ set(DEPENDENT_LIBS ${DEPENDENT_LIBS} ${SGCT_LIBRARIES}) # GLM set(GLM_ROOT_DIR "${GHOUL_ROOT_DIR}/ext/glm") find_package(GLM REQUIRED) +add_definitions(-DGLM_SWIZZLE) include_directories(${GLM_INCLUDE_DIRS}) # GLEW diff --git a/include/openspace/rendering/renderablevolumecl.h b/include/openspace/rendering/renderablevolumecl.h index cb7ab38790..43d5ad71a0 100644 --- a/include/openspace/rendering/renderablevolumecl.h +++ b/include/openspace/rendering/renderablevolumecl.h @@ -1,105 +1,106 @@ -/***************************************************************************************** - * * - * 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 __RENDERABLEVOLUMECL_H__ -#define __RENDERABLEVOLUMECL_H__ - -// open space includes -#include - -// ghoul includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SGCT_WINDOWS_INCLUDE -#include - -namespace sgct_utils { - class SGCTBox; -} - -//#include -//#include -#ifdef __APPLE__ - #include -#else - #include -#endif - -namespace openspace { - -class RenderableVolumeCL: public RenderableVolume { -public: - - // constructors & destructor - RenderableVolumeCL(const ghoul::Dictionary& dictionary); - ~RenderableVolumeCL(); - - bool initialize(); - bool deinitialize(); - - virtual void render(const Camera *camera, const psc& thisPosition); - virtual void update(); - -private: - - void safeKernelCompilation(); - - std::string _filename; - ghoul::RawVolumeReader::ReadHints _hints; - float _stepSize; - ghoul::opengl::FramebufferObject* _fbo; - ghoul::opengl::Texture* _backTexture; - ghoul::opengl::Texture* _frontTexture; - ghoul::opengl::Texture* _volume; - ghoul::opengl::Texture* _output; - ghoul::opengl::ProgramObject *_fboProgram; - ghoul::opengl::ProgramObject *_quadProgram; - sgct_utils::SGCTBox* _boundingBox; - GLuint _screenQuad; - - ghoul::opencl::CLContext _context; - ghoul::opencl::CLCommandQueue _commands; - ghoul::opencl::CLProgram _program; - ghoul::opencl::CLKernel _kernel; - ghoul::opencl::CLWorkSize* _ws; - cl_mem _clBackTexture, _clFrontTexture, _clVolume, _clOutput; - - ghoul::filesystem::File* _kernelSourceFile; - bool _kernelUpdateOnSave; - std::mutex* _kernelMutex; - -}; - -} // namespace openspace - -#endif \ No newline at end of file +// This is still in the repository to be cannibalized for a possible rewrite (ab) +///***************************************************************************************** +// * * +// * 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 __RENDERABLEVOLUMECL_H__ +//#define __RENDERABLEVOLUMECL_H__ +// +//// open space includes +//#include +// +//// ghoul includes +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +// +//#define SGCT_WINDOWS_INCLUDE +//#include +// +//namespace sgct_utils { +// class SGCTBox; +//} +// +////#include +////#include +//#ifdef __APPLE__ +// #include +//#else +// #include +//#endif +// +//namespace openspace { +// +//class RenderableVolumeCL: public RenderableVolume { +//public: +// +// // constructors & destructor +// RenderableVolumeCL(const ghoul::Dictionary& dictionary); +// ~RenderableVolumeCL(); +// +// bool initialize(); +// bool deinitialize(); +// +// virtual void render(const Camera *camera, const psc& thisPosition); +// virtual void update(); +// +//private: +// +// void safeKernelCompilation(); +// +// std::string _filename; +// ghoul::RawVolumeReader::ReadHints _hints; +// float _stepSize; +// ghoul::opengl::FramebufferObject* _fbo; +// ghoul::opengl::Texture* _backTexture; +// ghoul::opengl::Texture* _frontTexture; +// ghoul::opengl::Texture* _volume; +// ghoul::opengl::Texture* _output; +// ghoul::opengl::ProgramObject *_fboProgram; +// ghoul::opengl::ProgramObject *_quadProgram; +// sgct_utils::SGCTBox* _boundingBox; +// GLuint _screenQuad; +// +// ghoul::opencl::CLContext _context; +// ghoul::opencl::CLCommandQueue _commands; +// ghoul::opencl::CLProgram _program; +// ghoul::opencl::CLKernel _kernel; +// ghoul::opencl::CLWorkSize* _ws; +// cl_mem _clBackTexture, _clFrontTexture, _clVolume, _clOutput; +// +// ghoul::filesystem::File* _kernelSourceFile; +// bool _kernelUpdateOnSave; +// std::mutex* _kernelMutex; +// +//}; +// +//} // namespace openspace +// +//#endif \ No newline at end of file diff --git a/include/openspace/rendering/renderablevolumeexpert.h b/include/openspace/rendering/renderablevolumeexpert.h index 5d445a8abb..90f50ccbbd 100644 --- a/include/openspace/rendering/renderablevolumeexpert.h +++ b/include/openspace/rendering/renderablevolumeexpert.h @@ -1,118 +1,119 @@ -/***************************************************************************************** - * * - * 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 __RENDERABLEVOLUMEEXPERT_H__ -#define __RENDERABLEVOLUMEEXPERT_H__ - -// open space includes -#include -#include - -// ghoul includes -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __APPLE__ - #include -#else - #include -#endif - -namespace ghoul { - namespace opencl { - class CLWorkSize; - } -} - -namespace openspace { - -class RenderableVolumeExpert: public RenderableVolume { -public: - - // constructors & destructor - RenderableVolumeExpert(const ghoul::Dictionary& dictionary); - ~RenderableVolumeExpert(); - - bool initialize(); - bool deinitialize(); - - virtual void render(const Camera *camera, const psc& thisPosition); - virtual void update(); - -private: - - // private methods - void safeKernelCompilation(); - void safeUpdateTexture(const ghoul::filesystem::File& file); - - // Volumes - std::vector _volumePaths; - std::vector _volumeHints; - - // Textures - ghoul::opengl::Texture* _output; - std::vector _volumes; - std::vector _transferFunctions; - std::vector _transferFunctionsFiles; - - // opencl texture memory pointers - cl_mem _clBackTexture; - cl_mem _clFrontTexture; - cl_mem _clOutput; - std::vector _clVolumes; - std::vector _clTransferFunctions; - - // opencl program - ghoul::opencl::CLContext _context; - ghoul::opencl::CLCommandQueue _commands; - ghoul::opencl::CLProgram _program; - ghoul::opencl::CLKernel _kernel; - ghoul::opencl::CLWorkSize* _ws; - ghoul::filesystem::File* _kernelSourceFile; - std::vector > _kernelOptions; - std::vector _kernelIncludes; - std::vector > _kernelDefinitions; - bool _programUpdateOnSave; - - // mutexes to prevent inconsistencies - std::mutex* _kernelLock; - std::mutex* _textureLock; - - ghoul::opengl::ProgramObject *_quadProgram; - GLuint _screenQuad; - - VolumeRaycasterBox* _colorBoxRenderer; - glm::vec3 _boxScaling; - -}; - -} // namespace openspace - -#endif \ No newline at end of file +// This is still in the repository to be cannibalized for a possible rewrite (ab) +///***************************************************************************************** +// * * +// * 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 __RENDERABLEVOLUMEEXPERT_H__ +//#define __RENDERABLEVOLUMEEXPERT_H__ +// +//// open space includes +//#include +//#include +// +//// ghoul includes +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +// +//#ifdef __APPLE__ +// #include +//#else +// #include +//#endif +// +//namespace ghoul { +// namespace opencl { +// class CLWorkSize; +// } +//} +// +//namespace openspace { +// +//class RenderableVolumeExpert: public RenderableVolume { +//public: +// +// // constructors & destructor +// RenderableVolumeExpert(const ghoul::Dictionary& dictionary); +// ~RenderableVolumeExpert(); +// +// bool initialize(); +// bool deinitialize(); +// +// virtual void render(const Camera *camera, const psc& thisPosition); +// virtual void update(); +// +//private: +// +// // private methods +// void safeKernelCompilation(); +// void safeUpdateTexture(const ghoul::filesystem::File& file); +// +// // Volumes +// std::vector _volumePaths; +// std::vector _volumeHints; +// +// // Textures +// ghoul::opengl::Texture* _output; +// std::vector _volumes; +// std::vector _transferFunctions; +// std::vector _transferFunctionsFiles; +// +// // opencl texture memory pointers +// cl_mem _clBackTexture; +// cl_mem _clFrontTexture; +// cl_mem _clOutput; +// std::vector _clVolumes; +// std::vector _clTransferFunctions; +// +// // opencl program +// ghoul::opencl::CLContext _context; +// ghoul::opencl::CLCommandQueue _commands; +// ghoul::opencl::CLProgram _program; +// ghoul::opencl::CLKernel _kernel; +// ghoul::opencl::CLWorkSize* _ws; +// ghoul::filesystem::File* _kernelSourceFile; +// std::vector > _kernelOptions; +// std::vector _kernelIncludes; +// std::vector > _kernelDefinitions; +// bool _programUpdateOnSave; +// +// // mutexes to prevent inconsistencies +// std::mutex* _kernelLock; +// std::mutex* _textureLock; +// +// ghoul::opengl::ProgramObject *_quadProgram; +// GLuint _screenQuad; +// +// VolumeRaycasterBox* _colorBoxRenderer; +// glm::vec3 _boxScaling; +// +//}; +// +//} // namespace openspace +// +//#endif \ No newline at end of file diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index dce4c1942b..4706078bfd 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -25,7 +25,6 @@ #ifndef __RENDERABLEVOLUMEGL_H__ #define __RENDERABLEVOLUMEGL_H__ -// open space includes #include // ghoul includes @@ -39,7 +38,6 @@ namespace openspace { class RenderableVolumeGL: public RenderableVolume { public: - // constructors & destructor RenderableVolumeGL(const ghoul::Dictionary& dictionary); ~RenderableVolumeGL(); diff --git a/include/openspace/util/constants.h b/include/openspace/util/constants.h index 6b16882f15..51ca026cc7 100644 --- a/include/openspace/util/constants.h +++ b/include/openspace/util/constants.h @@ -61,6 +61,16 @@ namespace renderableplanet { const std::string keyGeometry = "Geometry"; } // namespace renderableplanet +namespace renderablevolumegl { + const std::string keyVolume = "Volume"; + const std::string keyHints = "Hints"; + const std::string keyTransferFunction = "TransferFunction"; + const std::string keySampler = "Sampler"; + const std::string keyBoxScaling = "BoxScaling"; + const std::string keyVolumeName = "VolumeName"; + const std::string keyTransferFunctionName = "TransferFunctionName"; +} // namespace renderablevolumegl + namespace planetgeometry { const std::string keyType = "Type"; } // namespace planetgeometry diff --git a/src/rendering/planets/renderableplanet.cpp b/src/rendering/planets/renderableplanet.cpp index 4f0700a763..266963bbe0 100644 --- a/src/rendering/planets/renderableplanet.cpp +++ b/src/rendering/planets/renderableplanet.cpp @@ -52,7 +52,8 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) assert(success); std::string path; - dictionary.getValue(constants::scenegraph::keyPathModule, path); + success = dictionary.getValue(constants::scenegraph::keyPathModule, path); + assert(success); ghoul::Dictionary geometryDictionary; success = dictionary.getValueSafe( @@ -67,10 +68,9 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) // TODO: textures need to be replaced by a good system similar to the geometry as soon // as the requirements are fixed (ab) std::string texturePath = ""; - if (dictionary.hasKey("Textures.Color")) { - dictionary.getValue("Textures.Color", texturePath); + success = dictionary.getValueSafe("Textures.Color", texturePath); + if (success) _colorTexturePath = path + "/" + texturePath; - } addPropertySubOwner(_geometry); diff --git a/src/rendering/renderablevolumecl.cpp b/src/rendering/renderablevolumecl.cpp index b87c395705..380ea1f805 100644 --- a/src/rendering/renderablevolumecl.cpp +++ b/src/rendering/renderablevolumecl.cpp @@ -1,401 +1,402 @@ -/***************************************************************************************** - * * - * 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. * - ****************************************************************************************/ - -// open space includes -#include - -#include - -#include -#include - -#include - -#include - -namespace { - std::string _loggerCat = "RenderableVolumeCL"; -} - -namespace openspace { - -RenderableVolumeCL::RenderableVolumeCL(const ghoul::Dictionary& dictionary): - RenderableVolume(dictionary), - _backTexture(nullptr), _frontTexture(nullptr), _output(nullptr), - _clBackTexture(0), _clFrontTexture(0), _clOutput(0), - _kernelSourceFile(nullptr) { - - _kernelMutex = new std::mutex; - - _filename = ""; - if(dictionary.hasKey("Volume")) { - if(dictionary.getValue("Volume", _filename)) { - _filename = findPath(_filename); - } - } - ghoul::Dictionary hintsDictionary; - if(dictionary.hasKey("Hints")) - dictionary.getValue("Hints", hintsDictionary); - _hints = readHints(hintsDictionary); - - /* - if(dictionary.hasKey("TransferFunctions")) { - ghoul::Dictionary transferFunctions; - if(dictionary.getValue("TransferFunctions", transferFunctions)) { - auto keys = transferFunctions.keys(); - for(auto key: keys) { - std::string transferFunctionPath = ""; - if(transferFunctions.getValue(key, transferFunctionPath)) { - transferFunctionPath = findPath(transferFunctionPath); - if(transferFunctionPath != "") { - ghoul::filesystem::File* tmp = new ghoul::filesystem::File(transferFunctionPath, false); - ghoul::opengl::Texture* tmpTexture = ghoul::opengl::loadTexture(tmp->path()); - - _transferFunctions.push_back(tmpTexture); - _transferFunctionsFiles.push_back(tmp); - } - } - } - } - } - */ - - if(dictionary.hasKey("UpdateOnSave")) { - dictionary.getValue("UpdateOnSave", _kernelUpdateOnSave); - } - - /* - if(dictionary.hasKey("KernelOptions")) { - using namespace ghoul::opencl; - ghoul::Dictionary kernelOptions; - if(dictionary.getValue("KernelOptions", kernelOptions)) { - auto keys = kernelOptions.keys(); - for(auto key: keys) { - bool value = false; - if(kernelOptions.getValue(key, value)) { - if(key == "DenormsAreZero") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::DenormsAreZero, value)); - } else if(key == "FastRelaxedMath") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::FastRelaxedMath, value)); - } else if(key == "FiniteMathOnly") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::FiniteMathOnly, value)); - } else if(key == "KernelArgInfo") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::KernelArgInfo, value)); - } else if(key == "MadEnable") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::MadEnable, value)); - } else if(key == "NoSignedZero") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::NoSignedZero, value)); - } else if(key == "OptDisable") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::OptDisable, value)); - } else if(key == "SinglePrecisionConstant") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::SinglePrecisionConstant, value)); - } else if(key == "StrictAliasing") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::StrictAliasing, value)); - } else if(key == "UnsafeMathOptimizations") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::UnsafeMathOptimizations, value)); - } - } - } - } - } - */ - - std::string kernelPath = ""; - if (dictionary.hasKey("Kernel")) { - if(dictionary.getValue("Kernel", kernelPath)) { - kernelPath = findPath(kernelPath); - } - } - if (kernelPath != "") { - _kernelSourceFile = new ghoul::filesystem::File(kernelPath, false); - } - -} - -RenderableVolumeCL::~RenderableVolumeCL() { - deinitialize(); - delete _kernelMutex; -} - -bool RenderableVolumeCL::initialize() { - assert(_filename != ""); - // ------ VOLUME READING ---------------- - ghoul::RawVolumeReader rawReader(_hints); - _volume = rawReader.read(_filename); - glm::size3_t d = _volume->dimensions(); - - // ------ SETUP GEOMETRY ---------------- - const GLfloat size = 1.0f; - const GLfloat vertex_texcoord_data[] = { // square of two triangles (sigh) - // x y z s t - -size, -size, 0.0f, 0.0f, 0.0f, - size, size, 0.0f, 1.0f, 1.0f, - -size, size, 0.0f, 0.0f, 1.0f, - -size, -size, 0.0f, 0.0f, 0.0f, - size, -size, 0.0f, 1.0f, 0.0f, - size, size, 0.0f, 1.0f, 1.0f - }; - - GLuint vertexPositionBuffer; - glGenVertexArrays(1, &_screenQuad); // generate array - glBindVertexArray(_screenQuad); // bind array - glGenBuffers(1, &vertexPositionBuffer); // generate buffer - glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_texcoord_data), vertex_texcoord_data, GL_STATIC_DRAW); - - // Vertex positions - GLuint vertexLocation = 2; - glEnableVertexAttribArray(vertexLocation); - glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), reinterpret_cast(0)); - - // Texture coordinates - GLuint texcoordLocation = 0; - glEnableVertexAttribArray(texcoordLocation); - glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)(3*sizeof(GLfloat))); - - glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer - glBindVertexArray(0); //unbind array - - _boundingBox = new sgct_utils::SGCTBox(1.0f, sgct_utils::SGCTBox::Regular); - - // ------ SETUP SHADERS ----------------- - // TODO error control or better design pattern - OsEng.ref().configurationManager().getValue("RaycastProgram", _fboProgram); - OsEng.ref().configurationManager().getValue("Quad", _quadProgram); - - // ------ SETUP FBO --------------------- - _fbo = new ghoul::opengl::FramebufferObject(); - _fbo->activate(); - - size_t x = sgct::Engine::instance()->getActiveXResolution(); - size_t y = sgct::Engine::instance()->getActiveYResolution(); - _backTexture = new ghoul::opengl::Texture(glm::size3_t(x,y,1)); - _frontTexture = new ghoul::opengl::Texture(glm::size3_t(x,y,1)); - _output = new ghoul::opengl::Texture(glm::size3_t(x,y,1)); - _backTexture->uploadTexture(); - _frontTexture->uploadTexture(); - _output->uploadTexture(); - _fbo->attachTexture(_backTexture, GL_COLOR_ATTACHMENT0); - _fbo->attachTexture(_frontTexture, GL_COLOR_ATTACHMENT1); - - _fbo->deactivate(); - - _context = OsEng.clContext(); - _commands = _context.createCommandQueue(); - - _clBackTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *_backTexture); - _clFrontTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *_frontTexture); - _clVolume = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *_volume); - _clOutput = _context.createTextureFromGLTexture(CL_MEM_WRITE_ONLY, *_output); - - auto privateCallback = [this](const ghoul::filesystem::File& file) { - safeKernelCompilation(); - }; - - _kernelSourceFile = new ghoul::filesystem::File(_kernelSourceFile->path(), false); - if(_kernelUpdateOnSave) - _kernelSourceFile->setCallback(privateCallback); - - safeKernelCompilation(); - - size_t local_x = 32; - size_t local_y = 32; - while (local_x > 1) { - if(x % local_x == 0) - break; - local_x /= 2; - } - while (local_y > 1) { - if(y % local_y == 0) - break; - local_y /= 2; - } - _ws = new ghoul::opencl::CLWorkSize ({x,y}, {local_x,local_y}); - - return true; - -} - -bool RenderableVolumeCL::deinitialize() { - - delete _ws; - _ws = nullptr; - - return true; -} - -void RenderableVolumeCL::render(const Camera *camera, const psc &thisPosition) { - - if( ! _kernel.isValidKernel()) - return; - - float speed = 50.0f; - float time = sgct::Engine::getTime(); - glm::mat4 transform = camera->viewProjectionMatrix(); - - double factor = pow(10.0,thisPosition[3]); - transform = glm::translate(transform, glm::vec3(thisPosition[0]*factor, thisPosition[1]*factor, thisPosition[2]*factor)); - transform = glm::rotate(transform, time*speed, glm::vec3(0.0f, 1.0f, 0.0f)); - - - if(_kernel.isValidKernel()) { - _stepSize = 0.01f; - - // ------ DRAW TO FBO ------------------- - GLuint sgctFBO = ghoul::opengl::FramebufferObject::getActiveObject(); // Save SGCTs main FBO - _fbo->activate(); - _fboProgram->activate(); - _fboProgram->setUniform("modelViewProjection", transform); - - // Draw backface - glDrawBuffer(GL_COLOR_ATTACHMENT0); - glClearColor(0.2f, 0.2f, 0.2f, 0); - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - _boundingBox->draw(); - glDisable(GL_CULL_FACE); - - // Draw frontface - glDrawBuffer(GL_COLOR_ATTACHMENT1); - glClear(GL_COLOR_BUFFER_BIT); - glClearColor(0.2f, 0.2f, 0.2f, 0); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - _boundingBox->draw(); - glDisable(GL_CULL_FACE); - - _fboProgram->deactivate(); - _fbo->deactivate(); - - // ------ DRAW TO SCREEN ---------------- - glBindFramebuffer(GL_FRAMEBUFFER, sgctFBO); // Re-bind SGCTs main FBO - - - - glFinish(); - _commands.enqueueKernelBlocking(_kernel, *_ws); - _commands.finish(); - _quadProgram->activate(); - glActiveTexture(GL_TEXTURE0); - _output->bind(); - glClearColor(0.0f, 0.0f, 0.0f, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glBindVertexArray(_screenQuad); - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); - - _quadProgram->deactivate(); - - } - - - -} - -void RenderableVolumeCL::update() { - -} - -void RenderableVolumeCL::safeKernelCompilation() { - std::string _loggerCat = "RenderableVolumeCL::safeKernelCompilation"; - if(_context.isValidContext()) { - - ghoul::opencl::CLProgram tmpProgram = _context.createProgram(_kernelSourceFile->path()); - tmpProgram.setOption(ghoul::opencl::CLProgram::Option::OptDisable, true); - tmpProgram.setOption(ghoul::opencl::CLProgram::Option::KernelArgInfo, true); - if(tmpProgram.build()) { - ghoul::opencl::CLKernel tmpKernel = tmpProgram.createKernel("volumeraycaster"); - if(tmpKernel.isValidKernel()) { - tmpKernel.setArgument(0, &_clFrontTexture); - tmpKernel.setArgument(1, &_clBackTexture); - tmpKernel.setArgument(2, &_clVolume); - tmpKernel.setArgument(3, &_clOutput); - - // do the actual assignment behind locked doors - _kernelMutex->lock(); - _program = tmpProgram; - _kernel = tmpKernel; - _kernelMutex->unlock(); - - LDEBUG("Done updating kernel"); - } else { - LWARNING("Kernel is not valid"); - } - } else { - LWARNING("Could not build CLProgram"); - } - } else { - LWARNING("No valid CLContext"); - } -} - /* -void RenderableVolumeCL::safeUpdateTexture(const ghoul::filesystem::File& file) { - int fileID = 0; - for (fileID = 0; fileID < _transferFunctionsFiles.size(); ++fileID) { - if (_transferFunctionsFiles.at(fileID) == &file) { - //LDEBUG("Transferfunction found at id " << fileID); - break; - } - } - if(fileID == _transferFunctionsFiles.size()) - return; - - LDEBUG("Updating transferfunction"); - // create the new texture - ghoul::opengl::Texture* newTexture = ghoul::opengl::loadTexture(file.path()); - - if(newTexture) { - - // upload the new texture and create a cl memory - newTexture->uploadTexture(); - cl_mem clNewTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *newTexture); - - if(clNewTexture == 0) { - delete newTexture; - return; - } - - // everything is ok, critical point to replace current texture pointers - _textureLock->lock(); - - // deallocate current texture - delete _transferFunctions.at(fileID); - clReleaseMemObject(_clTransferFunctions.at(fileID)); - - // set the new texture - _transferFunctions.at(fileID) = newTexture; - _clTransferFunctions.at(fileID) = clNewTexture; - - // update kernel - // __kernel arguments(front, back, output, [_volumes], .. fileID)) - _kernel.setArgument(3 + _volumes.size() + fileID, &clNewTexture); - - // end of critical section - _textureLock->unlock(); - } -} -*/ - -} // namespace openspace \ No newline at end of file +// This is still in the repository to be cannibalized for a possible rewrite (ab) +///***************************************************************************************** +// * * +// * 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. * +// ****************************************************************************************/ +// +//// open space includes +//#include +// +//#include +// +//#include +//#include +// +//#include +// +//#include +// +//namespace { +// std::string _loggerCat = "RenderableVolumeCL"; +//} +// +//namespace openspace { +// +//RenderableVolumeCL::RenderableVolumeCL(const ghoul::Dictionary& dictionary): +// RenderableVolume(dictionary), +// _backTexture(nullptr), _frontTexture(nullptr), _output(nullptr), +// _clBackTexture(0), _clFrontTexture(0), _clOutput(0), +// _kernelSourceFile(nullptr) { +// +// _kernelMutex = new std::mutex; +// +// _filename = ""; +// if(dictionary.hasKey("Volume")) { +// if(dictionary.getValue("Volume", _filename)) { +// _filename = findPath(_filename); +// } +// } +// ghoul::Dictionary hintsDictionary; +// if(dictionary.hasKey("Hints")) +// dictionary.getValue("Hints", hintsDictionary); +// _hints = readHints(hintsDictionary); +// +// /* +// if(dictionary.hasKey("TransferFunctions")) { +// ghoul::Dictionary transferFunctions; +// if(dictionary.getValue("TransferFunctions", transferFunctions)) { +// auto keys = transferFunctions.keys(); +// for(auto key: keys) { +// std::string transferFunctionPath = ""; +// if(transferFunctions.getValue(key, transferFunctionPath)) { +// transferFunctionPath = findPath(transferFunctionPath); +// if(transferFunctionPath != "") { +// ghoul::filesystem::File* tmp = new ghoul::filesystem::File(transferFunctionPath, false); +// ghoul::opengl::Texture* tmpTexture = ghoul::opengl::loadTexture(tmp->path()); +// +// _transferFunctions.push_back(tmpTexture); +// _transferFunctionsFiles.push_back(tmp); +// } +// } +// } +// } +// } +// */ +// +// if(dictionary.hasKey("UpdateOnSave")) { +// dictionary.getValue("UpdateOnSave", _kernelUpdateOnSave); +// } +// +// /* +// if(dictionary.hasKey("KernelOptions")) { +// using namespace ghoul::opencl; +// ghoul::Dictionary kernelOptions; +// if(dictionary.getValue("KernelOptions", kernelOptions)) { +// auto keys = kernelOptions.keys(); +// for(auto key: keys) { +// bool value = false; +// if(kernelOptions.getValue(key, value)) { +// if(key == "DenormsAreZero") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::DenormsAreZero, value)); +// } else if(key == "FastRelaxedMath") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::FastRelaxedMath, value)); +// } else if(key == "FiniteMathOnly") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::FiniteMathOnly, value)); +// } else if(key == "KernelArgInfo") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::KernelArgInfo, value)); +// } else if(key == "MadEnable") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::MadEnable, value)); +// } else if(key == "NoSignedZero") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::NoSignedZero, value)); +// } else if(key == "OptDisable") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::OptDisable, value)); +// } else if(key == "SinglePrecisionConstant") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::SinglePrecisionConstant, value)); +// } else if(key == "StrictAliasing") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::StrictAliasing, value)); +// } else if(key == "UnsafeMathOptimizations") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::UnsafeMathOptimizations, value)); +// } +// } +// } +// } +// } +// */ +// +// std::string kernelPath = ""; +// if (dictionary.hasKey("Kernel")) { +// if(dictionary.getValue("Kernel", kernelPath)) { +// kernelPath = findPath(kernelPath); +// } +// } +// if (kernelPath != "") { +// _kernelSourceFile = new ghoul::filesystem::File(kernelPath, false); +// } +// +//} +// +//RenderableVolumeCL::~RenderableVolumeCL() { +// deinitialize(); +// delete _kernelMutex; +//} +// +//bool RenderableVolumeCL::initialize() { +// assert(_filename != ""); +// // ------ VOLUME READING ---------------- +// ghoul::RawVolumeReader rawReader(_hints); +// _volume = rawReader.read(_filename); +// glm::size3_t d = _volume->dimensions(); +// +// // ------ SETUP GEOMETRY ---------------- +// const GLfloat size = 1.0f; +// const GLfloat vertex_texcoord_data[] = { // square of two triangles (sigh) +// // x y z s t +// -size, -size, 0.0f, 0.0f, 0.0f, +// size, size, 0.0f, 1.0f, 1.0f, +// -size, size, 0.0f, 0.0f, 1.0f, +// -size, -size, 0.0f, 0.0f, 0.0f, +// size, -size, 0.0f, 1.0f, 0.0f, +// size, size, 0.0f, 1.0f, 1.0f +// }; +// +// GLuint vertexPositionBuffer; +// glGenVertexArrays(1, &_screenQuad); // generate array +// glBindVertexArray(_screenQuad); // bind array +// glGenBuffers(1, &vertexPositionBuffer); // generate buffer +// glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer +// glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_texcoord_data), vertex_texcoord_data, GL_STATIC_DRAW); +// +// // Vertex positions +// GLuint vertexLocation = 2; +// glEnableVertexAttribArray(vertexLocation); +// glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), reinterpret_cast(0)); +// +// // Texture coordinates +// GLuint texcoordLocation = 0; +// glEnableVertexAttribArray(texcoordLocation); +// glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)(3*sizeof(GLfloat))); +// +// glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer +// glBindVertexArray(0); //unbind array +// +// _boundingBox = new sgct_utils::SGCTBox(1.0f, sgct_utils::SGCTBox::Regular); +// +// // ------ SETUP SHADERS ----------------- +// // TODO error control or better design pattern +// OsEng.ref().configurationManager().getValue("RaycastProgram", _fboProgram); +// OsEng.ref().configurationManager().getValue("Quad", _quadProgram); +// +// // ------ SETUP FBO --------------------- +// _fbo = new ghoul::opengl::FramebufferObject(); +// _fbo->activate(); +// +// size_t x = sgct::Engine::instance()->getActiveXResolution(); +// size_t y = sgct::Engine::instance()->getActiveYResolution(); +// _backTexture = new ghoul::opengl::Texture(glm::size3_t(x,y,1)); +// _frontTexture = new ghoul::opengl::Texture(glm::size3_t(x,y,1)); +// _output = new ghoul::opengl::Texture(glm::size3_t(x,y,1)); +// _backTexture->uploadTexture(); +// _frontTexture->uploadTexture(); +// _output->uploadTexture(); +// _fbo->attachTexture(_backTexture, GL_COLOR_ATTACHMENT0); +// _fbo->attachTexture(_frontTexture, GL_COLOR_ATTACHMENT1); +// +// _fbo->deactivate(); +// +// _context = OsEng.clContext(); +// _commands = _context.createCommandQueue(); +// +// _clBackTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *_backTexture); +// _clFrontTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *_frontTexture); +// _clVolume = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *_volume); +// _clOutput = _context.createTextureFromGLTexture(CL_MEM_WRITE_ONLY, *_output); +// +// auto privateCallback = [this](const ghoul::filesystem::File& file) { +// safeKernelCompilation(); +// }; +// +// _kernelSourceFile = new ghoul::filesystem::File(_kernelSourceFile->path(), false); +// if(_kernelUpdateOnSave) +// _kernelSourceFile->setCallback(privateCallback); +// +// safeKernelCompilation(); +// +// size_t local_x = 32; +// size_t local_y = 32; +// while (local_x > 1) { +// if(x % local_x == 0) +// break; +// local_x /= 2; +// } +// while (local_y > 1) { +// if(y % local_y == 0) +// break; +// local_y /= 2; +// } +// _ws = new ghoul::opencl::CLWorkSize ({x,y}, {local_x,local_y}); +// +// return true; +// +//} +// +//bool RenderableVolumeCL::deinitialize() { +// +// delete _ws; +// _ws = nullptr; +// +// return true; +//} +// +//void RenderableVolumeCL::render(const Camera *camera, const psc &thisPosition) { +// +// if( ! _kernel.isValidKernel()) +// return; +// +// float speed = 50.0f; +// float time = sgct::Engine::getTime(); +// glm::mat4 transform = camera->viewProjectionMatrix(); +// +// double factor = pow(10.0,thisPosition[3]); +// transform = glm::translate(transform, glm::vec3(thisPosition[0]*factor, thisPosition[1]*factor, thisPosition[2]*factor)); +// transform = glm::rotate(transform, time*speed, glm::vec3(0.0f, 1.0f, 0.0f)); +// +// +// if(_kernel.isValidKernel()) { +// _stepSize = 0.01f; +// +// // ------ DRAW TO FBO ------------------- +// GLuint sgctFBO = ghoul::opengl::FramebufferObject::getActiveObject(); // Save SGCTs main FBO +// _fbo->activate(); +// _fboProgram->activate(); +// _fboProgram->setUniform("modelViewProjection", transform); +// +// // Draw backface +// glDrawBuffer(GL_COLOR_ATTACHMENT0); +// glClearColor(0.2f, 0.2f, 0.2f, 0); +// glClear(GL_COLOR_BUFFER_BIT); +// glEnable(GL_CULL_FACE); +// glCullFace(GL_FRONT); +// _boundingBox->draw(); +// glDisable(GL_CULL_FACE); +// +// // Draw frontface +// glDrawBuffer(GL_COLOR_ATTACHMENT1); +// glClear(GL_COLOR_BUFFER_BIT); +// glClearColor(0.2f, 0.2f, 0.2f, 0); +// glEnable(GL_CULL_FACE); +// glCullFace(GL_BACK); +// _boundingBox->draw(); +// glDisable(GL_CULL_FACE); +// +// _fboProgram->deactivate(); +// _fbo->deactivate(); +// +// // ------ DRAW TO SCREEN ---------------- +// glBindFramebuffer(GL_FRAMEBUFFER, sgctFBO); // Re-bind SGCTs main FBO +// +// +// +// glFinish(); +// _commands.enqueueKernelBlocking(_kernel, *_ws); +// _commands.finish(); +// _quadProgram->activate(); +// glActiveTexture(GL_TEXTURE0); +// _output->bind(); +// glClearColor(0.0f, 0.0f, 0.0f, 0); +// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +// glBindVertexArray(_screenQuad); +// glDrawArrays(GL_TRIANGLES, 0, 6); +// glBindVertexArray(0); +// +// _quadProgram->deactivate(); +// +// } +// +// +// +//} +// +//void RenderableVolumeCL::update() { +// +//} +// +//void RenderableVolumeCL::safeKernelCompilation() { +// std::string _loggerCat = "RenderableVolumeCL::safeKernelCompilation"; +// if(_context.isValidContext()) { +// +// ghoul::opencl::CLProgram tmpProgram = _context.createProgram(_kernelSourceFile->path()); +// tmpProgram.setOption(ghoul::opencl::CLProgram::Option::OptDisable, true); +// tmpProgram.setOption(ghoul::opencl::CLProgram::Option::KernelArgInfo, true); +// if(tmpProgram.build()) { +// ghoul::opencl::CLKernel tmpKernel = tmpProgram.createKernel("volumeraycaster"); +// if(tmpKernel.isValidKernel()) { +// tmpKernel.setArgument(0, &_clFrontTexture); +// tmpKernel.setArgument(1, &_clBackTexture); +// tmpKernel.setArgument(2, &_clVolume); +// tmpKernel.setArgument(3, &_clOutput); +// +// // do the actual assignment behind locked doors +// _kernelMutex->lock(); +// _program = tmpProgram; +// _kernel = tmpKernel; +// _kernelMutex->unlock(); +// +// LDEBUG("Done updating kernel"); +// } else { +// LWARNING("Kernel is not valid"); +// } +// } else { +// LWARNING("Could not build CLProgram"); +// } +// } else { +// LWARNING("No valid CLContext"); +// } +//} +// /* +//void RenderableVolumeCL::safeUpdateTexture(const ghoul::filesystem::File& file) { +// int fileID = 0; +// for (fileID = 0; fileID < _transferFunctionsFiles.size(); ++fileID) { +// if (_transferFunctionsFiles.at(fileID) == &file) { +// //LDEBUG("Transferfunction found at id " << fileID); +// break; +// } +// } +// if(fileID == _transferFunctionsFiles.size()) +// return; +// +// LDEBUG("Updating transferfunction"); +// // create the new texture +// ghoul::opengl::Texture* newTexture = ghoul::opengl::loadTexture(file.path()); +// +// if(newTexture) { +// +// // upload the new texture and create a cl memory +// newTexture->uploadTexture(); +// cl_mem clNewTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *newTexture); +// +// if(clNewTexture == 0) { +// delete newTexture; +// return; +// } +// +// // everything is ok, critical point to replace current texture pointers +// _textureLock->lock(); +// +// // deallocate current texture +// delete _transferFunctions.at(fileID); +// clReleaseMemObject(_clTransferFunctions.at(fileID)); +// +// // set the new texture +// _transferFunctions.at(fileID) = newTexture; +// _clTransferFunctions.at(fileID) = clNewTexture; +// +// // update kernel +// // __kernel arguments(front, back, output, [_volumes], .. fileID)) +// _kernel.setArgument(3 + _volumes.size() + fileID, &clNewTexture); +// +// // end of critical section +// _textureLock->unlock(); +// } +//} +//*/ +// +//} // namespace openspace \ No newline at end of file diff --git a/src/rendering/renderablevolumeexpert.cpp b/src/rendering/renderablevolumeexpert.cpp index d1d33c9e51..49b22aab65 100644 --- a/src/rendering/renderablevolumeexpert.cpp +++ b/src/rendering/renderablevolumeexpert.cpp @@ -1,533 +1,534 @@ -/***************************************************************************************** - * * - * 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. * - ****************************************************************************************/ - -// open space includes -#include - -#include - -#include -#include -#include -#include - -#include - -namespace { - std::string _loggerCat = "RenderableVolumeExpert"; - - size_t countKernelArguments(ghoul::opencl::CLKernel& kernel) { - - using ghoul::opencl::CLKernel; - CLKernel::AddressQualifier adq; - CLKernel::AccessQualifier acq; - CLKernel::TypeQualifier atq; - - size_t arguments = 0; - do { - adq = kernel.argumentAddressQualifier(arguments); - acq = kernel.argumentAccessQualifier(arguments); - atq = kernel.argumentTypeQualifier(arguments); - ++arguments; - } while (adq != CLKernel::AddressQualifier::Error && - acq != CLKernel::AccessQualifier::Error && - atq != CLKernel::TypeQualifier::Error); - - return arguments - 1; - } -} - -namespace openspace { - -RenderableVolumeExpert::RenderableVolumeExpert(const ghoul::Dictionary& dictionary): - RenderableVolume(dictionary), - _output(nullptr), - _clBackTexture(0), _clFrontTexture(0), _clOutput(0), - _kernelSourceFile(nullptr), _programUpdateOnSave(false), _colorBoxRenderer(nullptr), - _boxScaling(1.0,1.0,1.0) { - - _kernelLock = new std::mutex; - _textureLock = new std::mutex; - - if(dictionary.hasKey("Volumes")) { - ghoul::Dictionary volumes; - if(dictionary.getValue("Volumes", volumes)) { - auto keys = volumes.keys(); - for(auto key: keys) { - ghoul::Dictionary volume; - if(volumes.getValue(key, volume)) { - if (volume.hasKey("File")) { - std::string file = ""; - if (volume.getValue("File", file)) { - file = findPath(file); - if (file != "") { - - // parse hints - ghoul::Dictionary hintsDictionary; - if(volume.hasKey("Hints")) - volume.getValue("Hints", hintsDictionary); - - _volumePaths.push_back(file); - _volumeHints.push_back(hintsDictionary); - } - } - } - } - } - } - } - - if(dictionary.hasKey("TransferFunctions")) { - ghoul::Dictionary transferFunctions; - if(dictionary.getValue("TransferFunctions", transferFunctions)) { - auto keys = transferFunctions.keys(); - for(auto key: keys) { - std::string transferFunctionPath = ""; - if(transferFunctions.getValue(key, transferFunctionPath)) { - transferFunctionPath = findPath(transferFunctionPath); - ghoul::opengl::Texture* tmpTexture = loadTransferFunction(transferFunctionPath); - if(tmpTexture) { - ghoul::filesystem::File* tmp = new ghoul::filesystem::File(transferFunctionPath, false); - _transferFunctions.push_back(tmpTexture); - _transferFunctionsFiles.push_back(tmp); - } - } - } - } - } - - std::string kernelPath = ""; - if (dictionary.hasKey("Kernel")) { - ghoul::Dictionary kernelDictionary; - if(dictionary.getValue("Kernel", kernelDictionary)) { - if(kernelDictionary.getValue("Source", kernelPath)) { - kernelPath = findPath(kernelPath); - - } - if(kernelDictionary.hasKey("UpdateOnSave")) { - kernelDictionary.getValue("UpdateOnSave", _programUpdateOnSave); - } - - if(kernelDictionary.hasKey("Options")) { - using namespace ghoul::opencl; - ghoul::Dictionary kernelOptions; - if(kernelDictionary.getValue("Options", kernelOptions)) { - auto keys = kernelOptions.keys(); - for(auto key: keys) { - bool value = false; - if(kernelOptions.getValue(key, value)) { - if(key == "DenormsAreZero") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::DenormsAreZero, value)); - } else if(key == "FastRelaxedMath") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::FastRelaxedMath, value)); - } else if(key == "FiniteMathOnly") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::FiniteMathOnly, value)); - } else if(key == "KernelArgInfo") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::KernelArgInfo, value)); - } else if(key == "MadEnable") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::MadEnable, value)); - } else if(key == "NoSignedZero") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::NoSignedZero, value)); - } else if(key == "OptDisable") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::OptDisable, value)); - } else if(key == "SinglePrecisionConstant") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::SinglePrecisionConstant, value)); - } else if(key == "StrictAliasing") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::StrictAliasing, value)); - } else if(key == "UnsafeMathOptimizations") { - _kernelOptions.push_back(std::make_pair(CLProgram::Option::UnsafeMathOptimizations, value)); - } - } - } - } - } - - ghoul::Dictionary includeDictionary; - if (kernelDictionary.hasKey("Includes") && kernelDictionary.getValue("Includes", includeDictionary)) { - auto keys = includeDictionary.keys(); - for(auto key: keys) { - std::string includePath; - if(includeDictionary.getValue(key, includePath)) { - if(FileSys.directoryExists(includePath)) { - _kernelIncludes.push_back(absPath(includePath)); - } - } - } - } - - ghoul::Dictionary defineDictionary; - if (kernelDictionary.hasKey("Definitions") && kernelDictionary.getValue("Definitions", defineDictionary)) { - auto keys = defineDictionary.keys(); - for(auto key: keys) { - std::string defintion; - if(defineDictionary.getValue(key, defintion)) { - _kernelDefinitions.push_back(std::make_pair(key, defintion)); - } - } - } - } - } - if (kernelPath != "") { - _kernelSourceFile = new ghoul::filesystem::File(kernelPath, false); - } - - _colorBoxRenderer = new VolumeRaycasterBox(); - double tempValue; - if(dictionary.hasKey("BoxScaling.1") && dictionary.getValue("BoxScaling.1", tempValue)) { - if(tempValue > 0.0) { - _boxScaling[0] = tempValue; - } - } - if(dictionary.hasKey("BoxScaling.2") && dictionary.getValue("BoxScaling.2", tempValue)) { - if(tempValue > 0.0) { - _boxScaling[1] = tempValue; - } - } - if(dictionary.hasKey("BoxScaling.3") && dictionary.getValue("BoxScaling.3", tempValue)) { - if(tempValue > 0.0) { - _boxScaling[2] = tempValue; - } - } - - setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling))); -} - -RenderableVolumeExpert::~RenderableVolumeExpert() { - deinitialize(); - delete _textureLock; - delete _kernelLock; -} - -bool RenderableVolumeExpert::initialize() { - if(_kernelSourceFile == nullptr) { - LERROR("Could not find the kernel file!"); - return false; - } - - _context = OsEng.clContext(); - - auto textureCallback = [this](const ghoul::filesystem::File& file) { - safeUpdateTexture(file); - }; - auto kernelCallback = [this](const ghoul::filesystem::File& file) { - safeKernelCompilation(); - }; - - for(auto texture: _transferFunctions) { - texture->uploadTexture(); - cl_mem transferMem = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *texture); - _clTransferFunctions.push_back(transferMem); - } - if(_programUpdateOnSave) { - _kernelSourceFile->setCallback(kernelCallback); - for(auto texture: _transferFunctionsFiles) { - texture->setCallback(textureCallback); - } - } - - for (int i = 0; i < _volumePaths.size(); ++i) { - ghoul::opengl::Texture* volume = loadVolume(_volumePaths.at(i), _volumeHints.at(i)); - if(volume) { - volume->uploadTexture(); - - LDEBUG("Creating CL texture from GL texture with path '" << _volumePaths.at(i) << "'"); - cl_mem volumeTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *volume); - - _volumes.push_back(volume); - _clVolumes.push_back(volumeTexture); - } else { - LERROR("Invalid volume"); - } - } - - // ------ SETUP GEOMETRY ---------------- - const GLfloat size = 1.0f; - const GLfloat vertex_texcoord_data[] = { // square of two triangles (sigh) - // x y z s t - -size, -size, 0.0f, 0.0f, 0.0f, - size, size, 0.0f, 1.0f, 1.0f, - -size, size, 0.0f, 0.0f, 1.0f, - -size, -size, 0.0f, 0.0f, 0.0f, - size, -size, 0.0f, 1.0f, 0.0f, - size, size, 0.0f, 1.0f, 1.0f - }; - - GLuint vertexPositionBuffer; - glGenVertexArrays(1, &_screenQuad); // generate array - glBindVertexArray(_screenQuad); // bind array - glGenBuffers(1, &vertexPositionBuffer); // generate buffer - glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_texcoord_data), vertex_texcoord_data, GL_STATIC_DRAW); - - // Vertex positions - GLuint vertexLocation = 2; - glEnableVertexAttribArray(vertexLocation); - glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), reinterpret_cast(0)); - - // Texture coordinates - GLuint texcoordLocation = 0; - glEnableVertexAttribArray(texcoordLocation); - glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)(3*sizeof(GLfloat))); - - glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer - glBindVertexArray(0); //unbind array - - if( ! OsEng.ref().configurationManager().getValue("Quad", _quadProgram)) { - LERROR("Could not find 'Quad'"); - return false; - } - - _colorBoxRenderer->initialize(); - glm::size2_t dimensions = _colorBoxRenderer->dimensions(); - ghoul::opengl::Texture* backTexture = _colorBoxRenderer->backFace(); - ghoul::opengl::Texture* frontTexture = _colorBoxRenderer->frontFace(); - _output = new ghoul::opengl::Texture(glm::size3_t(dimensions[0],dimensions[1],1)); - _output->uploadTexture(); - - _context = OsEng.clContext(); - _commands = _context.createCommandQueue(); - - _clBackTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *backTexture); - _clFrontTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *frontTexture); - _clOutput = _context.createTextureFromGLTexture(CL_MEM_WRITE_ONLY, *_output); - - // Compile kernels - safeKernelCompilation(); - - // create work group - size_t local_x = 32; - size_t local_y = 32; - while (local_x > 1) { - if(dimensions[0] % local_x == 0) - break; - local_x /= 2; - } - while (local_y > 1) { - if(dimensions[1] % local_y == 0) - break; - local_y /= 2; - } - _ws = new ghoul::opencl::CLWorkSize({dimensions[0],dimensions[1]}, {local_x,local_y}); - - return true; -} - -bool RenderableVolumeExpert::deinitialize() { - - - return true; -} - -void RenderableVolumeExpert::render(const Camera *camera, const psc &thisPosition) { - if( ! _kernel.isValidKernel()) - return; - - glm::mat4 transform = camera->viewProjectionMatrix(); - glm::mat4 camTransform = camera->viewRotationMatrix(); - psc relative = thisPosition-camera->position(); - - transform = transform*camTransform; - transform = glm::translate(transform, relative.vec3()); - transform = glm::scale(transform, _boxScaling); - - _colorBoxRenderer->render(transform); - - _textureLock->lock(); - _kernelLock->lock(); - - // tell opengl to finish everything before opencl takes ownerhip (uses) the textures - glFinish(); - - // Aquire GL objects - _commands.enqueueAcquireGLObjects(_clBackTexture); - _commands.enqueueAcquireGLObjects(_clFrontTexture); - _commands.enqueueAcquireGLObjects(_clOutput); - _commands.enqueueAcquireGLObjects(_clVolumes); - _commands.enqueueAcquireGLObjects(_clTransferFunctions); - - _commands.enqueueKernelBlocking(_kernel, *_ws); - _commands.finish(); - - // Release GL objects - _commands.enqueueReleaseGLObjects(_clBackTexture); - _commands.enqueueReleaseGLObjects(_clFrontTexture); - _commands.enqueueReleaseGLObjects(_clOutput); - _commands.enqueueReleaseGLObjects(_clVolumes); - _commands.enqueueReleaseGLObjects(_clTransferFunctions); - - _quadProgram->activate(); - glActiveTexture(GL_TEXTURE0); - _output->bind(); - - // enable blending - glEnable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); - - glBindVertexArray(_screenQuad); - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); - - _kernelLock->unlock(); - _textureLock->unlock(); - - // disable blending - glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); - glBlendFunc(GL_ONE, GL_ZERO); - - _quadProgram->deactivate(); -} - -void RenderableVolumeExpert::update() { - -} - -void RenderableVolumeExpert::safeKernelCompilation() { - if(_context.isValidContext()) { - - ghoul::opencl::CLProgram tmpProgram = _context.createProgram(_kernelSourceFile->path()); - for(auto option: _kernelOptions) { - tmpProgram.setOption(option.first, option.second); - } - - for(auto defintion: _kernelDefinitions) { - tmpProgram.addDefinition(defintion.first, defintion.second); - } - - // add the include directories - tmpProgram.addIncludeDirectory(_kernelIncludes); - - if(tmpProgram.build()) { - ghoul::opencl::CLKernel tmpKernel = tmpProgram.createKernel("volumeraycaster"); - if(tmpKernel.isValidKernel()) { - - auto begin = _kernelOptions.begin(); - auto end = _kernelOptions.end(); - auto f = std::find(begin, end, std::make_pair(ghoul::opencl::CLProgram::Option::KernelArgInfo, true)); - - int maxarguments = 1024; - bool argumentError = false; - if (f != end) { - LDEBUG("Checking argument types"); - - using ghoul::opencl::CLKernel; - maxarguments = countKernelArguments(tmpKernel); - - for (int i = 3; i maxarguments) { - LWARNING("More arguments set than kernel accepts."); - } - - // do the actual assignment behind locked doors - _kernelLock->lock(); - _program = tmpProgram; - _kernel = tmpKernel; - _kernelLock->unlock(); - LDEBUG("Done updating kernel"); - } - } - } -} - -void RenderableVolumeExpert::safeUpdateTexture(const ghoul::filesystem::File& file) { - int fileID = 0; - for (fileID = 0; fileID < _transferFunctionsFiles.size(); ++fileID) { - if (_transferFunctionsFiles.at(fileID) == &file) { - //LDEBUG("Transferfunction found at id " << fileID); - break; - } - } - if(fileID == _transferFunctionsFiles.size()) - return; - - LDEBUG("Updating transferfunction"); - - // create the new texture - ghoul::opengl::Texture* newTexture = loadTransferFunction(file.path()); - - if(newTexture) { - - // upload the new texture and create a cl memory - newTexture->uploadTexture(); - cl_mem clNewTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *newTexture); - - // check if opencl memory is unsuccessfull - if(clNewTexture == 0) { - delete newTexture; - return; - } - - // everything seems ok, critical point to replace current texture pointers - _textureLock->lock(); - - // deallocate current texture - clReleaseMemObject(_clTransferFunctions.at(fileID)); - delete _transferFunctions.at(fileID); - - // set the new texture - _transferFunctions.at(fileID) = newTexture; - _clTransferFunctions.at(fileID) = clNewTexture; - - // update kernel - // __kernel arguments(front, back, output, [_volumes], .. fileID)) - _kernel.setArgument(3 + _volumes.size() + fileID, &clNewTexture); - - LDEBUG("Transferfunction successfully updated"); - - // end of critical section - _textureLock->unlock(); - } -} - -} // namespace openspace +// This is still in the repository to be cannibalized for a possible rewrite (ab) +///***************************************************************************************** +// * * +// * 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. * +// ****************************************************************************************/ +// +//// open space includes +//#include +// +//#include +// +//#include +//#include +//#include +//#include +// +//#include +// +//namespace { +// std::string _loggerCat = "RenderableVolumeExpert"; +// +// size_t countKernelArguments(ghoul::opencl::CLKernel& kernel) { +// +// using ghoul::opencl::CLKernel; +// CLKernel::AddressQualifier adq; +// CLKernel::AccessQualifier acq; +// CLKernel::TypeQualifier atq; +// +// size_t arguments = 0; +// do { +// adq = kernel.argumentAddressQualifier(arguments); +// acq = kernel.argumentAccessQualifier(arguments); +// atq = kernel.argumentTypeQualifier(arguments); +// ++arguments; +// } while (adq != CLKernel::AddressQualifier::Error && +// acq != CLKernel::AccessQualifier::Error && +// atq != CLKernel::TypeQualifier::Error); +// +// return arguments - 1; +// } +//} +// +//namespace openspace { +// +//RenderableVolumeExpert::RenderableVolumeExpert(const ghoul::Dictionary& dictionary): +// RenderableVolume(dictionary), +// _output(nullptr), +// _clBackTexture(0), _clFrontTexture(0), _clOutput(0), +// _kernelSourceFile(nullptr), _programUpdateOnSave(false), _colorBoxRenderer(nullptr), +// _boxScaling(1.0,1.0,1.0) { +// +// _kernelLock = new std::mutex; +// _textureLock = new std::mutex; +// +// if(dictionary.hasKey("Volumes")) { +// ghoul::Dictionary volumes; +// if(dictionary.getValue("Volumes", volumes)) { +// auto keys = volumes.keys(); +// for(auto key: keys) { +// ghoul::Dictionary volume; +// if(volumes.getValue(key, volume)) { +// if (volume.hasKey("File")) { +// std::string file = ""; +// if (volume.getValue("File", file)) { +// file = findPath(file); +// if (file != "") { +// +// // parse hints +// ghoul::Dictionary hintsDictionary; +// if(volume.hasKey("Hints")) +// volume.getValue("Hints", hintsDictionary); +// +// _volumePaths.push_back(file); +// _volumeHints.push_back(hintsDictionary); +// } +// } +// } +// } +// } +// } +// } +// +// if(dictionary.hasKey("TransferFunctions")) { +// ghoul::Dictionary transferFunctions; +// if(dictionary.getValue("TransferFunctions", transferFunctions)) { +// auto keys = transferFunctions.keys(); +// for(auto key: keys) { +// std::string transferFunctionPath = ""; +// if(transferFunctions.getValue(key, transferFunctionPath)) { +// transferFunctionPath = findPath(transferFunctionPath); +// ghoul::opengl::Texture* tmpTexture = loadTransferFunction(transferFunctionPath); +// if(tmpTexture) { +// ghoul::filesystem::File* tmp = new ghoul::filesystem::File(transferFunctionPath, false); +// _transferFunctions.push_back(tmpTexture); +// _transferFunctionsFiles.push_back(tmp); +// } +// } +// } +// } +// } +// +// std::string kernelPath = ""; +// if (dictionary.hasKey("Kernel")) { +// ghoul::Dictionary kernelDictionary; +// if(dictionary.getValue("Kernel", kernelDictionary)) { +// if(kernelDictionary.getValue("Source", kernelPath)) { +// kernelPath = findPath(kernelPath); +// +// } +// if(kernelDictionary.hasKey("UpdateOnSave")) { +// kernelDictionary.getValue("UpdateOnSave", _programUpdateOnSave); +// } +// +// if(kernelDictionary.hasKey("Options")) { +// using namespace ghoul::opencl; +// ghoul::Dictionary kernelOptions; +// if(kernelDictionary.getValue("Options", kernelOptions)) { +// auto keys = kernelOptions.keys(); +// for(auto key: keys) { +// bool value = false; +// if(kernelOptions.getValue(key, value)) { +// if(key == "DenormsAreZero") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::DenormsAreZero, value)); +// } else if(key == "FastRelaxedMath") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::FastRelaxedMath, value)); +// } else if(key == "FiniteMathOnly") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::FiniteMathOnly, value)); +// } else if(key == "KernelArgInfo") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::KernelArgInfo, value)); +// } else if(key == "MadEnable") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::MadEnable, value)); +// } else if(key == "NoSignedZero") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::NoSignedZero, value)); +// } else if(key == "OptDisable") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::OptDisable, value)); +// } else if(key == "SinglePrecisionConstant") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::SinglePrecisionConstant, value)); +// } else if(key == "StrictAliasing") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::StrictAliasing, value)); +// } else if(key == "UnsafeMathOptimizations") { +// _kernelOptions.push_back(std::make_pair(CLProgram::Option::UnsafeMathOptimizations, value)); +// } +// } +// } +// } +// } +// +// ghoul::Dictionary includeDictionary; +// if (kernelDictionary.hasKey("Includes") && kernelDictionary.getValue("Includes", includeDictionary)) { +// auto keys = includeDictionary.keys(); +// for(auto key: keys) { +// std::string includePath; +// if(includeDictionary.getValue(key, includePath)) { +// if(FileSys.directoryExists(includePath)) { +// _kernelIncludes.push_back(absPath(includePath)); +// } +// } +// } +// } +// +// ghoul::Dictionary defineDictionary; +// if (kernelDictionary.hasKey("Definitions") && kernelDictionary.getValue("Definitions", defineDictionary)) { +// auto keys = defineDictionary.keys(); +// for(auto key: keys) { +// std::string defintion; +// if(defineDictionary.getValue(key, defintion)) { +// _kernelDefinitions.push_back(std::make_pair(key, defintion)); +// } +// } +// } +// } +// } +// if (kernelPath != "") { +// _kernelSourceFile = new ghoul::filesystem::File(kernelPath, false); +// } +// +// _colorBoxRenderer = new VolumeRaycasterBox(); +// double tempValue; +// if(dictionary.hasKey("BoxScaling.1") && dictionary.getValue("BoxScaling.1", tempValue)) { +// if(tempValue > 0.0) { +// _boxScaling[0] = tempValue; +// } +// } +// if(dictionary.hasKey("BoxScaling.2") && dictionary.getValue("BoxScaling.2", tempValue)) { +// if(tempValue > 0.0) { +// _boxScaling[1] = tempValue; +// } +// } +// if(dictionary.hasKey("BoxScaling.3") && dictionary.getValue("BoxScaling.3", tempValue)) { +// if(tempValue > 0.0) { +// _boxScaling[2] = tempValue; +// } +// } +// +// setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling))); +//} +// +//RenderableVolumeExpert::~RenderableVolumeExpert() { +// deinitialize(); +// delete _textureLock; +// delete _kernelLock; +//} +// +//bool RenderableVolumeExpert::initialize() { +// if(_kernelSourceFile == nullptr) { +// LERROR("Could not find the kernel file!"); +// return false; +// } +// +// _context = OsEng.clContext(); +// +// auto textureCallback = [this](const ghoul::filesystem::File& file) { +// safeUpdateTexture(file); +// }; +// auto kernelCallback = [this](const ghoul::filesystem::File& file) { +// safeKernelCompilation(); +// }; +// +// for(auto texture: _transferFunctions) { +// texture->uploadTexture(); +// cl_mem transferMem = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *texture); +// _clTransferFunctions.push_back(transferMem); +// } +// if(_programUpdateOnSave) { +// _kernelSourceFile->setCallback(kernelCallback); +// for(auto texture: _transferFunctionsFiles) { +// texture->setCallback(textureCallback); +// } +// } +// +// for (int i = 0; i < _volumePaths.size(); ++i) { +// ghoul::opengl::Texture* volume = loadVolume(_volumePaths.at(i), _volumeHints.at(i)); +// if(volume) { +// volume->uploadTexture(); +// +// LDEBUG("Creating CL texture from GL texture with path '" << _volumePaths.at(i) << "'"); +// cl_mem volumeTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *volume); +// +// _volumes.push_back(volume); +// _clVolumes.push_back(volumeTexture); +// } else { +// LERROR("Invalid volume"); +// } +// } +// +// // ------ SETUP GEOMETRY ---------------- +// const GLfloat size = 1.0f; +// const GLfloat vertex_texcoord_data[] = { // square of two triangles (sigh) +// // x y z s t +// -size, -size, 0.0f, 0.0f, 0.0f, +// size, size, 0.0f, 1.0f, 1.0f, +// -size, size, 0.0f, 0.0f, 1.0f, +// -size, -size, 0.0f, 0.0f, 0.0f, +// size, -size, 0.0f, 1.0f, 0.0f, +// size, size, 0.0f, 1.0f, 1.0f +// }; +// +// GLuint vertexPositionBuffer; +// glGenVertexArrays(1, &_screenQuad); // generate array +// glBindVertexArray(_screenQuad); // bind array +// glGenBuffers(1, &vertexPositionBuffer); // generate buffer +// glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer +// glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_texcoord_data), vertex_texcoord_data, GL_STATIC_DRAW); +// +// // Vertex positions +// GLuint vertexLocation = 2; +// glEnableVertexAttribArray(vertexLocation); +// glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), reinterpret_cast(0)); +// +// // Texture coordinates +// GLuint texcoordLocation = 0; +// glEnableVertexAttribArray(texcoordLocation); +// glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (void*)(3*sizeof(GLfloat))); +// +// glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer +// glBindVertexArray(0); //unbind array +// +// if( ! OsEng.ref().configurationManager().getValue("Quad", _quadProgram)) { +// LERROR("Could not find 'Quad'"); +// return false; +// } +// +// _colorBoxRenderer->initialize(); +// glm::size2_t dimensions = _colorBoxRenderer->dimensions(); +// ghoul::opengl::Texture* backTexture = _colorBoxRenderer->backFace(); +// ghoul::opengl::Texture* frontTexture = _colorBoxRenderer->frontFace(); +// _output = new ghoul::opengl::Texture(glm::size3_t(dimensions[0],dimensions[1],1)); +// _output->uploadTexture(); +// +// _context = OsEng.clContext(); +// _commands = _context.createCommandQueue(); +// +// _clBackTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *backTexture); +// _clFrontTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *frontTexture); +// _clOutput = _context.createTextureFromGLTexture(CL_MEM_WRITE_ONLY, *_output); +// +// // Compile kernels +// safeKernelCompilation(); +// +// // create work group +// size_t local_x = 32; +// size_t local_y = 32; +// while (local_x > 1) { +// if(dimensions[0] % local_x == 0) +// break; +// local_x /= 2; +// } +// while (local_y > 1) { +// if(dimensions[1] % local_y == 0) +// break; +// local_y /= 2; +// } +// _ws = new ghoul::opencl::CLWorkSize({dimensions[0],dimensions[1]}, {local_x,local_y}); +// +// return true; +//} +// +//bool RenderableVolumeExpert::deinitialize() { +// +// +// return true; +//} +// +//void RenderableVolumeExpert::render(const Camera *camera, const psc &thisPosition) { +// if( ! _kernel.isValidKernel()) +// return; +// +// glm::mat4 transform = camera->viewProjectionMatrix(); +// glm::mat4 camTransform = camera->viewRotationMatrix(); +// psc relative = thisPosition-camera->position(); +// +// transform = transform*camTransform; +// transform = glm::translate(transform, relative.vec3()); +// transform = glm::scale(transform, _boxScaling); +// +// _colorBoxRenderer->render(transform); +// +// _textureLock->lock(); +// _kernelLock->lock(); +// +// // tell opengl to finish everything before opencl takes ownerhip (uses) the textures +// glFinish(); +// +// // Aquire GL objects +// _commands.enqueueAcquireGLObjects(_clBackTexture); +// _commands.enqueueAcquireGLObjects(_clFrontTexture); +// _commands.enqueueAcquireGLObjects(_clOutput); +// _commands.enqueueAcquireGLObjects(_clVolumes); +// _commands.enqueueAcquireGLObjects(_clTransferFunctions); +// +// _commands.enqueueKernelBlocking(_kernel, *_ws); +// _commands.finish(); +// +// // Release GL objects +// _commands.enqueueReleaseGLObjects(_clBackTexture); +// _commands.enqueueReleaseGLObjects(_clFrontTexture); +// _commands.enqueueReleaseGLObjects(_clOutput); +// _commands.enqueueReleaseGLObjects(_clVolumes); +// _commands.enqueueReleaseGLObjects(_clTransferFunctions); +// +// _quadProgram->activate(); +// glActiveTexture(GL_TEXTURE0); +// _output->bind(); +// +// // enable blending +// glEnable(GL_BLEND); +// glDisable(GL_DEPTH_TEST); +// glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); +// +// glBindVertexArray(_screenQuad); +// glDrawArrays(GL_TRIANGLES, 0, 6); +// glBindVertexArray(0); +// +// _kernelLock->unlock(); +// _textureLock->unlock(); +// +// // disable blending +// glDisable(GL_BLEND); +// glEnable(GL_DEPTH_TEST); +// glBlendFunc(GL_ONE, GL_ZERO); +// +// _quadProgram->deactivate(); +//} +// +//void RenderableVolumeExpert::update() { +// +//} +// +//void RenderableVolumeExpert::safeKernelCompilation() { +// if(_context.isValidContext()) { +// +// ghoul::opencl::CLProgram tmpProgram = _context.createProgram(_kernelSourceFile->path()); +// for(auto option: _kernelOptions) { +// tmpProgram.setOption(option.first, option.second); +// } +// +// for(auto defintion: _kernelDefinitions) { +// tmpProgram.addDefinition(defintion.first, defintion.second); +// } +// +// // add the include directories +// tmpProgram.addIncludeDirectory(_kernelIncludes); +// +// if(tmpProgram.build()) { +// ghoul::opencl::CLKernel tmpKernel = tmpProgram.createKernel("volumeraycaster"); +// if(tmpKernel.isValidKernel()) { +// +// auto begin = _kernelOptions.begin(); +// auto end = _kernelOptions.end(); +// auto f = std::find(begin, end, std::make_pair(ghoul::opencl::CLProgram::Option::KernelArgInfo, true)); +// +// int maxarguments = 1024; +// bool argumentError = false; +// if (f != end) { +// LDEBUG("Checking argument types"); +// +// using ghoul::opencl::CLKernel; +// maxarguments = countKernelArguments(tmpKernel); +// +// for (int i = 3; i maxarguments) { +// LWARNING("More arguments set than kernel accepts."); +// } +// +// // do the actual assignment behind locked doors +// _kernelLock->lock(); +// _program = tmpProgram; +// _kernel = tmpKernel; +// _kernelLock->unlock(); +// LDEBUG("Done updating kernel"); +// } +// } +// } +//} +// +//void RenderableVolumeExpert::safeUpdateTexture(const ghoul::filesystem::File& file) { +// int fileID = 0; +// for (fileID = 0; fileID < _transferFunctionsFiles.size(); ++fileID) { +// if (_transferFunctionsFiles.at(fileID) == &file) { +// //LDEBUG("Transferfunction found at id " << fileID); +// break; +// } +// } +// if(fileID == _transferFunctionsFiles.size()) +// return; +// +// LDEBUG("Updating transferfunction"); +// +// // create the new texture +// ghoul::opengl::Texture* newTexture = loadTransferFunction(file.path()); +// +// if(newTexture) { +// +// // upload the new texture and create a cl memory +// newTexture->uploadTexture(); +// cl_mem clNewTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *newTexture); +// +// // check if opencl memory is unsuccessfull +// if(clNewTexture == 0) { +// delete newTexture; +// return; +// } +// +// // everything seems ok, critical point to replace current texture pointers +// _textureLock->lock(); +// +// // deallocate current texture +// clReleaseMemObject(_clTransferFunctions.at(fileID)); +// delete _transferFunctions.at(fileID); +// +// // set the new texture +// _transferFunctions.at(fileID) = newTexture; +// _clTransferFunctions.at(fileID) = clNewTexture; +// +// // update kernel +// // __kernel arguments(front, back, output, [_volumes], .. fileID)) +// _kernel.setArgument(3 + _volumes.size() + fileID, &clNewTexture); +// +// LDEBUG("Transferfunction successfully updated"); +// +// // end of critical section +// _textureLock->unlock(); +// } +//} +// +//} // namespace openspace diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index ce6480c8e8..232b443b18 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -22,7 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -// open space includes #include #include #include @@ -35,78 +34,84 @@ #include #include +#include namespace { - std::string _loggerCat = "RenderableVolumeGL"; + const std::string _loggerCat = "RenderableVolumeGL"; } namespace openspace { -RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): - RenderableVolume(dictionary), _boxScaling(1.0, 1.0, 1.0), - _updateTransferfunction(false), _id(-1) { +RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary) + : RenderableVolume(dictionary) + , _transferFunctionName("") + , _volumeName("") + , _boxScaling(1.0, 1.0, 1.0) + , _w(0.f) + , _updateTransferfunction(false) + , _id(-1) +{ + std::string name; + bool success = dictionary.getValue(constants::scenegraphnode::keyName, name); + assert(success); _filename = ""; - if(dictionary.hasKey("Volume")) { - if(dictionary.getValue("Volume", _filename)) { - _filename = findPath(_filename); - } - } + success = dictionary.getValueSafe(constants::renderablevolumegl::keyVolume, + _filename); + if (!success) { + LERROR("Node '" << name << "' did not contain a valid '" << + constants::renderablevolumegl::keyVolume << "'"); + return; + } + _filename = findPath(_filename); - LDEBUG("filename: " << _filename); - - if(dictionary.hasKey("Hints")) - dictionary.getValue("Hints", _hintsDictionary); + LDEBUG("Volume Filename: " << _filename); + + dictionary.getValueSafe(constants::renderablevolumegl::keyHints, _hintsDictionary); _transferFunction = nullptr; _transferFunctionFile = nullptr; _transferFunctionPath = ""; - if (dictionary.hasKey("TransferFunction")) { - std::string transferFunctionPath = ""; - if(dictionary.getValue("TransferFunction", transferFunctionPath)) { - _transferFunctionPath = findPath(transferFunctionPath); - } - } - _samplerFilename = ""; - if (dictionary.hasKey("Sampler")) { - if(dictionary.getValue("Sampler", _samplerFilename)) { - _samplerFilename = findPath(_samplerFilename); - } - } - if( _transferFunctionPath == "") { - LERROR("No transferFunction!"); - } else { - _transferFunctionFile = new ghoul::filesystem::File(_transferFunctionPath, true); - } - if( _samplerFilename == "") { - LERROR("No samplerfile!"); - } + success = dictionary.getValueSafe( + constants::renderablevolumegl::keyTransferFunction, _transferFunctionPath); + if (!success) { + LERROR("Node '" << name << "' did not contain a valid '" << + constants::renderablevolumegl::keyTransferFunction << "'"); + return; + } + _transferFunctionPath = findPath(_transferFunctionPath); + _transferFunctionFile = new ghoul::filesystem::File(_transferFunctionPath, true); + + _samplerFilename = ""; + success = dictionary.getValueSafe(constants::renderablevolumegl::keySampler, + _samplerFilename); + if (!success) { + LERROR("Node '" << name << "' did not contain a valid '" << + constants::renderablevolumegl::keySampler << "'"); + return; + } + _samplerFilename = findPath(_samplerFilename); - double tempValue; - if(dictionary.hasKey("BoxScaling.1") && dictionary.getValue("BoxScaling.1", tempValue)) { - if(tempValue > 0.0) - _boxScaling[0] = tempValue; - } - if(dictionary.hasKey("BoxScaling.2") && dictionary.getValue("BoxScaling.2", tempValue)) { - if(tempValue > 0.0) - _boxScaling[1] = tempValue; - } - if(dictionary.hasKey("BoxScaling.3") && dictionary.getValue("BoxScaling.3", tempValue)) { - if(tempValue > 0.0) - _boxScaling[2] = tempValue; - } - if(dictionary.hasKey("BoxScaling.4") && dictionary.getValue("BoxScaling.4", tempValue)) { - _w = tempValue; - } - else - _w = 0.0; + glm::vec4 scalingVec4(_boxScaling, _w); + success = dictionary.getValueSafe(constants::renderablevolumegl::keyBoxScaling, + scalingVec4); + if (success) { + _boxScaling = scalingVec4.xyz; + _w = scalingVec4.w; + } + else { + success = dictionary.getValueSafe(constants::renderablevolumegl::keyBoxScaling, + _boxScaling); + if (!success) { + LERROR("Node '" << name << "' did not contain a valid '" << + constants::renderablevolumegl::keyBoxScaling << "'"); + return; + } + } - _volumeName = ""; - if (dictionary.hasKey("VolumeName")) - dictionary.getValue("VolumeName", _volumeName); - _transferFunctionName = ""; - if (dictionary.hasKey("TransferFunctionName")) - dictionary.getValue("TransferFunctionName", _transferFunctionName); + dictionary.getValueSafe(constants::renderablevolumegl::keyVolumeName, _volumeName); + dictionary.getValueSafe(constants::renderablevolumegl::keyTransferFunctionName, + _transferFunctionName); setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling)*pow(10,_w))); } diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index b42fd198a2..6e64d380c2 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -318,9 +318,9 @@ void ScriptEngine::addLibraryFunctions(const LuaLibrary& library, bool replace) { for (LuaLibrary::Function p : library.functions) { if (!replace) { - ghoul::lua::logStack(_state); + //ghoul::lua::logStack(_state); lua_getfield(_state, -1, p.name.c_str()); - ghoul::lua::logStack(_state); + //ghoul::lua::logStack(_state); const bool isNil = lua_isnil(_state, -1); if (!isNil) { LERROR("Function name '" << p.name << "' was already assigned"); diff --git a/src/util/factorymanager.cpp b/src/util/factorymanager.cpp index 4a6e71ff59..90b5f7eb47 100644 --- a/src/util/factorymanager.cpp +++ b/src/util/factorymanager.cpp @@ -56,13 +56,8 @@ void FactoryManager::initialize() _manager->addFactory(new ghoul::TemplateFactory); _manager->factory()->registerClass( "RenderablePlanet"); - _manager->factory()->registerClass( - "RenderableVolumeCL"); _manager->factory()->registerClass( "RenderableVolumeGL"); - _manager->factory()->registerClass( - "RenderableVolumeExpert"); - _manager->factory()->registerClass("RenderableFlare"); _manager->factory()->registerClass("RenderableFieldlines"); // Add Ephimerides From 43610798f6dff593f242d5458ca6f6f552ddf18a Mon Sep 17 00:00:00 2001 From: jonasstrandstedt Date: Tue, 23 Sep 2014 13:39:39 +0200 Subject: [PATCH 112/113] Made it easier to get started on Windows --- CMakeLists.txt | 7 ++++++- src/CMakeLists.txt | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff62ae9684..712d929af4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,7 +102,12 @@ endif(OPENCL_FOUND) # Kameleon option(KAMELEON_LIBRARY_ONLY "Build with Kameleon as library only" ON) -option(BUILD_SHARED_LIBS "Build Shared Libraries" ON) +if(WIN32) + option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF) +else(WIN32) + option(BUILD_SHARED_LIBS "Build Shared Libraries" ON) +endif(WIN32) +option(KAMELEON_USE_HDF5 "Kameleon use HDF5" OFF) set(KAMELEON_ROOT_DIR ${OPENSPACE_EXT_DIR}/kameleon) set(KAMELEON_INCLUDES ${KAMELEON_ROOT_DIR}/src) add_subdirectory(${KAMELEON_ROOT_DIR}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9099e1666d..0a2b8101ae 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -142,5 +142,23 @@ include_directories("${HEADER_ROOT_DIR}") add_executable(OpenSpace ${SOURCE_ROOT_DIR}/main.cpp ${OPENSPACE_HEADER} ${OPENSPACE_SOURCE}) target_link_libraries(OpenSpace ${DEPENDENT_LIBS}) +if (WIN32) + if (CMAKE_CL_64) + set(OPENSPACE_DLL_LIBS ${OPENSPACE_DLL_LIBS} ${GHOUL_ROOT_DIR}/ext/il/lib/win64/DevIL.dll) + set(OPENSPACE_DLL_LIBS ${OPENSPACE_DLL_LIBS} ${GHOUL_ROOT_DIR}/ext/il/lib/win64/ILU.dll) + set(OPENSPACE_DLL_LIBS ${OPENSPACE_DLL_LIBS} ${GHOUL_ROOT_DIR}/ext/il/lib/win64/ILUT.dll) + else (CMAKE_CL_64) + set(OPENSPACE_DLL_LIBS ${OPENSPACE_DLL_LIBS} ${GHOUL_ROOT_DIR}/ext/il/lib/win32/DevIL.dll) + set(OPENSPACE_DLL_LIBS ${OPENSPACE_DLL_LIBS} ${GHOUL_ROOT_DIR}/ext/il/lib/win32/ILU.dll) + set(OPENSPACE_DLL_LIBS ${OPENSPACE_DLL_LIBS} ${GHOUL_ROOT_DIR}/ext/il/lib/win32/ILUT.dll) + endif (CMAKE_CL_64) + foreach( file_i ${OPENSPACE_DLL_LIBS}) + add_custom_command(TARGET OpenSpace POST_BUILD # Adds a post-build event to MyTest + COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..." + "${file_i}" # <--this is in-file + $) + endforeach( file_i ) +endif(WIN32) + add_subdirectory(tests) From 326599c538df25f4aa34e8c5ae2aa822137110cc Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Wed, 24 Sep 2014 13:46:04 +0200 Subject: [PATCH 113/113] Small fix for missing Boost --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 712d929af4..980e2615c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,7 @@ endif () # Ghoul set(GHOUL_ROOT_DIR "${OPENSPACE_EXT_DIR}/ghoul") include_directories("${GHOUL_ROOT_DIR}/include") +set(BOOST_ROOT "${GHOUL_ROOT_DIR}/ext/boost") add_subdirectory(${GHOUL_ROOT_DIR}) set(DEPENDENT_LIBS ${DEPENDENT_LIBS} Ghoul)