From 576710f1efd353e56fabb453678e4d0975125a3b Mon Sep 17 00:00:00 2001 From: Jonas Strandstedt Date: Tue, 8 Jul 2014 13:29:15 -0400 Subject: [PATCH] Added fixed ABuffer implementation --- include/openspace/abuffer/abuffer.h | 3 + .../openspace/abuffer/abufferSingleLinked.h | 2 +- include/openspace/abuffer/abufferdynamic.h | 60 ++++++++ include/openspace/abuffer/abufferfixed.h | 61 ++++++++ .../openspace/rendering/renderablevolumegl.h | 4 + shaders/ABuffer/abufferAddToBuffer.hglsl | 45 +++++- shaders/ABuffer/abufferResolveFragment.glsl | 93 ++++++++---- shaders/ABuffer/abufferSort.hglsl | 23 ++- shaders/ABuffer/abufferStruct.hglsl | 56 ++++--- shaders/exitpoints.frag | 4 +- src/abuffer/abuffer.cpp | 71 +++++++-- src/abuffer/abufferSingleLinked.cpp | 2 +- src/abuffer/abufferdynamic.cpp | 124 ++++++++++++++++ src/abuffer/abufferfixed.cpp | 137 ++++++++++++++++++ src/rendering/renderablevolumegl.cpp | 15 +- src/rendering/renderengine.cpp | 6 +- src/scenegraph/scenegraph.cpp | 110 ++++++-------- src/scenegraph/scenegraphnode.cpp | 5 +- src/util/kameleonwrapper.cpp | 45 ++++-- 19 files changed, 723 insertions(+), 143 deletions(-) create mode 100644 include/openspace/abuffer/abufferdynamic.h create mode 100644 include/openspace/abuffer/abufferfixed.h create mode 100644 src/abuffer/abufferdynamic.cpp create mode 100644 src/abuffer/abufferfixed.cpp diff --git a/include/openspace/abuffer/abuffer.h b/include/openspace/abuffer/abuffer.h index 96e35ec9dd..f7c2f9e032 100644 --- a/include/openspace/abuffer/abuffer.h +++ b/include/openspace/abuffer/abuffer.h @@ -63,6 +63,7 @@ protected: std::string openspaceHeaders(); std::string openspaceSamplerCalls(); std::string openspaceSamplers(); + std::string openspaceTransferFunction(); unsigned int _width, _height, _totalPixels; @@ -82,6 +83,8 @@ private: // Development functionality to update shader for changes in several files std::vector _shaderFiles; + float _volumeStepFactor; + }; // ABuffer diff --git a/include/openspace/abuffer/abufferSingleLinked.h b/include/openspace/abuffer/abufferSingleLinked.h index b800dfb856..c348abee52 100644 --- a/include/openspace/abuffer/abufferSingleLinked.h +++ b/include/openspace/abuffer/abufferSingleLinked.h @@ -54,7 +54,7 @@ private: -}; // ABuffer_I +}; // ABufferSingleLinked } // openspace #endif // __ABUFFERSINGLELINKED_H__ \ No newline at end of file diff --git a/include/openspace/abuffer/abufferdynamic.h b/include/openspace/abuffer/abufferdynamic.h new file mode 100644 index 0000000000..23959f08f1 --- /dev/null +++ b/include/openspace/abuffer/abufferdynamic.h @@ -0,0 +1,60 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __ABUFFERDYNAMIC_H__ +#define __ABUFFERDYNAMIC_H__ + +#include + +namespace openspace { + +class ABufferDynamic: public ABuffer { +public: + + ABufferDynamic(); + virtual ~ABufferDynamic(); + virtual bool initialize(); + + virtual void clear(); + virtual void preRender(); + virtual void postRender(); + + virtual std::string settings(); + +private: + + GLuint *_data; + GLuint _anchorPointerTexture; + GLuint _anchorPointerTextureInitializer; + GLuint _atomicCounterBuffer; + GLuint _fragmentBuffer; + GLuint _fragmentTexture; + + + + +}; // ABufferDynamic +} // openspace + +#endif // __ABUFFERDYNAMIC_H__ \ No newline at end of file diff --git a/include/openspace/abuffer/abufferfixed.h b/include/openspace/abuffer/abufferfixed.h new file mode 100644 index 0000000000..cc211e0b57 --- /dev/null +++ b/include/openspace/abuffer/abufferfixed.h @@ -0,0 +1,61 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __ABUFFERFIXED_H__ +#define __ABUFFERFIXED_H__ + +#include + +namespace openspace { + +class ABufferFixed: public ABuffer { +public: + + ABufferFixed(); + virtual ~ABufferFixed(); + virtual bool initialize(); + + virtual void clear(); + virtual void preRender(); + virtual void postRender(); + + virtual std::string settings(); + +private: + + GLuint *_data; + GLuint _anchorPointerTexture; + GLuint _anchorPointerTextureInitializer; + GLuint _atomicCounterBuffer; + GLuint _atomicCounterTexture; + GLuint _fragmentBuffer; + GLuint _fragmentTexture; + + + + +}; // ABufferFixed +} // openspace + +#endif // __ABUFFERFIXED_H__ \ No newline at end of file diff --git a/include/openspace/rendering/renderablevolumegl.h b/include/openspace/rendering/renderablevolumegl.h index c368e41cfc..56792624bc 100644 --- a/include/openspace/rendering/renderablevolumegl.h +++ b/include/openspace/rendering/renderablevolumegl.h @@ -57,6 +57,10 @@ private: ghoul::Dictionary _hintsDictionary; std::string _filename; + + std::string _transferFunctionName; + std::string _volumeName; + std::string _transferFunctionPath; std::string _samplerFilename; diff --git a/shaders/ABuffer/abufferAddToBuffer.hglsl b/shaders/ABuffer/abufferAddToBuffer.hglsl index 3ee940f0d7..92248796c0 100644 --- a/shaders/ABuffer/abufferAddToBuffer.hglsl +++ b/shaders/ABuffer/abufferAddToBuffer.hglsl @@ -22,11 +22,22 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; layout (binding = 0, offset = 0) uniform atomic_uint atomicCounterBuffer; +#endif -ABufferStruct_t createGeometryFragment(vec4 fragColor, vec4 position = vec4(0), float z = gl_FragCoord.z) { +#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED +layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; +layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; + + #define _MAX_LAYERS_ 16 + #define _SCREEN_WIDTH_ 1280 + #define _SCREEN_HEIGHT_ 720 +#endif + +ABufferStruct_t createGeometryFragment(vec4 fragColor, vec4 position, float z = gl_FragCoord.z) { ABufferStruct_t frag; _col_(frag, fragColor); _z_(frag, z); @@ -37,6 +48,7 @@ ABufferStruct_t createGeometryFragment(vec4 fragColor, vec4 position = vec4(0), void addToBuffer(ABufferStruct_t frag) { +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED uint index = atomicCounterIncrement(atomicCounterBuffer); index *= 2; uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); @@ -47,17 +59,44 @@ void addToBuffer(ABufferStruct_t frag) { imageStore(fragmentTexture, int(index), p1); imageStore(fragmentTexture, int(index+1), p2); +#endif + +#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED + uint index = imageAtomicAdd(anchorPointerTexture, ivec2(gl_FragCoord.xy), 1); + if(index < _MAX_LAYERS_) { + int offset = (int(gl_FragCoord.y) * _SCREEN_WIDTH_ + int(gl_FragCoord.x))*_MAX_LAYERS_ + int(index)*2; + + uvec4 p1 = uvec4(frag.z, frag.id, frag.rg, frag.ba); + uvec4 p2 = uvec4(floatBitsToUint(frag.position.x),floatBitsToUint(frag.position.y),floatBitsToUint(frag.position.z),floatBitsToUint(frag.position.w)); + + imageStore(fragmentTexture, int(offset ), p1); + imageStore(fragmentTexture, int(offset+1), p2); + } else { + imageAtomicAdd(anchorPointerTexture, ivec2(gl_FragCoord.xy), -1); + } + +#endif + } ABufferStruct_t loadFromBuffer(uint id) { +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED uvec4 u1 = imageLoad(fragmentTexture, int(id)); - uvec4 u2 = imageLoad(fragmentTexture, int(id+1)); - + uvec4 u2 = imageLoad(fragmentTexture, int(id+1)); +#endif + +#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED + int offset = (int(gl_FragCoord.y) * _SCREEN_WIDTH_ + int(gl_FragCoord.x))*_MAX_LAYERS_ + int(id)*2; + uvec4 u1 = imageLoad(fragmentTexture, int(offset)); + uvec4 u2 = imageLoad(fragmentTexture, int(offset+1)); +#endif + vec4 position = vec4( uintBitsToFloat(u2.x), uintBitsToFloat(u2.y), uintBitsToFloat(u2.z), uintBitsToFloat(u2.w)); return ABufferStruct_t(u1.x, u1.y, u1.z, u1.w, position); + } \ No newline at end of file diff --git a/shaders/ABuffer/abufferResolveFragment.glsl b/shaders/ABuffer/abufferResolveFragment.glsl index 7e2c233a83..b230a51e23 100644 --- a/shaders/ABuffer/abufferResolveFragment.glsl +++ b/shaders/ABuffer/abufferResolveFragment.glsl @@ -28,15 +28,32 @@ // Settings // ================================================================================ #pragma openspace insert SETTINGS -// #define LOOP_LIMIT 500 #define MAX_FRAGMENTS 16 -#define SHOWFUNC 0 +#define SHOWFUNC +// #define JITTERING #define PSCDEPTH 1 #define ZDEPTH 2 -#define ZTYPE PSCDEPTH -const float stepSize = 0.01; +#define ZTYPE ZDEPTH + +// Math defintions +#define M_E 2.7182818284590452354 +#define M_LOG2E 1.4426950408889634074 /* log_2 e */ +#define M_LOG10E 0.43429448190325182765 /* log_10 e */ +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#define M_PI 3.14159265358979323846 /* pi */ +// #define M_PI 3.141592653589793238462643383279 /* pi */ +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#define M_PI_4 0.78539816339744830962 /* pi/4 */ +#define M_1_PI 0.31830988618379067154 /* 1/pi */ +#define M_2_PI 0.63661977236758134308 /* 2/pi */ +#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ + +const float stepSize = 0.01; const float samplingRate = 1.0; uniform int SCREEN_WIDTH; @@ -52,11 +69,36 @@ out vec4 color; // ================================================================================ #pragma openspace insert HEADERS +vec3 CartesianToSpherical(vec3 _cartesian) { + // Put cartesian in [-1..1] range first + vec3 cartesian = vec3(-1.0,-1.0,-1.0) + _cartesian * 2.0f; + + float r = length(cartesian); + float theta, phi; + + if (r == 0.0) { + theta = phi = 0.0; + } else { + theta = acos(cartesian.z/r) / M_PI; + phi = (M_PI + atan(cartesian.y, cartesian.x)) / (2.0*M_PI); + // phi = (M_PI + atan(cartesian.x, cartesian.y)) / (2.0*M_PI); + } + // r *= 0.57735026919; + r = r / sqrt(3.0f); + + // Sampler ignores w component + // return vec3(r, phi, theta); + return vec3(r, theta, phi); + // return vec3(r, phi*0.7, theta); +} + // ================================================================================ // The ABuffer specific includes and definitions // ================================================================================ #include "abufferStruct.hglsl" ABufferStruct_t fragments[MAX_FRAGMENTS]; + +#if MAX_VOLUMES > 0 vec3 volume_direction[MAX_VOLUMES]; float volume_length[MAX_VOLUMES]; vec3 volume_position[MAX_VOLUMES]; @@ -66,8 +108,7 @@ vec3 volume_position[MAX_VOLUMES]; #elif ZTYPE == PSCDEPTH float volume_zlength[MAX_VOLUMES]; #endif - - +#endif #include "abufferSort.hglsl" // ================================================================================ @@ -83,6 +124,7 @@ vec4 blend(vec4 src, vec4 dst) { void blendStep(inout vec4 dst, in vec4 src, in float stepSize) { src.a = 1.0 - pow(1.0 - src.a, stepSize ); + // src.a = 1.0 -(1.0 - src.a*stepSize); dst.rgb = dst.rgb + (1.0 - dst.a) * src.a * src.rgb; dst.a = dst.a + (1.0 -dst.a) * src.a; } @@ -126,20 +168,18 @@ vec4 calculate_final_color(uint frag_count) { int frag_count_1 = int(frag_count)-1; for(int i = 0; i < frag_count_1 && final_color.a < ALPHA_LIMIT; i++) { - //int maxFrags = int(frag_count)-1; - //for(int i = 0; i < frag_count; i++) { ABufferStruct_t startFrag = fragments[i]; ABufferStruct_t endFrag = fragments[i+1]; - //vec4 frag_color = _col_(startFrag); - //vec4 position = _pos_(startFrag); int type = int(_type_(startFrag)); - currentVolumeBitmask = currentVolumeBitmask ^ (type); if(type == 0) //blendStep(final_color, _col_(startFrag), stepSize); final_color = blend(final_color, _col_(startFrag)); - if(bool(currentVolumeBitmask)) { + +#if MAX_VOLUMES > 0 + currentVolumeBitmask = currentVolumeBitmask ^ type; + if(currentVolumeBitmask != 0) { int volID = type -1; float p = 0.0f; #if ZTYPE == ZDEPTH @@ -152,7 +192,6 @@ vec4 calculate_final_color(uint frag_count) { // const float z2 = _z_(endFrag); const float l = ((z1 - S1) / L - (z2 - S1) / L) * volume_length[volID]; int max_iterations = int(l / volumeStepSize[volID]); - int iterations = 0; vec3 position; #elif ZTYPE == PSCDEPTH const float L = volume_zlength[volID]; @@ -163,7 +202,6 @@ vec4 calculate_final_color(uint frag_count) { // const float z2 = _z_(endFrag); const float l = (dist / L) * volume_length[volID]; int max_iterations = int(l / volumeStepSize[volID]); - int iterations = 0; vec3 position; #endif @@ -199,6 +237,7 @@ vec4 calculate_final_color(uint frag_count) { } } +#endif @@ -223,26 +262,28 @@ vec4 calculate_final_color(uint frag_count) { // ================================================================================ // Transferfunction visualizer // ================================================================================ -#if (SHOWFUNC >= 0) && (SHOWFUNC < MAX_TF) - float showfunc_size = 20.0; - if(gl_FragCoord.y > float(SCREEN_HEIGHT) - showfunc_size) { - float normalizedIntensity = gl_FragCoord.x / float(SCREEN_WIDTH) ; - vec4 tfc = texture(transferFunction1, normalizedIntensity); - final_color = tfc; - } else if(ceil(gl_FragCoord.y) == float(SCREEN_HEIGHT) - showfunc_size) { - const float intensity = 0.4; - final_color = vec4(intensity,intensity,intensity,1.0); - } +#ifdef SHOWFUNC +#pragma openspace insert TRANSFERFUNC #endif // if(frag_count == 1) { - // final_color = vec4(0.0,0.0,1.0,1.0); + // final_color = vec4(1.0,0.0,0.0,1.0); // } else if(frag_count == 2) { - // final_color = vec4(volume_direction[0],1.0); + // final_color = vec4(0.0,1.0,0.0,1.0); + // // final_color = vec4(volume_direction[0],1.0); + // } else if(frag_count == 3) { + // final_color = vec4(0.0,0.0,1.0,1.0); + // // final_color = vec4(volume_direction[0],1.0); + // } else if(frag_count == 4) { + // final_color = vec4(1.0,1.0,0.0,1.0); + // // final_color = vec4(volume_direction[0],1.0); // } else { // final_color = vec4(1.0,1.0,1.0,1.0); // } + final_color.rgb = final_color.rgb * final_color.a; + final_color.a = 1.0; + return final_color; } diff --git a/shaders/ABuffer/abufferSort.hglsl b/shaders/ABuffer/abufferSort.hglsl index 61381bc7d1..5d05460117 100644 --- a/shaders/ABuffer/abufferSort.hglsl +++ b/shaders/ABuffer/abufferSort.hglsl @@ -27,6 +27,8 @@ uniform float volumeStepFactor = 1.0f; int build_local_fragments_list() { + +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED uint current; int frag_count = 0; @@ -42,6 +44,19 @@ int build_local_fragments_list() { } return frag_count; +#endif + +#if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED + uint frag_count = imageLoad(anchorPointerTexture, ivec2(gl_FragCoord.xy)).x; + + int i; + for(i = 0; i < frag_count && i < MAX_FRAGMENTS; ++i) { + fragments[i] = loadFromBuffer(i); + } + + return int(frag_count); +#endif + } float pscLength(vec4 v1, vec4 v2) { @@ -75,12 +90,13 @@ void sort_fragments_list(uint frag_count) { fragments[j] = tmp; } +#if MAX_VOLUMES > 0 int ii, jj; for(ii = 0; ii < MAX_VOLUMES; ++ii) { bool start = true; vec3 startColor; vec4 startPosition; - for(jj = ii; jj < frag_count; ++jj) { + for(jj = 0; jj < frag_count; ++jj) { int type = int(_type_(fragments[jj])) - 1; if(type== ii) { if(start) { @@ -96,12 +112,13 @@ void sort_fragments_list(uint frag_count) { volume_length[ii] = length(dir); volume_direction[ii] = normalize(dir); volumeStepSize[ii] = 1.0/(volumeStepFactor * length(volume_direction[ii]*volume_dim[ii])); + volumeStepSizeOriginal[ii] = volumeStepSize[ii]; #if ZTYPE == ZDEPTH volume_zlength[ii].y = _z_(fragments[jj]); #elif ZTYPE == PSCDEPTH volume_zlength[ii] = pscLength(_pos_(fragments[jj]), startPosition); #endif - +#ifdef JITTERING if(volumeStepSize[ii] < volume_length[ii]) { // jittering float x = gl_FragCoord.x; @@ -110,12 +127,14 @@ void sort_fragments_list(uint frag_count) { vec3 frontPosNew = startColor + (jitterValue*volumeStepSize[ii])*volume_direction[ii]; volume_position[ii] = frontPosNew; } +#endif break; } } } } +#endif //volume_direction[0] = vec3(1.0,0.0,0.0); //volume_direction[0] = _col_(fragments[0]).rgb; } diff --git a/shaders/ABuffer/abufferStruct.hglsl b/shaders/ABuffer/abufferStruct.hglsl index a63499ef6d..0153aecad6 100644 --- a/shaders/ABuffer/abufferStruct.hglsl +++ b/shaders/ABuffer/abufferStruct.hglsl @@ -25,10 +25,17 @@ #ifndef ABUFFERSTRUCT_H_HGLSL #define ABUFFERSTRUCT_H_HGLSL +// The different kinds of implementation +#define ABUFFER_SINGLE_LINKED 1 +#define ABUFFER_FIXED 2 +#define ABUFFER_DYNAMIC 3 -//======================================================= +#define ABUFFER_IMPLEMENTATION ABUFFER_SINGLE_LINKED + + +//======================================================================================== // ABufferStruct_t declaration -//======================================================= +//======================================================================================== // struct ABufferStruct_t { // uint z; // the depth value // uint id; // bits 0-28 next, bits 29-32 type @@ -46,9 +53,9 @@ struct ABufferStruct_t { }; -//======================================================= +//======================================================================================== // Bitwise operations -//======================================================= +//======================================================================================== const uint mask_1 = 1; const uint mask_8 = 255; const uint mask_16 = 65535; @@ -92,9 +99,9 @@ int bitextract_i(in int pack, uint mask, uint shift) { return int( (uint(pack) >> shift) & (mask >> shift) ); } -//======================================================= +//======================================================================================== // Access functions -//======================================================= +//======================================================================================== float _z_(ABufferStruct_t frag) { return uintBitsToFloat(frag.z); } @@ -102,15 +109,6 @@ void _z_(inout ABufferStruct_t frag, float z) { frag.z = floatBitsToUint(z); } -uint _next_(ABufferStruct_t frag) { - return bitextract_u(frag.id, mask_id_next, shift_id_next); - //return frag.id; -} -void _next_(inout ABufferStruct_t frag, uint id) { - bitinsert_u(frag.id, id, mask_id_next, shift_id_next); - //frag.id = id; -} - vec4 _pos_(ABufferStruct_t frag) { // return vec4(0.0,0.0,0.0,0.0); return frag.position; @@ -132,12 +130,34 @@ void _col_(inout ABufferStruct_t frag, vec4 color) { } uint _type_(ABufferStruct_t frag) { - return bitextract_u(frag.id, mask_id_type, shift_id_type); - //return frag.type; +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED + return bitextract_u(frag.id, mask_id_type, shift_id_type); +#else + return frag.id; +#endif } void _type_(inout ABufferStruct_t frag, uint type) { +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED bitinsert_u(frag.id, type, mask_id_type, shift_id_type); - //frag.type = type; +#else + frag.id = type; +#endif } +//======================================================================================== +// Implementation specific functions +//======================================================================================== + +// _next_ is only needed for the single linked implementation +#if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED +uint _next_(ABufferStruct_t frag) { + return bitextract_u(frag.id, mask_id_next, shift_id_next); + //return frag.id; +} +void _next_(inout ABufferStruct_t frag, uint id) { + bitinsert_u(frag.id, id, mask_id_next, shift_id_next); + //frag.id = id; +} +#endif + #endif \ No newline at end of file diff --git a/shaders/exitpoints.frag b/shaders/exitpoints.frag index 89fe78224b..71dac97245 100644 --- a/shaders/exitpoints.frag +++ b/shaders/exitpoints.frag @@ -35,10 +35,12 @@ in float s; #include "PowerScaling/powerScaling_fs.hglsl" void main() { - vec4 fragColor = vec4(vPosition+0.5, 0.3); + vec4 fragColor = vec4(vPosition+0.5, 1.0); vec4 position = vec4(worldPosition,s); float depth = pscDepth(position); + gl_FragDepth = depth; + ABufferStruct_t frag; _col_(frag, fragColor); _z_(frag, depth); diff --git a/src/abuffer/abuffer.cpp b/src/abuffer/abuffer.cpp index f8f8063726..744e27a402 100644 --- a/src/abuffer/abuffer.cpp +++ b/src/abuffer/abuffer.cpp @@ -91,9 +91,7 @@ bool ABuffer::initializeABuffer() { addFunc("${SHADERS}/ABuffer/abufferAddToBuffer.hglsl"); addFunc("${SHADERS}/ABuffer/abufferStruct.hglsl"); addFunc("${SHADERS}/PowerScaling/powerScaling_fs.hglsl"); - addFunc("${SHADERS}/PowerScaling/powerScaling_vs.hglsl"); - - + addFunc("${SHADERS}/PowerScaling/powerScaling_vs.hglsl"); _resolveShader = nullptr; generateShaderSource(); @@ -148,10 +146,10 @@ void ABuffer::resolve() { // Decrease stepsize in volumes if right click is pressed // TODO: Let the interactionhandler handle this int val = sgct::Engine::getMouseButton(0, SGCT_MOUSE_BUTTON_RIGHT); - if(val) { - _resolveShader->setUniform("volumeStepFactor", 0.2f); - } else { - _resolveShader->setUniform("volumeStepFactor", 1.0f); + float volumeStepFactor = (val) ? 0.2: 1.0; + if(volumeStepFactor != _volumeStepFactor) { + _volumeStepFactor = volumeStepFactor; + _resolveShader->setUniform("volumeStepFactor", _volumeStepFactor); } glBindVertexArray(_screenQuad); @@ -254,6 +252,8 @@ void ABuffer::generateShaderSource() { line = padGeneratedString(openspaceSamplers()); } else if(line == "#pragma openspace insert SETTINGS") { line = padGeneratedString(settings()); + } else if(line == "#pragma openspace insert TRANSFERFUNC") { + line = padGeneratedString(openspaceTransferFunction()); } source += line + "\n"; } @@ -270,6 +270,8 @@ std::string ABuffer::openspaceHeaders() { std::string headers; headers += "#define MAX_VOLUMES " + std::to_string(_samplers.size()) + "\n"; headers += "#define MAX_TF " + std::to_string(_transferFunctions.size()) + "\n"; + + for (int i = 0; i < _volumes.size(); ++i) { headers += "uniform sampler3D " + _volumes.at(i).first + ";\n"; } @@ -284,6 +286,9 @@ std::string ABuffer::openspaceHeaders() { } } + if(_volumes.size() < 1) + return headers; + size_t maxLoop = 0; headers += "const vec3 volume_dim[] = {\n"; for (int i = 0; i < _volumes.size(); ++i) { @@ -294,6 +299,7 @@ std::string ABuffer::openspaceHeaders() { + std::to_string(size[2]) + ".0),\n"; } headers += "};\n"; + headers += "#define LOOP_LIMIT " + std::to_string(maxLoop) + "\n"; headers += "float volumeStepSize[] = {\n"; @@ -303,6 +309,13 @@ std::string ABuffer::openspaceHeaders() { } headers += "};\n"; + headers += "float volumeStepSizeOriginal[] = {\n"; + for (int i = 0; i < _volumes.size(); ++i) { + glm::size3_t size = _volumes.at(i).second->dimensions(); + headers += " stepSize,\n"; + } + headers += "};\n"; + return headers; } @@ -310,13 +323,23 @@ std::string ABuffer::openspaceSamplerCalls() { std::string samplercalls; for (int i = 0; i < _samplers.size(); ++i) { - auto found1 = _samplers.at(i).find_first_not_of("void "); + auto found1 = _samplers.at(i).find_first_not_of("vec4 "); auto found2 = _samplers.at(i).find_first_of("(",found1); if(found1 != std::string::npos && found2 != std::string::npos) { std::string functionName = _samplers.at(i).substr(found1, found2 - found1); - samplercalls += "if((currentVolumeBitmask & (1 << " + std::to_string(i) + ")) == 1) {\n"; - samplercalls += functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; - samplercalls += "volume_position[" + std::to_string(i) + "] += volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];;\n"; + samplercalls += "if((currentVolumeBitmask & (1 << " + std::to_string(i) + ")) == "+std::to_string(i+1)+") {\n"; + samplercalls += " vec4 c = " + functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; + // samplercalls += " if(c.a < 0.1) { \n"; + // samplercalls += " if( volumeStepSize[" + std::to_string(i) + "] < 16.0*volumeStepSizeOriginal[" + std::to_string(i) + "]) \n"; + // samplercalls += " volumeStepSize[" + std::to_string(i) + "] *= 2.0; \n"; + // samplercalls += " } else {\n"; + // samplercalls += " //volume_position[" + std::to_string(i) + "] -= volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];\n"; + // samplercalls += " volumeStepSize[" + std::to_string(i) + "] = volumeStepSizeOriginal[" + std::to_string(i) + "]; \n"; + // samplercalls += " //c = " + functionName + "(final_color,volume_position[" + std::to_string(i) + "]);\n"; + // samplercalls += " } \n"; + samplercalls += " blendStep(final_color, c, volumeStepSize[" + std::to_string(i) + "]);\n"; + // samplercalls += " blendStep(final_color, c, stepSize);\n"; + samplercalls += " volume_position[" + std::to_string(i) + "] += volume_direction[" + std::to_string(i) + "]*volumeStepSize[" + std::to_string(i) + "];\n"; samplercalls += "}\n"; } @@ -333,5 +356,31 @@ std::string ABuffer::openspaceSamplers() { return samplers; } +std::string ABuffer::openspaceTransferFunction() { + std::string tf; + tf += "float showfunc_size = 20.0;\n"; + tf += "float SCREEN_HEIGHTf = float(SCREEN_HEIGHT);\n"; + tf += "float SCREEN_WIDTHf = float(SCREEN_WIDTH);\n"; + for(int i = 0; i < _transferFunctions.size(); ++i) { + tf += "if( gl_FragCoord.y > SCREEN_HEIGHTf-showfunc_size*"+std::to_string(i+1)+ + " && gl_FragCoord.y < SCREEN_HEIGHTf-showfunc_size*"+std::to_string(i)+") {\n"; + tf += " float normalizedIntensity = gl_FragCoord.x / SCREEN_WIDTHf ;\n"; + tf += " vec4 tfc = texture("+ _transferFunctions.at(i).first +", normalizedIntensity);\n"; + tf += " final_color = tfc;\n"; + tf += " float cmpf = SCREEN_HEIGHTf-showfunc_size*"+std::to_string(i+1)+" + tfc.a*showfunc_size;\n"; + tf += " if(gl_FragCoord.y > cmpf) {\n"; + tf += " final_color = vec4(0,0,0,0);\n"; + tf += " } else {\n"; + tf += " final_color.a = 1.0;\n"; + tf += " }\n"; + tf += "} else if(ceil(gl_FragCoord.y) == SCREEN_HEIGHTf - showfunc_size*"+std::to_string(i+1)+") {\n"; + tf += " const float intensity = 0.4;\n"; + tf += " final_color = vec4(intensity,intensity,intensity,1.0);\n"; + tf += "}\n"; + } + + return tf; +} + } // openspace \ No newline at end of file diff --git a/src/abuffer/abufferSingleLinked.cpp b/src/abuffer/abufferSingleLinked.cpp index 166ded0302..f1a09b3c2d 100644 --- a/src/abuffer/abufferSingleLinked.cpp +++ b/src/abuffer/abufferSingleLinked.cpp @@ -117,7 +117,7 @@ void ABufferSingleLinked::postRender() { } std::string ABufferSingleLinked::settings() { - return R"(#define SINGLE_LINKED)"; + return R"()"; } diff --git a/src/abuffer/abufferdynamic.cpp b/src/abuffer/abufferdynamic.cpp new file mode 100644 index 0000000000..8943905eda --- /dev/null +++ b/src/abuffer/abufferdynamic.cpp @@ -0,0 +1,124 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include + +#include +#include + +#include +#include +#include + +#define MAX_LAYERS 10 + +namespace { + std::string _loggerCat = "ABufferDynamic"; +} + +namespace openspace { + +ABufferDynamic::ABufferDynamic(): _data(0), _anchorPointerTexture(0), + _anchorPointerTextureInitializer(0), _atomicCounterBuffer(0), _fragmentBuffer(0), + _fragmentTexture(0) +{} + +ABufferDynamic::~ABufferDynamic() { + if(_data != 0) + delete _data; + + glDeleteTextures(1,&_anchorPointerTexture); + glDeleteTextures(1,&_fragmentTexture); + glDeleteBuffers(1,&_anchorPointerTextureInitializer); + glDeleteBuffers(1,&_atomicCounterBuffer); + glDeleteBuffers(1,&_anchorPointerTextureInitializer); +} + +bool ABufferDynamic::initialize() { + // ============================ + // BUFFERS + // ============================ + glGenTextures(1, &_anchorPointerTexture); + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + + glGenBuffers(1, &_anchorPointerTextureInitializer); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + glBufferData(GL_PIXEL_UNPACK_BUFFER, _totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW); + + _data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); + memset(_data, 0x00, _totalPixels * sizeof(GLuint)); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + glGenBuffers(1, &_atomicCounterBuffer); + glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, _atomicCounterBuffer); + glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY); + + glGenBuffers(1, &_fragmentBuffer); + glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer); + glBufferData(GL_TEXTURE_BUFFER, MAX_LAYERS*_totalPixels*sizeof(GLfloat)*4, NULL, GL_DYNAMIC_COPY); + + glGenTextures(1, &_fragmentTexture); + glBindTexture(GL_TEXTURE_BUFFER, _fragmentTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, _fragmentBuffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); + + return initializeABuffer(); +} + +void ABufferDynamic::clear() { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + static const GLuint zero = 1; + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); + glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(zero), &zero); + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0); +} + +void ABufferDynamic::preRender() { + + // Bind head-pointer image for read-write + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer); + glBindImageTexture(0, _anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); +} + +void ABufferDynamic::postRender() { + +} + +std::string ABufferDynamic::settings() { + return R"(#define ABUFFER_SINGLE_LINKED)"; +} + + +} // openspace \ No newline at end of file diff --git a/src/abuffer/abufferfixed.cpp b/src/abuffer/abufferfixed.cpp new file mode 100644 index 0000000000..36c5a7aeae --- /dev/null +++ b/src/abuffer/abufferfixed.cpp @@ -0,0 +1,137 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include + +#include +#include + +#include +#include +#include + +#define MAX_LAYERS 32 + +namespace { + std::string _loggerCat = "ABufferFixed"; +} + +namespace openspace { + +ABufferFixed::ABufferFixed(): _data(0), _anchorPointerTexture(0), + _anchorPointerTextureInitializer(0), _atomicCounterBuffer(0), _fragmentBuffer(0), + _fragmentTexture(0) +{} + +ABufferFixed::~ABufferFixed() { + if(_data != 0) + delete _data; + + glDeleteTextures(1,&_anchorPointerTexture); + glDeleteTextures(1,&_fragmentTexture); + // glDeleteTextures(1,&_atomicCounterTexture); + glDeleteBuffers(1,&_anchorPointerTextureInitializer); + // glDeleteBuffers(1,&_atomicCounterBuffer); + glDeleteBuffers(1,&_anchorPointerTextureInitializer); +} + +bool ABufferFixed::initialize() { + // ============================ + // BUFFERS + // ============================ + glGenTextures(1, &_anchorPointerTexture); + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + + glGenBuffers(1, &_anchorPointerTextureInitializer); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + glBufferData(GL_PIXEL_UNPACK_BUFFER, _totalPixels * sizeof(GLuint), NULL, GL_STATIC_DRAW); + + _data = (GLuint*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); + memset(_data, 0x00, _totalPixels * sizeof(GLuint)); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + + // glGenBuffers(1, &_atomicCounterBuffer); + // glBindBuffer(GL_TEXTURE_BUFFER, _atomicCounterBuffer); + // glBufferData(GL_TEXTURE_BUFFER, _totalPixels*sizeof(GLuint), NULL, GL_DYNAMIC_COPY); + + // glGenTextures(1, &_atomicCounterTexture); + // glBindTexture(GL_TEXTURE_2D, _atomicCounterTexture); + // glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, _atomicCounterBuffer); + // glBindTexture(GL_TEXTURE_BUFFER, 0); + + + glGenBuffers(1, &_fragmentBuffer); + glBindBuffer(GL_TEXTURE_BUFFER, _fragmentBuffer); + glBufferData(GL_TEXTURE_BUFFER, MAX_LAYERS*_totalPixels*sizeof(GLfloat)*4, NULL, GL_DYNAMIC_COPY); + + glGenTextures(1, &_fragmentTexture); + glBindTexture(GL_TEXTURE_BUFFER, _fragmentTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, _fragmentBuffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); + + return initializeABuffer(); +} + +void ABufferFixed::clear() { + + // Bind texture initializer + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); + + // clear _anchorPointerTexture + glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + + // // clear _atomicCounterTexture + // glBindTexture(GL_TEXTURE_2D, _atomicCounterTexture); + // glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, _width, _height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + + // reset GL_PIXEL_UNPACK_BUFFER + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + +} + +void ABufferFixed::preRender() { + + // Bind head-pointer image for read-write + glBindImageTexture(0, _anchorPointerTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); + glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); + // glBindImageTexture(2, _atomicCounterTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); +} + +void ABufferFixed::postRender() { + +} + +std::string ABufferFixed::settings() { + return R"()"; +} + + +} // openspace \ No newline at end of file diff --git a/src/rendering/renderablevolumegl.cpp b/src/rendering/renderablevolumegl.cpp index bdcdc9ae79..ddbf548138 100644 --- a/src/rendering/renderablevolumegl.cpp +++ b/src/rendering/renderablevolumegl.cpp @@ -97,6 +97,13 @@ RenderableVolumeGL::RenderableVolumeGL(const ghoul::Dictionary& dictionary): _boxScaling[2] = tempValue; } + _volumeName = ""; + if (dictionary.hasKey("VolumeName")) + dictionary.getValue("VolumeName", _volumeName); + _transferFunctionName = ""; + if (dictionary.hasKey("TransferFunctionName")) + dictionary.getValue("TransferFunctionName", _transferFunctionName); + setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling))); } @@ -121,8 +128,8 @@ bool RenderableVolumeGL::initialize() { _transferFunction->uploadTexture(); // TODO: fix volume an transferfunction names - OsEng.renderEngine().abuffer()->addVolume("volume1", _volume); - OsEng.renderEngine().abuffer()->addTransferFunction("transferFunction1", _transferFunction); + OsEng.renderEngine().abuffer()->addVolume(_volumeName, _volume); + OsEng.renderEngine().abuffer()->addTransferFunction(_transferFunctionName, _transferFunction); _id = OsEng.renderEngine().abuffer()->addSamplerfile(_samplerFilename); auto textureCallback = [this](const ghoul::filesystem::File& file) { @@ -235,8 +242,8 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) { glm::mat4 camrot = camera->viewRotationMatrix(); PowerScaledScalar scaling = camera->scaling(); - psc addon(-1.1,0.0,0.0,0.0); - currentPosition += addon; + // psc addon(-1.1,0.0,0.0,0.0); + // currentPosition += addon; // TODO: Use _id to identify this volume _boxProgram->activate(); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 70fd59661d..4e1123d11c 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -35,6 +35,8 @@ #include #include +#include +#include namespace { const std::string _loggerCat = "RenderEngine"; @@ -66,6 +68,8 @@ bool RenderEngine::initialize() OsEng.interactionHandler().setCamera(_mainCamera); _abuffer = new ABufferSingleLinked(); + // _abuffer = new ABufferFixed(); + // _abuffer = new ABufferDynamic(); return true; } @@ -82,7 +86,7 @@ bool RenderEngine::initializeGL() // set the close clip plane and the far clip plane to extreme values while in // development // sgct::Engine::instance()->setNearAndFarClippingPlanes(0.1f,100.0f); - sgct::Engine::instance()->setNearAndFarClippingPlanes(0.00001f, 100.0f); + sgct::Engine::instance()->setNearAndFarClippingPlanes(0.1f, 200.0f); // calculating the maximum field of view for the camera, used to // determine visibility of objects in the scene graph diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 75434d2a54..be80e87ac9 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -82,77 +82,63 @@ bool SceneGraph::initialize() using ghoul::opengl::ShaderObject; using ghoul::opengl::ProgramObject; - // pscstandard + auto programCreator = [] ( const std::string& name, + const std::string& vpath, + const std::string& fpath) { - std::string programObjectName = "pscstandard"; - ProgramObject* po = new ProgramObject(programObjectName); - ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/pscstandard_vs.glsl"), - programObjectName + "Vertex"); - ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/pscstandard_fs.glsl"), - programObjectName + "Fragment"); + const std::string vsPath = absPath(vpath); + const std::string fsPath = absPath(fpath); + const ShaderObject::ShaderType vsType = ShaderObject::ShaderType::ShaderTypeVertex; + const ShaderObject::ShaderType fsType = ShaderObject::ShaderType::ShaderTypeFragment; + + ProgramObject* po = new ProgramObject(name); + ShaderObject* vs = new ShaderObject(vsType, vsPath, name + "Vertex"); + ShaderObject* fs = new ShaderObject(fsType, fsPath, name + "Fragment"); po->attachObject(vs); po->attachObject(fs); - if ( ! po->compileShaderObjects()) return false; - if ( ! po->linkProgramObject()) return false; - OsEng.ref().configurationManager().setValue("pscShader", po); - } + if ( po->compileShaderObjects() && po->linkProgramObject()) + return po; + + // unsuccessful compilation, cleanup and return nullptr + delete po; + po = nullptr; + return po; + }; + + ProgramObject* tmpProgram; + + // pscstandard + tmpProgram = programCreator("pscstandard", + "${SHADERS}/pscstandard_vs.glsl", + "${SHADERS}/pscstandard_fs.glsl"); + if( ! tmpProgram) return false; + OsEng.ref().configurationManager().setValue("pscShader", tmpProgram); // RaycastProgram - { - std::string programObjectName = "RaycastProgram"; - ProgramObject* po = new ProgramObject(programObjectName); - ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/exitpoints.vert"), - programObjectName + "Vertex"); - ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/exitpoints.frag"), - programObjectName + "Fragment"); - po->attachObject(vs); - po->attachObject(fs); - if ( ! po->compileShaderObjects()) return false; - if ( ! po->linkProgramObject()) return false; - OsEng.ref().configurationManager().setValue("RaycastProgram", po); - } + tmpProgram = programCreator("RaycastProgram", + "${SHADERS}/exitpoints.vert", + "${SHADERS}/exitpoints.frag"); + if( ! tmpProgram) return false; + OsEng.ref().configurationManager().setValue("RaycastProgram", tmpProgram); + // TwoPassProgram - { - std::string programObjectName = "TwoPassProgram"; - ProgramObject* po = new ProgramObject(programObjectName); - ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/twopassraycaster.vert"), - programObjectName + "Vertex"); - ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/twopassraycaster.frag"), - programObjectName + "Fragment"); - po->attachObject(vs); - po->attachObject(fs); - if ( ! po->compileShaderObjects()) return false; - if ( ! po->linkProgramObject()) return false; - po->setUniform("texBack", 0); - po->setUniform("texFront", 1); - po->setUniform("texVolume", 2); - OsEng.ref().configurationManager().setValue("TwoPassProgram", po); - } + tmpProgram = programCreator("TwoPassProgram", + "${SHADERS}/twopassraycaster.vert", + "${SHADERS}/twopassraycaster.frag"); + if( ! tmpProgram) return false; + tmpProgram->setUniform("texBack", 0); + tmpProgram->setUniform("texFront", 1); + tmpProgram->setUniform("texVolume", 2); + OsEng.ref().configurationManager().setValue("TwoPassProgram", tmpProgram); // Quad - { - std::string programObjectName = "Quad"; - ProgramObject* po = new ProgramObject(programObjectName); - ShaderObject* vs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeVertex, - absPath("${SHADERS}/quadVert.glsl"), - programObjectName + "Vertex"); - ShaderObject* fs = new ShaderObject( ShaderObject::ShaderType::ShaderTypeFragment, - absPath("${SHADERS}/quadFrag.glsl"), - programObjectName + "Fragment"); - po->attachObject(vs); - po->attachObject(fs); - if ( ! po->compileShaderObjects()) return false; - if ( ! po->linkProgramObject()) return false; - po->setUniform("quadTex", 0); - OsEng.ref().configurationManager().setValue("Quad", po); - } + tmpProgram = programCreator("Quad", + "${SHADERS}/quadVert.glsl", + "${SHADERS}/quadFrag.glsl"); + if( ! tmpProgram) return false; + tmpProgram->setUniform("quadTex", 0); + OsEng.ref().configurationManager().setValue("Quad", tmpProgram); // Initialize all nodes for (auto node : _nodes) { diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index b0e5f25616..146f922a87 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -193,8 +193,9 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) // this node has an renderable if (_renderable) { // check if the renderable boundingsphere is visible - _renderableVisible = sphereInsideFrustum( - thisPosition, _renderable->getBoundingSphere(), camera); + // _renderableVisible = sphereInsideFrustum( + // thisPosition, _renderable->getBoundingSphere(), camera); + _renderableVisible = true; } // evaluate all the children, tail-recursive function(?) diff --git a/src/util/kameleonwrapper.cpp b/src/util/kameleonwrapper.cpp index 1fa2b423f6..f9157f681f 100644 --- a/src/util/kameleonwrapper.cpp +++ b/src/util/kameleonwrapper.cpp @@ -126,11 +126,9 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz // get interpolated data value for (xPos, yPos, zPos) // swap yPos and zPos because model has Z as up double value = _interpolator->interpolate(var, xPos, zPos, yPos); - - // scale to [0,1] - //doubleData[index] = (value-varMin)/(varMax-varMin); doubleData[index] = value; histogram[mapToHistogram(value)]++; + } else if (_type == Model::ENLIL) { // Put r in the [0..sqrt(3)] range @@ -150,7 +148,7 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz // avoid rounding errors when comparing to phiMax. double phiPh = _zMin + phiNorm/(2.0*M_PI)*(_zMax-_zMin-0.000001); - double varValue = 0.f; + double value = 0.0; // See if sample point is inside domain if (rPh < _xMin || rPh > _xMax || thetaPh < _yMin || thetaPh > _yMax || phiPh < _zMin || phiPh > _zMax) { @@ -168,10 +166,12 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz // Convert from [0, 2pi] rad to [0, 360] degrees phiPh = phiPh*180.f/M_PI; // Sample - varValue = _interpolator->interpolate(var, rPh, thetaPh, phiPh); + value = _interpolator->interpolate(var, rPh, thetaPh, phiPh); + // value = _interpolator->interpolate(var, rPh, phiPh, thetaPh); } - doubleData[index] = (varValue-varMin)/(varMax-varMin); + doubleData[index] = value; + histogram[mapToHistogram(value)]++; } } } @@ -179,17 +179,34 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz std::cout << std::endl; LINFO("Done!"); + // for (int i = 0; i < outDimensions.x * outDimensions.y * outDimensions.z; ++i) + // { + // std::cout << std::setfill(' ') << std::setw(15) << doubleData[i] << ", "; + // if(i % 10 == 0) + // std::cout << std::endl; + // } + // + // for(int i = 0; i < bins-1; ++i) { + // // sum += histogram[i]; + // // if(sum + histogram[i+1] > sumuntil) { + // // stop = i; + // // LDEBUG("===================="); + // // break; + // // } + // LDEBUG("histogram[" << i << "]: " << histogram[i]); + // } + int sum = 0; int stop; const int sumuntil = size * truncLim; - for(int i = 0; i < bins-1; ++i) { + for(int i = 0; i < bins; ++i) { sum += histogram[i]; - if(sum + histogram[i+1] > sumuntil) { + if(sum > sumuntil) { stop = i; - LDEBUG("===================="); + // LDEBUG("===================="); break; } - LDEBUG(histogram[i]); + // LDEBUG("histogram[" << i << "]: " << histogram[i]); } double dist = varMax - varMin; @@ -201,8 +218,14 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz data[i] = static_cast(glm::clamp(normalizedVal, 0.0, 1.0)); } - delete[] doubleData; + // for(int i = 0; i < size; ++i) { + // double normalizedVal = (doubleData[i]-varMin)/(varMax-varMin); + // // data[i] = static_cast(glm::clamp(normalizedVal, 0.0, 1.0)); + // data[i] = static_cast(normalizedVal); + // } + + delete[] doubleData; return data; }