diff --git a/README.md b/README.md index 8e735931b28917791b68f64eb0f369de7953d403..4b8c16abd2308f65f6f3503cbe9ee4d1ac87fb94 100644 --- a/README.md +++ b/README.md @@ -85,10 +85,11 @@ used in the following projects : ## Authors: * Florent Berthaut, Assistant Professor, Université de Lille, CRIStAL/MINT - florent_DOT_berthaut_AT_univ-lille_DOT_fr -* Alan Menit alanmenit_AT_gmail_DOT_com + (https://pro.univ-lille.fr/florent-berthaut) +* Alan Menit * Boris Legal * Anthony Beuchey * Cagan Arslan +* Luka Claeys diff --git a/src/Reveal.cpp b/src/Reveal.cpp index 44c7273a730e1dd7a933c19bcb5f3be356da81d4..9e8e981fb7783c09404e0acaeaac295fa9ca7b08 100644 --- a/src/Reveal.cpp +++ b/src/Reveal.cpp @@ -60,6 +60,7 @@ #include "osc/OscManager.hpp" #include "osc/OscListener.hpp" + using namespace std; Reveal* Reveal::getInstance() { diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..16c294169c63ae5bff9f3e96e678f944a4ce9ee6 --- /dev/null +++ b/src/audio/AudioManager.cpp @@ -0,0 +1,146 @@ +/*************************************************************************** + * AudioManager.cpp + * Part of Rivill + * 2015- Florent Berthaut / Luka Claeys + * https://gitlab.univ-lille.fr/mint/rivill + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "AudioManager.hpp" + +void* audioThreadFunction(void* pvParam) { + AudioManager *pThis=(AudioManager*)pvParam; + RtAudio *audio = pThis->audio; + audio->startStream(); + return 0; +} + +AudioManager* AudioManager::getInstance() { + static AudioManager rev; + return &rev; +} + +AudioManager::~AudioManager() {} + +int AudioManager::getRate(){ + return data.nRate; +} + +int AudioManager::getBufferSize(){ + return buf; +} + +int AudioManager::getMixSize(){ + return data.mixSize; +} + +static int rtaudio_callback(void *outbuf, void *inbuf, unsigned int nFrames, double streamtime, RtAudioStreamStatus status, void *userdata){ + (void)inbuf; + float *buf = (float*)outbuf; + CallbackData *data = (CallbackData*) userdata; + unsigned int i = 0; + int j = 0; + int audioIndex = 0; + + //check if there is audio value to play + if(ringbuffer_read_space(data->audioBuf) > 2*(nFrames + data->mixSize)){//!=0){ + + //read the audio values + ringbuffer_read(data->audioBuf, data->audio, nFrames + data->mixSize); + + //put the values to play in the audio buffer + while(i < nFrames * data->nChannel) { + if(j < data->mixSize){ + buf[i] = data->audio[j] + data->mix[j]; + buf[i+1] = data->audio[j] + data->mix[j]; + + } + else{ + buf[i] = data->audio[j]; + buf[i+1] = data->audio[j]; + } + audioIndex += 1; + j += 1; + i += 2; + } + //save the value for the next crossfading + memcpy(&data->mix[0], data->audio + nFrames, data->mixSize*sizeof(float)); + } + return 0; +} + +AudioManager::AudioManager(){ + buf = 4096; + audio = new RtAudio(RtAudio::LINUX_PULSE); + param = new RtAudio::StreamParameters(); + param->deviceId = audio->getDefaultOutputDevice(); + param->nChannels = 2; + + audio->openStream(param, NULL, RTAUDIO_FLOAT32, 44100, &buf, rtaudio_callback, &data); + + data.mixSize = 100; + data.nRate = audio->getDeviceInfo(param->deviceId).preferredSampleRate; + data.nChannel = param->nChannels; + data.ratioSampleFreq = data.nRate/440.0; + data.ratioFreqSample = 1.0/data.ratioSampleFreq; + size_t size = 10 * buf; + data.audioBuf = ringbuffer_create(size); + + data.audio = new float[buf + data.mixSize]; + data.mix = new float[data.mixSize]; + memset(&data.mix[0], 0, data.mixSize*4); + audioValue = new float[buf + data.mixSize]; + m_thread = new std::thread(audioThreadFunction, this); + + +} + + +void AudioManager::changeBuf(float* outputBuf, float maxSinValue){ + + //check if there is space to write the new values + //if not, move write_ptr of both ringbuffer size index back + size_t write_space = ringbuffer_write_space(data.audioBuf); + if(write_space >= (buf+data.mixSize)){//!= 0){ + float phase = 0; + float pas = 1.0/float(data.mixSize); + + //fill the audioValue array with the audio value + for(int i=0; i < int(buf); i++){ + if(i < data.mixSize){ + audioValue[i] = outputBuf[i]*phase; + phase += pas; + } + else{ + audioValue[i] = outputBuf[i]; + } + + } + + //pas = 1/data.mixSize; + //fill the audioValue array with the values for the next crossfading + for(int i=0; i < data.mixSize; i++){ + audioValue[buf + i] = outputBuf[buf + i]*phase; + phase -= pas; + } + constAudioValue = const_cast<const float *>(audioValue); + + ringbuffer_write(data.audioBuf, constAudioValue, buf + data.mixSize); + } +} + + diff --git a/src/audio/AudioManager.hpp b/src/audio/AudioManager.hpp index ead8896e254322cd5d57d0f00d5f351516e347c0..f67d62a5c41b7ea10ec74dc470a6e0dc7e7c5e58 100644 --- a/src/audio/AudioManager.hpp +++ b/src/audio/AudioManager.hpp @@ -1,8 +1,8 @@ /*************************************************************************** * AudioManager.hpp - * Part of Revil - * 2015- Florent Berthaut - * hitmuri.net + * Part of Rivill + * 2015- Florent Berthaut / Luka Claeys + * https://gitlab.univ-lille.fr/mint/rivill ****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify @@ -20,22 +20,69 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <portaudio.h> +#include <rtaudio/RtAudio.h> +#include <cstring> +#include <math.h> +#include <unistd.h> +#include <mutex> +#include <thread> +#include <queue> +#include <iostream> +#include <fstream> +using namespace std; -#ifndef OscManager_h -#define OscManager_h +#include <sys/time.h> +#include "Ringbuffer.hpp" + + +#ifndef AudioManager_h +#define AudioManager_h + +//#define POWER32 pow(2,31) + +static std::mutex mtx_audio; + +typedef struct { + unsigned int nRate; /* Sampling Rate (sample/sec) */ + unsigned int nChannel; /* Channel Number */ + float ratioSampleFreq; /* Ratio between the sample frequence and the signal frequency */ + float ratioFreqSample; /* Ratio between the signal frequency and the sample frequence */ + int mixSize; /* the number of values to crossfade */ + ringbuffer *mixBuf; /* ringbuffer with the value for the crossfading */ + ringbuffer *audioBuf; /* ringbuffer with the value for audio render */ + float *audio; /* buffer to save the current audio value */ + float *mix; /* buffer to save the mix value */ +} CallbackData; + +static int rtaudio_callback(void *outbuf, void *inbuf, unsigned int nFrames, double streamtime, RtAudioStreamStatus status, void *userdata); class AudioManager { + public: + RtAudio *audio; + RtAudio::StreamParameters *param; + unsigned int buf; //the size of the audio buffer + CallbackData data; //the audio data structure + pthread_t t; + + public: static AudioManager* getInstance(); ~AudioManager(); + void changeBuf(float* outputBuf, float maxSinValue); + int getRate(); + int getBufferSize(); + int getMixSize(); private: - AudioManager(){} + std::thread* m_thread; + AudioManager(); + float * audioValue; //array to save the audio value before writing + const float *constAudioValue; //array to write the audio value in the ringbuffer + -} +}; #endif diff --git a/src/audio/Ringbuffer.cpp b/src/audio/Ringbuffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1a0103fbc3ff63f3a64b0892218413f86c4d2908 --- /dev/null +++ b/src/audio/Ringbuffer.cpp @@ -0,0 +1,264 @@ +#include "Ringbuffer.hpp" +#include <iostream> +ringbuffer* ringbuffer_create(size_t sz){ + int power_of_two; + ringbuffer* rb; + rb = (ringbuffer*) malloc(sizeof(ringbuffer)); + + if(rb == NULL){ + return NULL; + } + + //for(power_of_two = 1; 1 << power_of_two < sz; power_of_two++); + rb->size = sz;//1 << power_of_two; + rb->size_mask = rb->size; + rb->write_ptr = 0; + rb->read_ptr = 0; + rb->buf = (float *) malloc (rb->size * sizeof(float)); + if(rb->buf == NULL) { + free (rb); + return NULL; + } + memset(rb->buf, 0, rb->size * sizeof(float)); + + rb->mlocked = 0; + rb->writed = 0; + + return rb; +} + +void ringbuffer_free(ringbuffer *rb){ + free(rb->buf); + free(rb); +} + +int ringbuffer_mlock(ringbuffer *rb){ + rb->mlocked = 1; + return 0; +} + +void ringbuffer_reset(ringbuffer *rb){ + rb->read_ptr = 0; + rb->write_ptr = 0; + memset(rb->buf, 0, rb->size); +} + +void ringbuffer_reset_size(ringbuffer *rb, size_t sz){ + rb->size = sz; + rb->size_mask = rb->size; + //rb->size_mask -= 1; + rb->read_ptr = 0; + rb->write_ptr = 0; +} + +size_t ringbuffer_read_space(const ringbuffer *rb){ + size_t w,r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if(w>r){ + return w - r; + } + else if(w==r){ + if(rb->writed){ + return rb->size; + } + else{ + return 0; + } + //return (w - r + rb->size) & rb->size_mask; + } + else{ + return rb->size - (r - w); + } +} + +size_t ringbuffer_get_write_vector(const ringbuffer *rb){ + size_t w, r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if (w > r) { + return ((r - w + rb->size) & rb->size_mask) - 1; + } else if (w < r) { + return (r - w) - 1; + } else { + return rb->size - 1; + } +} + +size_t ringbuffer_read(ringbuffer *rb, float *dest, size_t cnt){ + size_t free_cnt; + size_t cnt2; + size_t to_read; + size_t n1,n2; + + free_cnt = ringbuffer_read_space(rb); + //std::cout<<free_cnt<<std::endl; + if(free_cnt == 0){ + return 0; + } + + if(free_cnt < cnt){ + to_read = free_cnt; + } + else{ + to_read = cnt; + } + + //to_read = cnt > free_cnt ? free_cnt : cnt; + cnt2 = rb->read_ptr + to_read; + + if(cnt2 > rb->size){ + n1 = rb->size - rb->read_ptr; + n2 = to_read - n1;//cnt2 & rb->size_mask; + } + else{ + n1 = to_read; + n2 = 0; + } + + memcpy(dest, &(rb->buf[rb->read_ptr]), n1*sizeof(float)); + + //rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask; + rb->read_ptr = rb->read_ptr + n1; + if(rb->read_ptr >= rb->size){ + rb->read_ptr = rb->read_ptr - rb->size; + } + + if(n2){ + memcpy(dest + n1, &(rb->buf[rb->read_ptr]), n2*sizeof(float)); + //rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask; + rb->read_ptr = rb->read_ptr + n2; + if(rb->read_ptr >= rb->size){ + rb->read_ptr = rb->read_ptr - rb->size; + } + } + + if(rb->read_ptr == rb->write_ptr){ + rb->writed = 0; + } + + return to_read; +} + +size_t ringbuffer_write_space (const ringbuffer * rb) +{ + size_t w, r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if (w > r) { + return rb->size -(w - r); + //return ((r - w + rb->size) & rb->size_mask) - 1; + } else if (w < r) { + return (r - w);// - 1; + } else { + if(!(rb->writed)){ + return rb->size; + } + else{ + return 0;//rb->size - 1; + } + } +} + +size_t ringbuffer_peek(ringbuffer *rb, float *dest, size_t cnt){ + size_t free_cnt; + size_t cnt2; + size_t to_read; + size_t n1, n2; + size_t tmp_read_ptr; + + tmp_read_ptr = rb->read_ptr; + free_cnt = ringbuffer_read_space(rb); + if (free_cnt == 0) { + return 0; + } + + to_read = cnt > free_cnt ? free_cnt : cnt; + + cnt2 = tmp_read_ptr + to_read; + + if (cnt2 > rb->size) { + n1 = rb->size - tmp_read_ptr; + n2 = cnt2 & rb->size_mask; + } else { + n1 = to_read; + n2 = 0; + } + + memcpy(dest, &(rb->buf[tmp_read_ptr]), n1); + tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask; + + if (n2) { + memcpy(dest + n1, &(rb->buf[tmp_read_ptr]), n2); + } + + return to_read; +} + +size_t ringbuffer_write(ringbuffer *rb, const float *src, size_t cnt){ + size_t free_cnt; + size_t cnt2; + size_t to_write; + size_t n1, n2; + + free_cnt = ringbuffer_write_space(rb); + if (free_cnt == 0) { + return 0; + } + + if(free_cnt < cnt){ + to_write = free_cnt; + } + else{ + to_write = cnt; + } + //to_write = cnt > free_cnt ? free_cnt : cnt; + + cnt2 = rb->write_ptr + to_write; + + if (cnt2 > rb->size) { + n1 = rb->size - rb->write_ptr; + n2 = to_write - n1;//cnt2 & rb->size_mask; + } else { + n1 = to_write; + n2 = 0; + } + + memcpy(&(rb->buf[rb->write_ptr]), src, n1*sizeof(float)); + //rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask; + rb->write_ptr = rb->write_ptr + n1; + + if(rb->write_ptr >= rb->size){ + rb->write_ptr = rb->write_ptr - rb->size; + } + + + if(n2){ + memcpy(&(rb->buf[rb->write_ptr]), src + n1, n2*sizeof(float)); + //rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask; + rb->write_ptr = rb->write_ptr + n2; + if(rb->write_ptr >= rb->size){ + rb->write_ptr = rb->write_ptr - rb->size; + } + } + + rb->writed = 1; + return to_write; +} + +void ringbuffer_read_advance(ringbuffer *rb, size_t cnt){ + size_t temp = (rb->read_ptr + cnt) & rb->size_mask; + rb->read_ptr = temp; +} + +void ringbuffer_write_advance(ringbuffer *rb, size_t cnt){ + size_t temp = (rb->write_ptr + cnt) & rb->size_mask; + rb->write_ptr = temp; +} + diff --git a/src/audio/Ringbuffer.hpp b/src/audio/Ringbuffer.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7f4a298c9b93097897f7727c9ae4aa603b48f5ec --- /dev/null +++ b/src/audio/Ringbuffer.hpp @@ -0,0 +1,35 @@ + +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> + +typedef struct +{ + float *buf; + size_t len; +} ringbuffer_data; + +typedef struct +{ + float* buf; + volatile size_t write_ptr; + volatile size_t read_ptr; + size_t size; + size_t size_mask; + int mlocked; + int writed; +}ringbuffer; + +ringbuffer *ringbuffer_create(size_t size); +void ringbuffer_free(ringbuffer *rb); +size_t ringbuffer_read(ringbuffer *rb, float *dest, size_t cnt); +size_t ringbuffer_peek(ringbuffer *rb, float *dest, size_t cnt); +void ringbuffer_read_advance(ringbuffer *rb, size_t cnt); +size_t ringbuffer_read_space(const ringbuffer *rb); +int ringbuffer_mlock(ringbuffer *rb); +void ringbuffer_reset(ringbuffer *rb); +void ringbuffer_reset_size (ringbuffer * rb, size_t sz); +size_t ringbuffer_write(ringbuffer *rb, const float *src, size_t cnt); +void ringbuffer_write_advance(ringbuffer *rb, size_t cnt); +size_t ringbuffer_write_space(const ringbuffer *rb); + diff --git a/src/modules/DepthCamModule.hpp b/src/modules/DepthCamModule.hpp index ac9ee78a97cf1b0a947fd87a3483d0943f00f44f..9fcae7e5d2e51e307acb169dc925f13a27e2aa45 100644 --- a/src/modules/DepthCamModule.hpp +++ b/src/modules/DepthCamModule.hpp @@ -33,7 +33,7 @@ #include <mutex> #include <OpenNI.h> -#include <opencv2/core/core.hpp> +#include <opencv2/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/calib3d/calib3d.hpp> diff --git a/src/modules/ProjectorModule.cpp b/src/modules/ProjectorModule.cpp index d59f86867e0ee50e0208eacec0a19d11010b94d5..3b0bbecc041accbe9c51f555b651e576542ac260 100644 --- a/src/modules/ProjectorModule.cpp +++ b/src/modules/ProjectorModule.cpp @@ -39,6 +39,7 @@ https://github.com/kylemcdonald/ofxCv #include "SpaceModule.hpp" #include "RevealedModule.hpp" +#include "shaders.h.in" using namespace std; using namespace glm; @@ -310,7 +311,7 @@ void ProjectorModule::draw() { glActiveTexture(GL_TEXTURE1); glUniform1i(m_uniforms[Reveal::RENDERPROG][Reveal::SELECTTEX], 1); glBindTexture(GL_TEXTURE_2D, m_selectTex); -#ifdef GL42 +#ifdef GL43 glActiveTexture(GL_TEXTURE7); glUniform1i(m_uniforms[Reveal::RENDERPROG][Reveal::OUTPUTTEX], 7); glBindImageTexture(7, m_outputTex, 0, GL_FALSE, 0, @@ -356,7 +357,7 @@ void ProjectorModule::draw() { glfwSwapBuffers(m_projWindow); //PROCESS OUTPUT -#ifdef GL42 +#ifdef GL43 if(m_processOutput) { processOutput(); } @@ -372,59 +373,16 @@ void ProjectorModule::initGL() { //POSTPROCESSING { - const char * vertSource = { -#ifdef GL42 - "#version 430 \n" -#else - "#version 410 \n" -#endif - " \n" - "in vec3 vertex; \n" - " \n" - "void main(void) {\n" - " gl_Position = vec4(vertex, 1.0);\n" - "}\n"}; - - const char * fragSource = { -#ifdef GL42 - "#version 430 \n" -#else - "#version 410 \n" -#endif - " \n" - "uniform float viewportWidth;\n" - "uniform float viewportHeight;\n" - "uniform float postFilter;\n" -#ifdef GL42 - "layout(binding=0) uniform sampler2D renderTex;\n" + +#ifdef GL43 + m_programs[Reveal::POSTPROG] + = Reveal::getInstance()->createProgram(post43VS.c_str(), + post43FS.c_str()); #else - "uniform sampler2D renderTex;\n" -#endif - " \n" - "out vec4 color;\n" - " \n" - "void main(void) {\n" - " float coordX = gl_FragCoord.x;\n" - " float coordY = gl_FragCoord.y;\n" - " ivec2 patSize = textureSize(renderTex, 0);\n" - " vec3 sumCol = vec3(0,0,0);\n" - " float cnt=0;\n" - " for(float dX = coordX-postFilter; dX <= coordX+postFilter; ++dX) {\n" - " for(float dY = coordY-postFilter; dY <= coordY+postFilter; ++dY) {\n" - " if(dX>=0 && dX<viewportWidth \n" - " && dY>=0 && dY<viewportHeight) {\n" - " sumCol+=texelFetch(renderTex, \n" - " ivec2((dX-0.5)/viewportWidth*patSize.x,\n" - " (dY-0.5)/viewportHeight*patSize.y),\n" - " 0).xyz; \n" - " cnt+=1;\n" - " }\n" - " }\n" - " }\n" - " color=vec4(sumCol.xyz/cnt, 1.0);\n" - "}\n"}; m_programs[Reveal::POSTPROG] - = Reveal::getInstance()->createProgram(vertSource, fragSource); + = Reveal::getInstance()->createProgram(post30VS.c_str(), + post30FS.c_str()); +#endif m_uniforms[Reveal::POSTPROG]=map<Reveal::REVIL_UNIFORM, GLint>(); m_uniforms[Reveal::POSTPROG][Reveal::VIEWPORTWIDTH] = glGetUniformLocation(m_programs[Reveal::POSTPROG],"viewportWidth"); @@ -436,653 +394,18 @@ void ProjectorModule::initGL() { = glGetUniformLocation(m_programs[Reveal::POSTPROG],"renderTex"); } - - //RENDER { - const char * vertSource = { - #ifdef GL42 - "#version 430 \n" - #else - "#version 410 \n" - #endif - " \n" - "in vec3 vertex; \n" - "in vec2 texCoords;\n" - " \n" - "uniform mat4 modelMat;\n" - "uniform mat4 viewMat;\n" - "uniform mat4 viewProjMat;\n" - "uniform float mirrored;\n" - " \n" - "out vec3 viewRay;\n" - "out vec2 uvCoords;\n" - " \n" - "void main(void) {\n" - " vec4 posWS = modelMat * vec4(vertex, 1.0);\n" - " if(mirrored<1) {\n" - " posWS.x = -posWS.x;\n" - " }\n" - " gl_Position = viewProjMat * posWS;\n" - " viewRay = posWS.xyz - vec3(viewMat[3][0],\n" - " viewMat[3][1],\n" - " viewMat[3][2]);\n" - " uvCoords=texCoords;\n" - "}\n"}; - - const char * fragSource = { -#ifdef GL42 - "#version 430 \n" -#else - "#version 410 \n" -#endif - "\n"//defined in Reveal.hpp - "const int BOX=0;\n" - "const int SPHERE=1;\n" - "const int TUBE=2;\n" - "const int CONE=3;\n" - "const int FRAME=4;\n" - "const int PATH=5;\n" - "const int MODEL=10;\n" - "\n" - "in vec3 viewRay;\n" - "in vec2 uvCoords;\n" - " \n" -#ifdef GL42 - "layout(binding=0) uniform sampler2D sliceTex;\n" - "layout(binding=1) uniform sampler2D selectTex;\n" - "layout(binding=2) uniform sampler3D insideTex;\n" - "layout(binding=3) uniform sampler2D surfaceTex;\n" - "layout(binding=4) uniform sampler3D reactTex;\n" - "layout(binding=5) uniform sampler3D surfDistTex;\n" - "layout(binding=6) uniform sampler2D gradientTex;\n" - "layout(r32ui, binding=7) uniform coherent uimage2D outputTex;\n" +#ifdef GL43 + m_programs[Reveal::RENDERPROG] + = Reveal::getInstance()->createProgram(render43VS.c_str(), + render43FS.c_str()); #else - "uniform sampler2D sliceTex;\n" - "uniform sampler2D selectTex;\n" - "uniform sampler3D insideTex;\n" - "uniform sampler2D surfaceTex;\n" - "uniform sampler3D reactTex;\n" - "uniform sampler3D surfDistTex;\n" - "uniform sampler2D gradientTex;\n" -#endif - "uniform float viewportWidth;\n" - "uniform float viewportHeight;\n" - "uniform float mirrored;\n" - "uniform float shapeID;\n" - "uniform float shapeIDBit;\n" - "uniform int shapeGeom;\n" - "uniform float subShapeID;\n" - "uniform float subShapesNb;\n" - "uniform mat4 subShapeInvMat;\n" - "uniform mat4 viewMat;\n" - "uniform mat4 modelMat;\n" - "uniform mat4 invModelMat;\n" - "uniform vec3 modelScale;\n" - "uniform int revealedBy;\n" - "\n" - "uniform vec3 shapeColor;\n" - //0: none, 1:color, 2:texture - "uniform int surface;\n" - "uniform vec3 surfaceColor;\n" - "uniform int insideOutputOnly;\n" - "uniform int reactivity;\n" - "uniform float thickness;\n" - "\n" - "uniform int insideVisible;\n" - //0:from center, 1:along x, 2: along y, 3:along z, 4 :from surface - "uniform int insideStructure;\n" - "uniform float structureRatio;\n" - "\n" - "uniform float gradientAlpha;\n" - //0:greyscale, 1:texture - "uniform int gradientType;\n" - "uniform int gradientSteps;\n" - "uniform float gradientCurveRatio;\n" - "\n" - "uniform float densityAlpha;\n" - //0:layers, 1:grid, 2:pointcloud - "uniform int densityType;\n" - "uniform float densityRatio;\n" - "uniform float densitySize;\n" - "uniform float densityCurveRatio;\n" - "\n" - "uniform float texAlpha;\n" - "uniform vec3 texOffset;\n" - "uniform vec3 texScale;\n" - "uniform int texGray;\n" -#ifdef GL42 - "uniform int revSize;\n" - "uniform int revSurface;\n" - "uniform int revInside;\n" - "uniform int revCenter;\n" - "uniform int revCursor;\n" - "uniform int revColor;\n" - "uniform int revHisto;\n" - "uniform int revVoxels;\n" - "uniform float revSubShapeID;\n" - "uniform int shapeOutSize;\n" - "uniform int histoOutSize;\n" - "uniform int voxelOutSize;\n" - "uniform int depthOutSize;\n" - "uniform int depthOutNb;\n" - "uniform vec4 boundingRect;\n" -#endif - " \n" - "vec3 rgb2hsv(vec3 c) {\n" - " vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n" - " vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n" - " vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n" - " float d = q.x - min(q.w, q.y);\n" - " float e = 1.0e-10;\n" - " return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)),d/(q.x + e), q.x);\n" - "}\n" - - "float random (vec3 st) {\n" - " return fract(sin(dot(st.xyz,\n" - " vec3(12.9898,78.233, 102.234)))*\n" - " 43758.5453123);\n" - "}\n" - - "out vec4 color;\n" - " \n" - "void main(void) {\n" - //get fragment coordinates - " float coordX = (gl_FragCoord.x-0.5)/viewportWidth;\n" - " float coordY = (gl_FragCoord.y-0.5)/viewportHeight;\n" - " ivec2 sliSize = textureSize(sliceTex, 0);\n" - //retrieve pixel in slicing texture - " vec4 sli = texelFetch(sliceTex,\n" - " ivec2(coordX*float(sliSize.x), \n" - " coordY*float(sliSize.y)), \n" - " 0);\n" - " float pixZ=abs(gl_FragCoord.z);\n" - " float cutZ=abs(sli.z);\n" - " int depthID=int(sli.y)-1;\n" -#ifdef GL42 - " int outCols=imageSize(outputTex).x;\n" - " int outOffset=(int(shapeID-1)*depthOutNb+(depthID-1))*revSize;\n" -#endif - " int rendered=0;\n" - " vec3 finalColor = shapeColor;\n" - " float alpha=0;\n" - " vec3 pixelPosW;\n" - " vec3 pixelPos = vec3(0.0, 0.0, 1.0);\n" - " vec3 ratioWithinBox = vec3(0.0, 0.0, 0.0);\n" - " vec3 outRatioWithinBox = vec3(0.0, 0.0, 0.0);\n" - //if there is a slicing pixel aligned with our coordinate - //and we are revealed by this depth module - " if(cutZ>0 && (revealedBy & (1<<(1+depthID)))>0 ) { \n" - //compute the slicing pixel world position - " pixelPosW = vec3(viewMat[3][0], \n" - " viewMat[3][1], \n" - " viewMat[3][2])\n" - " + vec3(normalize(viewRay) * sli.w);\n" - " pixelPosW.x = pixelPosW.x*(-2.0*(1-mirrored)+1.0);\n" - //compute the slicing pixel position in model coords - " pixelPos = (invModelMat * vec4(pixelPosW,1.0)).xyz;\n" - "\n" - //depending on type, test if slicing pixel inside - //and retrieve distance to the surface on each axis - " vec3 diffMin = vec3(1.0);\n" - " vec3 diffMax = vec3(1.0);\n" - " switch(shapeGeom) {\n" - " case PATH : {\n"//use min/max/size of current segment - " pixelPos = (subShapeInvMat*vec4(pixelPos,1.0)).xyz;\n" - " if(length(vec2(pixelPos.x, pixelPos.y))<=0.5\n" - " && (pixelPos.z>-0.5 && pixelPos.z<0.5)) { \n" - " float xx = (pixelPos.x)*(pixelPos.x);\n" - " float yy = (pixelPos.y)*(pixelPos.y);\n" - " float ax = sqrt(0.25-yy);\n" - " diffMin.x = pixelPos.x+ax;\n" - " diffMax.x = ax-pixelPos.x;\n" - " float ay = sqrt(0.25-xx);\n" - " diffMin.y = pixelPos.y+ay;\n" - " diffMax.y = ay-pixelPos.y;\n" - " diffMin.z = pixelPos.z+0.5;\n" - " diffMax.z = 0.5-pixelPos.z;\n" - " rendered=1;\n" - " }\n" - " }break;\n" - " case CONE : {\n" - " if(pixelPos.y<0.5 && pixelPos.y>-0.5) {\n" - " float xx = (pixelPos.x)*(pixelPos.x);\n" - " float yy = (pixelPos.y-0.5)*(pixelPos.y-0.5);\n" - " float zz = (pixelPos.z)*(pixelPos.z);\n" - " if((xx+zz)/yy<0.25){ \n" - " float ax = sqrt(0.25*yy-zz);\n" - " diffMin.x = pixelPos.x+ax;\n" - " diffMax.x = ax-pixelPos.x;\n" - " float ay = sqrt((yy+xx)/0.25);\n" - " diffMin.y = pixelPos.y+0.5;\n" - " diffMax.y = 0.5-pixelPos.y;\n" - " float az = sqrt(0.25*yy-xx);\n" - " diffMin.z = pixelPos.z+az;\n" - " diffMax.z = az-pixelPos.z;\n" - " rendered=1;\n" - " }\n" - " }\n" - " } break;\n" - " case TUBE : {\n" - " if(length(vec2(pixelPos.x, pixelPos.z))<=0.5\n" - " && (pixelPos.y>-0.5 && pixelPos.y<0.5)) { \n" - " float xx = (pixelPos.x)*(pixelPos.x);\n" - " float zz = (pixelPos.z)*(pixelPos.z);\n" - " float ax = sqrt(0.25-zz);\n" - " diffMin.x = pixelPos.x+ax;\n" - " diffMax.x = ax-pixelPos.x;\n" - " float az = sqrt(0.25-xx);\n" - " diffMin.z = pixelPos.z+az;\n" - " diffMax.z = az-pixelPos.z;\n" - " diffMin.y = pixelPos.y+0.5;\n" - " diffMax.y = 0.5-pixelPos.y;\n" - " rendered=1;\n" - " }\n" - " } break;\n" - " case SPHERE : {\n" - " if(length(pixelPos)<=0.5) { \n" - " float xx = (pixelPos.x)*(pixelPos.x);\n" - " float yy = (pixelPos.y)*(pixelPos.y);\n" - " float zz = (pixelPos.z)*(pixelPos.z);\n" - " float ax = sqrt(0.25-yy-zz);\n" - " diffMin.x = pixelPos.x+ax;\n" - " diffMax.x = ax-pixelPos.x;\n" - " float ay = sqrt(0.25-xx-zz);\n" - " diffMin.y = pixelPos.y+ay;\n" - " diffMax.y = ay-pixelPos.y;\n" - " float az = sqrt(0.25-xx-yy);\n" - " diffMin.z = pixelPos.z+az;\n" - " diffMax.z = az-pixelPos.z;\n" - " rendered=1;\n" - " }\n" - " } break;\n" - " case BOX : {\n" - " diffMin = pixelPos - vec3(-0.5, -0.5, -0.5);\n" - " diffMax = vec3(0.5, 0.5, 0.5) - pixelPos;\n" - " if(diffMin.x>0 && diffMax.x>0\n" - " && diffMin.y>0 && diffMax.y>0\n" - " && diffMin.z>0 && diffMax.z>0){\n" - " rendered=1;\n" - " } \n" - " } break;\n" - " case FRAME : {\n" - " diffMin = pixelPos - vec3(-0.5, -0.5, -0.5);\n" - " diffMax = vec3(0.5, 0.5, 0.5) - pixelPos;\n" - " if(diffMin.x>0 && diffMax.x>0\n" - " && diffMin.y>0 && diffMax.y>0\n" - " && diffMin.z>0 && diffMax.z>0){\n" - " rendered=1;\n" - " } \n" - " } break;\n" - " case MODEL : {\n" - " ivec2 selSize = textureSize(selectTex, 0);\n" - " vec4 sel = texelFetch(selectTex,\n" - " ivec2(coordX*float(selSize.x), \n" - " coordY*float(selSize.y)), \n" - " 0);\n" - //get front surfaces before depth map - " if(pixZ<=cutZ+thickness/1000.0) { \n" - " if(sel.z==0) {\n" - " if(sel.x==shapeID) {\n" - " rendered=1;\n" - " }\n" - " else if((int(shapeIDBit)&int(sel.w))>0) {\n" - " diffMin = pixelPos - vec3(-0.5, -0.5, -0.5);\n" - " diffMax = vec3(0.5, 0.5, 0.5) - pixelPos;\n" - " if(diffMin.x>0 && diffMax.x>0\n" - " && diffMin.y>0 && diffMax.y>0\n" - " && diffMin.z>0 && diffMax.z>0){\n" - " rendered=1;\n" - " }\n" - " }\n" - " }\n" - " if(surface>0 \n" - " && (pixZ>cutZ \n" - " || (sel.z>0 && (int(shapeIDBit)&int(sel.w))>0))) {\n" - " rendered=2;\n" - " }\n" - " }\n" - " } break;\n" - " }\n" - " if(rendered>0) {\n" - " ratioWithinBox = (pixelPos)+0.5;\n" - //test if on the surface - " if(diffMin.x*modelScale.x<thickness || \n" - " diffMax.x*modelScale.x<thickness || \n" - " diffMin.y*modelScale.y<thickness || \n" - " diffMax.y*modelScale.y<thickness || \n" - " diffMin.z*modelScale.z<thickness || \n" - " diffMax.z*modelScale.z<thickness) { \n" - " rendered=2;\n" - " } \n" - //extend ratiowithinbox to multiplesubshapes - //and get gradient ratio according to type - " float gradRatio = 0;\n" - " vec3 subAdd;\n" - " vec3 subDiv;\n" - " if(insideStructure==0) {\n"//from center - " subAdd = vec3(subShapeID, subShapeID, subShapeID);\n" - " subDiv = vec3(subShapesNb, subShapesNb, subShapesNb);\n" - " ratioWithinBox.xyz=(ratioWithinBox.xyz+subAdd)/subDiv;\n" - " outRatioWithinBox.xyz=ratioWithinBox.xyz;\n" - " gradRatio = length(ratioWithinBox.xyz\n" - " - vec3(0.5,0.5,0.5))/0.5;\n" - " }\n" - " else {\n"//from surface or along axes - " subAdd = vec3(0,0, subShapeID);\n" - " subDiv = vec3(1,1, subShapesNb);\n" - " ratioWithinBox.xyz=(ratioWithinBox.xyz+subAdd)/subDiv;\n" - " outRatioWithinBox.xyz=ratioWithinBox.xyz;\n" - " if(insideStructure==1) {\n" - " ratioWithinBox.x=0.5;\n" - " }\n" - " else if(insideStructure==2) {\n" - " ratioWithinBox.y=0.5;\n" - " }\n" - " else if(insideStructure==3 && shapeGeom!=PATH) {\n" - " ratioWithinBox.z=0.5;\n" - " }\n" - " switch(shapeGeom) {\n" - " case BOX : {\n" - " vec3 q = abs(ratioWithinBox.xyz\n" - " -vec3(0.5,0.5,0.5))*2.0\n" - " - vec3(1.0,1.0,1.0);\n" - " gradRatio = 1.0-abs(length(max(q,0.0)) \n" - " + min(max(q.x,max(q.y,q.z)),0.0));\n" - " } break;\n" - " case SPHERE : {\n" - " gradRatio = length(ratioWithinBox.xyz\n" - " - vec3(0.5,0.5,0.5))/0.5;\n" - " } break;\n" - " case PATH : {\n" - " vec2 d = abs(vec2(length((ratioWithinBox.xy-vec2(0.5, 0.5))*2.0), \n" - " (ratioWithinBox.z-0.5)*2.0)) \n" - " - vec2(1.0,1.0);\n" - " gradRatio = 1.0 - abs(min(max(d.x,d.y),0.0)\n" - " + length(max(d,0.0)));\n" - " } break;\n" - " case TUBE : {\n" - " vec2 d = abs(vec2(length((ratioWithinBox.xz-vec2(0.5, 0.5))*2.0), \n" - " (ratioWithinBox.y-0.5)*2.0)) \n" - " - vec2(1.0,1.0);\n" - " gradRatio = 1.0 - abs(min(max(d.x,d.y),0.0)\n" - " + length(max(d,0.0)));\n" - " } break;\n" - " case CONE : {\n" - " float q = length((ratioWithinBox.xz\n" - " - vec2(0.5,0.5))*2.0);\n" - " gradRatio = 1.0-abs(max(dot(vec2(0.5,0.5),\n" - " vec2(q,(ratioWithinBox.y-1.0))),\n" - " -1.0-(ratioWithinBox.y-1.0)));\n" - " } break;\n" - " case FRAME : {\n" //FIXME compute frame SDF - " vec3 q = abs(ratioWithinBox.xyz\n" - " -vec3(0.5,0.5,0.5))*2.0\n" - " - vec3(1.0,1.0,1.0);\n" - " gradRatio = 1.0-abs(length(max(q,0.0)) \n" - " + min(max(q.x,max(q.y,q.z)),0.0));\n" - " } break;\n" - " case MODEL : {\n" - " gradRatio = texture(surfDistTex, \n" - " ratioWithinBox).r\n" - " * structureRatio;\n" - " } break;\n" - " default :{\n"//defaults to sphere - " gradRatio = length(ratioWithinBox.xyz\n" - " - vec3(0.5,0.5,0.5))/0.5;\n" - " } break;\n" - " }\n" - " }\n" - //texture coordinates - " vec3 texCoords = vec3(1-ratioWithinBox.x,\n" - " 1-ratioWithinBox.y,\n" - " ratioWithinBox.z);\n" - "\n" - //start with shapeColor - " finalColor = shapeColor;\n" - //test gradient - " if(gradientAlpha>0) {\n" - " float gradColor = \n" - " pow(gradientCurveRatio<0?1.0-gradRatio:gradRatio,\n" - " abs(gradientCurveRatio));\n" - " if(gradientSteps>1) {\n" - " gradColor = floor(gradColor*gradientSteps)\n" - " / gradientSteps;\n" - " }\n" - " gradColor*=(gradRatio<=1.0)?1.0:0.0;\n" - " if(gradientType>0) {\n"//gradient texture - " finalColor=finalColor*(1.0-gradientAlpha) \n" - " + finalColor*gradientAlpha\n" - " * texture(gradientTex, \n" - " vec2(gradRatio, 0.0)).xyz;\n" - " }\n" - " else {\n" - " finalColor=finalColor*(1.0-gradientAlpha) \n" - " + finalColor*gradColor*gradientAlpha;\n" - " }\n" - " }\n" - //test density - " if(densityAlpha>0) {\n" - " float densColor = \n" - " pow(densityCurveRatio<0?1.0-gradRatio:gradRatio,\n" - " abs(densityCurveRatio));\n" - " if(densityType==0 && \n" //layers - " length(mod(densColor*100.0, \n" - " densitySize*100.0))\n" - " < densityRatio*densitySize*100.0) {\n" - " densColor = 1.0;\n" - " densColor*=(gradRatio<=1.0)?1.0:0.0;\n" - " }\n" - " else if(densityType==1\n" //grid - " && (length(mod(ratioWithinBox.x*100,\n" - " densitySize*100.0))\n" - " <densitySize*densityRatio*100.0 \n" - " || length(mod(ratioWithinBox.y*100,\n" - " densitySize*100.0))\n" - " <densitySize*densityRatio*100.0 \n" - " || length(mod(ratioWithinBox.z*100,\n" - " densitySize*100.0))\n" - " <densitySize*densityRatio*100.0)) { \n" - " densColor = 1.0;\n" - " }\n" - " else if(densityType==2 \n" //pointcloud - " && floor(random(ratioWithinBox.xyz)\n" - " *floor(100.0))>100.0*densColor) {\n" - " densColor = 1.0; \n" - " densColor*=(gradRatio<=1.0)?1.0:0.0;\n" - " }\n" - " else {\n" - " densColor = 0.0;\n" - " }\n" - " finalColor=finalColor*(1.0-densityAlpha) \n" - " + finalColor*densColor*densityAlpha;\n" - " }\n" - //test texture - " if(texAlpha>0) {\n" - " vec3 texColor = texture(insideTex, \n" - " texOffset+texScale*texCoords).xyz;\n" - " if(texGray>0) {\n" - " texColor=vec3((texColor.r+texColor.g+texColor.b)\n" - " / 3.0);\n" - " }\n" - " finalColor=finalColor*(1.0-texAlpha) \n" - " + finalColor*texColor*texAlpha;\n" - " }\n" -#ifdef GL42 - //if revealing something, output values - " if(sli.x>=1.0 && depthID<=depthOutNb) {\n" - //inside output - " if(revInside>0 && rendered==1) {\n" - " imageAtomicMax(outputTex, \n" - " ivec2(mod(outOffset+revInside,outCols), \n" - " floor((outOffset+revInside))/outCols),\n" - " 1);\n" - " }\n" - " outRatioWithinBox.x=clamp(outRatioWithinBox.x, 0, 1);\n" - " outRatioWithinBox.y=clamp(outRatioWithinBox.y, 0, 1);\n" - " outRatioWithinBox.z=clamp(outRatioWithinBox.z, 0, 1);\n" - //compute min,max on the three axes - " int xk=int(outRatioWithinBox.x*1000.0);\n" - " int yk=int(outRatioWithinBox.y*1000.0);\n" - " int zk=int(outRatioWithinBox.z*1000.0);\n" - //output min/max ratios - " if(revCenter>0) {\n" - " imageAtomicMax(outputTex, \n" - " ivec2(mod(outOffset+revCenter+0,outCols), \n" - " floor((outOffset+revCenter+0)/outCols)),\n" - " 1000-xk);\n" - " imageAtomicMax(outputTex, \n" - " ivec2(mod(outOffset+revCenter+1,outCols), \n" - " floor((outOffset+revCenter+1)/outCols)),\n" - " xk);\n" - " imageAtomicMax(outputTex, \n" - " ivec2(mod(outOffset+revCenter+2,outCols), \n" - " floor((outOffset+revCenter+2)/outCols)),\n" - " 1000-yk);\n" - " imageAtomicMax(outputTex, \n" - " ivec2(mod(outOffset+revCenter+3,outCols), \n" - " floor((outOffset+revCenter+3)/outCols)),\n" - " yk);\n" - " imageAtomicMax(outputTex, \n" - " ivec2(mod(outOffset+revCenter+4,outCols), \n" - " floor((outOffset+revCenter+4)/outCols)),\n" - " 1000-zk);\n" - " imageAtomicMax(outputTex, \n" - " ivec2(mod(outOffset+revCenter+5,outCols), \n" - " floor((outOffset+revCenter+5)/outCols)),\n" - " zk);\n" - " }\n" - //convert from rgb to hsv - " vec3 hsv = rgb2hsv(finalColor);\n" - //Sum color channels - " if(revColor>0) {\n" - //count nb revealed points - " imageAtomicAdd(outputTex,\n" - " ivec2(mod(outOffset+revColor+0,outCols), \n" - " floor((outOffset+revColor+0)/outCols)),\n" - " 1);\n" - //sum point h - " imageAtomicAdd(outputTex,\n" - " ivec2(mod(outOffset+revColor+1,outCols), \n" - " floor((outOffset+revColor+1)/outCols)),\n" - " clamp(int(hsv.x*1000.0),0,1000));\n" - //sum s - " imageAtomicAdd(outputTex,\n" - " ivec2(mod(outOffset+revColor+2,outCols), \n" - " floor((outOffset+revColor+2)/outCols)),\n" - " clamp(int(hsv.y*1000.0),0,1000));\n" - //sum v - " imageAtomicAdd(outputTex,\n" - " ivec2(mod(outOffset+revColor+3,outCols), \n" - " floor((outOffset+revColor+3)/outCols)),\n" - " clamp(int(hsv.z*1000.0),0,1000));\n" - " }\n" - //histo : accumulate on luminance bins - " if(revHisto>0) {\n" - //count nb revealed points - " imageAtomicAdd(outputTex,\n" - " ivec2(mod(outOffset+revHisto,outCols), \n" - " floor((outOffset+revHisto)/outCols)),\n" - " 1);\n" - " int bin = int(hsv.z*float(histoOutSize-1));\n" - " imageAtomicAdd(outputTex,\n" - " ivec2(mod(outOffset+revHisto+1+bin,outCols), \n" - " floor((outOffset+revHisto+1+bin)/outCols)),\n" - " 1);\n" - " }\n" - - //2D grid of projected voxels (nbvox, 3D coords, lum) - " if(revVoxels>0) {\n" - //compute pixel ratio within 2D bounding rect - " vec2 pixRatio = (vec2(coordX, coordY)\n" - " - boundingRect.xy) / \n" - " (boundingRect.zw-boundingRect.xy);\n" - " pixRatio.x = clamp(pixRatio.x, 0.0, 1.0);\n" - " pixRatio.y = clamp(pixRatio.y, 0.0, 1.0);\n" - //compute offset in voxel output - " int voxOff = outOffset+revVoxels;\n" - " voxOff+=5*(int(pixRatio.x*voxelOutSize)\n" - " + int((1.0-pixRatio.y)*voxelOutSize)\n" - " *voxelOutSize);\n" - //accumulate points - " imageAtomicAdd(outputTex,\n" - " ivec2(mod(voxOff,outCols), \n" - " floor((voxOff)/outCols)),\n" - " 1);\n" - //accumulate coords - " imageAtomicAdd(outputTex, \n" - " ivec2(mod(voxOff+1,outCols), \n" - " floor((voxOff+1)/outCols)),\n" - " clamp(int(outRatioWithinBox.x*1000.0),0,1000));\n" - " imageAtomicAdd(outputTex, \n" - " ivec2(mod(voxOff+2,outCols), \n" - " floor((voxOff+2)/outCols)),\n" - " clamp(int(outRatioWithinBox.y*1000.0),0,1000));\n" - " imageAtomicAdd(outputTex, \n" - " ivec2(mod(voxOff+3,outCols), \n" - " floor((voxOff+3)/outCols)),\n" - " clamp(int(outRatioWithinBox.z*1000.0),0,1000));\n" - //accumulate lum - " imageAtomicAdd(outputTex, \n" - " ivec2(mod(voxOff+4,outCols), \n" - " floor((voxOff+4)/outCols)),\n" - " clamp(int(hsv.z*1000.0),0,1000));\n" - " }\n" - " }\n" -#endif - " }\n" - //SURFACE test - " if(rendered>1) { \n" - " finalColor = surfaceColor;\n" -#ifdef GL42 - " if(revSurface>0 && sli.x>=1.0 && depthID<=depthOutNb) {\n" - " imageAtomicMax(outputTex,\n" - " ivec2(mod(outOffset+revSurface,outCols), \n" - " floor((outOffset+revSurface)/outCols)),\n" - " 1);\n" - " }\n" -#endif - " }\n" - " }\n" - //final test, output if rendered or not, output final color - " if(rendered>0 && length(finalColor)>0) { \n" -#ifdef GL42 - " if(revSize>0) {\n" - " imageAtomicOr(outputTex, \n" - " ivec2(mod(outOffset,outCols), \n" - " floor((outOffset))/outCols),\n" - " rendered);\n" - " }\n" -#endif - " if((insideVisible>0 && rendered==1) \n" - " || (surface>0 && rendered==2)) {\n" - " color = vec4(finalColor, 1.0);\n"//display - //" color = vec4(finalColor, sli.x);\n"//display - /* - " if(sli.x>0.5) {\n" - " color = vec4(1.0, 0.0, 0.0, 1.0);\n"//display - " }\n" - " else {\n" - " color = vec4(0.0, 1.0, 0.0, 1.0);\n"//display - " }\n" - */ - " }\n" - " else {\n" - " color = vec4(0.0, 0.0, 0.0, 1.0);\n" - " }\n" - //" color = vec4((pixelPos+0.5)/2.0, 1.0);\n"//debug pix coords - //" color = vec4(cutZ*10.0, pixZ*10.0, 0.0, 1.0);\n"//debug slice texture - //" color = vec4(texture(surfDistTex, ratioWithinBox).r*10.0, 1.0,1.0,1.0);\n" - //" color = vec4(texture(insideTex, ratioWithinBox).r*10.0, 1.0,1.0,1.0);\n" - //" color = vec4(ratioWithinBox.xyz, 1.0);\n" - " }\n" - " else {\n" //DISCARD - //" color = vec4(1.0,0.0,0.0,1.0);\n" - " discard;\n" - " }\n" - "}\n"}; m_programs[Reveal::RENDERPROG] - = Reveal::getInstance()->createProgram(vertSource, fragSource); + = Reveal::getInstance()->createProgram(render30VS.c_str(), + render30FS.c_str()); +#endif + m_uniforms[Reveal::RENDERPROG] = map<Reveal::REVIL_UNIFORM, GLint>(); m_uniforms[Reveal::RENDERPROG][Reveal::MIRRORED] = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "mirrored"); @@ -1188,7 +511,7 @@ void ProjectorModule::initGL() { = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "bboxLocalSize"); m_uniforms[Reveal::RENDERPROG][Reveal::BBOXROT] = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "bboxRot"); -#ifdef GL42 +#ifdef GL43 //output texture m_outputImg = new unsigned int[m_outputImgSize*m_outputImgSize]; m_outputImgInit = new unsigned int[m_outputImgSize*m_outputImgSize]; @@ -1236,78 +559,15 @@ void ProjectorModule::initGL() { { //select prog - const char * vertSource = { -#ifdef GL42 - "#version 430 \n" -#else - "#version 410 \n" -#endif - " \n" - "in vec3 vertex;\n" - " \n" - "uniform mat4 modelMat;\n" - "uniform mat4 viewMat;\n" - "uniform mat4 viewProjMat;\n" - "uniform float mirrored;\n" - " \n" - "void main(void) {\n" - " vec4 posWS = modelMat * vec4(vertex, 1.0);\n" - " if(mirrored<1) {\n" - " posWS.x = -posWS.x;\n" - " }\n" - " gl_Position = viewProjMat * posWS;\n" - "}\n"}; - - const char * fragSource = { -#ifdef GL42 - "#version 430 \n" -#else - "#version 410 \n" -#endif - " \n" -#ifdef GL42 - "layout(binding=0) uniform sampler2D sliceTex;\n" +#ifdef GL43 + m_programs[Reveal::SELECTPROG] + = Reveal::getInstance()->createProgram(select43VS.c_str(), + select43FS.c_str()); #else - "uniform sampler2D sliceTex;\n" -#endif - "uniform float viewportWidth;\n" - "uniform float viewportHeight;\n" - "uniform float shapeID;\n" - "uniform float shapeIDBit;\n" - "uniform float mirrored;\n" - "uniform float thickness;\n" - "uniform int surface;\n" - " \n" - "out vec4 color;\n" - " \n" - "void main(void) {\n" - " float coordX = (gl_FragCoord.x-0.5)/viewportWidth;\n" - " float coordY = (gl_FragCoord.y-0.5)/viewportHeight;\n" - " ivec2 sliSize = textureSize(sliceTex, 0);\n" - " vec4 sli = texelFetch(sliceTex,\n" - " ivec2(coordX*float(sliSize.x),\n" - " coordY*float(sliSize.y)),\n" - " 0);\n" - " float pixZ=abs(gl_FragCoord.z);\n" - " float cutZ=abs(sli.z);\n" - // keep all ids of back surfaces after depth map - " if(pixZ>cutZ && cutZ>0) {\n" - " if((mirrored<1 && !gl_FrontFacing)\n" - " || (mirrored>0 && gl_FrontFacing)) {\n" - " color = vec4(shapeID, 0, \n" - " (abs(pixZ-cutZ)<thickness/1000.0 && surface>0)?1:0, \n" - " shapeIDBit);\n" - " }\n" - " else {\n" //occlude back when front face also behind - " color = vec4(-shapeID, 0, 0, -shapeIDBit);\n" - " }\n" - " }\n" - " else {\n" - " discard;\n" - " }\n" - "}\n"}; m_programs[Reveal::SELECTPROG] - = Reveal::getInstance()->createProgram(vertSource, fragSource); + = Reveal::getInstance()->createProgram(select30VS.c_str(), + select30FS.c_str()); +#endif m_uniforms[Reveal::SELECTPROG]=map<Reveal::REVIL_UNIFORM, GLint>(); m_uniforms[Reveal::SELECTPROG][Reveal::MIRRORED] = glGetUniformLocation(m_programs[Reveal::SELECTPROG], "mirrored"); @@ -1336,193 +596,16 @@ void ProjectorModule::initGL() { //SLICE { - const char * vertSource = { -#ifdef GL42 - "#version 430 \n" -#else - "#version 410 \n" -#endif - " \n" - "#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b);\n" - "#define mn3(a, b, c) s2(a, b); s2(a, c);\n" - "#define mx3(a, b, c) s2(b, c); s2(a, c);\n" - "#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b);\n" - "#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d);\n" - "#define mnmx5(a, b, c, d, e) s2(a,b); s2(c,d);mn3(a,c,e);mx3(b,d,e);\n" - "#define mnmx6(a,b,c,d,e,f) s2(a,d);s2(b,e);s2(c,f);mn3(a,b,c);mx3(d,e,f);\n" - "in vec3 vertex; \n" - " \n" -#ifdef GL42 - "layout(binding=0) uniform sampler2D depthCamTex;\n" - "layout(binding=1) uniform sampler2D depthCamTexFil;\n" - "layout(binding=2) uniform sampler2D markersTex;\n" - //"layout(r32ui, binding=2) uniform coherent uimage2D outputTex;\n" -#else - "uniform sampler2D depthCamTex;\n" - "uniform sampler2D depthCamTexFil;\n" - "uniform sampler2D markersTex;\n" -#endif - "uniform mat4 modelMat;\n" - "uniform mat4 viewMat;\n" - "uniform mat4 viewProjMat;\n" - "uniform float camXReso;\n" - "uniform float camYReso;\n" - "uniform float camXZFactor;\n" - "uniform float camYZFactor;\n" - "uniform int camFilter;\n" - "uniform int background;\n" - "uniform float camContThresh;\n" - "uniform float camMarkers;\n" - "uniform int depthType;\n" - "uniform int depthID;\n" - "uniform float outputCurs;\n" - "uniform float mirrored;\n" - " \n" - "out vec3 viewRay;\n" - "out float kept;\n" - "flat out int outDepthID;\n" - " \n" - "void main(void) {\n" - " vec4 depthPos = vec4(0, 0, 0, 1);\n" - " vec4 posWS = vec4(0, 0, 0, 1);\n" - //depth camera - " if(depthType==0) {\n" - " vec2 coords = vertex.xy;\n" - //get marker if any - " if(camMarkers>0) {\n" - " outDepthID = int(float(texture(markersTex,\n" - " vec2(coords.x/camXReso,\n" - " coords.y/camYReso)).r)\n" - " * 255.0);\n" - " }\n" - " else {\n" - " outDepthID=depthID+1;\n" - " }\n" - //get depth pixel in camera texture - " float depth = \n" - " float(texture(depthCamTex,\n" - " vec2(coords.x/camXReso,\n" - " coords.y/camYReso)).r)\n" - " * 65535.0;\n" - " kept=1.0;\n" - " float backgroundDepth=0;\n" - " if(background>0) {\n" - " float backDepth = float(texture(depthCamTex,\n" - " vec2(coords.x/camXReso,\n" - " coords.y/camYReso)).r)\n" - " * 65535.0;\n" - " if(backDepth<depth) {\n" - " depth=backDepth;\n" - " backgroundDepth=1;\n" - " }\n" - " }\n" - " if(depth<=500.0 || depth>8000.0) {\n" - " kept=0.0;\n" - " }\n" - " else if(backgroundDepth==0) {\n" - //filter out contours - " float maxD=camContThresh;\n" - " bool contour=false;\n" - " for(int dX = -1; dX <= 1; ++dX) {\n" - " for(int dY = -1; dY <= 1; ++dY) {\n" - " if(abs(float(texture(depthCamTex,\n" - " vec2((coords.x+dX)/camXReso,\n" - " (coords.y+dY)/camYReso)).r)\n" - " * 65535.0\n" - " - depth) > maxD) {\n" - " contour=true;\n" - " }\n" - " }\n" - " }\n" - " if(contour) {\n" - " kept=0.0;\n" - " }\n" - //see if needs filtering - " if(camFilter>0) {\n" - " float filtDepth = float(texture(depthCamTexFil,\n" - " vec2(coords.x/camXReso,\n" - " coords.y/camYReso)).r)\n" - " * 65535.0;\n" - //select either filtered version or current one - //depending on movement - " if(abs(filtDepth-depth)<camContThresh) {\n" - " float filRatio = abs(filtDepth-depth)/camContThresh;\n" - " depth=(1-filRatio)*filtDepth+(filRatio)*depth;\n" - " }\n" - " }\n" - " }\n" - //test distance again - " if(depth<=500.0 || depth>8000.0) {\n" - " kept=0.0;\n" - " }\n" - //compute position in world units - " depthPos = vec4((vertex.x/camXReso-0.5)\n" - " *depth*camXZFactor,\n" - " (0.5-(vertex.y/camYReso))\n" - " *depth*camYZFactor,\n" - " depth,\n" - " 1.0);\n" - //get world pos - " posWS = modelMat * depthPos;\n" - " }\n" - //other slicing shapes - " else {\n" - " outDepthID=depthID+1;\n" - " kept=1.0;\n" - " depthPos=vec4(vertex, 1.0);\n" - " posWS = modelMat * depthPos;\n" - " if(mirrored<1) {\n" - " posWS.x = -posWS.x;\n" - " }\n" - " }\n" -#ifdef GL42 -/* - //output minimum point on z axis if output is active - " if(outputCurs>0 && kept>0.0) {\n" - " imageAtomicMin(outputTex,ivec2(0,int(depthID)+500),\n" - " int(floor(1000.0+posWS.z/10.0)*1000000\n" - " +floor(posWS.y/10.0+500.0)*1000\n" - " +floor(posWS.x/10.0+500.0)));\n" - //" imageAtomicMin(outputTex,ivec2(0, int(depthID)+500),4400600);\n" - //" imageAtomicMin(outputTex,ivec2(0, int(depthID)+500),6400600);\n" - " }\n" -*/ -#endif - //keep/interpolate ray from view to each vertex - " viewRay = (posWS.xyz - vec3(viewMat[3][0],\n" - " viewMat[3][1],\n" - " viewMat[3][2]));\n" - " gl_Position = viewProjMat * posWS;\n" - "}\n"}; - const char * fragSource = { -#ifdef GL42 - "#version 430 \n" +#ifdef GL43 + m_programs[Reveal::SLICEPROG] + = Reveal::getInstance()->createProgram(slice43VS.c_str(), + slice43FS.c_str()); #else - "#version 410 \n" + m_programs[Reveal::SLICEPROG] + = Reveal::getInstance()->createProgram(slice30VS.c_str(), + slice30FS.c_str()); #endif - " \n" - "in float kept;\n" - "in vec3 viewRay;\n" - "flat in int outDepthID;\n" - " \n" - "out vec4 color;\n" - " \n" - "void main(void) {\n" - " float thresh=0.8;\n" - " if(kept>=thresh) {\n" - " color = vec4((kept-thresh)/(1.0-thresh),\n" - " float(outDepthID),\n" - " gl_FragCoord.z,\n" - " length(viewRay));\n" - " }\n" - " else {\n" - " discard;\n" - " }\n" -// " color = vec4(1.0, 1.0, 0.0, 1.0);\n" - "}\n"}; - m_programs[Reveal::SLICEPROG] - = Reveal::getInstance()->createProgram(vertSource, fragSource); m_uniforms[Reveal::SLICEPROG]=map<Reveal::REVIL_UNIFORM, GLint>(); m_uniforms[Reveal::SLICEPROG][Reveal::BACKGROUND] = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "background"); @@ -1563,84 +646,15 @@ void ProjectorModule::initGL() { //Calibration { - const char * vertSource = { -#ifdef GL42 - "#version 430 \n" -#else - "#version 410 \n" -#endif - " \n" - "in vec3 vertex; \n" - " \n" - "void main(void) {\n" - " gl_Position = vec4(vertex, 1.0);\n" - "}\n"}; - - const char * fragSource = { -#ifdef GL42 - "#version 430 \n" -#else - "#version 410 \n" -#endif - " \n" - "uniform float viewportWidth;\n" - "uniform float viewportHeight;\n" - "uniform float patW;\n" - "uniform float patPosX;\n" - "uniform float patPosY;\n" - "uniform float patNbX;\n" - "uniform float patNbY;\n" - "uniform float patBright;\n" - "uniform vec2 patOffset;\n" - "uniform vec2 patRange;\n" -#ifdef GL42 - "layout(binding=0) uniform sampler2D patternTex;\n" +#ifdef GL43 + m_programs[Reveal::CALIBPROG] + = Reveal::getInstance()->createProgram(calib43VS.c_str(), + calib43FS.c_str()); #else - "uniform sampler2D patternTex;\n" -#endif - " \n" - "out vec4 color;\n" - " \n" - "void main(void) {\n" - /* - " float coordX = (gl_FragCoord.x-0.5)/viewportWidth;\n" - " float coordY = (gl_FragCoord.y-0.5)/viewportHeight;\n" - " ivec2 patSize = textureSize(patternTex, 0);\n" - " float pat = texelFetch(patternTex,\n" - " ivec2(coordX*float(patSize.x),\n" - " (1.0-coordY)*float(patSize.y)),\n" - " 0).r;\n" - " color=vec4(pat, pat, pat, 1.0);\n" - //" color=vec4(1.0,1.0,1.0,1.0);\n" - */ - //pixel is white by default - " color = vec4(patBright);\n" - " float offX = gl_FragCoord.x - patPosX;\n" - " float offY = (viewportHeight-gl_FragCoord.y) - patPosY;\n" - //black squares - " if(offX>=0 && offX<patW*(patNbX+1)\n" - " && offY>=0 && offY<patW*(patNbY+1)) {\n" - " if((mod(offX,patW*2)<patW && mod(offY,patW*2)<patW) \n" - " || (mod(offX,patW*2)>patW && mod(offY,patW*2)>patW)) {\n" - " color = vec4(0, 0, 0, 1);\n" - " }\n" - " }\n" - //color in red the pattern range border - " float thick=2;\n" - " float coordY = viewportHeight-gl_FragCoord.y;\n" - " if(((abs(gl_FragCoord.x-patOffset.x)<thick\n" - " || abs(gl_FragCoord.x-(patOffset.x+patRange.x))<thick)\n" - " && coordY>patOffset.y\n" - " && coordY<(patOffset.y+patRange.y))\n" - " ||((abs(coordY-patOffset.y)<thick\n" - " || abs(coordY-(patOffset.y+patRange.y))<thick)\n" - " && gl_FragCoord.x>patOffset.x\n" - " && gl_FragCoord.x<(patOffset.x+patRange.x))) {\n" - " color=vec4(1,0,0,1);\n" - " }\n" - "}\n"}; m_programs[Reveal::CALIBPROG] - = Reveal::getInstance()->createProgram(vertSource, fragSource); + = Reveal::getInstance()->createProgram(calib30VS.c_str(), + calib30FS.c_str()); +#endif m_uniforms[Reveal::CALIBPROG]=map<Reveal::REVIL_UNIFORM, GLint>(); m_uniforms[Reveal::CALIBPROG][Reveal::VIEWPORTWIDTH] = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"viewportWidth"); diff --git a/src/shaders/calib30.fs b/src/shaders/calib30.fs new file mode 100644 index 0000000000000000000000000000000000000000..fe27b5678be2aecb2c4339367ff9a57a99246d40 --- /dev/null +++ b/src/shaders/calib30.fs @@ -0,0 +1,55 @@ +#version 130 + +uniform float viewportWidth; +uniform float viewportHeight; +uniform float patW; +uniform float patPosX; +uniform float patPosY; +uniform float patNbX; +uniform float patNbY; +uniform float patBright; +uniform vec2 patOffset; +uniform vec2 patRange; +uniform sampler2D patternTex; + +out vec4 color; + +void main(void) { + /* + float coordX = (gl_FragCoord.x-0.5)/viewportWidth; + float coordY = (gl_FragCoord.y-0.5)/viewportHeight; + ivec2 patSize = textureSize(patternTex, 0); + float pat = texelFetch(patternTex, + ivec2(coordX*float(patSize.x), + (1.0-coordY)*float(patSize.y)), + 0).r; + color=vec4(pat, pat, pat, 1.0); + // color=vec4(1.0,1.0,1.0,1.0); + */ + //pixel is white by default + color = vec4(patBright); + float offX = gl_FragCoord.x - patPosX; + float offY = (viewportHeight-gl_FragCoord.y) - patPosY; + //black squares + if(offX>=0 && offX<patW*(patNbX+1) + && offY>=0 && offY<patW*(patNbY+1)) { + if((mod(offX,patW*2)<patW && mod(offY,patW*2)<patW) + || (mod(offX,patW*2)>patW && mod(offY,patW*2)>patW)) { + color = vec4(0, 0, 0, 1); + } + } + //color in red the pattern range border + float thick=2; + float coordY = viewportHeight-gl_FragCoord.y; + if(((abs(gl_FragCoord.x-patOffset.x)<thick + || abs(gl_FragCoord.x-(patOffset.x+patRange.x))<thick) + && coordY>patOffset.y + && coordY<(patOffset.y+patRange.y)) + ||((abs(coordY-patOffset.y)<thick + || abs(coordY-(patOffset.y+patRange.y))<thick) + && gl_FragCoord.x>patOffset.x + && gl_FragCoord.x<(patOffset.x+patRange.x))) { + color=vec4(1,0,0,1); + } +}; + diff --git a/src/shaders/calib30.vs b/src/shaders/calib30.vs new file mode 100644 index 0000000000000000000000000000000000000000..3248ef02dd8c745b0406ba6d16692549ad60772b --- /dev/null +++ b/src/shaders/calib30.vs @@ -0,0 +1,7 @@ +#version 130 + +in vec3 vertex; + +void main(void) { + gl_Position = vec4(vertex, 1.0); +}; diff --git a/src/shaders/calib43.fs b/src/shaders/calib43.fs new file mode 100644 index 0000000000000000000000000000000000000000..bc3b96dde957ca9845387f005ff9a9543cd81685 --- /dev/null +++ b/src/shaders/calib43.fs @@ -0,0 +1,56 @@ +#version 430 + +uniform float viewportWidth; +uniform float viewportHeight; +uniform float patW; +uniform float patPosX; +uniform float patPosY; +uniform float patNbX; +uniform float patNbY; +uniform float patBright; +uniform vec2 patOffset; +uniform vec2 patRange; + +layout(binding=0) uniform sampler2D patternTex; + +out vec4 color; + +void main(void) { + /* + float coordX = (gl_FragCoord.x-0.5)/viewportWidth; + float coordY = (gl_FragCoord.y-0.5)/viewportHeight; + ivec2 patSize = textureSize(patternTex, 0); + float pat = texelFetch(patternTex, + ivec2(coordX*float(patSize.x), + (1.0-coordY)*float(patSize.y)), + 0).r; + color=vec4(pat, pat, pat, 1.0); + // color=vec4(1.0,1.0,1.0,1.0); + */ + //pixel is white by default + color = vec4(patBright); + float offX = gl_FragCoord.x - patPosX; + float offY = (viewportHeight-gl_FragCoord.y) - patPosY; + //black squares + if(offX>=0 && offX<patW*(patNbX+1) + && offY>=0 && offY<patW*(patNbY+1)) { + if((mod(offX,patW*2)<patW && mod(offY,patW*2)<patW) + || (mod(offX,patW*2)>patW && mod(offY,patW*2)>patW)) { + color = vec4(0, 0, 0, 1); + } + } + //color in red the pattern range border + float thick=2; + float coordY = viewportHeight-gl_FragCoord.y; + if(((abs(gl_FragCoord.x-patOffset.x)<thick + || abs(gl_FragCoord.x-(patOffset.x+patRange.x))<thick) + && coordY>patOffset.y + && coordY<(patOffset.y+patRange.y)) + ||((abs(coordY-patOffset.y)<thick + || abs(coordY-(patOffset.y+patRange.y))<thick) + && gl_FragCoord.x>patOffset.x + && gl_FragCoord.x<(patOffset.x+patRange.x))) { + color=vec4(1,0,0,1); + } +}; + diff --git a/src/shaders/calib43.vs b/src/shaders/calib43.vs new file mode 100644 index 0000000000000000000000000000000000000000..6c127fdd330f1eeab1cba29de2da1da6c962aee9 --- /dev/null +++ b/src/shaders/calib43.vs @@ -0,0 +1,7 @@ +#version 430 + +in vec3 vertex; + +void main(void) { + gl_Position = vec4(vertex, 1.0); +}; diff --git a/src/shaders/post30.fs b/src/shaders/post30.fs new file mode 100644 index 0000000000000000000000000000000000000000..bb679be38fec94d58f62eaf6090d3f581b14a68f --- /dev/null +++ b/src/shaders/post30.fs @@ -0,0 +1,29 @@ +#version 130 + +uniform float viewportWidth; +uniform float viewportHeight; +uniform float postFilter; +uniform sampler2D renderTex; + +out vec4 color; + +void main(void) { + float coordX = gl_FragCoord.x; + float coordY = gl_FragCoord.y; + ivec2 patSize = textureSize(renderTex, 0); + vec3 sumCol = vec3(0,0,0); + float cnt=0; + for(float dX = coordX-postFilter; dX <= coordX+postFilter; ++dX) { + for(float dY = coordY-postFilter; dY <= coordY+postFilter; ++dY) { + if(dX>=0 && dX<viewportWidth + && dY>=0 && dY<viewportHeight) { + sumCol+=texelFetch(renderTex, + ivec2((dX-0.5)/viewportWidth*patSize.x, + (dY-0.5)/viewportHeight*patSize.y), + 0).xyz; + cnt+=1; + } + } + } + color=vec4(sumCol.xyz/cnt, 1.0); +} diff --git a/src/shaders/post30.vs b/src/shaders/post30.vs new file mode 100644 index 0000000000000000000000000000000000000000..ee33b5fbe14b555ad3431f47c0a8411e02e3cf75 --- /dev/null +++ b/src/shaders/post30.vs @@ -0,0 +1,8 @@ +#version 130 + +in vec3 vertex; + +void main(void) { + gl_Position = vec4(vertex, 1.0); +}; + diff --git a/src/shaders/post43.fs b/src/shaders/post43.fs new file mode 100644 index 0000000000000000000000000000000000000000..d09abf4e48b2cbbb980f7250514f6226e5173d5e --- /dev/null +++ b/src/shaders/post43.fs @@ -0,0 +1,30 @@ +#version 430 + +uniform float viewportWidth; +uniform float viewportHeight; +uniform float postFilter; +layout(binding=0) uniform sampler2D renderTex; + +out vec4 color; + +void main(void) { + float coordX = gl_FragCoord.x; + float coordY = gl_FragCoord.y; + ivec2 patSize = textureSize(renderTex, 0); + vec3 sumCol = vec3(0,0,0); + float cnt=0; + for(float dX = coordX-postFilter; dX <= coordX+postFilter; ++dX) { + for(float dY = coordY-postFilter; dY <= coordY+postFilter; ++dY) { + if(dX>=0 && dX<viewportWidth + && dY>=0 && dY<viewportHeight) { + sumCol+=texelFetch(renderTex, + ivec2((dX-0.5)/viewportWidth*patSize.x, + (dY-0.5)/viewportHeight*patSize.y), + 0).xyz; + cnt+=1; + } + } + } + color=vec4(sumCol.xyz/cnt, 1.0); +}; + diff --git a/src/shaders/post43.vs b/src/shaders/post43.vs new file mode 100644 index 0000000000000000000000000000000000000000..d7116e788ca3b1011dd4df79b9abfd45a9307c2a --- /dev/null +++ b/src/shaders/post43.vs @@ -0,0 +1,8 @@ +#version 430 + +in vec3 vertex; + +void main(void) { + gl_Position = vec4(vertex, 1.0); +}; + diff --git a/src/shaders/render30.fs b/src/shaders/render30.fs new file mode 100644 index 0000000000000000000000000000000000000000..a65ee8a3624383475fa91c6a01f94941ae8b5acf --- /dev/null +++ b/src/shaders/render30.fs @@ -0,0 +1,25 @@ +#version 130 + +in vec3 vertex; +in vec2 texCoords; + +uniform mat4 modelMat; +uniform mat4 viewMat; +uniform mat4 viewProjMat; +uniform float mirrored; + +out vec3 viewRay; +out vec2 uvCoords; + +void main(void) { + vec4 posWS = modelMat * vec4(vertex, 1.0); + if(mirrored<1) { + posWS.x = -posWS.x; + } + gl_Position = viewProjMat * posWS; + viewRay = posWS.xyz - vec3(viewMat[3][0], + viewMat[3][1], + viewMat[3][2]); + uvCoords=texCoords; +}; + diff --git a/src/shaders/render30.vs b/src/shaders/render30.vs new file mode 100644 index 0000000000000000000000000000000000000000..5aeef20973ff7947076498cf3e9fe499ab73f7fa --- /dev/null +++ b/src/shaders/render30.vs @@ -0,0 +1,420 @@ +#version 130 +const int BOX=0; +const int SPHERE=1; +const int TUBE=2; +const int CONE=3; +const int FRAME=4; +const int PATH=5; +const int MODEL=10; + +in vec3 viewRay; +in vec2 uvCoords; + +uniform sampler2D sliceTex; +uniform sampler2D selectTex; +uniform sampler3D insideTex; +uniform sampler2D surfaceTex; +uniform sampler3D reactTex; +uniform sampler3D surfDistTex; +uniform sampler2D gradientTex; +uniform float viewportWidth; +uniform float viewportHeight; +uniform float mirrored; +uniform float shapeID; +uniform float shapeIDBit; +uniform int shapeGeom; +uniform float subShapeID; +uniform float subShapesNb; +uniform mat4 subShapeInvMat; +uniform mat4 viewMat; +uniform mat4 modelMat; +uniform mat4 invModelMat; +uniform vec3 modelScale; +uniform int revealedBy; + +uniform vec3 shapeColor; +//0: none, 1:color, 2:texture +uniform int surface; +uniform vec3 surfaceColor; +uniform int insideOutputOnly; +uniform int reactivity; +uniform float thickness; + +uniform int insideVisible; +//0:from center, 1:along x, 2: along y, 3:along z, 4 :from surface +uniform int insideStructure; +uniform float structureRatio; + +uniform float gradientAlpha; +//0:greyscale, 1:texture +uniform int gradientType; +uniform int gradientSteps; +uniform float gradientCurveRatio; + +uniform float densityAlpha; +//0:layers, 1:grid, 2:pointcloud +uniform int densityType; +uniform float densityRatio; +uniform float densitySize; +uniform float densityCurveRatio; + +uniform float texAlpha; +uniform vec3 texOffset; +uniform vec3 texScale; +uniform int texGray; + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)),d/(q.x + e), q.x); +} + +float random (vec3 st) { + return fract(sin(dot(st.xyz, + vec3(12.9898,78.233, 102.234)))* + 43758.5453123); +} + +out vec4 color; + +void main(void) { + //get fragment coordinates + float coordX = (gl_FragCoord.x-0.5)/viewportWidth; + float coordY = (gl_FragCoord.y-0.5)/viewportHeight; + ivec2 sliSize = textureSize(sliceTex, 0); + //retrieve pixel in slicing texture + vec4 sli = texelFetch(sliceTex, + ivec2(coordX*float(sliSize.x), + coordY*float(sliSize.y)), + 0); + float pixZ=abs(gl_FragCoord.z); + float cutZ=abs(sli.z); + int depthID=int(sli.y)-1; + int rendered=0; + vec3 finalColor = shapeColor; + float alpha=0; + vec3 pixelPosW; + vec3 pixelPos = vec3(0.0, 0.0, 1.0); + vec3 ratioWithinBox = vec3(0.0, 0.0, 0.0); + vec3 outRatioWithinBox = vec3(0.0, 0.0, 0.0); + //if there is a slicing pixel aligned with our coordinate + //and we are revealed by this depth module + if(cutZ>0 && (revealedBy & (1<<(1+depthID)))>0 ) { + //compute the slicing pixel world position + pixelPosW = vec3(viewMat[3][0], + viewMat[3][1], + viewMat[3][2]) + + vec3(normalize(viewRay) * sli.w); + pixelPosW.x = pixelPosW.x*(-2.0*(1-mirrored)+1.0); + //compute the slicing pixel position in model coords + pixelPos = (invModelMat * vec4(pixelPosW,1.0)).xyz; + + //depending on type, test if slicing pixel inside + //and retrieve distance to the surface on each axis + vec3 diffMin = vec3(1.0); + vec3 diffMax = vec3(1.0); + switch(shapeGeom) { + case PATH : {//use min/max/size of current segment + pixelPos = (subShapeInvMat*vec4(pixelPos,1.0)).xyz; + if(length(vec2(pixelPos.x, pixelPos.y))<=0.5 + && (pixelPos.z>-0.5 && pixelPos.z<0.5)) { + float xx = (pixelPos.x)*(pixelPos.x); + float yy = (pixelPos.y)*(pixelPos.y); + float ax = sqrt(0.25-yy); + diffMin.x = pixelPos.x+ax; + diffMax.x = ax-pixelPos.x; + float ay = sqrt(0.25-xx); + diffMin.y = pixelPos.y+ay; + diffMax.y = ay-pixelPos.y; + diffMin.z = pixelPos.z+0.5; + diffMax.z = 0.5-pixelPos.z; + rendered=1; + } + }break; + case CONE : { + if(pixelPos.y<0.5 && pixelPos.y>-0.5) { + float xx = (pixelPos.x)*(pixelPos.x); + float yy = (pixelPos.y-0.5)*(pixelPos.y-0.5); + float zz = (pixelPos.z)*(pixelPos.z); + if((xx+zz)/yy<0.25){ + float ax = sqrt(0.25*yy-zz); + diffMin.x = pixelPos.x+ax; + diffMax.x = ax-pixelPos.x; + float ay = sqrt((yy+xx)/0.25); + diffMin.y = pixelPos.y+0.5; + diffMax.y = 0.5-pixelPos.y; + float az = sqrt(0.25*yy-xx); + diffMin.z = pixelPos.z+az; + diffMax.z = az-pixelPos.z; + rendered=1; + } + } + } break; + case TUBE : { + if(length(vec2(pixelPos.x, pixelPos.z))<=0.5 + && (pixelPos.y>-0.5 && pixelPos.y<0.5)) { + float xx = (pixelPos.x)*(pixelPos.x); + float zz = (pixelPos.z)*(pixelPos.z); + float ax = sqrt(0.25-zz); + diffMin.x = pixelPos.x+ax; + diffMax.x = ax-pixelPos.x; + float az = sqrt(0.25-xx); + diffMin.z = pixelPos.z+az; + diffMax.z = az-pixelPos.z; + diffMin.y = pixelPos.y+0.5; + diffMax.y = 0.5-pixelPos.y; + rendered=1; + } + } break; + case SPHERE : { + if(length(pixelPos)<=0.5) { + float xx = (pixelPos.x)*(pixelPos.x); + float yy = (pixelPos.y)*(pixelPos.y); + float zz = (pixelPos.z)*(pixelPos.z); + float ax = sqrt(0.25-yy-zz); + diffMin.x = pixelPos.x+ax; + diffMax.x = ax-pixelPos.x; + float ay = sqrt(0.25-xx-zz); + diffMin.y = pixelPos.y+ay; + diffMax.y = ay-pixelPos.y; + float az = sqrt(0.25-xx-yy); + diffMin.z = pixelPos.z+az; + diffMax.z = az-pixelPos.z; + rendered=1; + } + } break; + case BOX : { + diffMin = pixelPos - vec3(-0.5, -0.5, -0.5); + diffMax = vec3(0.5, 0.5, 0.5) - pixelPos; + if(diffMin.x>0 && diffMax.x>0 + && diffMin.y>0 && diffMax.y>0 + && diffMin.z>0 && diffMax.z>0){ + rendered=1; + } + } break; + case FRAME : { + diffMin = pixelPos - vec3(-0.5, -0.5, -0.5); + diffMax = vec3(0.5, 0.5, 0.5) - pixelPos; + if(diffMin.x>0 && diffMax.x>0 + && diffMin.y>0 && diffMax.y>0 + && diffMin.z>0 && diffMax.z>0){ + rendered=1; + } + } break; + case MODEL : { + ivec2 selSize = textureSize(selectTex, 0); + vec4 sel = texelFetch(selectTex, + ivec2(coordX*float(selSize.x), + coordY*float(selSize.y)), + 0); + //get front surfaces before depth map + if(pixZ<=cutZ+thickness/1000.0) { + if(sel.z==0) { + if(sel.x==shapeID) { + rendered=1; + } + else if((int(shapeIDBit)&int(sel.w))>0) { + diffMin = pixelPos - vec3(-0.5, -0.5, -0.5); + diffMax = vec3(0.5, 0.5, 0.5) - pixelPos; + if(diffMin.x>0 && diffMax.x>0 + && diffMin.y>0 && diffMax.y>0 + && diffMin.z>0 && diffMax.z>0){ + rendered=1; + } + } + } + if(surface>0 + && (pixZ>cutZ + || (sel.z>0 && (int(shapeIDBit)&int(sel.w))>0))) { + rendered=2; + } + } + } break; + } + if(rendered>0) { + ratioWithinBox = (pixelPos)+0.5; + //test if on the surface + if(diffMin.x*modelScale.x<thickness || + diffMax.x*modelScale.x<thickness || + diffMin.y*modelScale.y<thickness || + diffMax.y*modelScale.y<thickness || + diffMin.z*modelScale.z<thickness || + diffMax.z*modelScale.z<thickness) { + rendered=2; + } + //extend ratiowithinbox to multiplesubshapes + //and get gradient ratio according to type + float gradRatio = 0; + vec3 subAdd; + vec3 subDiv; + if(insideStructure==0) {//from center + subAdd = vec3(subShapeID, subShapeID, subShapeID); + subDiv = vec3(subShapesNb, subShapesNb, subShapesNb); + ratioWithinBox.xyz=(ratioWithinBox.xyz+subAdd)/subDiv; + outRatioWithinBox.xyz=ratioWithinBox.xyz; + gradRatio = length(ratioWithinBox.xyz + - vec3(0.5,0.5,0.5))/0.5; + } + else {//from surface or along axes + subAdd = vec3(0,0, subShapeID); + subDiv = vec3(1,1, subShapesNb); + ratioWithinBox.xyz=(ratioWithinBox.xyz+subAdd)/subDiv; + outRatioWithinBox.xyz=ratioWithinBox.xyz; + if(insideStructure==1) { + ratioWithinBox.x=0.5; + } + else if(insideStructure==2) { + ratioWithinBox.y=0.5; + } + else if(insideStructure==3 && shapeGeom!=PATH) { + ratioWithinBox.z=0.5; + } + switch(shapeGeom) { + case BOX : { + vec3 q = abs(ratioWithinBox.xyz + -vec3(0.5,0.5,0.5))*2.0 + - vec3(1.0,1.0,1.0); + gradRatio = 1.0-abs(length(max(q,0.0)) + + min(max(q.x,max(q.y,q.z)),0.0)); + } break; + case SPHERE : { + gradRatio = length(ratioWithinBox.xyz + - vec3(0.5,0.5,0.5))/0.5; + } break; + case PATH : { + vec2 d = abs(vec2(length((ratioWithinBox.xy-vec2(0.5, 0.5))*2.0), + (ratioWithinBox.z-0.5)*2.0)) + - vec2(1.0,1.0); + gradRatio = 1.0 - abs(min(max(d.x,d.y),0.0) + + length(max(d,0.0))); + } break; + case TUBE : { + vec2 d = abs(vec2(length((ratioWithinBox.xz-vec2(0.5, 0.5))*2.0), + (ratioWithinBox.y-0.5)*2.0)) + - vec2(1.0,1.0); + gradRatio = 1.0 - abs(min(max(d.x,d.y),0.0) + + length(max(d,0.0))); + } break; + case CONE : { + float q = length((ratioWithinBox.xz + - vec2(0.5,0.5))*2.0); + gradRatio = 1.0-abs(max(dot(vec2(0.5,0.5), + vec2(q,(ratioWithinBox.y-1.0))), + -1.0-(ratioWithinBox.y-1.0))); + } break; + case FRAME : { //FIXME compute frame SDF + vec3 q = abs(ratioWithinBox.xyz + -vec3(0.5,0.5,0.5))*2.0 + - vec3(1.0,1.0,1.0); + gradRatio = 1.0-abs(length(max(q,0.0)) + + min(max(q.x,max(q.y,q.z)),0.0)); + } break; + case MODEL : { + gradRatio = texture(surfDistTex, + ratioWithinBox).r + * structureRatio; + } break; + default :{//defaults to sphere + gradRatio = length(ratioWithinBox.xyz + - vec3(0.5,0.5,0.5))/0.5; + } break; + } + } + //texture coordinates + vec3 texCoords = vec3(1-ratioWithinBox.x, + 1-ratioWithinBox.y, + ratioWithinBox.z); + + //start with shapeColor + finalColor = shapeColor; + //test gradient + if(gradientAlpha>0) { + float gradColor = + pow(gradientCurveRatio<0?1.0-gradRatio:gradRatio, + abs(gradientCurveRatio)); + if(gradientSteps>1) { + gradColor = floor(gradColor*gradientSteps) + / gradientSteps; + } + gradColor*=(gradRatio<=1.0)?1.0:0.0; + if(gradientType>0) {//gradient texture + finalColor=finalColor*(1.0-gradientAlpha) + + finalColor*gradientAlpha + * texture(gradientTex, + vec2(gradRatio, 0.0)).xyz; + } + else { + finalColor=finalColor*(1.0-gradientAlpha) + + finalColor*gradColor*gradientAlpha; + } + } + //test density + if(densityAlpha>0) { + float densColor = + pow(densityCurveRatio<0?1.0-gradRatio:gradRatio, + abs(densityCurveRatio)); + if(densityType==0 && //layers + length(mod(densColor*100.0, + densitySize*100.0)) + < densityRatio*densitySize*100.0) { + densColor = 1.0; + densColor*=(gradRatio<=1.0)?1.0:0.0; + } + else if(densityType==1 //grid + && (length(mod(ratioWithinBox.x*100, + densitySize*100.0)) + <densitySize*densityRatio*100.0 + || length(mod(ratioWithinBox.y*100, + densitySize*100.0)) + <densitySize*densityRatio*100.0 + || length(mod(ratioWithinBox.z*100, + densitySize*100.0)) + <densitySize*densityRatio*100.0)) { + densColor = 1.0; + } + else if(densityType==2 //pointcloud + && floor(random(ratioWithinBox.xyz) + *floor(100.0))>100.0*densColor) { + densColor = 1.0; + densColor*=(gradRatio<=1.0)?1.0:0.0; + } + else { + densColor = 0.0; + } + finalColor=finalColor*(1.0-densityAlpha) + + finalColor*densColor*densityAlpha; + } + //test texture + if(texAlpha>0) { + vec3 texColor = texture(insideTex, + texOffset+texScale*texCoords).xyz; + if(texGray>0) { + texColor=vec3((texColor.r+texColor.g+texColor.b) + / 3.0); + } + finalColor=finalColor*(1.0-texAlpha) + + finalColor*texColor*texAlpha; + } + } + //SURFACE test + if(rendered>1) { + finalColor = surfaceColor; + } + } + //final test, output if rendered or not, output final color + if(rendered>0 && length(finalColor)>0) { + if((insideVisible>0 && rendered==1) + || (surface>0 && rendered==2)) { + color = vec4(finalColor, 1.0);//display + } + else { + color = vec4(0.0, 0.0, 0.0, 1.0); + } + } + else { //DISCARD + discard; + } +}; diff --git a/src/shaders/render43.fs b/src/shaders/render43.fs new file mode 100644 index 0000000000000000000000000000000000000000..f1eb72e53b6e2032b39685ac2b1af2dc2c4b1645 --- /dev/null +++ b/src/shaders/render43.fs @@ -0,0 +1,557 @@ +#version 430 + +const int BOX=0; +const int SPHERE=1; +const int TUBE=2; +const int CONE=3; +const int FRAME=4; +const int PATH=5; +const int MODEL=10; + +in vec3 viewRay; +in vec2 uvCoords; + +layout(binding=0) uniform sampler2D sliceTex; +layout(binding=1) uniform sampler2D selectTex; +layout(binding=2) uniform sampler3D insideTex; +layout(binding=3) uniform sampler2D surfaceTex; +layout(binding=4) uniform sampler3D reactTex; +layout(binding=5) uniform sampler3D surfDistTex; +layout(binding=6) uniform sampler2D gradientTex; +layout(r32ui, binding=0) uniform coherent uimage2D outputTex; +layout(r32i, binding=1) uniform coherent iimage2D outputAudioTex; +layout(r32i, binding=2) uniform coherent iimage2D phases; + +uniform int mixSize; +uniform float maxSinValue; +uniform int nRate; +uniform float phase; +uniform int bufSize; + +uniform float viewportWidth; +uniform float viewportHeight; +uniform float mirrored; +uniform float shapeID; +uniform float shapeIDBit; +uniform int shapeGeom; +uniform float subShapeID; +uniform float subShapesNb; +uniform mat4 subShapeInvMat; +uniform mat4 viewMat; +uniform mat4 modelMat; +uniform mat4 invModelMat; +uniform vec3 modelScale; +uniform int revealedBy; + +uniform vec3 shapeColor; +//0: none, 1:color, 2:texture +uniform int surface; +uniform vec3 surfaceColor; +uniform int insideOutputOnly; +uniform int reactivity; +uniform float thickness; + +uniform int insideVisible; +//0:from center, 1:along x, 2: along y, 3:along z, 4 :from surface +uniform int insideStructure; +uniform float structureRatio; + +uniform float gradientAlpha; +//0:greyscale, 1:texture +uniform int gradientType; +uniform int gradientSteps; +uniform float gradientCurveRatio; + +uniform float densityAlpha; +//0:layers, 1:grid, 2:pointcloud +uniform int densityType; +uniform float densityRatio; +uniform float densitySize; +uniform float densityCurveRatio; + +uniform float texAlpha; +uniform vec3 texOffset; +uniform vec3 texScale; +uniform int texGray; + +uniform int revSize; +uniform int revSurface; +uniform int revInside; +uniform int revCenter; +uniform int revCursor; +uniform int revColor; +uniform int revHisto; +uniform int revVoxels; +uniform float revSubShapeID; +uniform int shapeOutSize; +uniform int histoOutSize; +uniform int voxelOutSize; +uniform int depthOutSize; +uniform int depthOutNb; +uniform vec4 boundingRect; + +vec3 rgb2hsv(vec3 c){ + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)),d/(q.x + e), q.x); +} + +float random (vec3 st){ + return fract(sin(dot(st.xyz, + vec3(12.9898,78.233, 102.234)))* + 43758.5453123); +} + +out vec4 color; + +void additiveSynth(vec4 color){ + int freq; + int i = 2; + float note = 20 + color.x * 50;//color.x * 127; + int octave = int(note/12); + float modNote = int(note) % 12; + int ratioSampleFreq; + float ratioFreqSample; + int initPhase; + int fragPhase; + int ind; + + if(modNote >= 8.5){ + note = octave * 12 + 10; + ind = 4 * octave + 3; + } + else if(modNote >= 5.5){ + note = octave * 12 + 7; + ind = 4 * octave + 2; + } + else if(modNote >= 2.0){ + note = octave * 12 + 4; + ind = 4 * octave + 1; + } + else{ + note = octave * 12; + ind = 4 * octave; + } + + /*int n = int(color.x * 3); + int note = 0; + if(n == 0){ + note = 40; + } + else if(n == 1){ + note = 44; + } + else if(n == 2){ + note = 47; + } + else{ + note = 50; + } + ind = n;*/ + + freq = int(440 * pow(2, (note-69)/12)); + + ratioSampleFreq = nRate/freq; + ratioFreqSample = 1.0/ratioSampleFreq; + + fragPhase = imageLoad(phases, ivec2(ind, 0)).x; + + float a = sin(fragPhase *(3.14f) * freq/nRate); + + float s[2]; + + s[0] = 1.0f; + s[1] = 0.0f; + imageStore(outputAudioTex, ivec2(0, ind), ivec4(42)); + + while (i < bufSize) { + imageStore(outputAudioTex, ivec2(i, ind), ivec4(int(s[1]*maxSinValue))); + + s[0] = s[0] - a*s[1]; + s[1] = s[1] + a*s[0]; + + i += 1; + } + + imageStore(outputAudioTex, ivec2(1, ind), ivec4(ratioSampleFreq)); +} + +void main(void) { + //get fragment coordinates + float coordX = (gl_FragCoord.x-0.5)/viewportWidth; + float coordY = (gl_FragCoord.y-0.5)/viewportHeight; + ivec2 sliSize = textureSize(sliceTex, 0); + + //retrieve pixel in slicing texture + vec4 sli = texelFetch(sliceTex, ivec2(coordX*float(sliSize.x), coordY*float(sliSize.y)), 0); + float pixZ=abs(gl_FragCoord.z); + float cutZ=abs(sli.z); + int depthID=int(sli.y)-1; + + int outCols=imageSize(outputTex).x; + int outOffset=(int(shapeID-1)*depthOutNb+(depthID-1))*revSize; + + int rendered=0; + vec3 finalColor = shapeColor; + float alpha=0; + vec3 pixelPosW; + vec3 pixelPos = vec3(0.0, 0.0, 1.0); + vec3 ratioWithinBox = vec3(0.0, 0.0, 0.0); + vec3 outRatioWithinBox = vec3(0.0, 0.0, 0.0); + + //if there is a slicing pixel aligned with our coordinate + //and we are revealed by this depth module + if(cutZ>0 && (revealedBy & (1<<(1+depthID)))>0 ) { + //compute the slicing pixel world position + pixelPosW = vec3(viewMat[3][0], viewMat[3][1], viewMat[3][2]) + vec3(normalize(viewRay) * sli.w); + pixelPosW.x = pixelPosW.x*(-2.0*(1-mirrored)+1.0); + //compute the slicing pixel position in model coords + pixelPos = (invModelMat * vec4(pixelPosW,1.0)).xyz; + + //depending on type, test if slicing pixel inside + //and retrieve distance to the surface on each axis + vec3 diffMin = vec3(1.0); + vec3 diffMax = vec3(1.0); + + switch(shapeGeom) { + case PATH : { + //use min/max/size of current segment + pixelPos = (subShapeInvMat*vec4(pixelPos,1.0)).xyz; + if(length(vec2(pixelPos.x, pixelPos.y))<=0.5 && (pixelPos.z>-0.5 && pixelPos.z<0.5)) { + float xx = (pixelPos.x)*(pixelPos.x); + float yy = (pixelPos.y)*(pixelPos.y); + float ax = sqrt(0.25-yy); + diffMin.x = pixelPos.x+ax; + diffMax.x = ax-pixelPos.x; + float ay = sqrt(0.25-xx); + diffMin.y = pixelPos.y+ay; + diffMax.y = ay-pixelPos.y; + diffMin.z = pixelPos.z+0.5; + diffMax.z = 0.5-pixelPos.z; + rendered=1; + } + } break; + case CONE : { + if(pixelPos.y<0.5 && pixelPos.y>-0.5) { + float xx = (pixelPos.x)*(pixelPos.x); + float yy = (pixelPos.y-0.5)*(pixelPos.y-0.5); + float zz = (pixelPos.z)*(pixelPos.z); + if((xx+zz)/yy<0.25){ + float ax = sqrt(0.25*yy-zz); + diffMin.x = pixelPos.x+ax; + diffMax.x = ax-pixelPos.x; + float ay = sqrt((yy+xx)/0.25); + diffMin.y = pixelPos.y+0.5; + diffMax.y = 0.5-pixelPos.y; + float az = sqrt(0.25*yy-xx); + diffMin.z = pixelPos.z+az; + diffMax.z = az-pixelPos.z; + rendered=1; + } + } + } break; + case TUBE : { + if(length(vec2(pixelPos.x, pixelPos.z))<=0.5 && (pixelPos.y>-0.5 && pixelPos.y<0.5)) { + float xx = (pixelPos.x)*(pixelPos.x); + float zz = (pixelPos.z)*(pixelPos.z); + float ax = sqrt(0.25-zz); + diffMin.x = pixelPos.x+ax; + diffMax.x = ax-pixelPos.x; + float az = sqrt(0.25-xx); + diffMin.z = pixelPos.z+az; + diffMax.z = az-pixelPos.z; + diffMin.y = pixelPos.y+0.5; + diffMax.y = 0.5-pixelPos.y; + rendered=1; + } + } break; + case SPHERE : { + if(length(pixelPos)<=0.5) { + float xx = (pixelPos.x)*(pixelPos.x); + float yy = (pixelPos.y)*(pixelPos.y); + float zz = (pixelPos.z)*(pixelPos.z); + float ax = sqrt(0.25-yy-zz); + diffMin.x = pixelPos.x+ax; + diffMax.x = ax-pixelPos.x; + float ay = sqrt(0.25-xx-zz); + diffMin.y = pixelPos.y+ay; + diffMax.y = ay-pixelPos.y; + float az = sqrt(0.25-xx-yy); + diffMin.z = pixelPos.z+az; + diffMax.z = az-pixelPos.z; + rendered=1; + } + } break; + case BOX : { + diffMin = pixelPos - vec3(-0.5, -0.5, -0.5); + diffMax = vec3(0.5, 0.5, 0.5) - pixelPos; + if(diffMin.x>0 && diffMax.x>0 && diffMin.y>0 && diffMax.y>0 && diffMin.z>0 && diffMax.z>0){ + rendered=1; + } + } break; + case FRAME : { + diffMin = pixelPos - vec3(-0.5, -0.5, -0.5); + diffMax = vec3(0.5, 0.5, 0.5) - pixelPos; + if(diffMin.x>0 && diffMax.x>0 && diffMin.y>0 && diffMax.y>0 && diffMin.z>0 && diffMax.z>0){ + rendered=1; + } + } break; + case MODEL : { + ivec2 selSize = textureSize(selectTex, 0); + vec4 sel = texelFetch(selectTex, + ivec2(coordX*float(selSize.x), coordY*float(selSize.y)), 0); + //get front surfaces before depth map + if(pixZ<=cutZ+thickness/1000.0) { + if(sel.z==0) { + if(sel.x==shapeID) { + rendered=1; + } + else if((int(shapeIDBit)&int(sel.w))>0) { + diffMin = pixelPos - vec3(-0.5, -0.5, -0.5); + diffMax = vec3(0.5, 0.5, 0.5) - pixelPos; + if(diffMin.x>0 && diffMax.x>0 && diffMin.y>0 && diffMax.y>0 && diffMin.z>0 && diffMax.z>0){ + rendered=1; + } + } + } + if(surface>0 && (pixZ>cutZ || (sel.z>0 && (int(shapeIDBit)&int(sel.w))>0))) { + rendered=2; + } + } + } break; + } + if(rendered>0) { + ratioWithinBox = (pixelPos)+0.5; + //test if on the surface + if(diffMin.x*modelScale.x<thickness || diffMax.x*modelScale.x<thickness || diffMin.y*modelScale.y<thickness || + diffMax.y*modelScale.y<thickness || diffMin.z*modelScale.z<thickness || diffMax.z*modelScale.z<thickness) { + rendered=2; + } + //extend ratiowithinbox to multiplesubshapes + //and get gradient ratio according to type + float gradRatio = 0; + vec3 subAdd; + vec3 subDiv; + if(insideStructure==0) { + //from center + subAdd = vec3(subShapeID, subShapeID, subShapeID); + subDiv = vec3(subShapesNb, subShapesNb, subShapesNb); + ratioWithinBox.xyz=(ratioWithinBox.xyz+subAdd)/subDiv; + outRatioWithinBox.xyz=ratioWithinBox.xyz; + gradRatio = length(ratioWithinBox.xyz - vec3(0.5,0.5,0.5))/0.5; + } + else { + //from surface or along axes + subAdd = vec3(0,0, subShapeID); + subDiv = vec3(1,1, subShapesNb); + ratioWithinBox.xyz=(ratioWithinBox.xyz+subAdd)/subDiv; + outRatioWithinBox.xyz=ratioWithinBox.xyz; + if(insideStructure==1) { + ratioWithinBox.x=0.5; + } + else if(insideStructure==2) { + ratioWithinBox.y=0.5; + } + else if(insideStructure==3 && shapeGeom!=PATH) { + ratioWithinBox.z=0.5; + } + switch(shapeGeom) { + case BOX : { + vec3 q = abs(ratioWithinBox.xyz - vec3(0.5,0.5,0.5))*2.0 - vec3(1.0,1.0,1.0); + gradRatio = 1.0-abs(length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0)); + } break; + case SPHERE : { + gradRatio = length(ratioWithinBox.xyz - vec3(0.5,0.5,0.5))/0.5; + } break; + case PATH : { + vec2 d = abs(vec2(length((ratioWithinBox.xy-vec2(0.5, 0.5))*2.0), (ratioWithinBox.z-0.5)*2.0)) - vec2(1.0,1.0); + gradRatio = 1.0 - abs(min(max(d.x,d.y),0.0) + length(max(d,0.0))); + } break; + case TUBE : { + vec2 d = abs(vec2(length((ratioWithinBox.xz-vec2(0.5, 0.5))*2.0), (ratioWithinBox.y-0.5)*2.0)) - vec2(1.0,1.0); + gradRatio = 1.0 - abs(min(max(d.x,d.y),0.0) + length(max(d,0.0))); + } break; + case CONE : { + float q = length((ratioWithinBox.xz - vec2(0.5,0.5))*2.0); + gradRatio = 1.0-abs(max(dot(vec2(0.5,0.5), vec2(q,(ratioWithinBox.y-1.0))), -1.0-(ratioWithinBox.y-1.0))); + } break; + case FRAME : { + //FIXME compute frame SDF + vec3 q = abs(ratioWithinBox.xyz - vec3(0.5,0.5,0.5))*2.0 - vec3(1.0,1.0,1.0); + gradRatio = 1.0-abs(length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0)); + } break; + case MODEL : { + gradRatio = texture(surfDistTex, ratioWithinBox).r * structureRatio; + } break; + default :{ + //defaults to sphere + gradRatio = length(ratioWithinBox.xyz - vec3(0.5,0.5,0.5))/0.5; + } break; + } + } + /*imageAtomicAdd(outputAudioTex, ivec2(0,0), 1); + int i = 1; + float ratioSampleFreq = nRate/700.0; + float ratioFreqSample = 1.0/ratioSampleFreq; + int fragPhase = int(phase); + while (i < bufSize) { + int val = int(cos(fragPhase * ratioFreqSample * (2 * 3.14))*maxSinValue); + imageAtomicAdd(outputAudioTex, ivec2(i,0), val); + //imageAtomicAdd(outputAudioTex, ivec2(i+1,0),val); + fragPhase += 1; + fragPhase = fragPhase % int(ratioSampleFreq); + i += 1; + }*/ + + //texture coordinates + vec3 texCoords = vec3(1-ratioWithinBox.x, 1-ratioWithinBox.y, ratioWithinBox.z); + + //start with shapeColor + finalColor = shapeColor; + //test gradient + if(gradientAlpha>0) { + float gradColor = pow(gradientCurveRatio<0?1.0-gradRatio:gradRatio, abs(gradientCurveRatio)); + if(gradientSteps>1) { + gradColor = floor(gradColor*gradientSteps) / gradientSteps; + } + gradColor*=(gradRatio<=1.0)?1.0:0.0; + if(gradientType>0) { + //gradient texture + finalColor=finalColor*(1.0-gradientAlpha) + finalColor*gradientAlpha * texture(gradientTex, vec2(gradRatio, 0.0)).xyz; + } + else { + finalColor=finalColor*(1.0-gradientAlpha) + finalColor*gradColor*gradientAlpha; + } + } + //test density + if(densityAlpha>0) { + float densColor = pow(densityCurveRatio<0?1.0-gradRatio:gradRatio, abs(densityCurveRatio)); + if(densityType==0 && //layers + length(mod(densColor*100.0, densitySize*100.0)) < densityRatio*densitySize*100.0) { + densColor = 1.0; + densColor*=(gradRatio<=1.0)?1.0:0.0; + } + else if(densityType==1 //grid + && (length(mod(ratioWithinBox.x*100, densitySize*100.0)) < densitySize*densityRatio*100.0 + || length(mod(ratioWithinBox.y*100, densitySize*100.0)) < densitySize*densityRatio*100.0 + || length(mod(ratioWithinBox.z*100, densitySize*100.0)) < densitySize*densityRatio*100.0)) { + densColor = 1.0; + } + else if(densityType==2 //pointcloud + && floor(random(ratioWithinBox.xyz)*floor(100.0))>100.0*densColor) { + densColor = 1.0; + densColor*=(gradRatio<=1.0)?1.0:0.0; + } + else { + densColor = 0.0; + } + finalColor=finalColor*(1.0-densityAlpha) + finalColor*densColor*densityAlpha; + } + //test texture + if(texAlpha>0) { + vec3 texColor = texture(insideTex, texOffset+texScale*texCoords).xyz; + if(texGray>0) { + texColor=vec3((texColor.r+texColor.g+texColor.b) / 3.0); + } + finalColor=finalColor*(1.0-texAlpha) + finalColor*texColor*texAlpha; + } + + //if revealing something, output values + if(sli.x>=1.0 && depthID<=depthOutNb) { + //inside output + if(revInside>0 && rendered==1) { + imageAtomicMax(outputTex, ivec2(mod(outOffset+revInside,outCols), floor((outOffset+revInside))/outCols), 1); + } + outRatioWithinBox.x=clamp(outRatioWithinBox.x, 0, 1); + outRatioWithinBox.y=clamp(outRatioWithinBox.y, 0, 1); + outRatioWithinBox.z=clamp(outRatioWithinBox.z, 0, 1); + //compute min,max on the three axes + int xk=int(outRatioWithinBox.x*1000.0); + int yk=int(outRatioWithinBox.y*1000.0); + int zk=int(outRatioWithinBox.z*1000.0); + //output min/max ratios + if(revCenter>0) { + imageAtomicMax(outputTex, ivec2(mod(outOffset+revCenter+0,outCols), floor((outOffset+revCenter+0)/outCols)), 1000-xk); + imageAtomicMax(outputTex, ivec2(mod(outOffset+revCenter+1,outCols), floor((outOffset+revCenter+1)/outCols)), xk); + imageAtomicMax(outputTex, ivec2(mod(outOffset+revCenter+2,outCols), floor((outOffset+revCenter+2)/outCols)), 1000-yk); + imageAtomicMax(outputTex, ivec2(mod(outOffset+revCenter+3,outCols), floor((outOffset+revCenter+3)/outCols)), yk); + imageAtomicMax(outputTex, ivec2(mod(outOffset+revCenter+4,outCols), floor((outOffset+revCenter+4)/outCols)), 1000-zk); + imageAtomicMax(outputTex, ivec2(mod(outOffset+revCenter+5,outCols), floor((outOffset+revCenter+5)/outCols)), zk); + } + //convert from rgb to hsv + vec3 hsv = rgb2hsv(finalColor); + //Sum color channels + if(revColor>0) { + //count nb revealed points + imageAtomicAdd(outputTex, ivec2(mod(outOffset+revColor+0,outCols), floor((outOffset+revColor+0)/outCols)), 1); + //sum point h + imageAtomicAdd(outputTex, ivec2(mod(outOffset+revColor+1,outCols), floor((outOffset+revColor+1)/outCols)), clamp(int(hsv.x*1000.0),0,1000)); + //sum s + imageAtomicAdd(outputTex, ivec2(mod(outOffset+revColor+2,outCols), floor((outOffset+revColor+2)/outCols)), clamp(int(hsv.y*1000.0),0,1000)); + //sum v + imageAtomicAdd(outputTex, ivec2(mod(outOffset+revColor+3,outCols), floor((outOffset+revColor+3)/outCols)), clamp(int(hsv.z*1000.0),0,1000)); + } + //histo : accumulate on luminance bins + if(revHisto>0) { + //count nb revealed points + imageAtomicAdd(outputTex, ivec2(mod(outOffset+revHisto,outCols), + floor((outOffset+revHisto)/outCols)), 1); + int bin = int(hsv.z*float(histoOutSize-1)); + imageAtomicAdd(outputTex, ivec2(mod(outOffset+revHisto+1+bin,outCols), floor((outOffset+revHisto+1+bin)/outCols)), 1); + } + + //2D grid of projected voxels (nbvox, 3D coords, lum) + if(revVoxels>0) { + //compute pixel ratio within 2D bounding rect + vec2 pixRatio = (vec2(coordX, coordY) - boundingRect.xy) / (boundingRect.zw-boundingRect.xy); + pixRatio.x = clamp(pixRatio.x, 0.0, 1.0); + pixRatio.y = clamp(pixRatio.y, 0.0, 1.0); + //compute offset in voxel output + int voxOff = outOffset+revVoxels; + voxOff+=5*(int(pixRatio.x*voxelOutSize) + int((1.0-pixRatio.y)*voxelOutSize)*voxelOutSize); + //accumulate points + imageAtomicAdd(outputTex, ivec2(mod(voxOff,outCols), floor((voxOff)/outCols)), 1); + //accumulate coords + imageAtomicAdd(outputTex, ivec2(mod(voxOff+1,outCols), floor((voxOff+1)/outCols)), clamp(int(outRatioWithinBox.x*1000.0),0,1000)); + imageAtomicAdd(outputTex, ivec2(mod(voxOff+2,outCols),floor((voxOff+2)/outCols)), clamp(int(outRatioWithinBox.y*1000.0),0,1000)); + imageAtomicAdd(outputTex, ivec2(mod(voxOff+3,outCols), floor((voxOff+3)/outCols)), clamp(int(outRatioWithinBox.z*1000.0),0,1000)); + //accumulate lum + imageAtomicAdd(outputTex, ivec2(mod(voxOff+4,outCols), floor((voxOff+4)/outCols)), + clamp(int(hsv.z*1000.0),0,1000)); + } + } + } + + //SURFACE test + if(rendered>1) { + finalColor = surfaceColor; + + if(revSurface>0 && sli.x>=1.0 && depthID<=depthOutNb) { + imageAtomicMax(outputTex, ivec2(mod(outOffset+revSurface,outCols), floor((outOffset+revSurface)/outCols)), 1); + } + } + } + //final test, output if rendered or not, output final color + if(rendered>0 && length(finalColor)>0) { + + if(revSize>0) { + imageAtomicOr(outputTex, ivec2(mod(outOffset,outCols), floor((outOffset))/outCols), rendered); + } + + if((insideVisible>0 && rendered==1) || (surface>0 && rendered==2)) { + color = vec4(finalColor, 1.0); + + additiveSynth(color); + } + else { + color = vec4(0.0, 0.0, 0.0, 1.0); + } + } + else { //DISCARD + discard; + } +}; + diff --git a/src/shaders/render43.vs b/src/shaders/render43.vs new file mode 100644 index 0000000000000000000000000000000000000000..277dfc1029c7492d3d890ff1cb811dcd50916791 --- /dev/null +++ b/src/shaders/render43.vs @@ -0,0 +1,25 @@ +#version 430 + +in vec3 vertex; +in vec2 texCoords; + +uniform mat4 modelMat; +uniform mat4 viewMat; +uniform mat4 viewProjMat; +uniform float mirrored; + +out vec3 viewRay; +out vec2 uvCoords; + +void main(void) { + vec4 posWS = modelMat * vec4(vertex, 1.0); + if(mirrored<1) { + posWS.x = -posWS.x; + } + gl_Position = viewProjMat * posWS; + viewRay = posWS.xyz - vec3(viewMat[3][0], + viewMat[3][1], + viewMat[3][2]); + uvCoords=texCoords; +}; + diff --git a/src/shaders/select30.fs b/src/shaders/select30.fs new file mode 100644 index 0000000000000000000000000000000000000000..874a0b1508f25cb52618252799124d4cb25145f5 --- /dev/null +++ b/src/shaders/select30.fs @@ -0,0 +1,40 @@ +#version 130 + +uniform sampler2D sliceTex; +uniform float viewportWidth; +uniform float viewportHeight; +uniform float shapeID; +uniform float shapeIDBit; +uniform float mirrored; +uniform float thickness; +uniform int surface; + +out vec4 color; + +void main(void) { + float coordX = (gl_FragCoord.x-0.5)/viewportWidth; + float coordY = (gl_FragCoord.y-0.5)/viewportHeight; + ivec2 sliSize = textureSize(sliceTex, 0); + vec4 sli = texelFetch(sliceTex, + ivec2(coordX*float(sliSize.x), + coordY*float(sliSize.y)), + 0); + float pixZ=abs(gl_FragCoord.z); + float cutZ=abs(sli.z); + // keep all ids of back surfaces after depth map + if(pixZ>cutZ && cutZ>0) { + if((mirrored<1 && !gl_FrontFacing) + || (mirrored>0 && gl_FrontFacing)) { + color = vec4(shapeID, 0, + (abs(pixZ-cutZ)<thickness/1000.0 && surface>0)?1:0, + shapeIDBit); + } + else { //occlude back when front face also behind + color = vec4(-shapeID, 0, 0, -shapeIDBit); + } + } + else { + discard; + } +}; + diff --git a/src/shaders/select30.vs b/src/shaders/select30.vs new file mode 100644 index 0000000000000000000000000000000000000000..2d99e129a72851fbf1c062f59c25542f18ec86bd --- /dev/null +++ b/src/shaders/select30.vs @@ -0,0 +1,16 @@ +#version 130 + +in vec3 vertex; + +uniform mat4 modelMat; +uniform mat4 viewMat; +uniform mat4 viewProjMat; +uniform float mirrored; + +void main(void) { + vec4 posWS = modelMat * vec4(vertex, 1.0); + if(mirrored<1) { + posWS.x = -posWS.x; + } + gl_Position = viewProjMat * posWS; +} diff --git a/src/shaders/select43.fs b/src/shaders/select43.fs new file mode 100644 index 0000000000000000000000000000000000000000..6a4473c41806f651829ce9ef8715967ddeb785de --- /dev/null +++ b/src/shaders/select43.fs @@ -0,0 +1,40 @@ +#version 430 + +layout(binding=0) uniform sampler2D sliceTex; +uniform float viewportWidth; +uniform float viewportHeight; +uniform float shapeID; +uniform float shapeIDBit; +uniform float mirrored; +uniform float thickness; +uniform int surface; + +out vec4 color; + +void main(void) { + float coordX = (gl_FragCoord.x-0.5)/viewportWidth; + float coordY = (gl_FragCoord.y-0.5)/viewportHeight; + ivec2 sliSize = textureSize(sliceTex, 0); + vec4 sli = texelFetch(sliceTex, + ivec2(coordX*float(sliSize.x), + coordY*float(sliSize.y)), + 0); + float pixZ=abs(gl_FragCoord.z); + float cutZ=abs(sli.z); + // keep all ids of back surfaces after depth map + if(pixZ>cutZ && cutZ>0) { + if((mirrored<1 && !gl_FrontFacing) + || (mirrored>0 && gl_FrontFacing)) { + color = vec4(shapeID, 0, + (abs(pixZ-cutZ)<thickness/1000.0 && surface>0)?1:0, + shapeIDBit); + } + else { //occlude back when front face also behind + color = vec4(-shapeID, 0, 0, -shapeIDBit); + } + } + else { + discard; + } +}; + diff --git a/src/shaders/select43.vs b/src/shaders/select43.vs new file mode 100644 index 0000000000000000000000000000000000000000..c9eb457bfaea1922a5527ded223e6ead65eec56e --- /dev/null +++ b/src/shaders/select43.vs @@ -0,0 +1,16 @@ +#version 430 + +in vec3 vertex; + +uniform mat4 modelMat; +uniform mat4 viewMat; +uniform mat4 viewProjMat; +uniform float mirrored; + +void main(void) { + vec4 posWS = modelMat * vec4(vertex, 1.0); + if(mirrored<1) { + posWS.x = -posWS.x; + } + gl_Position = viewProjMat * posWS; +} diff --git a/src/shaders/slice30.fs b/src/shaders/slice30.fs new file mode 100644 index 0000000000000000000000000000000000000000..43069830abd4581f35f0531486d1dac56f1f1440 --- /dev/null +++ b/src/shaders/slice30.fs @@ -0,0 +1,21 @@ +#version 130 + +in float kept; +in vec3 viewRay; +flat in int outDepthID; + +out vec4 color; + +void main(void) { + float thresh=0.8; + if(kept>=thresh) { + color = vec4((kept-thresh)/(1.0-thresh), + float(outDepthID), + gl_FragCoord.z, + length(viewRay)); + } + else { + discard; + } +// color = vec4(1.0, 1.0, 0.0, 1.0); +}; diff --git a/src/shaders/slice30.vs b/src/shaders/slice30.vs new file mode 100644 index 0000000000000000000000000000000000000000..9ad4c20387e49546ab0533941de73c22e6fbe949 --- /dev/null +++ b/src/shaders/slice30.vs @@ -0,0 +1,134 @@ +#version 130 + +#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b); +#define mn3(a, b, c) s2(a, b); s2(a, c); +#define mx3(a, b, c) s2(b, c); s2(a, c); +#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); +#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); +#define mnmx5(a, b, c, d, e) s2(a,b); s2(c,d);mn3(a,c,e);mx3(b,d,e); +#define mnmx6(a,b,c,d,e,f) s2(a,d);s2(b,e);s2(c,f);mn3(a,b,c);mx3(d,e,f); +in vec3 vertex; + +uniform sampler2D depthCamTex; +uniform sampler2D depthCamTexFil; +uniform sampler2D markersTex; +uniform mat4 modelMat; +uniform mat4 viewMat; +uniform mat4 viewProjMat; +uniform float camXReso; +uniform float camYReso; +uniform float camXZFactor; +uniform float camYZFactor; +uniform int camFilter; +uniform int background; +uniform float camContThresh; +uniform float camMarkers; +uniform int depthType; +uniform int depthID; +uniform float outputCurs; +uniform float mirrored; + +out vec3 viewRay; +out float kept; +flat out int outDepthID; + +void main(void) { + vec4 depthPos = vec4(0, 0, 0, 1); + vec4 posWS = vec4(0, 0, 0, 1); + //depth camera + if(depthType==0) { + vec2 coords = vertex.xy; + //get marker if any + if(camMarkers>0) { + outDepthID = int(float(texture(markersTex, + vec2(coords.x/camXReso, + coords.y/camYReso)).r) + * 255.0); + } + else { + outDepthID=depthID+1; + } + //get depth pixel in camera texture + float depth = + float(texture(depthCamTex, + vec2(coords.x/camXReso, + coords.y/camYReso)).r) + * 65535.0; + kept=1.0; + float backgroundDepth=0; + if(background>0) { + float backDepth = float(texture(depthCamTex, + vec2(coords.x/camXReso, + coords.y/camYReso)).r) + * 65535.0; + if(backDepth<depth) { + depth=backDepth; + backgroundDepth=1; + } + } + if(depth<=500.0 || depth>8000.0) { + kept=0.0; + } + else if(backgroundDepth==0) { + //filter out contours + float maxD=camContThresh; + bool contour=false; + for(int dX = -1; dX <= 1; ++dX) { + for(int dY = -1; dY <= 1; ++dY) { + if(abs(float(texture(depthCamTex, + vec2((coords.x+dX)/camXReso, + (coords.y+dY)/camYReso)).r) + * 65535.0 + - depth) > maxD) { + contour=true; + } + } + } + if(contour) { + kept=0.0; + } + //see if needs filtering + if(camFilter>0) { + float filtDepth = float(texture(depthCamTexFil, + vec2(coords.x/camXReso, + coords.y/camYReso)).r) + * 65535.0; + //select either filtered version or current one + //depending on movement + if(abs(filtDepth-depth)<camContThresh) { + float filRatio = abs(filtDepth-depth)/camContThresh; + depth=(1-filRatio)*filtDepth+(filRatio)*depth; + } + } + } + //test distance again + if(depth<=500.0 || depth>8000.0) { + kept=0.0; + } + //compute position in world units + depthPos = vec4((vertex.x/camXReso-0.5) + *depth*camXZFactor, + (0.5-(vertex.y/camYReso)) + *depth*camYZFactor, + depth, + 1.0); + //get world pos + posWS = modelMat * depthPos; + } + //other slicing shapes + else { + outDepthID=depthID+1; + kept=1.0; + depthPos=vec4(vertex, 1.0); + posWS = modelMat * depthPos; + if(mirrored<1) { + posWS.x = -posWS.x; + } + } + //keep/interpolate ray from view to each vertex + viewRay = (posWS.xyz - vec3(viewMat[3][0], + viewMat[3][1], + viewMat[3][2])); + gl_Position = viewProjMat * posWS; +}; + diff --git a/src/shaders/slice43.fs b/src/shaders/slice43.fs new file mode 100644 index 0000000000000000000000000000000000000000..f1201a390610e1f9be9eb5cebe80f82772c711fe --- /dev/null +++ b/src/shaders/slice43.fs @@ -0,0 +1,22 @@ +#version 430 + +in float kept; +in vec3 viewRay; +flat in int outDepthID; + +out vec4 color; + +void main(void) { + float thresh=0.8; + if(kept>=thresh) { + color = vec4((kept-thresh)/(1.0-thresh), + float(outDepthID), + gl_FragCoord.z, + length(viewRay)); + } + else { + discard; + } +// color = vec4(1.0, 1.0, 0.0, 1.0); +}; + diff --git a/src/shaders/slice43.vs b/src/shaders/slice43.vs new file mode 100644 index 0000000000000000000000000000000000000000..660d649311496c5ed0eb23e06c8b02a808dc60f6 --- /dev/null +++ b/src/shaders/slice43.vs @@ -0,0 +1,145 @@ +#version 430 + +#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b); +#define mn3(a, b, c) s2(a, b); s2(a, c); +#define mx3(a, b, c) s2(b, c); s2(a, c); +#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); +#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); +#define mnmx5(a, b, c, d, e) s2(a,b); s2(c,d);mn3(a,c,e);mx3(b,d,e); +#define mnmx6(a,b,c,d,e,f) s2(a,d);s2(b,e);s2(c,f);mn3(a,b,c);mx3(d,e,f); +in vec3 vertex; + +layout(binding=0) uniform sampler2D depthCamTex; +layout(binding=1) uniform sampler2D depthCamTexFil; +layout(binding=2) uniform sampler2D markersTex; +//layout(r32ui, binding=2) uniform coherent uimage2D outputTex; +uniform mat4 modelMat; +uniform mat4 viewMat; +uniform mat4 viewProjMat; +uniform float camXReso; +uniform float camYReso; +uniform float camXZFactor; +uniform float camYZFactor; +uniform int camFilter; +uniform int background; +uniform float camContThresh; +uniform float camMarkers; +uniform int depthType; +uniform int depthID; +uniform float outputCurs; +uniform float mirrored; + +out vec3 viewRay; +out float kept; +flat out int outDepthID; + +void main(void) { + vec4 depthPos = vec4(0, 0, 0, 1); + vec4 posWS = vec4(0, 0, 0, 1); + //depth camera + if(depthType==0) { + vec2 coords = vertex.xy; + //get marker if any + if(camMarkers>0) { + outDepthID = int(float(texture(markersTex, + vec2(coords.x/camXReso, + coords.y/camYReso)).r) + * 255.0); + } + else { + outDepthID=depthID+1; + } + //get depth pixel in camera texture + float depth = + float(texture(depthCamTex, + vec2(coords.x/camXReso, + coords.y/camYReso)).r) + * 65535.0; + kept=1.0; + float backgroundDepth=0; + if(background>0) { + float backDepth = float(texture(depthCamTex, + vec2(coords.x/camXReso, + coords.y/camYReso)).r) + * 65535.0; + if(backDepth<depth) { + depth=backDepth; + backgroundDepth=1; + } + } + if(depth<=500.0 || depth>8000.0) { + kept=0.0; + } + else if(backgroundDepth==0) { + //filter out contours + float maxD=camContThresh; + bool contour=false; + for(int dX = -1; dX <= 1; ++dX) { + for(int dY = -1; dY <= 1; ++dY) { + if(abs(float(texture(depthCamTex, + vec2((coords.x+dX)/camXReso, + (coords.y+dY)/camYReso)).r) + * 65535.0 + - depth) > maxD) { + contour=true; + } + } + } + if(contour) { + kept=0.0; + } + //see if needs filtering + if(camFilter>0) { + float filtDepth = float(texture(depthCamTexFil, + vec2(coords.x/camXReso, + coords.y/camYReso)).r) + * 65535.0; + //select either filtered version or current one + //depending on movement + if(abs(filtDepth-depth)<camContThresh) { + float filRatio = abs(filtDepth-depth)/camContThresh; + depth=(1-filRatio)*filtDepth+(filRatio)*depth; + } + } + } + //test distance again + if(depth<=500.0 || depth>8000.0) { + kept=0.0; + } + //compute position in world units + depthPos = vec4((vertex.x/camXReso-0.5) + *depth*camXZFactor, + (0.5-(vertex.y/camYReso)) + *depth*camYZFactor, + depth, + 1.0); + //get world pos + posWS = modelMat * depthPos; + } + //other slicing shapes + else { + outDepthID=depthID+1; + kept=1.0; + depthPos=vec4(vertex, 1.0); + posWS = modelMat * depthPos; + if(mirrored<1) { + posWS.x = -posWS.x; + } + } + /* + //output minimum point on z axis if output is active + if(outputCurs>0 && kept>0.0) { + imageAtomicMin(outputTex,ivec2(0,int(depthID)+500), + int(floor(1000.0+posWS.z/10.0)*1000000 + +floor(posWS.y/10.0+500.0)*1000 + +floor(posWS.x/10.0+500.0))); + // imageAtomicMin(outputTex,ivec2(0, int(depthID)+500),4400600); + // imageAtomicMin(outputTex,ivec2(0, int(depthID)+500),6400600); + } + */ + //keep/interpolate ray from view to each vertex + viewRay = (posWS.xyz - vec3(viewMat[3][0], + viewMat[3][1], + viewMat[3][2])); + gl_Position = viewProjMat * posWS; +}; diff --git a/wscript b/wscript index 2cdda6d4844fe425ecd9c6a9f614ce639436efa6..7363cc04c74d2c1aef365a98bdb6cc7139c2b4e7 100755 --- a/wscript +++ b/wscript @@ -1,138 +1,155 @@ #!/usr/bin/env python import sys, os +from waflib import Utils def options(opt): - opt.load('compiler_cxx') - opt.load('compiler_c') + opt.load('compiler_cxx') + opt.load('compiler_c') def configure(conf): - conf.load('compiler_cxx') - conf.load('compiler_c') - - #conf.check_cxx(lib="glfw", - # errmsg="Please install the glfw library", - # mandatory=True) - #conf.check_cxx(lib="glm", - # errmsg="Please install the glm library", - # mandatory=True) - #conf.check_cxx(lib="openni", - # errmsg="Please install the openni2 library", - # mandatory=True) - #conf.check_cxx(lib="fltk", - # errmsg="Please install the fltk library", - # mandatory=True) - #conf.check_cxx(lib="opencv2", - # errmsg="Please install the opencv library", - # mandatory=True) - - - #platform specific - if sys.platform == 'darwin': - conf.env.INCLUDES_OS = ['/opt/local/include', - '/opt/local/include/libxml2', - '/opt/local/include/opencv4', - '/opt/local/include/opencv3', - '/opt/local/include/openni'] - conf.env.LIBPATH_OS = ['/opt/local/lib','/opt/local/lib/opencv3'] - conf.env.LIB_OS = ['m', 'xml2', 'fltk', 'fltk_images', - 'glfw', 'glew','OpenNI2', - 'opencv_core', 'opencv_highgui', - 'opencv_calib3d', 'opencv_imgproc', - 'opencv_imgcodecs', 'opencv_videoio', - 'opencv_aruco', 'opencv_features2d', - 'assimp'] - conf.env.FRAMEWORK_OS = ['Cocoa','OpenGL', 'AGL', 'Carbon', - 'Accelerate', 'IOKit','System', 'AppKit', - 'CoreFoundation'] - conf.env.DEFINES_OS = ['OSX=1', 'POSIX=1'] - elif sys.platform == 'win32' or sys.platform == 'cygwin': - conf.env.INCLUDES_OS = ['os/win/include/', 'C:\MinGW\include'] - conf.env.LIBPATH_OS = [os.path.join(os.getcwd(), 'os/win/lib/')] - conf.env.LIB_OS = ['m', 'pthreadGC1', - 'ws2_32', 'xml2', 'GLU', 'GL', - 'OpenNI2', 'fltk', 'fltk_gl', - 'opencv_core', 'opencv_highgui', - 'opencv_calib3d', 'opencv_imgproc'] - else : #linux - conf.env.INCLUDES_OS = ['/usr/include', '/usr/local/include', - '/usr/include/libxml2', - '/usr/include/opencv4', - '/usr/local/include/opencv4', - '/usr/include/opencv4', - '/usr/local/include/openni2', - '/usr/include/openni2'] - conf.env.LIB_OS = ['jpeg', 'X11', 'm', - 'xml2', 'GLU', 'GL', 'pthread', - 'glfw', 'GLEW', - 'OpenNI2', 'fltk', 'fltk_images', - 'opencv_core', 'opencv_highgui', - 'opencv_calib3d', 'opencv_imgproc', - 'opencv_imgcodecs', 'opencv_videoio', - 'opencv_aruco', 'opencv_features2d', - 'assimp', 'portaudio'] - conf.env.LIBPATH_OS = ['/usr/local/lib/'] - conf.env.DEFINES_OS = ['POSIX=1','GL42=1', 'LINUX=1'] - - #release specific - conf.env.CXXFLAGS = ['-O3', '-Wall', '-std=c++2a'] - conf.env.DEFINES = ['DEBUG(x)=//x'] - - #debug specific - conf.setenv('debug', env=conf.env.derive()) - conf.env.CXXFLAGS = ['-g', '-Wall', '-std=c++2a'] - conf.env.DEFINES = ['DEBUG(x)=std::cout<< x <<std::endl;'] + conf.load('compiler_cxx') + conf.load('compiler_c') + + #conf.check_cxx(lib="glfw", + # errmsg="Please install the glfw library", + # mandatory=True) + #conf.check_cxx(lib="glm", + # errmsg="Please install the glm library", + # mandatory=True) + #conf.check_cxx(lib="openni", + # errmsg="Please install the openni2 library", + # mandatory=True) + #conf.check_cxx(lib="fltk", + # errmsg="Please install the fltk library", + # mandatory=True) + #conf.check_cxx(lib="opencv2", + # errmsg="Please install the opencv library", + # mandatory=True) + + + #platform specific + if sys.platform == 'darwin': + conf.env.INCLUDES_OS = ['/opt/local/include', + '/opt/local/include/libxml2', + '/opt/local/include/opencv4', + '/opt/local/include/opencv3', + '/opt/local/include/openni'] + conf.env.LIBPATH_OS = ['/opt/local/lib','/opt/local/lib/opencv3'] + conf.env.LIB_OS = ['m', 'xml2', 'fltk', 'fltk_images', + 'glfw', 'glew','OpenNI2', + 'opencv_core', 'opencv_highgui', + 'opencv_calib3d', 'opencv_imgproc', + 'opencv_imgcodecs', 'opencv_videoio', + 'opencv_aruco', 'opencv_features2d', + 'assimp'] + conf.env.FRAMEWORK_OS = ['Cocoa','OpenGL', 'AGL', 'Carbon', + 'Accelerate', 'IOKit','System', 'AppKit', + 'CoreFoundation'] + conf.env.DEFINES_OS = ['OSX=1', 'POSIX=1'] + elif sys.platform == 'win32' or sys.platform == 'cygwin': + conf.env.INCLUDES_OS = ['os/win/include/', 'C:\MinGW\include'] + conf.env.LIBPATH_OS = [os.path.join(os.getcwd(), 'os/win/lib/')] + conf.env.LIB_OS = ['m', 'pthreadGC1', + 'ws2_32', 'xml2', 'GLU', 'GL', + 'OpenNI2', 'fltk', 'fltk_gl', + 'opencv_core', 'opencv_highgui', + 'opencv_calib3d', 'opencv_imgproc'] + else : #linux + conf.env.INCLUDES_OS = ['/usr/include', '/usr/local/include', + '/usr/include/libxml2', + '/usr/include/opencv4', + '/usr/local/include/opencv4', + '/usr/local/include/openni2', + '/usr/include/openni2', + 'build/'] + conf.env.LIB_OS = ['jpeg', 'X11', 'm', + 'xml2', 'GLU', 'GL', 'pthread', + 'glfw', 'GLEW', + 'OpenNI2', 'fltk', 'fltk_images', + 'opencv_core', 'opencv_highgui', + 'opencv_calib3d', 'opencv_imgproc', + 'opencv_imgcodecs', 'opencv_videoio', + 'opencv_aruco', 'opencv_features2d', + 'assimp', 'rtaudio'] + conf.env.LIBPATH_OS = ['/usr/local/lib/'] + conf.env.DEFINES_OS = ['POSIX=1','GL43=1', 'LINUX=1'] + + #release specific + conf.env.CXXFLAGS = ['-O3', '-w', '-std=c++2a'] + conf.env.DEFINES = ['DEBUG(x)=//x'] + + #debug specific + conf.setenv('debug', env=conf.env.derive()) + conf.env.CXXFLAGS = ['-g', '-Wall', '-std=c++2a'] + conf.env.DEFINES = ['DEBUG(x)=std::cout<< x <<std::endl;'] def build(bld): - macApp = False - if sys.platform == 'win32' or sys.platform == 'msys' : - bld.objects( - source = bld.path.ant_glob('src/osc/oscPack/ip/win32/*.cpp') - +bld.path.ant_glob('src/osc/oscPack/ip/*.cpp') - +bld.path.ant_glob('src/osc/oscPack/osc/*.cpp'), - use = ['OS'], - target = 'oscpack') - else : - bld.objects( - source = bld.path.ant_glob('src/osc/oscPack/ip/posix/*.cpp') - +bld.path.ant_glob('src/osc/oscPack/ip/*.cpp') - +bld.path.ant_glob('src/osc/oscPack/osc/*.cpp'), - use = ['OS'], - target = 'oscpack') - - if sys.platform == 'darwin': - installPath = '/opt/bin/' - macApp = 'True' - - bld.program( - source = bld.path.ant_glob('src/gui/*.cpp') - + bld.path.ant_glob('src/modules/*.cpp') - + bld.path.ant_glob('src/geoms/*.cpp') - + bld.path.ant_glob('src/osc/*.cpp') - + bld.path.ant_glob('src/audio/*.cpp') - + bld.path.ant_glob('src/*.cpp'), - use = ['OS','ringbuf','oscpack'], - target = 'rivill'+bld.variant, - vnum = '0.0.1', - mac_app = macApp, - mac_plist = 'data/Info.plist', - mac_resources = 'data/rivill.icns', - ) - - bld.program( - source="src/utils/create_marker.cpp", - use="OS", - target="rivill_create_marker") - - bld.install_files('${PREFIX}/share/applications', - ['data/rivill.desktop']) - bld.install_files('${PREFIX}/share/mime/packages', - ['data/rivill.xml']) - bld.install_files('${PREFIX}/share/icons', - ['data/rivill.png']) + macApp = False + if sys.platform == 'win32' or sys.platform == 'msys' : + bld.objects( + source = bld.path.ant_glob('src/osc/oscPack/ip/win32/*.cpp') + +bld.path.ant_glob('src/osc/oscPack/ip/*.cpp') + +bld.path.ant_glob('src/osc/oscPack/osc/*.cpp'), + use = ['OS'], + target = 'oscpack') + else : + bld.objects( + source = bld.path.ant_glob('src/osc/oscPack/ip/posix/*.cpp') + +bld.path.ant_glob('src/osc/oscPack/ip/*.cpp') + +bld.path.ant_glob('src/osc/oscPack/osc/*.cpp'), + use = ['OS'], + target = 'oscpack') + + if sys.platform == 'darwin': + installPath = '/opt/bin/' + macApp = 'True' + + #Create shaders.h.in file to integrate shaders in binary + shaders = "" + for s in ["render", "post", "select", "slice", "calib"] : + for v in ["43", "30"] : + shaders += 'std::string '+s+v+'FS = R"('\ + + Utils.readf('src/shaders/'+s+v+'.fs')\ + + ')";\n\n' + shaders += 'std::string '+s+v+'VS = R"('\ + + Utils.readf('src/shaders/'+s+v+'.vs')\ + + ')";\n\n' + + Utils.writef('build/shaders.h.in', shaders) + bld(rule='touch shaders.h.in', + source=bld.path.ant_glob('src/shaders/*'), + target="shaders.h.in") + + bld.program( + source = bld.path.ant_glob('src/gui/*.cpp') + + bld.path.ant_glob('src/modules/*.cpp') + + bld.path.ant_glob('src/geoms/*.cpp') + + bld.path.ant_glob('src/osc/*.cpp') + + bld.path.ant_glob('src/audio/*.cpp') + + bld.path.ant_glob('src/*.cpp'), + use = ['OS','ringbuf','oscpack', 'shaders.h.in'], + target = 'rivill'+bld.variant, + vnum = '0.0.1', + mac_app = macApp, + mac_plist = 'data/Info.plist', + mac_resources = 'data/rivill.icns', + ) + + bld.program( + source="src/utils/create_marker.cpp", + use="OS", + target="rivill_create_marker") + + bld.install_files('${PREFIX}/share/applications', + ['data/rivill.desktop']) + bld.install_files('${PREFIX}/share/mime/packages', + ['data/rivill.xml']) + bld.install_files('${PREFIX}/share/icons', + ['data/rivill.png']) from waflib.Build import BuildContext, CleanContext class debug(BuildContext): - cmd = 'debug' - variant = 'debug' + cmd = 'debug' + variant = 'debug'