mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-06 03:29:44 -06:00
Moved from VolumeRaycaster to RenderableVolume
- Removed old classes and moved code to the Renderables - RenderableVolume is now abstract with some helpful functions - Added swapinterval=0 to sgct config for performance analysis
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Cluster masterAddress="localhost">
|
||||
<Settings>
|
||||
<Display swapInterval="0" />
|
||||
</Settings>
|
||||
<Node address="localhost" port="20401">
|
||||
<Window fullScreen="false">
|
||||
<!-- 16:9 aspect ratio -->
|
||||
|
||||
Submodule ext/ghoul updated: e82d83f0d9...f5c64aca95
@@ -35,7 +35,6 @@
|
||||
#include <ghoul/opencl/clprogram.h>
|
||||
#include <ghoul/opencl/clkernel.h>
|
||||
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
#include <openspace/flare/flare.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -1,9 +1,32 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 RENDERABLEVOLUME_H
|
||||
#define RENDERABLEVOLUME_H
|
||||
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
|
||||
// ghoul includes
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
@@ -19,25 +42,15 @@ public:
|
||||
RenderableVolume(const ghoul::Dictionary& dictionary);
|
||||
~RenderableVolume();
|
||||
|
||||
bool initialize();
|
||||
bool deinitialize();
|
||||
|
||||
virtual void render(const Camera *camera, const psc& thisPosition);
|
||||
virtual void update();
|
||||
|
||||
protected:
|
||||
std::string findPath(const std::string& path);
|
||||
ghoul::RawVolumeReader::ReadHints readHints(const ghoul::Dictionary& dictionary);
|
||||
std::string findPath(const std::string& path, const std::string& relativePath);
|
||||
ghoul::opengl::Texture* loadTransferFunction(const std::string& filepath);
|
||||
|
||||
private:
|
||||
|
||||
// texture
|
||||
std::string _volumePath;
|
||||
|
||||
// Object
|
||||
VolumeRaycaster *_rayCaster;
|
||||
ghoul::RawVolumeReader::ReadHints _hints;
|
||||
bool _programUpdateOnSave;
|
||||
|
||||
// relative path
|
||||
std::string _relativePath;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,34 +22,53 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __VOLUMERAYCASTERCL_H__
|
||||
#define __VOLUMERAYCASTERCL_H__
|
||||
#ifndef __RENDERABLEVOLUMECL_H__
|
||||
#define __RENDERABLEVOLUMECL_H__
|
||||
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderablevolume.h>
|
||||
|
||||
// ghoul includes
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/framebufferobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/framebufferobject.h>
|
||||
#include <ghoul/opencl/clcontext.h>
|
||||
#include <ghoul/opencl/clcommandqueue.h>
|
||||
#include <ghoul/opencl/clprogram.h>
|
||||
#include <ghoul/opencl/clkernel.h>
|
||||
#include <ghoul/opencl/clworksize.h>
|
||||
#include <ghoul/io/rawvolumereader.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
|
||||
#include <sgct.h>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
//#include <vector>
|
||||
//#include <string>
|
||||
#ifdef __APPLE__
|
||||
#include <memory>
|
||||
#else
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class VolumeRaycasterCL: public VolumeRaycaster {
|
||||
class RenderableVolumeCL: public RenderableVolume {
|
||||
public:
|
||||
VolumeRaycasterCL(const ghoul::Dictionary& dictionary);
|
||||
~VolumeRaycasterCL();
|
||||
|
||||
|
||||
// constructors & destructor
|
||||
RenderableVolumeCL(const ghoul::Dictionary& dictionary);
|
||||
~RenderableVolumeCL();
|
||||
|
||||
bool initialize();
|
||||
void render(const glm::mat4& modelViewProjection);
|
||||
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;
|
||||
@@ -67,16 +86,15 @@ private:
|
||||
ghoul::opencl::CLCommandQueue _commands;
|
||||
ghoul::opencl::CLProgram _program;
|
||||
ghoul::opencl::CLKernel _kernel;
|
||||
ghoul::opencl::CLWorkSize* _ws;
|
||||
cl_mem _clBackTexture, _clFrontTexture, _clVolume, _clOutput;
|
||||
|
||||
|
||||
std::string _kernelPath;
|
||||
ghoul::filesystem::File* _kernelSourceFile;
|
||||
bool _kernelUpdateOnSave;
|
||||
std::mutex _kernelMutex;
|
||||
void _safeKernelCompilation();
|
||||
std::mutex* _kernelMutex;
|
||||
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // VOLUMERAYCASTER_H
|
||||
#endif
|
||||
113
include/openspace/rendering/renderablevolumeexpert.h
Normal file
113
include/openspace/rendering/renderablevolumeexpert.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <openspace/rendering/renderablevolume.h>
|
||||
|
||||
// ghoul includes
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/framebufferobject.h>
|
||||
#include <ghoul/opencl/clcontext.h>
|
||||
#include <ghoul/opencl/clcommandqueue.h>
|
||||
#include <ghoul/opencl/clprogram.h>
|
||||
#include <ghoul/opencl/clkernel.h>
|
||||
#include <ghoul/io/rawvolumereader.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
|
||||
#include <sgct.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <memory>
|
||||
#else
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
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<std::string> _volumePaths;
|
||||
std::vector<ghoul::RawVolumeReader::ReadHints> _volumeHints;
|
||||
|
||||
// Textures
|
||||
ghoul::opengl::Texture* _backTexture;
|
||||
ghoul::opengl::Texture* _frontTexture;
|
||||
ghoul::opengl::Texture* _output;
|
||||
std::vector<ghoul::opengl::Texture*> _volumes;
|
||||
std::vector<ghoul::opengl::Texture*> _transferFunctions;
|
||||
std::vector<ghoul::filesystem::File*> _transferFunctionsFiles;
|
||||
|
||||
// opencl texture memory pointers
|
||||
cl_mem _clBackTexture;
|
||||
cl_mem _clFrontTexture;
|
||||
cl_mem _clOutput;
|
||||
std::vector<cl_mem> _clVolumes;
|
||||
std::vector<cl_mem> _clTransferFunctions;
|
||||
|
||||
// opencl program
|
||||
ghoul::opencl::CLContext _context;
|
||||
ghoul::opencl::CLCommandQueue _commands;
|
||||
ghoul::opencl::CLProgram _program;
|
||||
ghoul::opencl::CLKernel _kernel;
|
||||
ghoul::filesystem::File* _kernelSourceFile;
|
||||
std::vector<std::pair<ghoul::opencl::CLProgram::Option, bool> > _kernelOptions;
|
||||
bool _programUpdateOnSave;
|
||||
|
||||
// mutexes to prevent inconsistencies
|
||||
std::mutex* _kernelLock;
|
||||
std::mutex* _textureLock;
|
||||
|
||||
ghoul::opengl::FramebufferObject* _fbo;
|
||||
ghoul::opengl::ProgramObject *_fboProgram;
|
||||
ghoul::opengl::ProgramObject *_quadProgram;
|
||||
sgct_utils::SGCTBox* _boundingBox;
|
||||
GLuint _screenQuad;
|
||||
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif
|
||||
@@ -22,55 +22,66 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __VOLUMERAYCASTERGL_H__
|
||||
#define __VOLUMERAYCASTERGL_H__
|
||||
#ifndef __RENDERABLEVOLUMEGL_H__
|
||||
#define __RENDERABLEVOLUMEGL_H__
|
||||
|
||||
#include <openspace/rendering/volumeraycaster.h>
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderablevolume.h>
|
||||
|
||||
// ghoul includes
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/framebufferobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/opengl/framebufferobject.h>
|
||||
#include <ghoul/io/rawvolumereader.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
|
||||
#include <sgct.h>
|
||||
|
||||
#include <memory>
|
||||
#ifdef __APPLE__
|
||||
#include <memory>
|
||||
#else
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
namespace openspace {
|
||||
using namespace ghoul::opengl;
|
||||
|
||||
class VolumeRaycasterGL: public VolumeRaycaster {
|
||||
class RenderableVolumeGL: public RenderableVolume {
|
||||
public:
|
||||
VolumeRaycasterGL(const ghoul::Dictionary& dictionary);
|
||||
~VolumeRaycasterGL();
|
||||
|
||||
|
||||
// constructors & destructor
|
||||
RenderableVolumeGL(const ghoul::Dictionary& dictionary);
|
||||
~RenderableVolumeGL();
|
||||
|
||||
bool initialize();
|
||||
void render(const glm::mat4& modelViewProjection);
|
||||
bool deinitialize();
|
||||
|
||||
virtual void render(const Camera *camera, const psc& thisPosition);
|
||||
virtual void update();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
std::string _filename;
|
||||
ghoul::RawVolumeReader::ReadHints _hints;
|
||||
float _stepSize;
|
||||
FramebufferObject* _fbo;
|
||||
Texture* _backTexture;
|
||||
Texture* _frontTexture;
|
||||
Texture* _volume;
|
||||
ProgramObject *_fboProgram, *_twopassProgram;
|
||||
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;
|
||||
GLuint _screenQuad;
|
||||
|
||||
std::mutex _shaderMutex;
|
||||
std::mutex* _shaderMutex;
|
||||
|
||||
std::string _vshaderpath;
|
||||
std::string _fshaderpath;
|
||||
ghoul::filesystem::File* _vertexSourceFile;
|
||||
ghoul::filesystem::File* _fragmentSourceFile;
|
||||
bool _programUpdateOnSave;
|
||||
|
||||
void safeShaderCompilation();
|
||||
|
||||
void _safeShaderCompilation();
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // VOLUMERAYCASTER_H
|
||||
#endif
|
||||
@@ -1,44 +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 __VOLUMERAYCASTER_H__
|
||||
#define __VOLUMERAYCASTER_H__
|
||||
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class VolumeRaycaster {
|
||||
public:
|
||||
VolumeRaycaster() = default;
|
||||
VolumeRaycaster(const ghoul::Dictionary& dictionary);
|
||||
virtual ~VolumeRaycaster();
|
||||
|
||||
virtual bool initialize() = 0;
|
||||
virtual void render(const glm::mat4& modelViewProjection) = 0;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // VOLUMERAYCASTER_H
|
||||
@@ -21,7 +21,7 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
/*
|
||||
#ifndef __VOLUMERAYCASTERSINGLEPASS_H__
|
||||
#define __VOLUMERAYCASTERSINGLEPASS_H__
|
||||
|
||||
@@ -59,3 +59,4 @@ private:
|
||||
} // namespace openspace
|
||||
|
||||
#endif // VOLUMERAYCASTER_H
|
||||
*/
|
||||
Submodule openspace-data updated: cc46c9a885...e49a0abea9
@@ -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. *
|
||||
****************************************************************************************/
|
||||
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderablevolume.h>
|
||||
@@ -6,8 +29,6 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/volumeraycastergl.h>
|
||||
#include <openspace/rendering/volumeraycastercl.h>
|
||||
#include <sgct.h>
|
||||
|
||||
namespace {
|
||||
@@ -16,109 +37,25 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
RenderableVolume::RenderableVolume(const ghoul::Dictionary& dictionary): _volumePath("") {
|
||||
RenderableVolume::RenderableVolume(const ghoul::Dictionary& dictionary) {
|
||||
|
||||
// get path if available
|
||||
std::string path = "";
|
||||
_relativePath = "";
|
||||
if(dictionary.hasKey("Path")) {
|
||||
dictionary.getValue("Path", path);
|
||||
path += "/";
|
||||
dictionary.getValue("Path", _relativePath);
|
||||
_relativePath += "/";
|
||||
}
|
||||
|
||||
if(dictionary.hasKey("Volume")) {
|
||||
dictionary.getValue("Volume", _volumePath);
|
||||
_volumePath = findPath(_volumePath, path);
|
||||
}
|
||||
|
||||
// parse hints
|
||||
ghoul::Dictionary hintsDictionary;
|
||||
if(dictionary.hasKey("Hints"))
|
||||
dictionary.getValue("Hints", hintsDictionary);
|
||||
_hints = readHints(hintsDictionary);
|
||||
|
||||
_programUpdateOnSave = false;
|
||||
if(dictionary.hasKey("UpdateOnSave")) {
|
||||
if(dictionary.getValue("UpdateOnSave", _programUpdateOnSave)) {
|
||||
}
|
||||
}
|
||||
|
||||
ghoul::Dictionary raycasterDictionary;
|
||||
raycasterDictionary.setValue("Filepath", _volumePath);
|
||||
raycasterDictionary.setValue("Hints", _hints);
|
||||
raycasterDictionary.setValue("ProgramUpdateOnSave", _programUpdateOnSave);
|
||||
|
||||
if (dictionary.hasKey("Kernel")) {
|
||||
std::string kernelPath = "";
|
||||
if(dictionary.getValue("Kernel", kernelPath)) {
|
||||
kernelPath = findPath(kernelPath, path);
|
||||
}
|
||||
// opencl
|
||||
raycasterDictionary.setValue("Kernel", kernelPath);
|
||||
_rayCaster = new VolumeRaycasterCL(raycasterDictionary);
|
||||
} else if(dictionary.hasKey("Shaders")){
|
||||
|
||||
ghoul::Dictionary shadersDictionary;
|
||||
if(dictionary.getValue("Shaders", shadersDictionary)) {
|
||||
std::string vertexShaderPath = "";
|
||||
std::string fragShaderPath = "";
|
||||
shadersDictionary.getValue("VertexShader", vertexShaderPath);
|
||||
shadersDictionary.getValue("FragmentShader", fragShaderPath);
|
||||
|
||||
LDEBUG("vertexShaderPath: " << vertexShaderPath);
|
||||
LDEBUG("fragShaderPath: " << fragShaderPath);
|
||||
vertexShaderPath = findPath(vertexShaderPath, path);
|
||||
fragShaderPath = findPath(fragShaderPath, path);
|
||||
|
||||
raycasterDictionary.setValue("VertexShader", vertexShaderPath);
|
||||
raycasterDictionary.setValue("FragmentShader", fragShaderPath);
|
||||
}
|
||||
|
||||
// glsl
|
||||
_rayCaster = new VolumeRaycasterGL(raycasterDictionary);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RenderableVolume::~RenderableVolume() {
|
||||
deinitialize();
|
||||
}
|
||||
|
||||
bool RenderableVolume::initialize() {
|
||||
return _rayCaster->initialize();
|
||||
}
|
||||
|
||||
bool RenderableVolume::deinitialize() {
|
||||
if(_rayCaster)
|
||||
delete _rayCaster;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderableVolume::render(const Camera *camera, const psc &thisPosition) {
|
||||
|
||||
// check so that the raycaster is set
|
||||
assert(_rayCaster);
|
||||
|
||||
float speed = 50.0f;
|
||||
float time = sgct::Engine::getTime();
|
||||
glm::mat4 transform = camera->getViewProjectionMatrix();
|
||||
|
||||
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));
|
||||
_rayCaster->render(transform);
|
||||
}
|
||||
|
||||
void RenderableVolume::update() {
|
||||
|
||||
}
|
||||
|
||||
std::string RenderableVolume::findPath(const std::string& path, const std::string& relativePath) {
|
||||
std::string RenderableVolume::findPath(const std::string& path) {
|
||||
std::string tmp = absPath(path);
|
||||
if(FileSys.fileExists(tmp))
|
||||
return tmp;
|
||||
|
||||
tmp = absPath(relativePath + path);
|
||||
tmp = absPath(_relativePath + path);
|
||||
if(FileSys.fileExists(tmp))
|
||||
return tmp;
|
||||
|
||||
@@ -130,8 +67,8 @@ std::string RenderableVolume::findPath(const std::string& path, const std::strin
|
||||
ghoul::RawVolumeReader::ReadHints RenderableVolume::readHints(const ghoul::Dictionary& dictionary) {
|
||||
ghoul::RawVolumeReader::ReadHints hints;
|
||||
hints._dimensions = glm::ivec3(1, 1, 1);
|
||||
hints._format = ghoul::opengl::Texture::Format::Red;
|
||||
hints._internalFormat = GL_R8;
|
||||
hints._format = ghoul::opengl::Texture::Format::Red;
|
||||
hints._internalFormat = GL_R8;
|
||||
|
||||
// parse hints
|
||||
double tempValue;
|
||||
@@ -186,5 +123,13 @@ ghoul::RawVolumeReader::ReadHints RenderableVolume::readHints(const ghoul::Dicti
|
||||
}
|
||||
return hints;
|
||||
}
|
||||
|
||||
|
||||
ghoul::opengl::Texture* RenderableVolume::loadTransferFunction(const std::string& filepath) {
|
||||
if ( ! FileSys.fileExists(filepath)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ghoul::opengl::loadTexture(filepath);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -22,64 +22,121 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/rendering/volumeraycastercl.h>
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderablevolumecl.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <ghoul/opengl/texturereader.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/opencl/clworksize.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
std::string _loggerCat = "VolumeRaycasterCL";
|
||||
std::string _loggerCat = "RenderableVolumeCL";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
VolumeRaycasterCL::VolumeRaycasterCL(const ghoul::Dictionary& dictionary):
|
||||
_fbo(nullptr), _backTexture(nullptr), _frontTexture(nullptr), _volume(nullptr),
|
||||
_fboProgram(nullptr), _boundingBox(nullptr), _screenQuad(0),
|
||||
_kernelPath(""), _kernelSourceFile(nullptr), _kernelUpdateOnSave(false) {
|
||||
RenderableVolumeCL::RenderableVolumeCL(const ghoul::Dictionary& dictionary):
|
||||
RenderableVolume(dictionary),
|
||||
_backTexture(nullptr), _frontTexture(nullptr), _output(nullptr),
|
||||
_clBackTexture(0), _clFrontTexture(0), _clOutput(0),
|
||||
_kernelSourceFile(nullptr) {
|
||||
|
||||
if (dictionary.hasKey("Filepath")) {
|
||||
std::string filename;
|
||||
if(dictionary.getValue("Filepath", filename)) {
|
||||
if (FileSys.ref().fileExists(absPath(filename))) {
|
||||
_filename = absPath(filename);
|
||||
_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("Hints")) {
|
||||
if(dictionary.getValue("Hints", _hints)) {
|
||||
}
|
||||
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")) {
|
||||
std::string filename;
|
||||
if(dictionary.getValue("Kernel", filename)) {
|
||||
if (FileSys.ref().fileExists(absPath(filename))) {
|
||||
_kernelPath = absPath(filename);
|
||||
}
|
||||
if(dictionary.getValue("Kernel", kernelPath)) {
|
||||
kernelPath = findPath(kernelPath);
|
||||
}
|
||||
}
|
||||
|
||||
if (dictionary.hasKey("KernelUpdateOnSave")) {
|
||||
if(dictionary.getValue("KernelUpdateOnSave", _kernelUpdateOnSave)) {
|
||||
}
|
||||
if (kernelPath != "") {
|
||||
_kernelSourceFile = new ghoul::filesystem::File(kernelPath, false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
VolumeRaycasterCL::~VolumeRaycasterCL() {
|
||||
RenderableVolumeCL::~RenderableVolumeCL() {
|
||||
deinitialize();
|
||||
delete _kernelMutex;
|
||||
}
|
||||
|
||||
bool VolumeRaycasterCL::initialize() {
|
||||
bool RenderableVolumeCL::initialize() {
|
||||
assert(_filename != "");
|
||||
// ------ VOLUME READING ----------------
|
||||
ghoul::RawVolumeReader rawReader(_hints);
|
||||
@@ -129,8 +186,8 @@ bool VolumeRaycasterCL::initialize() {
|
||||
_fbo = new ghoul::opengl::FramebufferObject();
|
||||
_fbo->activate();
|
||||
|
||||
int x = sgct::Engine::instance()->getActiveXResolution();
|
||||
int y = sgct::Engine::instance()->getActiveYResolution();
|
||||
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));
|
||||
@@ -151,44 +208,55 @@ bool VolumeRaycasterCL::initialize() {
|
||||
_clOutput = _context.createTextureFromGLTexture(CL_MEM_WRITE_ONLY, *_output);
|
||||
|
||||
auto privateCallback = [this](const ghoul::filesystem::File& file) {
|
||||
_safeKernelCompilation();
|
||||
safeKernelCompilation();
|
||||
};
|
||||
_kernelSourceFile = new ghoul::filesystem::File(_kernelPath, false);
|
||||
|
||||
_kernelSourceFile = new ghoul::filesystem::File(_kernelSourceFile->path(), false);
|
||||
if(_kernelUpdateOnSave)
|
||||
_kernelSourceFile->setCallback(privateCallback);
|
||||
privateCallback(*_kernelSourceFile);
|
||||
|
||||
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 VolumeRaycasterCL::_safeKernelCompilation() {
|
||||
if(_context.isValidContext()) {
|
||||
void RenderableVolumeCL::render(const Camera *camera, const psc &thisPosition) {
|
||||
|
||||
ghoul::opencl::CLProgram tmpProgram = _context.createProgram(_kernelSourceFile->path());
|
||||
tmpProgram.setOption(ghoul::opencl::CLProgram::Option::OptDisable, 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ! _kernel.isValidKernel())
|
||||
return;
|
||||
|
||||
void VolumeRaycasterCL::render(const glm::mat4& modelViewProjection) {
|
||||
|
||||
float speed = 50.0f;
|
||||
float time = sgct::Engine::getTime();
|
||||
glm::mat4 transform = camera->getViewProjectionMatrix();
|
||||
|
||||
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;
|
||||
|
||||
@@ -196,7 +264,7 @@ void VolumeRaycasterCL::render(const glm::mat4& modelViewProjection) {
|
||||
GLuint sgctFBO = ghoul::opengl::FramebufferObject::getActiveObject(); // Save SGCTs main FBO
|
||||
_fbo->activate();
|
||||
_fboProgram->activate();
|
||||
_fboProgram->setUniform("modelViewProjection", modelViewProjection);
|
||||
_fboProgram->setUniform("modelViewProjection", transform);
|
||||
|
||||
// Draw backface
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
@@ -222,24 +290,10 @@ void VolumeRaycasterCL::render(const glm::mat4& modelViewProjection) {
|
||||
// ------ DRAW TO SCREEN ----------------
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sgctFBO); // Re-bind SGCTs main FBO
|
||||
|
||||
size_t x = sgct::Engine::instance()->getActiveXResolution();
|
||||
size_t y = sgct::Engine::instance()->getActiveYResolution();
|
||||
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;
|
||||
}
|
||||
ghoul::opencl::CLWorkSize ws({x,y}, {local_x,local_y});
|
||||
|
||||
|
||||
glFinish();
|
||||
_commands.enqueueKernelBlocking(_kernel, ws);
|
||||
_commands.enqueueKernelBlocking(_kernel, *_ws);
|
||||
_commands.finish();
|
||||
_quadProgram->activate();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@@ -252,30 +306,94 @@ void VolumeRaycasterCL::render(const glm::mat4& modelViewProjection) {
|
||||
|
||||
_quadProgram->deactivate();
|
||||
|
||||
/*
|
||||
_twopassProgram->activate();
|
||||
_twopassProgram->setUniform("stepSize", _stepSize);
|
||||
|
||||
// Set textures
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
_backTexture->bind();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
_frontTexture->bind();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
_volume->bind();
|
||||
|
||||
// Draw screenquad
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
_twopassProgram->deactivate();
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}// namespace openspace
|
||||
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
|
||||
503
src/rendering/renderablevolumeexpert.cpp
Normal file
503
src/rendering/renderablevolumeexpert.cpp
Normal file
@@ -0,0 +1,503 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <openspace/rendering/renderablevolumeexpert.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
#include <ghoul/opengl/texturereader.h>
|
||||
#include <ghoul/opencl/clworksize.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
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),
|
||||
_backTexture(nullptr), _frontTexture(nullptr), _output(nullptr),
|
||||
_clBackTexture(0), _clFrontTexture(0), _clOutput(0),
|
||||
_kernelSourceFile(nullptr), _programUpdateOnSave(false) {
|
||||
|
||||
_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);
|
||||
ghoul::RawVolumeReader::ReadHints hints = readHints(hintsDictionary);
|
||||
|
||||
_volumePaths.push_back(file);
|
||||
_volumeHints.push_back(hints);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (kernelPath != "") {
|
||||
_kernelSourceFile = new ghoul::filesystem::File(kernelPath, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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::RawVolumeReader rawReader(_volumeHints.at(i));
|
||||
ghoul::opengl::Texture* volume = rawReader.read(_volumePaths.at(i));
|
||||
volume->uploadTexture();
|
||||
cl_mem volumeTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *volume);
|
||||
|
||||
_volumes.push_back(volume);
|
||||
_clVolumes.push_back(volumeTexture);
|
||||
}
|
||||
|
||||
// ------ 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<void*>(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
|
||||
|
||||
if( ! OsEng.ref().configurationManager().getValue("RaycastProgram", _fboProgram)) {
|
||||
LERROR("Could not find 'RaycastProgram'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ! OsEng.ref().configurationManager().getValue("Quad", _quadProgram)) {
|
||||
LERROR("Could not find 'Quad'");
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------ 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));
|
||||
_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);
|
||||
_clOutput = _context.createTextureFromGLTexture(CL_MEM_WRITE_ONLY, *_output);
|
||||
|
||||
// Compile kernels
|
||||
safeKernelCompilation();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderableVolumeExpert::deinitialize() {
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderableVolumeExpert::render(const Camera *camera, const psc &thisPosition) {
|
||||
|
||||
// check so that the raycaster is set
|
||||
//assert(_rayCaster);
|
||||
|
||||
if( ! _kernel.isValidKernel())
|
||||
return;
|
||||
|
||||
float speed = 50.0f;
|
||||
float time = sgct::Engine::getTime();
|
||||
glm::mat4 transform = camera->getViewProjectionMatrix();
|
||||
|
||||
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));
|
||||
|
||||
|
||||
// ------ 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
|
||||
|
||||
size_t x = sgct::Engine::instance()->getActiveXResolution();
|
||||
size_t y = sgct::Engine::instance()->getActiveYResolution();
|
||||
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;
|
||||
}
|
||||
ghoul::opencl::CLWorkSize ws({x,y}, {local_x,local_y});
|
||||
|
||||
_textureLock->lock();
|
||||
_kernelLock->lock();
|
||||
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);
|
||||
_kernelLock->unlock();
|
||||
_textureLock->unlock();
|
||||
|
||||
_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);
|
||||
}
|
||||
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; ++i) {
|
||||
CLKernel::AccessQualifier acq = tmpKernel.argumentAccessQualifier(i);
|
||||
CLKernel::AccessQualifier expected = CLKernel::AccessQualifier::READ_ONLY;
|
||||
if (acq != expected) {
|
||||
LWARNING("Argument " << i << " is '" <<
|
||||
CLKernel::AccessQualifierName(acq) <<"', expected '" <<
|
||||
CLKernel::AccessQualifierName(expected) << "'");
|
||||
argumentError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(argumentError)
|
||||
return;
|
||||
|
||||
|
||||
tmpKernel.setArgument(0, &_clFrontTexture);
|
||||
tmpKernel.setArgument(1, &_clBackTexture);
|
||||
tmpKernel.setArgument(2, &_clOutput);
|
||||
|
||||
size_t argumentNr = 3;
|
||||
for(auto volume: _clVolumes) {
|
||||
tmpKernel.setArgument(argumentNr, &volume);
|
||||
++argumentNr;
|
||||
}
|
||||
for(auto transferFunction: _clTransferFunctions) {
|
||||
tmpKernel.setArgument(argumentNr, &transferFunction);
|
||||
++argumentNr;
|
||||
}
|
||||
|
||||
if (argumentNr > 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());
|
||||
//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
|
||||
@@ -22,59 +22,81 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/rendering/volumeraycastergl.h>
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderablevolumegl.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <ghoul/opengl/texturereader.h>
|
||||
#include <ghoul/opencl/clworksize.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/io/rawvolumereader.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
|
||||
namespace {
|
||||
std::string _loggerCat = "VolumeRaycasterGL";
|
||||
std::string _loggerCat = "RenderableVolumeGL";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
VolumeRaycasterGL::VolumeRaycasterGL(const ghoul::Dictionary& dictionary):
|
||||
_fbo(nullptr), _backTexture(nullptr), _frontTexture(nullptr), _volume(nullptr),
|
||||
_fboProgram(nullptr), _twopassProgram(nullptr), _boundingBox(nullptr), _screenQuad(0) {
|
||||
RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary):
|
||||
RenderableVolume(dictionary),
|
||||
_backTexture(nullptr), _frontTexture(nullptr), _screenQuad(0),
|
||||
_programUpdateOnSave(false) {
|
||||
|
||||
_shaderMutex = new std::mutex;
|
||||
|
||||
if (dictionary.hasKey("Filepath")) {
|
||||
std::string filename;
|
||||
if(dictionary.getValue("Filepath", filename)) {
|
||||
if (FileSys.ref().fileExists(absPath(filename))) {
|
||||
_filename = absPath(filename);
|
||||
_filename = "";
|
||||
if(dictionary.hasKey("Volume")) {
|
||||
if(dictionary.getValue("Volume", _filename)) {
|
||||
_filename = findPath(_filename);
|
||||
}
|
||||
}
|
||||
|
||||
LDEBUG("filename: " << _filename);
|
||||
|
||||
ghoul::Dictionary hintsDictionary;
|
||||
if(dictionary.hasKey("Hints"))
|
||||
dictionary.getValue("Hints", hintsDictionary);
|
||||
_hints = readHints(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);
|
||||
}
|
||||
}
|
||||
|
||||
if (dictionary.hasKey("Hints")) {
|
||||
if(dictionary.getValue("Hints", _hints)) {
|
||||
}
|
||||
|
||||
}
|
||||
_vshaderpath = "";
|
||||
_fshaderpath = "";
|
||||
|
||||
if (dictionary.hasKey("VertexShader")) {
|
||||
dictionary.getValue("VertexShader", _vshaderpath);
|
||||
if(dictionary.hasKey("UpdateOnSave")) {
|
||||
dictionary.getValue("UpdateOnSave", _programUpdateOnSave);
|
||||
}
|
||||
if (dictionary.hasKey("FragmentShader")) {
|
||||
dictionary.getValue("FragmentShader", _fshaderpath);
|
||||
}
|
||||
|
||||
_twopassProgram = new ProgramObject("TwoPassProgram");
|
||||
ShaderObject* vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex,_vshaderpath);
|
||||
ShaderObject* fragmentShader = new ShaderObject(ShaderObject::ShaderTypeFragment,_fshaderpath);
|
||||
_twopassProgram->attachObject(vertexShader);
|
||||
_twopassProgram->attachObject(fragmentShader);
|
||||
|
||||
}
|
||||
|
||||
VolumeRaycasterGL::~VolumeRaycasterGL() {
|
||||
RenderableVolumeGL::~RenderableVolumeGL() {
|
||||
deinitialize();
|
||||
if(_fbo)
|
||||
delete _fbo;
|
||||
if(_backTexture)
|
||||
@@ -87,12 +109,12 @@ VolumeRaycasterGL::~VolumeRaycasterGL() {
|
||||
delete _boundingBox;
|
||||
}
|
||||
|
||||
bool VolumeRaycasterGL::initialize() {
|
||||
bool RenderableVolumeGL::initialize() {
|
||||
assert(_filename != "");
|
||||
// ------ VOLUME READING ----------------
|
||||
// ------ VOLUME READING ----------------
|
||||
ghoul::RawVolumeReader rawReader(_hints);
|
||||
_volume = rawReader.read(_filename);
|
||||
|
||||
|
||||
// ------ SETUP GEOMETRY ----------------
|
||||
const GLfloat size = 1.0f;
|
||||
const GLfloat vertex_texcoord_data[] = { // square of two triangles (sigh)
|
||||
@@ -132,13 +154,13 @@ bool VolumeRaycasterGL::initialize() {
|
||||
OsEng.ref().configurationManager().getValue("RaycastProgram", _fboProgram);
|
||||
|
||||
auto privateCallback = [this](const ghoul::filesystem::File& file) {
|
||||
_safeShaderCompilation();
|
||||
safeShaderCompilation();
|
||||
};
|
||||
_vertexSourceFile = new ghoul::filesystem::File(_vshaderpath, false);
|
||||
_fragmentSourceFile = new ghoul::filesystem::File(_fshaderpath, false);
|
||||
_vertexSourceFile->setCallback(privateCallback);
|
||||
_fragmentSourceFile->setCallback(privateCallback);
|
||||
|
||||
if(_programUpdateOnSave) {
|
||||
_vertexSourceFile->setCallback(privateCallback);
|
||||
_fragmentSourceFile->setCallback(privateCallback);
|
||||
}
|
||||
|
||||
_twopassProgram->compileShaderObjects();
|
||||
_twopassProgram->linkProgramObject();
|
||||
_twopassProgram->setUniform("texBack", 0);
|
||||
@@ -147,13 +169,13 @@ bool VolumeRaycasterGL::initialize() {
|
||||
//OsEng.ref().configurationManager().getValue("TwoPassProgram", _twopassProgram);
|
||||
|
||||
// ------ SETUP FBO ---------------------
|
||||
_fbo = new FramebufferObject();
|
||||
_fbo = new ghoul::opengl::FramebufferObject();
|
||||
_fbo->activate();
|
||||
|
||||
int x = sgct::Engine::instance()->getActiveXResolution();
|
||||
int y = sgct::Engine::instance()->getActiveYResolution();
|
||||
_backTexture = new Texture(glm::size3_t(x,y,1));
|
||||
_frontTexture = new Texture(glm::size3_t(x,y,1));
|
||||
_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);
|
||||
@@ -161,17 +183,34 @@ bool VolumeRaycasterGL::initialize() {
|
||||
|
||||
_fbo->deactivate();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VolumeRaycasterGL::render(const glm::mat4& modelViewProjection) {
|
||||
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->getViewProjectionMatrix();
|
||||
|
||||
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 = FramebufferObject::getActiveObject(); // Save SGCTs main FBO
|
||||
GLuint sgctFBO = ghoul::opengl::FramebufferObject::getActiveObject(); // Save SGCTs main FBO
|
||||
_fbo->activate();
|
||||
_fboProgram->activate();
|
||||
_fboProgram->setUniform("modelViewProjection", modelViewProjection);
|
||||
_fboProgram->setUniform("modelViewProjection", transform);
|
||||
|
||||
// Draw backface
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
@@ -196,6 +235,12 @@ void VolumeRaycasterGL::render(const glm::mat4& modelViewProjection) {
|
||||
|
||||
// ------ 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);
|
||||
|
||||
_shaderMutex->lock();
|
||||
_twopassProgram->activate();
|
||||
_twopassProgram->setUniform("stepSize", _stepSize);
|
||||
|
||||
@@ -207,25 +252,30 @@ void VolumeRaycasterGL::render(const glm::mat4& modelViewProjection) {
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
_volume->bind();
|
||||
|
||||
// Draw screenquad
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
_twopassProgram->deactivate();
|
||||
_shaderMutex->unlock();
|
||||
|
||||
}
|
||||
|
||||
void VolumeRaycasterGL::_safeShaderCompilation() {
|
||||
_shaderMutex.lock();
|
||||
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();
|
||||
_shaderMutex->unlock();
|
||||
}
|
||||
|
||||
|
||||
}// namespace openspace
|
||||
|
||||
} // namespace openspace
|
||||
@@ -1,42 +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/rendering/volumeraycaster.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
|
||||
VolumeRaycaster::VolumeRaycaster(const ghoul::Dictionary& dictionary) {}
|
||||
|
||||
VolumeRaycaster::~VolumeRaycaster() {}
|
||||
|
||||
}// namespace openspace
|
||||
@@ -22,6 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
/*
|
||||
#include <openspace/rendering/volumeraycastersinglepass.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
@@ -135,3 +136,4 @@ void VolumeRaycasterSinglePass::render(const glm::mat4& modelViewProjection) {
|
||||
}
|
||||
|
||||
}// namespace openspace
|
||||
*/
|
||||
@@ -26,9 +26,14 @@
|
||||
|
||||
#include <cassert>
|
||||
|
||||
// renderables
|
||||
#include <openspace/rendering/renderableplanet.h>
|
||||
#include <openspace/rendering/renderablevolume.h>
|
||||
#include <openspace/rendering/renderablevolumeexpert.h>
|
||||
#include <openspace/rendering/renderablevolumecl.h>
|
||||
#include <openspace/rendering/renderablevolumegl.h>
|
||||
#include <openspace/flare/flare.h>
|
||||
|
||||
// positioninformation
|
||||
#include <openspace/scenegraph/constantpositioninformation.h>
|
||||
#include <openspace/scenegraph/spicepositioninformation.h>
|
||||
|
||||
@@ -54,11 +59,15 @@ void FactoryManager::initialize() {
|
||||
|
||||
// Add Renderables
|
||||
_manager->factoryByType<Renderable>()->
|
||||
registerClass<RenderablePlanet>("RenderablePlanet");
|
||||
registerClass<RenderablePlanet>("RenderablePlanet");
|
||||
_manager->factoryByType<Renderable>()->
|
||||
registerClass<RenderableVolume>("RenderableVolume");
|
||||
registerClass<RenderableVolumeCL>("RenderableVolumeCL");
|
||||
_manager->factoryByType<Renderable>()->
|
||||
registerClass<Flare>("RenderableFlare");
|
||||
registerClass<RenderableVolumeGL>("RenderableVolumeGL");
|
||||
_manager->factoryByType<Renderable>()->
|
||||
registerClass<RenderableVolumeExpert>("RenderableVolumeExpert");
|
||||
_manager->factoryByType<Renderable>()->
|
||||
registerClass<Flare>("RenderableFlare");
|
||||
|
||||
// Add PositionInformations
|
||||
_manager->factoryByType<PositionInformation>()->
|
||||
|
||||
Reference in New Issue
Block a user