diff --git a/include/openspace/rendering/renderablevolumeexpert.h b/include/openspace/rendering/renderablevolumeexpert.h index 82170ea19a..3583d7df12 100644 --- a/include/openspace/rendering/renderablevolumeexpert.h +++ b/include/openspace/rendering/renderablevolumeexpert.h @@ -27,6 +27,7 @@ // open space includes #include +#include // ghoul includes #include @@ -39,14 +40,18 @@ #include #include -#include - #ifdef __APPLE__ #include #else #include #endif +namespace ghoul { + namespace opencl { + class CLWorkSize; + } +} + namespace openspace { class RenderableVolumeExpert: public RenderableVolume { @@ -73,8 +78,6 @@ private: std::vector _volumeHints; // Textures - ghoul::opengl::Texture* _backTexture; - ghoul::opengl::Texture* _frontTexture; ghoul::opengl::Texture* _output; std::vector _volumes; std::vector _transferFunctions; @@ -92,6 +95,7 @@ private: ghoul::opencl::CLCommandQueue _commands; ghoul::opencl::CLProgram _program; ghoul::opencl::CLKernel _kernel; + ghoul::opencl::CLWorkSize* _ws; ghoul::filesystem::File* _kernelSourceFile; std::vector > _kernelOptions; bool _programUpdateOnSave; @@ -100,12 +104,12 @@ private: std::mutex* _kernelLock; std::mutex* _textureLock; - ghoul::opengl::FramebufferObject* _fbo; - ghoul::opengl::ProgramObject *_fboProgram; ghoul::opengl::ProgramObject *_quadProgram; sgct_utils::SGCTBox* _boundingBox; GLuint _screenQuad; + VolumeRaycasterBox* _colorBoxRenderer; + }; } // namespace openspace diff --git a/include/openspace/rendering/volumeraycasterbox.h b/include/openspace/rendering/volumeraycasterbox.h new file mode 100644 index 0000000000..d32302f627 --- /dev/null +++ b/include/openspace/rendering/volumeraycasterbox.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 VOLUMERAYCASTERBOX_H_ +#define VOLUMERAYCASTERBOX_H_ + +#include +#include +#include + +namespace sgct_utils { + class SGCTBox; +} + +namespace openspace { + +class VolumeRaycasterBox { +public: + VolumeRaycasterBox(); + ~VolumeRaycasterBox(); + bool initialize(); + void render(glm::mat4 MVP); + + ghoul::opengl::Texture* backFace(); + ghoul::opengl::Texture* frontFace(); + glm::size2_t dimensions(); + +private: + ghoul::opengl::FramebufferObject* _fbo; + ghoul::opengl::Texture *_backTexture, *_frontTexture; + ghoul::opengl::ProgramObject *_boxProgram; + sgct_utils::SGCTBox* _boundingBox; + GLint _MVPLocation; + + glm::size2_t _dimensions; +}; + +} /* namespace openspace */ +#endif /* VOLUMERAYCASTERBOX_H_ */ diff --git a/src/rendering/renderablevolumeexpert.cpp b/src/rendering/renderablevolumeexpert.cpp index d689e9c313..fa7d1048f6 100644 --- a/src/rendering/renderablevolumeexpert.cpp +++ b/src/rendering/renderablevolumeexpert.cpp @@ -61,9 +61,9 @@ namespace openspace { RenderableVolumeExpert::RenderableVolumeExpert(const ghoul::Dictionary& dictionary): RenderableVolume(dictionary), - _backTexture(nullptr), _frontTexture(nullptr), _output(nullptr), + _output(nullptr), _clBackTexture(0), _clFrontTexture(0), _clOutput(0), - _kernelSourceFile(nullptr), _programUpdateOnSave(false) { + _kernelSourceFile(nullptr), _programUpdateOnSave(false), _colorBoxRenderer(nullptr) { _kernelLock = new std::mutex; _textureLock = new std::mutex; @@ -166,7 +166,8 @@ RenderableVolumeExpert::RenderableVolumeExpert(const ghoul::Dictionary& dictiona if (kernelPath != "") { _kernelSourceFile = new ghoul::filesystem::File(kernelPath, false); } - + + _colorBoxRenderer = new VolumeRaycasterBox(); } RenderableVolumeExpert::~RenderableVolumeExpert() { @@ -244,50 +245,44 @@ bool RenderableVolumeExpert::initialize() { 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(); + _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(); - _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); + _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(); + + 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; } @@ -299,9 +294,6 @@ bool RenderableVolumeExpert::deinitialize() { void RenderableVolumeExpert::render(const Camera *camera, const psc &thisPosition) { - // check so that the raycaster is set - //assert(_rayCaster); - if( ! _kernel.isValidKernel()) return; @@ -313,58 +305,13 @@ void RenderableVolumeExpert::render(const Camera *camera, const psc &thisPositio 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}); + _colorBoxRenderer->render(transform); _textureLock->lock(); _kernelLock->lock(); glFinish(); - _commands.enqueueKernelBlocking(_kernel, ws); + _commands.enqueueKernelBlocking(_kernel, *_ws); _commands.finish(); _quadProgram->activate(); @@ -465,9 +412,9 @@ void RenderableVolumeExpert::safeUpdateTexture(const ghoul::filesystem::File& fi 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) { @@ -495,6 +442,8 @@ void RenderableVolumeExpert::safeUpdateTexture(const ghoul::filesystem::File& fi // __kernel arguments(front, back, output, [_volumes], .. fileID)) _kernel.setArgument(3 + _volumes.size() + fileID, &clNewTexture); + LDEBUG("Transferfunction successfully updated"); + // end of critical section _textureLock->unlock(); } diff --git a/src/rendering/volumeraycasterbox.cpp b/src/rendering/volumeraycasterbox.cpp new file mode 100644 index 0000000000..59eac9b173 --- /dev/null +++ b/src/rendering/volumeraycasterbox.cpp @@ -0,0 +1,130 @@ +/***************************************************************************************** + * * + * 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 + + +namespace { + std::string _loggerCat = "VolumeRaycasterBox"; +} + +using namespace ghoul::opengl; + +namespace openspace { + +VolumeRaycasterBox::VolumeRaycasterBox() { + +} + +VolumeRaycasterBox::~VolumeRaycasterBox() {} + +bool VolumeRaycasterBox::initialize() { + _boundingBox = new sgct_utils::SGCTBox(1.0f, sgct_utils::SGCTBox::Regular); + + // ------ SETUP SHADER ----------------- + _boxProgram = new ProgramObject("RaycastBoxProgram"); + /* + ShaderObject* vertexShader = new ShaderObject(ShaderObject::ShaderTypeVertex, + absPath("${BASE_PATH}/shaders/exitpoints.vert")); + ShaderObject* fragmentShader = new ShaderObject(ShaderObject::ShaderTypeFragment, + absPath("${BASE_PATH}/shaders/exitpoints.frag")); + + + _boxProgram->attachObject(vertexShader); + _boxProgram->attachObject(fragmentShader); + _boxProgram->compileShaderObjects(); + _boxProgram->linkProgramObject(); + */ + OsEng.configurationManager().getValue("RaycastProgram", _boxProgram); + _MVPLocation = _boxProgram->uniformLocation("modelViewProjection"); + + // ------ SETUP FBO --------------------- + _fbo = new FramebufferObject(); + _fbo->activate(); + + + size_t x = sgct::Engine::instance()->getActiveXResolution(); + size_t y = sgct::Engine::instance()->getActiveYResolution(); + _dimensions = glm::size2_t(x, y); + + _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; +} + +void VolumeRaycasterBox::render(glm::mat4 MVP) { + GLuint activeFBO = ghoul::opengl::FramebufferObject::getActiveObject(); // Save SGCTs main FBO + _fbo->activate(); + _boxProgram->activate(); + _boxProgram->setUniform(_MVPLocation, MVP); + + // 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); + + _boxProgram->deactivate(); + _fbo->deactivate(); + glBindFramebuffer(GL_FRAMEBUFFER, activeFBO); +} + +Texture* VolumeRaycasterBox::backFace() { + return _backTexture; +} + +Texture* VolumeRaycasterBox::frontFace() { + return _frontTexture; +} + +glm::size2_t VolumeRaycasterBox::dimensions() { + return _dimensions; +} + +} /* namespace openspace */