mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-26 14:58:51 -06:00
Added fixed ABuffer implementation
This commit is contained in:
@@ -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<ghoul::filesystem::File*> _shaderFiles;
|
||||
|
||||
float _volumeStepFactor;
|
||||
|
||||
|
||||
|
||||
}; // ABuffer
|
||||
|
||||
@@ -54,7 +54,7 @@ private:
|
||||
|
||||
|
||||
|
||||
}; // ABuffer_I
|
||||
}; // ABufferSingleLinked
|
||||
} // openspace
|
||||
|
||||
#endif // __ABUFFERSINGLELINKED_H__
|
||||
60
include/openspace/abuffer/abufferdynamic.h
Normal file
60
include/openspace/abuffer/abufferdynamic.h
Normal file
@@ -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 <openspace/abuffer/abuffer.h>
|
||||
|
||||
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__
|
||||
61
include/openspace/abuffer/abufferfixed.h
Normal file
61
include/openspace/abuffer/abufferfixed.h
Normal file
@@ -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 <openspace/abuffer/abuffer.h>
|
||||
|
||||
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__
|
||||
@@ -57,6 +57,10 @@ private:
|
||||
ghoul::Dictionary _hintsDictionary;
|
||||
|
||||
std::string _filename;
|
||||
|
||||
std::string _transferFunctionName;
|
||||
std::string _volumeName;
|
||||
|
||||
std::string _transferFunctionPath;
|
||||
std::string _samplerFilename;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -117,7 +117,7 @@ void ABufferSingleLinked::postRender() {
|
||||
}
|
||||
|
||||
std::string ABufferSingleLinked::settings() {
|
||||
return R"(#define SINGLE_LINKED)";
|
||||
return R"()";
|
||||
}
|
||||
|
||||
|
||||
|
||||
124
src/abuffer/abufferdynamic.cpp
Normal file
124
src/abuffer/abufferdynamic.cpp
Normal file
@@ -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 <openspace/abuffer/abufferdynamic.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#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
|
||||
137
src/abuffer/abufferfixed.cpp
Normal file
137
src/abuffer/abufferfixed.cpp
Normal file
@@ -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 <openspace/abuffer/abufferfixed.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#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
|
||||
@@ -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();
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <array>
|
||||
|
||||
#include <openspace/abuffer/abufferSingleLinked.h>
|
||||
#include <openspace/abuffer/abufferfixed.h>
|
||||
#include <openspace/abuffer/abufferdynamic.h>
|
||||
|
||||
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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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(?)
|
||||
|
||||
@@ -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<float>(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<float>(glm::clamp(normalizedVal, 0.0, 1.0));
|
||||
// data[i] = static_cast<float>(normalizedVal);
|
||||
// }
|
||||
|
||||
delete[] doubleData;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user