/***************************************************************************************** * * * 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 APPLE #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 #if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED layout (binding = 0, r32ui) uniform uimage2D anchorPointerTexture; layout (binding = 1, rgba32ui) uniform uimageBuffer fragmentTexture; #define _MAX_LAYERS_ MAX_LAYERS #define _SCREEN_WIDTH_ SCREEN_WIDTH #define _SCREEN_HEIGHT_ SCREEN_HEIGHT #endif #endif layout(location = 0) out vec4 framebuffer_output_color; ABufferStruct_t createGeometryFragment(vec4 fragColor, vec4 position) { ABufferStruct_t frag; _col_(frag, fragColor); _z_(frag, gl_FragCoord.z); _type_(frag, 0); _pos_(frag, position); return frag; } ABufferStruct_t createGeometryFragment(vec4 fragColor, vec4 position, float z) { ABufferStruct_t frag; _col_(frag, fragColor); _z_(frag, z); _type_(frag, 0); _pos_(frag, position); return frag; } void addToBuffer(ABufferStruct_t frag) { #if ABUFFER_IMPLEMENTATION == ABUFFER_FRAMEBUFFER framebuffer_output_color = _col_(frag); gl_FragDepth = _z_(frag); #endif #ifndef APPLE #if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED #ifdef ABUFFER_INCLUDE_POSITION uint index = atomicCounterIncrement(atomicCounterBuffer); index *= 2; uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); _next_(frag,old_head); 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(index), p1); imageStore(fragmentTexture, int(index+1), p2); #else uint index = atomicCounterIncrement(atomicCounterBuffer); uint old_head = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), index); _next_(frag,old_head); uvec4 p1 = uvec4(frag.z, frag.id, frag.rg, frag.ba); imageStore(fragmentTexture, int(index), p1); #endif discard; #endif #if ABUFFER_IMPLEMENTATION == ABUFFER_FIXED #ifdef ABUFFER_INCLUDE_POSITION 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); } #else 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); uvec4 p1 = uvec4(frag.z, frag.id, frag.rg, frag.ba); imageStore(fragmentTexture, int(offset), p1); } else { imageAtomicAdd(anchorPointerTexture, ivec2(gl_FragCoord.xy), -1); } #endif discard; #endif #endif } #ifndef APPLE ABufferStruct_t loadFromBuffer(uint id) { #ifdef ABUFFER_INCLUDE_POSITION #if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED uvec4 u1 = imageLoad(fragmentTexture, int(id)); 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); 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); #else #if ABUFFER_IMPLEMENTATION == ABUFFER_SINGLE_LINKED uvec4 u1 = imageLoad(fragmentTexture, int(id)); //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); uvec4 u1 = imageLoad(fragmentTexture, int(offset)); //uvec4 u2 = imageLoad(fragmentTexture, int(offset+1)); #endif return ABufferStruct_t(u1.x, u1.y, u1.z, u1.w); #endif } #endif