├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── COPYING ├── Doxyfile.in ├── README.md ├── cmake └── Modules │ ├── FindGLM.cmake │ └── MacroOutOfSourceBuild.cmake ├── glcorew ├── CMakeLists.txt ├── glcorearb.h ├── glcorew.cpp ├── glcorew.h └── glcorew_gen.py ├── shaders ├── CMakeLists.txt ├── blur │ ├── fragment.glsl │ └── vertex.glsl ├── depthblur │ ├── fragment.glsl │ └── vertex.glsl ├── font │ ├── fragment.glsl │ └── vertex.glsl ├── framing │ ├── fragment.glsl │ └── vertex.glsl ├── fsquad │ ├── fragment.glsl │ └── vertex.glsl ├── neighbourcellfinder │ ├── findcells.glsl │ └── neighbourcells.glsl ├── noise │ ├── LICENSE │ ├── noise2D.glsl │ └── noise3D.glsl ├── particledepth │ ├── fragment.glsl │ └── vertex.glsl ├── particles │ ├── fragment.glsl │ └── vertex.glsl ├── radixsort │ ├── addblocksum.glsl │ ├── blockscan.glsl │ ├── counting.glsl │ └── globalsort.glsl ├── selection │ ├── fragment.glsl │ └── vertex.glsl ├── skybox │ ├── fragment.glsl │ └── vertex.glsl ├── sph │ ├── calclambda.glsl │ ├── clearhighlight.glsl │ ├── foreachneighbour.glsl │ ├── highlight.glsl │ ├── predictpos.glsl │ ├── update.glsl │ ├── updatepos.glsl │ └── vorticity.glsl └── thickness │ ├── fragment.glsl │ └── vertex.glsl ├── src ├── Blur.cpp ├── Blur.h ├── CMakeLists.txt ├── Camera.cpp ├── Camera.h ├── Font.cpp ├── Font.h ├── Framing.cpp ├── Framing.h ├── FullscreenQuad.cpp ├── FullscreenQuad.h ├── NeighbourCellFinder.cpp ├── NeighbourCellFinder.h ├── PointSprite.cpp ├── PointSprite.h ├── RadixSort.cpp ├── RadixSort.h ├── SPH.cpp ├── SPH.h ├── Selection.cpp ├── Selection.h ├── ShaderProgram.cpp ├── ShaderProgram.h ├── Simulation.cpp ├── Simulation.h ├── Skybox.cpp ├── Skybox.h ├── SurfaceReconstruction.cpp ├── SurfaceReconstruction.h ├── Texture.cpp ├── Texture.h ├── common.h └── main.cpp └── textures ├── CMakeLists.txt ├── font.png ├── framing.png └── sky ├── readme.txt ├── skybox_negx.png ├── skybox_negy.png ├── skybox_negz.png ├── skybox_posx.png ├── skybox_posy.png └── skybox_posz.png /.gitignore: -------------------------------------------------------------------------------- 1 | build*/ 2 | cmake-build-*/ 3 | Debug/ 4 | Release/ 5 | .project 6 | .cproject 7 | .settings/ 8 | html/ 9 | .idea/ 10 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libs/spdlog"] 2 | path = libs/spdlog 3 | url = https://github.com/gabime/spdlog.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.5) 2 | set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules") 3 | 4 | project (pbf C CXX) 5 | 6 | set(CMAKE_CXX_STANDARD 17) 7 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 8 | 9 | # ensure that the build directory is not the source directory 10 | include(MacroOutOfSourceBuild) 11 | MACRO_ENSURE_OUT_OF_SOURCE_BUILD("${PROJECT_NAME} requires an out source build.") 12 | 13 | add_subdirectory(libs/spdlog) 14 | 15 | add_subdirectory (shaders) 16 | add_subdirectory (textures) 17 | add_subdirectory (src) 18 | add_subdirectory (glcorew) 19 | 20 | find_package (Doxygen QUIET) 21 | 22 | if (DOXYGEN_FOUND) 23 | find_package (LATEX QUIET) 24 | find_program (DOXYFILE_MAKE make) 25 | mark_as_advanced(DOXYFILE_MAKE) 26 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) 27 | add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 28 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 29 | COMMENT "Generating API documentation with Doxygen" VERBATIM) 30 | if(LATEX_COMPILER AND MAKEINDEX_COMPILER AND DOXYFILE_MAKE) 31 | add_custom_command(TARGET doc 32 | POST_BUILD 33 | COMMAND "${DOXYFILE_MAKE}" 34 | COMMENT "Running LaTeX for Doxygen documentation in ${CMAKE_CURRENT_BINARY_DIR}/latex..." 35 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/latex") 36 | endif() 37 | endif (DOXYGEN_FOUND) 38 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2014 Daniel Kirchner 2 | 3 | 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: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | 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. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Position Based Fluids 2 | ===================== 3 | Dependencies 4 | ------------ 5 | - GLFW (http://www.glfw.org/) 6 | - glm (http://glm.g-truc.net/) 7 | - libpng (http://libpng.org/pub/png/libpng.html) 8 | - cmake (http://www.cmake.org/) 9 | - _optional_: doxygen (http://doxygen.org/) 10 | 11 | Compiling 12 | --------- 13 | Create a build directory and use the following commands to compile the project: 14 | 15 | cmake [path to source directory] 16 | make 17 | 18 | This will create the executable `src/pbf`. Note that it has to be executed with the 19 | subdirectories _shaders_ and _textures_ in its working directory. This documentation 20 | can be generated with `make doc`. 21 | 22 | References 23 | ---------- 24 | This position based fluids implementation is based on the following scientific paper: 25 | 26 | http://www.matthiasmueller.info/publications/pbf_sig_preprint.pdf 27 | 28 | 29 | Furthermore techniques from the following papers have been used: 30 | 31 | http://www.sci.utah.edu/~csilva/papers/cgf.pdf 32 | 33 | http://beowulf.lcs.mit.edu/18.337-2008/lectslides/scan.pdf 34 | 35 | http://developer.download.nvidia.com/presentations/2010/gdc/Direct3D_Effects.pdf 36 | 37 | Documentation 38 | ------------- 39 | 40 | More extensive documentation than the current doxygen generated reference will be 41 | available shortly. 42 | 43 | Demonstration videos of a former version of the implementation can currently be 44 | found at (they were recorded using a NVIDIA GeForce GTX 560 Ti): 45 | http://mokaga.userpage.fu-berlin.de/pbfvids/ 46 | -------------------------------------------------------------------------------- /cmake/Modules/FindGLM.cmake: -------------------------------------------------------------------------------- 1 | # FindGLM - attempts to locate the glm matrix/vector library. 2 | # 3 | # This module defines the following variables (on success): 4 | # GLM_INCLUDE_DIRS - where to find glm/glm.hpp 5 | # GLM_FOUND - if the library was successfully located 6 | # 7 | # It is trying a few standard installation locations, but can be customized 8 | # with the following variables: 9 | # GLM_ROOT_DIR - root directory of a glm installation 10 | # Headers are expected to be found in either: 11 | # /glm/glm.hpp OR 12 | # /include/glm/glm.hpp 13 | # This variable can either be a cmake or environment 14 | # variable. Note however that changing the value 15 | # of the environment varible will NOT result in 16 | # re-running the header search and therefore NOT 17 | # adjust the variables set by this module. 18 | 19 | #============================================================================= 20 | # Copyright 2012 Carsten Neumann 21 | # 22 | # Distributed under the OSI-approved BSD License (the "License"); 23 | # see accompanying file Copyright.txt for details. 24 | # 25 | # This software is distributed WITHOUT ANY WARRANTY; without even the 26 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 27 | # See the License for more information. 28 | #============================================================================= 29 | # (To distribute this file outside of CMake, substitute the full 30 | # License text for the above reference.) 31 | 32 | # default search dirs 33 | SET(_glm_HEADER_SEARCH_DIRS 34 | "/usr/include" 35 | "/usr/local/include") 36 | 37 | # check environment variable 38 | SET(_glm_ENV_ROOT_DIR "$ENV{GLM_ROOT_DIR}") 39 | 40 | IF(NOT GLM_ROOT_DIR AND _glm_ENV_ROOT_DIR) 41 | SET(GLM_ROOT_DIR "${_glm_ENV_ROOT_DIR}") 42 | ENDIF(NOT GLM_ROOT_DIR AND _glm_ENV_ROOT_DIR) 43 | 44 | # put user specified location at beginning of search 45 | IF(GLM_ROOT_DIR) 46 | SET(_glm_HEADER_SEARCH_DIRS "${GLM_ROOT_DIR}" 47 | "${GLM_ROOT_DIR}/include" 48 | ${_glm_HEADER_SEARCH_DIRS}) 49 | ENDIF(GLM_ROOT_DIR) 50 | 51 | # locate header 52 | FIND_PATH(GLM_INCLUDE_DIR "glm/glm.hpp" 53 | PATHS ${_glm_HEADER_SEARCH_DIRS}) 54 | 55 | INCLUDE(FindPackageHandleStandardArgs) 56 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLM DEFAULT_MSG 57 | GLM_INCLUDE_DIR) 58 | 59 | IF(GLM_FOUND) 60 | SET(GLM_INCLUDE_DIRS "${GLM_INCLUDE_DIR}") 61 | 62 | MESSAGE(STATUS "GLM_INCLUDE_DIR = ${GLM_INCLUDE_DIR}") 63 | ENDIF(GLM_FOUND) 64 | -------------------------------------------------------------------------------- /cmake/Modules/MacroOutOfSourceBuild.cmake: -------------------------------------------------------------------------------- 1 | # Ensures that we do an out of source build 2 | MACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD MSG) 3 | STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" insource) 4 | GET_FILENAME_COMPONENT(PARENTDIR ${CMAKE_SOURCE_DIR} PATH) 5 | STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${PARENTDIR}" insourcesubdir) 6 | IF (insource OR insourcesubdir) 7 | MESSAGE(FATAL_ERROR "${MSG}") 8 | ENDIF (insource OR insourcesubdir) 9 | ENDMACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD) -------------------------------------------------------------------------------- /glcorew/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file (GLOB GLCOREW_SOURCES *.cpp) 2 | add_library (glcorew ${GLCOREW_SOURCES}) 3 | -------------------------------------------------------------------------------- /glcorew/glcorew_gen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This is a highly modified version of gl3w_gen.py. 4 | # The original version was written by Slavomir Kaslev 5 | # as part of gl3w which is in the public domain 6 | # and available at https://github.com/skaslev/gl3w. 7 | # 8 | # Copyright (c) 2013 Daniel Kirchner 9 | # 10 | # Copying and distribution of this file, with or without modification, 11 | # are permitted in any medium without royalty provided the copyright 12 | # notice and this notice are preserved. This file is offered as-is, 13 | # without any warranty. 14 | # 15 | import re 16 | import os 17 | import urllib.request, urllib.error, urllib.parse 18 | 19 | # Parse function names from glcorearb.h 20 | procs = [] 21 | p = re.compile(r'GLAPI.*APIENTRY\s+(\w+)') 22 | with open('glcorearb.h', 'r') as f: 23 | for line in f: 24 | m = p.match(line) 25 | if m: 26 | procs.append(m.group(1)) 27 | 28 | def proc_t(proc): 29 | return { 'p': proc, 30 | 'p_s': proc[2:], 31 | 'p_t': 'PFN' + proc.upper() + 'PROC' } 32 | 33 | # Generate glcorew.h 34 | with open('glcorew.h', 'wt') as f: 35 | f.write (r'''/* 36 | * Copyright (c) 2013 Daniel Kirchner 37 | * 38 | * Copying and distribution of this file, with or without modification, 39 | * are permitted in any medium without royalty provided the copyright 40 | * notice and this notice are preserved. This file is offered as-is, 41 | * without any warranty. 42 | */ 43 | /* This file was generated by glcorew_gen.py. 44 | * Don't change it directly, change glcorew_gen.py instead. */ 45 | #ifndef GLCOREW_H 46 | #define GLCOREW_H 47 | 48 | #include "glcorearb.h" 49 | 50 | typedef void *(*glcorewGetProcAddressCallback) (const char*); 51 | 52 | void glcorewInit (glcorewGetProcAddressCallback getprocaddress); 53 | GLAPI int APIENTRY glcorewUnsupported (...); 54 | 55 | ''') 56 | for proc in procs: 57 | f.write('extern %(p_t)s glcorew%(p_s)s;\n' % proc_t(proc)) 58 | 59 | for proc in procs: 60 | f.write('#define %(p)s glcorew%(p_s)s\n' % proc_t(proc)) 61 | f.write(r''' 62 | 63 | #endif /* !defined OGLP_GLCOREW_H */ 64 | ''') 65 | 66 | # Generate glcorew.cpp 67 | with open('glcorew.cpp', 'wt') as f: 68 | f.write(r'''/* 69 | * Copyright (c) 2013 Daniel Kirchner 70 | * 71 | * Copying and distribution of this file, with or without modification, 72 | * are permitted in any medium without royalty provided the copyright 73 | * notice and this notice are preserved. This file is offered as-is, 74 | * without any warranty. 75 | */ 76 | /* This file was generated by glcorew_gen.py. 77 | * Don't change it directoly, change glcorew_gen.py instead.*/ 78 | #include "glcorew.h" 79 | #include 80 | #include 81 | 82 | ''') 83 | for proc in procs: 84 | f.write('%(p_t)s glcorew%(p_s)s =\n' 85 | ' (%(p_t)s) glcorewUnsupported;\n' % proc_t(proc)) 86 | f.write(r''' 87 | 88 | GLAPI int APIENTRY glcorewUnsupported (...) 89 | { 90 | throw std::runtime_error ("An unsupported OpenGL entry point was called."); 91 | } 92 | 93 | void _glcorewInit (glcorewGetProcAddressCallback getprocaddress) 94 | { 95 | void *ptr; 96 | 97 | ''') 98 | for proc in procs: 99 | f.write(' ptr = getprocaddress ("%(p)s");\n' 100 | ' if (ptr) glcorew%(p_s)s = (%(p_t)s) ptr;\n' 101 | % proc_t(proc)) 102 | f.write(r''' 103 | } 104 | 105 | #ifdef _WIN32 106 | /* This workaround falls back to loading symbols 107 | * directly from OpenGL32.dll, as wglGetProcAddress 108 | * may return NULL for legacy opengl entry points. */ 109 | static HMODULE __glcorewOpengl32DllHandle = NULL; 110 | static glcorewGetProcAddressCallback __glcorewUserGetProcAddressCallback = NULL; 111 | inline void *__glcorewGetProcAddress (const char *name) 112 | { 113 | void *ptr = NULL; 114 | if (__glcorewUserGetProcAddressCallback) 115 | ptr = __glcorewUserGetProcAddressCallback (name); 116 | if (!ptr && __glcorewOpengl32DllHandle) 117 | ptr = (void*) GetProcAddress (__glcorewOpengl32DllHandle, name); 118 | return ptr; 119 | } 120 | #endif 121 | 122 | void glcorewInit (glcorewGetProcAddressCallback callback) { 123 | std::stringstream version; 124 | int major, minor; 125 | 126 | #ifdef _WIN32 127 | __glcorewOpengl32DllHandle = LoadLibrary ("OPENGL32.DLL"); 128 | __glcorewUserGetProcAddressCallback = callback; 129 | _glcorewInit (__glcorewGetProcAddress); 130 | #else 131 | _glcorewInit (callback); 132 | #endif 133 | if (!glcorewGetString || glcorewGetString == (PFNGLGETSTRINGPROC) glcorewUnsupported) 134 | throw std::runtime_error ("No entry point for glGetString found."); 135 | 136 | version << glcorewGetString (GL_VERSION); 137 | if (glGetError () != GL_NO_ERROR) 138 | throw std::runtime_error ("Cannot determine OpenGL version."); 139 | version >> major; 140 | version.ignore (1); 141 | version >> minor; 142 | 143 | if (major < 4 || minor < 3) 144 | throw std::runtime_error ("OpenGL version 4.3 or higher is required."); 145 | } 146 | ''') 147 | -------------------------------------------------------------------------------- /shaders/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(shaders_files 2 | blur/fragment.glsl blur/vertex.glsl 3 | depthblur/vertex.glsl depthblur/fragment.glsl 4 | font/fragment.glsl font/vertex.glsl 5 | framing/fragment.glsl framing/vertex.glsl 6 | fsquad/fragment.glsl fsquad/vertex.glsl 7 | neighbourcellfinder/findcells.glsl neighbourcellfinder/neighbourcells.glsl 8 | noise/noise2D.glsl noise/noise3D.glsl 9 | particledepth/vertex.glsl particledepth/fragment.glsl 10 | particles/vertex.glsl particles/fragment.glsl 11 | radixsort/addblocksum.glsl radixsort/blockscan.glsl radixsort/counting.glsl radixsort/globalsort.glsl 12 | selection/fragment.glsl selection/vertex.glsl 13 | skybox/vertex.glsl skybox/fragment.glsl 14 | sph/calclambda.glsl sph/clearhighlight.glsl sph/highlight.glsl sph/predictpos.glsl 15 | sph/update.glsl sph/updatepos.glsl sph/vorticity.glsl sph/foreachneighbour.glsl 16 | thickness/fragment.glsl thickness/vertex.glsl) 17 | 18 | foreach(item IN ITEMS ${shaders_files}) 19 | list(APPEND shaders_out "${CMAKE_CURRENT_BINARY_DIR}/${item}") 20 | add_custom_command( 21 | OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${item}" 22 | COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${item}" "${CMAKE_CURRENT_BINARY_DIR}/${item}" 23 | DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${item}" 24 | ) 25 | endforeach() 26 | 27 | message(STATUS "${shaders_out}") 28 | 29 | add_custom_target(shaders-target DEPENDS "${shaders_out}") 30 | -------------------------------------------------------------------------------- /shaders/blur/fragment.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | // #version 430 core 23 | 24 | layout (binding = 0) uniform sampler2D inputtex; 25 | layout (location = 0) out vec4 color; 26 | 27 | // input from vertex shader 28 | in vec2 fTexcoord; 29 | 30 | // blur weights 31 | layout (std430, binding = 0) readonly buffer Weights { 32 | vec2 weights[]; 33 | }; 34 | 35 | // offset scale indicating input size and blur direction 36 | uniform vec2 offsetscale; 37 | 38 | void main(void) 39 | { 40 | vec4 c; 41 | // sum weighted data 42 | c = texture (inputtex, fTexcoord) * weights[0].r; 43 | for (int i = 1; i < weights.length (); i++) 44 | { 45 | c += texture (inputtex, fTexcoord + weights[i].g * offsetscale) * weights[i].r; 46 | c += texture (inputtex, fTexcoord - weights[i].g * offsetscale) * weights[i].r; 47 | } 48 | 49 | // output resulting color 50 | color = c; 51 | } 52 | -------------------------------------------------------------------------------- /shaders/blur/vertex.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | // #version 430 core 23 | 24 | // input vertex attributes 25 | layout (location = 0) in vec2 vPosition; 26 | 27 | // output to the fragment shader 28 | out vec2 fTexcoord; 29 | 30 | void main (void) 31 | { 32 | // pass data to the fragment shader 33 | fTexcoord = 0.5 * vPosition + 0.5; 34 | // output the vertex position 35 | gl_Position = vec4 (vPosition, 0.0, 1.0); 36 | } 37 | -------------------------------------------------------------------------------- /shaders/depthblur/fragment.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | layout (binding = 0) uniform sampler2D depthtex; 25 | 26 | // input from vertex shader 27 | in vec2 fTexcoord; 28 | 29 | // blur weights 30 | layout (std430, binding = 0) readonly buffer Weights { 31 | vec2 weights[]; 32 | }; 33 | 34 | // offset scale indicating input size and blur direction 35 | uniform vec2 offsetscale; 36 | 37 | // falloff scaling depth differences in order to cutoff the blur 38 | const float falloff = 1000.0f; 39 | 40 | // linearize a depth value in order to determine a meaningful difference 41 | float linearizeDepth (in float d) 42 | { 43 | const float f = 1000.0f; 44 | const float n = 1.0f; 45 | return (2 * n) / (f + n - d * (f - n)); 46 | } 47 | 48 | void main(void) 49 | { 50 | // fetch current depth 51 | float depth = texture (depthtex, fTexcoord).x; 52 | // discard if nothing was rendered at the given position 53 | if (depth == 1.0) 54 | discard; 55 | 56 | float result; 57 | float wsum; 58 | 59 | // initialize with weighted current depth 60 | wsum = weights[0].r; 61 | result = depth * wsum; 62 | 63 | // sum weighted data 64 | for (int i = 1; i < weights.length (); i++) 65 | { 66 | // fetch depth values 67 | float d1 = texture (depthtex, fTexcoord + weights[i].g * offsetscale).x; 68 | float d2 = texture (depthtex, fTexcoord - weights[i].g * offsetscale).x; 69 | 70 | // compute cutoff weights from the linearized depth differences 71 | float r1 = (linearizeDepth (depth) - linearizeDepth (d1)) * falloff; 72 | float w1 = exp (-r1 * r1); 73 | 74 | float r2 = (linearizeDepth (depth) - linearizeDepth (d2)) * falloff; 75 | float w2 = exp (-r2 * r2); 76 | 77 | // sum values and weights 78 | wsum += weights[i].r * (w1 + w2); 79 | result += weights[i].r * (w1 * d1 + w2 * d2); 80 | } 81 | // normalize and return the result 82 | if (wsum > 0) result /= wsum; 83 | gl_FragDepth = result; 84 | } 85 | -------------------------------------------------------------------------------- /shaders/depthblur/vertex.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // input vertex attributes 25 | layout (location = 0) in vec2 vPosition; 26 | 27 | // output to the fragment shader 28 | out vec2 fTexcoord; 29 | 30 | void main (void) 31 | { 32 | // pass data to the fragment shader 33 | fTexcoord = 0.5 * vPosition + 0.5; 34 | // output the vertex position 35 | gl_Position = vec4 (vPosition, 0.0, 1.0); 36 | } 37 | -------------------------------------------------------------------------------- /shaders/font/fragment.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // output color 25 | layout (location = 0) out vec4 color; 26 | 27 | // font texture 28 | layout (binding = 0) uniform sampler2D tex; 29 | 30 | // texture coordinates 31 | in vec2 fTexcoord; 32 | 33 | void main (void) 34 | { 35 | // output the color value 36 | color = texture (tex, fTexcoord).x * vec4 (1, 1, 1, 1); 37 | } 38 | -------------------------------------------------------------------------------- /shaders/font/vertex.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // vertex attributes 25 | layout (location = 0) in vec2 vPosition; 26 | 27 | // view/projection matrix 28 | uniform mat4 mat; 29 | 30 | // texture coord for the fragment shader 31 | out vec2 fTexcoord; 32 | 33 | // which character to display 34 | uniform vec2 charpos; 35 | 36 | // raster position for the character 37 | uniform vec2 pos; 38 | 39 | void main (void) 40 | { 41 | // determine the texture coordinates for the character 42 | fTexcoord = charpos + vPosition / vec2 (16, 8); 43 | // output the position 44 | gl_Position = mat * vec4 (pos + vPosition, 0, 1); 45 | } 46 | -------------------------------------------------------------------------------- /shaders/framing/fragment.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // enable early z culling 25 | layout (early_fragment_tests) in; 26 | 27 | // output color 28 | layout (location = 0) out vec4 color; 29 | 30 | // texture 31 | layout (binding = 0) uniform sampler2D tex; 32 | 33 | // input from vertex shader 34 | in vec2 fTexcoord; 35 | in vec3 fPosition; 36 | in vec3 fNormal; 37 | 38 | // lighting parameters 39 | layout (binding = 1, std140) uniform LightingBuffer 40 | { 41 | vec3 lightpos; 42 | vec3 spotdir; 43 | vec3 eyepos; 44 | float spotexponent; 45 | float lightintensity; 46 | }; 47 | 48 | // projection and view matrix 49 | layout (binding = 0, std140) uniform TransformationBlock { 50 | mat4 viewmat; 51 | mat4 projmat; 52 | }; 53 | 54 | void main (void) 55 | { 56 | // lighting calculations 57 | // obtain light direction and distance 58 | vec3 lightdir = lightpos - fPosition; 59 | float lightdist = length (lightdir); 60 | lightdir /= lightdist; 61 | 62 | // compute light intensity as the cosine of the angle 63 | // between light direction and normal direction 64 | float intensity = max (dot (lightdir, fNormal), 0); 65 | 66 | // apply distance attenuation and light intensity 67 | intensity /= lightdist * lightdist; 68 | intensity *= lightintensity; 69 | 70 | // spot light effect 71 | float angle = dot (spotdir, - lightdir); 72 | intensity *= pow (angle, spotexponent); 73 | 74 | // ambient light 75 | intensity += 0.1; 76 | 77 | // fetch texture value and output resulting color 78 | color = clamp (intensity, 0, 1) * texture (tex, fTexcoord); 79 | } 80 | -------------------------------------------------------------------------------- /shaders/framing/vertex.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // input vertex attributes 25 | layout (location = 0) in vec3 vPosition; 26 | layout (location = 1) in vec2 vTexcoord; 27 | layout (location = 2) in vec3 vNormal; 28 | 29 | // projection and view matrix 30 | layout (binding = 0, std140) uniform TransformationBlock { 31 | mat4 viewmat; 32 | mat4 projmat; 33 | }; 34 | 35 | // output to the fragment shader 36 | out vec2 fTexcoord; 37 | out vec3 fNormal; 38 | out vec3 fPosition; 39 | 40 | void main (void) 41 | { 42 | // pass data to the fragment shader 43 | fTexcoord = vTexcoord; 44 | fNormal = vNormal; 45 | fPosition = vPosition; 46 | // compute and output the vertex position 47 | // after view transformation and projection 48 | gl_Position = projmat * viewmat * vec4 (vPosition, 1); 49 | } 50 | -------------------------------------------------------------------------------- /shaders/fsquad/fragment.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // enable early z culling 25 | layout (early_fragment_tests) in; 26 | 27 | // output color 28 | layout (location = 0) out vec4 color; 29 | 30 | // input from vertex shader 31 | in vec2 fTexcoord; 32 | 33 | // projection and view matrix 34 | layout (binding = 0, std140) uniform TransformationBlock { 35 | mat4 viewmat; 36 | mat4 projmat; 37 | mat4 invviewmat; 38 | }; 39 | 40 | layout (binding = 0) uniform sampler2D depthtex; 41 | layout (binding = 1) uniform sampler2D thicknesstex; 42 | layout (binding = 2) uniform samplerCube envmap; 43 | layout (binding = 3) uniform sampler2D noisetex; 44 | 45 | // lighting parameters 46 | layout (binding = 1, std140) uniform LightingBuffer 47 | { 48 | vec3 lightpos; 49 | vec3 spotdir; 50 | vec3 eyepos; 51 | float spotexponent; 52 | float lightintensity; 53 | }; 54 | 55 | // obtain position from texcoord and depth 56 | vec3 getpos (in vec3 p) 57 | { 58 | vec4 pos = inverse (projmat) * vec4 (p * 2 - 1, 1); 59 | pos /= pos.w; 60 | pos = inverse (viewmat) * pos; 61 | return pos.xyz / pos.w; 62 | } 63 | 64 | uniform bool useenvmap; 65 | uniform bool usenoise; 66 | 67 | void main (void) 68 | { 69 | // fetch depth from texture 70 | float depth = texture (depthtex, fTexcoord, 0).x; 71 | if (depth == 1.0) 72 | discard; 73 | 74 | vec3 pos = getpos (vec3 (fTexcoord, depth)); 75 | 76 | vec2 tmp; 77 | tmp = fTexcoord + vec2 (1.0f / 1280.0f, 0); 78 | vec3 ddx = getpos (vec3 (tmp, texture (depthtex, tmp, 0).x)) - pos; 79 | tmp = fTexcoord - vec2 (1.0f / 1280.0f, 0); 80 | vec3 ddx2 = pos - getpos (vec3 (tmp, texture (depthtex, tmp, 0).x)); 81 | if (abs (ddx.z) > abs (ddx2.z)) ddx = ddx2; 82 | 83 | tmp = fTexcoord + vec2 (0, 1.0f / 720.0f); 84 | vec3 ddy = getpos (vec3 (tmp, texture (depthtex, tmp, 0).x)) - pos; 85 | tmp = fTexcoord - vec2 (0, 1.0f / 720.0f); 86 | vec3 ddy2 = pos - getpos (vec3 (tmp, texture (depthtex, tmp, 0).x)); 87 | if (abs (ddy.z) < abs (ddy2.z)) ddy = ddy2; 88 | 89 | vec3 normal = normalize (cross (ddx, ddy)); 90 | 91 | // fetch thickness 92 | float thickness = texture (thicknesstex, fTexcoord).x * 10; 93 | 94 | vec3 N; 95 | if (usenoise) { 96 | // fetch noise 97 | N = texture (noisetex, fTexcoord).xyz; 98 | 99 | // perturb normal with scaled noise 100 | normal += N * 0.075; 101 | normal = normalize (normal); 102 | } 103 | 104 | // lighting calculations 105 | 106 | // obtain light direction and distance 107 | vec3 lightdir = lightpos - pos; 108 | float lightdist = length (lightdir); 109 | lightdir /= lightdist; 110 | 111 | // view direction 112 | vec3 viewdir = normalize (eyepos - pos); 113 | vec3 halfvec = normalize (viewdir + lightdir); 114 | 115 | // compute light intensity as the cosine of the angle 116 | // between light direction and normal direction 117 | float NdotL = dot (lightdir, normal); 118 | float intensity = max (NdotL * 0.5 + 0.5, 0); 119 | 120 | // apply distance attenuation and light intensity 121 | intensity /= lightdist * lightdist; 122 | intensity *= lightintensity; 123 | 124 | // spot light effect 125 | float angle = dot (spotdir, -lightdir); 126 | intensity *= pow (angle, spotexponent); 127 | 128 | // specular light 129 | float k = max (dot (viewdir, reflect (-lightdir, normal)), 0); 130 | k = pow (k, 8); 131 | 132 | // Schlick's approximation for the fresnel term 133 | float cos_theta = dot (viewdir, normal); 134 | float fresnel = 0.75 + (1 - 0.75) * pow (1 - cos_theta, 5); 135 | k *= fresnel; 136 | 137 | // Beer-Lambert law for coloring 138 | vec3 c = vec3 (exp (-0.5 * thickness), 139 | exp (-0.02 * thickness), 140 | exp (-0.005 * thickness)); 141 | 142 | // calculate specular color 143 | vec3 specular = k * min (c + 0.5, 1); 144 | 145 | // calculate alpha 146 | float alpha = min (dot (c, c), 0.8); 147 | 148 | // calculate diffuse color 149 | vec3 diffuse; 150 | if (useenvmap) 151 | { 152 | vec3 dir = normalize (reflect (-viewdir, normal.xyz)); 153 | vec3 reflection = texture (envmap, dir).xyz; 154 | diffuse += reflection * fresnel; 155 | } 156 | else 157 | { 158 | diffuse = c; 159 | } 160 | diffuse *= clamp (intensity, 0, 1); 161 | 162 | // combine diffuse and specular light and alpha to the final color value 163 | color = vec4 (diffuse + specular, alpha); 164 | } 165 | -------------------------------------------------------------------------------- /shaders/fsquad/vertex.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // input vertex attributes 25 | layout (location = 0) in vec2 vPosition; 26 | 27 | // output to the fragment shader 28 | out vec2 fTexcoord; 29 | 30 | // projection and view matrix 31 | layout (binding = 0, std140) uniform TransformationBlock { 32 | mat4 viewmat; 33 | mat4 projmat; 34 | mat4 invviewmat; 35 | }; 36 | 37 | 38 | void main (void) 39 | { 40 | // pass data to the fragment shader 41 | fTexcoord = 0.5 * vPosition + 0.5; 42 | // output the vertex position 43 | gl_Position = vec4 (vPosition, 0.0, 1.0); 44 | } 45 | -------------------------------------------------------------------------------- /shaders/neighbourcellfinder/findcells.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | // header is included here 23 | 24 | layout (local_size_x = BLOCKSIZE) in; 25 | 26 | layout (std430, binding = 0) readonly buffer ParticleKeys 27 | { 28 | vec4 particlekeys[]; 29 | }; 30 | 31 | layout (binding = 0, r32i) uniform writeonly iimage3D gridtexture; 32 | layout (binding = 1, r32i) uniform writeonly iimage3D gridendtexture; 33 | 34 | void main (void) 35 | { 36 | uint gid; 37 | gid = gl_GlobalInvocationID.x; 38 | 39 | if (gid == 0) 40 | { 41 | imageStore (gridtexture, ivec3 (0, 0, 0), ivec4 (0, 0, 0, 0)); 42 | return; 43 | } 44 | 45 | ivec3 gridpos = ivec3 (clamp (particlekeys[gid].xyz, vec3 (0, 0, 0), GRID_SIZE)); 46 | ivec3 gridpos2 = ivec3 (clamp (particlekeys[gid - 1].xyz, vec3 (0, 0, 0), GRID_SIZE)); 47 | 48 | if (gridpos != gridpos2) 49 | { 50 | imageStore (gridtexture, gridpos, ivec4 (gid, 0, 0, 0)); 51 | imageStore (gridendtexture, gridpos2, ivec4 (gid, 0, 0, 0)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /shaders/neighbourcellfinder/neighbourcells.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | // header is included here 23 | 24 | layout (local_size_x = BLOCKSIZE) in; 25 | 26 | layout (std430, binding = 0) readonly buffer ParticleKeys 27 | { 28 | vec4 particlekeys[]; 29 | }; 30 | 31 | layout (binding = 0) uniform isampler3D gridtexture; 32 | layout (binding = 1) uniform isampler3D gridendtexture; 33 | 34 | layout (binding = 0, rgba32i) uniform writeonly iimageBuffer neighbourtexture; 35 | 36 | // neighbour grids in y and z direction 37 | const ivec3 gridoffsets[9] = { 38 | ivec3 (0, -1, -1), 39 | ivec3 (0, -1, 0), 40 | ivec3 (0, -1, 1), 41 | ivec3 (0, 0, -1), 42 | ivec3 (0, 0, 0), 43 | ivec3 (0, 0, 1), 44 | ivec3 (0, 1, -1), 45 | ivec3 (0, 1, 0), 46 | ivec3 (0, 1, 1) 47 | }; 48 | 49 | // offset between grids in x direction 50 | const ivec3 gridxoffset = ivec3 (1, 0, 0); 51 | 52 | void main (void) 53 | { 54 | uint particleid; 55 | particleid = gl_GlobalInvocationID.x; 56 | 57 | ivec3 gridpos = ivec3 (particlekeys[particleid].xyz); 58 | 59 | int cells[9]; 60 | 61 | // go through all 9 neighbour directions in y/z direction 62 | for (int o = 0; o < 9; o++) { 63 | int numcells = 0; 64 | int entries = 0; 65 | int cell = -1; 66 | 67 | // got through all cells in x direction 68 | for (int j = -1; j <= 1; j++) 69 | { 70 | // fetch its starting position 71 | int c = texelFetch (gridtexture, gridpos + gridoffsets[o] + j * gridxoffset, 0).x; 72 | // store the position, if we don't already have a starting point 73 | if (cell == -1) cell = c; 74 | // if the cell exists 75 | if (c != -1) 76 | { 77 | // lookup its size and update entry count 78 | int end = texelFetch (gridendtexture, gridpos + gridoffsets[o] + j * gridxoffset, 0).x; 79 | entries += end - c; 80 | } 81 | } 82 | 83 | cells[o] = cell + (entries<<24); 84 | } 85 | 86 | for (int i = 0; i < 3; i++) 87 | { 88 | // store everything in the neighbour texture 89 | imageStore (neighbourtexture, int (particleid * 3 + i), ivec4 (cells[i*3+0], cells[i*3+1], cells[i*3+2], 0)); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /shaders/noise/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2011 by Ashima Arts (Simplex noise) 2 | Copyright (C) 2011 by Stefan Gustavson (Classic noise) 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /shaders/noise/noise2D.glsl: -------------------------------------------------------------------------------- 1 | // 2 | // Description : Array and textureless GLSL 2D simplex noise function. 3 | // Author : Ian McEwan, Ashima Arts. 4 | // Maintainer : ijm 5 | // Lastmod : 20110822 (ijm) 6 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 7 | // Distributed under the MIT License. See LICENSE file. 8 | // https://github.com/ashima/webgl-noise 9 | // 10 | 11 | vec3 mod289(vec3 x) { 12 | return x - floor(x * (1.0 / 289.0)) * 289.0; 13 | } 14 | 15 | vec2 mod289(vec2 x) { 16 | return x - floor(x * (1.0 / 289.0)) * 289.0; 17 | } 18 | 19 | vec3 permute(vec3 x) { 20 | return mod289(((x*34.0)+1.0)*x); 21 | } 22 | 23 | float snoise(vec2 v) 24 | { 25 | const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 26 | 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) 27 | -0.577350269189626, // -1.0 + 2.0 * C.x 28 | 0.024390243902439); // 1.0 / 41.0 29 | // First corner 30 | vec2 i = floor(v + dot(v, C.yy) ); 31 | vec2 x0 = v - i + dot(i, C.xx); 32 | 33 | // Other corners 34 | vec2 i1; 35 | //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 36 | //i1.y = 1.0 - i1.x; 37 | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); 38 | // x0 = x0 - 0.0 + 0.0 * C.xx ; 39 | // x1 = x0 - i1 + 1.0 * C.xx ; 40 | // x2 = x0 - 1.0 + 2.0 * C.xx ; 41 | vec4 x12 = x0.xyxy + C.xxzz; 42 | x12.xy -= i1; 43 | 44 | // Permutations 45 | i = mod289(i); // Avoid truncation effects in permutation 46 | vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) 47 | + i.x + vec3(0.0, i1.x, 1.0 )); 48 | 49 | vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); 50 | m = m*m ; 51 | m = m*m ; 52 | 53 | // Gradients: 41 points uniformly over a line, mapped onto a diamond. 54 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) 55 | 56 | vec3 x = 2.0 * fract(p * C.www) - 1.0; 57 | vec3 h = abs(x) - 0.5; 58 | vec3 ox = floor(x + 0.5); 59 | vec3 a0 = x - ox; 60 | 61 | // Normalise gradients implicitly by scaling m 62 | // Approximation of: m *= inversesqrt( a0*a0 + h*h ); 63 | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); 64 | 65 | // Compute final noise value at P 66 | vec3 g; 67 | g.x = a0.x * x0.x + h.x * x0.y; 68 | g.yz = a0.yz * x12.xz + h.yz * x12.yw; 69 | return 130.0 * dot(m, g); 70 | } 71 | -------------------------------------------------------------------------------- /shaders/noise/noise3D.glsl: -------------------------------------------------------------------------------- 1 | // 2 | // Description : Array and textureless GLSL 2D/3D/4D simplex 3 | // noise functions. 4 | // Author : Ian McEwan, Ashima Arts. 5 | // Maintainer : ijm 6 | // Lastmod : 20110822 (ijm) 7 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 8 | // Distributed under the MIT License. See LICENSE file. 9 | // https://github.com/ashima/webgl-noise 10 | // 11 | 12 | vec3 mod289(vec3 x) { 13 | return x - floor(x * (1.0 / 289.0)) * 289.0; 14 | } 15 | 16 | vec4 mod289(vec4 x) { 17 | return x - floor(x * (1.0 / 289.0)) * 289.0; 18 | } 19 | 20 | vec4 permute(vec4 x) { 21 | return mod289(((x*34.0)+1.0)*x); 22 | } 23 | 24 | vec4 taylorInvSqrt(vec4 r) 25 | { 26 | return 1.79284291400159 - 0.85373472095314 * r; 27 | } 28 | 29 | float snoise(vec3 v) 30 | { 31 | const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; 32 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); 33 | 34 | // First corner 35 | vec3 i = floor(v + dot(v, C.yyy) ); 36 | vec3 x0 = v - i + dot(i, C.xxx) ; 37 | 38 | // Other corners 39 | vec3 g = step(x0.yzx, x0.xyz); 40 | vec3 l = 1.0 - g; 41 | vec3 i1 = min( g.xyz, l.zxy ); 42 | vec3 i2 = max( g.xyz, l.zxy ); 43 | 44 | // x0 = x0 - 0.0 + 0.0 * C.xxx; 45 | // x1 = x0 - i1 + 1.0 * C.xxx; 46 | // x2 = x0 - i2 + 2.0 * C.xxx; 47 | // x3 = x0 - 1.0 + 3.0 * C.xxx; 48 | vec3 x1 = x0 - i1 + C.xxx; 49 | vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y 50 | vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y 51 | 52 | // Permutations 53 | i = mod289(i); 54 | vec4 p = permute( permute( permute( 55 | i.z + vec4(0.0, i1.z, i2.z, 1.0 )) 56 | + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) 57 | + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); 58 | 59 | // Gradients: 7x7 points over a square, mapped onto an octahedron. 60 | // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) 61 | float n_ = 0.142857142857; // 1.0/7.0 62 | vec3 ns = n_ * D.wyz - D.xzx; 63 | 64 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) 65 | 66 | vec4 x_ = floor(j * ns.z); 67 | vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) 68 | 69 | vec4 x = x_ *ns.x + ns.yyyy; 70 | vec4 y = y_ *ns.x + ns.yyyy; 71 | vec4 h = 1.0 - abs(x) - abs(y); 72 | 73 | vec4 b0 = vec4( x.xy, y.xy ); 74 | vec4 b1 = vec4( x.zw, y.zw ); 75 | 76 | //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; 77 | //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; 78 | vec4 s0 = floor(b0)*2.0 + 1.0; 79 | vec4 s1 = floor(b1)*2.0 + 1.0; 80 | vec4 sh = -step(h, vec4(0.0)); 81 | 82 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; 83 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; 84 | 85 | vec3 p0 = vec3(a0.xy,h.x); 86 | vec3 p1 = vec3(a0.zw,h.y); 87 | vec3 p2 = vec3(a1.xy,h.z); 88 | vec3 p3 = vec3(a1.zw,h.w); 89 | 90 | //Normalise gradients 91 | vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); 92 | p0 *= norm.x; 93 | p1 *= norm.y; 94 | p2 *= norm.z; 95 | p3 *= norm.w; 96 | 97 | // Mix final noise value 98 | vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); 99 | m = m * m; 100 | return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), 101 | dot(p2,x2), dot(p3,x3) ) ); 102 | } 103 | -------------------------------------------------------------------------------- /shaders/particledepth/fragment.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // input from vertex shader 25 | in vec3 fPosition; 26 | in vec2 fTexcoord; 27 | 28 | // projection and view matrix 29 | layout (binding = 0, std140) uniform TransformationBlock { 30 | mat4 viewmat; 31 | mat4 projmat; 32 | }; 33 | 34 | void main (void) 35 | { 36 | float r = dot (fTexcoord, fTexcoord); 37 | if (r > 1) 38 | discard; 39 | 40 | vec3 normal = vec3 (fTexcoord, -sqrt (1 - r)); 41 | 42 | vec4 fPos = vec4 (fPosition - 0.1 * normal, 1.0); 43 | vec4 clipPos = projmat * fPos; 44 | 45 | // non-linear depth buffer 46 | gl_FragDepth = clipPos.z / clipPos.w; 47 | } 48 | -------------------------------------------------------------------------------- /shaders/particledepth/vertex.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // input vertex attributes 25 | layout (location = 0) in vec2 vPosition; 26 | layout (location = 1) in vec3 particlePosition; 27 | 28 | // projection and view matrix 29 | layout (binding = 0, std140) uniform TransformationBlock { 30 | mat4 viewmat; 31 | mat4 projmat; 32 | }; 33 | 34 | out vec3 fPosition; 35 | out vec2 fTexcoord; 36 | 37 | void main (void) 38 | { 39 | 40 | // pass data to the fragment shader 41 | vec4 pos = viewmat * vec4 (0.2 * particlePosition + 0.2 * vec3 (-64, 1, -64), 1.0) + vec4 (0.1 * vPosition, 0, 1); 42 | fPosition = pos.xyz; 43 | fTexcoord = vPosition; 44 | // compute and output the vertex position 45 | // after view transformation and projection 46 | gl_Position = projmat * pos; 47 | } 48 | -------------------------------------------------------------------------------- /shaders/particles/fragment.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // output color 25 | layout (location = 0) out vec4 color; 26 | 27 | // input from vertex shader 28 | in vec3 fPosition; 29 | in vec3 fColor; 30 | in vec2 fTexcoord; 31 | 32 | // lighting parameters 33 | layout (binding = 1, std140) uniform LightingBuffer 34 | { 35 | vec3 lightpos; 36 | vec3 spotdir; 37 | vec3 eyepos; 38 | float spotexponent; 39 | float lightintensity; 40 | }; 41 | 42 | // projection and view matrix 43 | layout (binding = 0, std140) uniform TransformationBlock { 44 | mat4 viewmat; 45 | mat4 projmat; 46 | mat4 invviewmat; 47 | }; 48 | 49 | void main (void) 50 | { 51 | float r = dot (fTexcoord, fTexcoord); 52 | if (r > 0.6) 53 | discard; 54 | 55 | vec3 normal = vec3 (fTexcoord, -sqrt (1 - r)); 56 | 57 | vec4 fPos = vec4 (fPosition - 0.1 * normal, 1.0); 58 | vec4 clipPos = projmat * fPos; 59 | float d = clipPos.z / clipPos.w; 60 | gl_FragDepth = d; 61 | 62 | // lighting calculations 63 | 64 | // obtain light direction and distance 65 | vec3 lightdir = lightpos - (invviewmat * fPos).xyz; 66 | float lightdist = length (lightdir); 67 | lightdir /= lightdist; 68 | 69 | // compute light intensity as the cosine of the angle 70 | // between light direction and normal direction 71 | float intensity = max (dot (lightdir, normal), 0); 72 | 73 | // apply distance attenuation and light intensity 74 | intensity /= lightdist * lightdist; 75 | intensity *= lightintensity; 76 | 77 | // spot light effect 78 | float angle = dot (spotdir, -lightdir); 79 | intensity *= pow (angle, spotexponent); 80 | 81 | // ambient light 82 | intensity += 0.25; 83 | 84 | // fetch texture value and output resulting color 85 | color = clamp (intensity, 0, 1) * vec4 (fColor, 1); 86 | } 87 | -------------------------------------------------------------------------------- /shaders/particles/vertex.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // input vertex attributes 25 | layout (location = 0) in vec2 vPosition; 26 | layout (location = 1) in vec3 particlePosition; 27 | layout (location = 2) in uint highlight; 28 | 29 | // projection and view matrix 30 | layout (binding = 0, std140) uniform TransformationBlock { 31 | mat4 viewmat; 32 | mat4 projmat; 33 | mat4 invviewmat; 34 | }; 35 | 36 | // output to the fragment shader 37 | out vec3 fPosition; 38 | out vec3 fColor; 39 | out vec2 fTexcoord; 40 | 41 | void main (void) 42 | { 43 | // pass data to the fragment shader 44 | vec4 pos = viewmat * vec4 (0.2 * particlePosition + 0.2 * vec3 (-64, 1, -64), 1.0); 45 | pos.xy += vPosition * 0.1; 46 | fPosition = pos.xyz; 47 | fTexcoord = vPosition; 48 | if (highlight == 0) 49 | fColor = vec3 (0.25, 0, 1); 50 | else if (highlight == 1) 51 | fColor = vec3 (1, 0, 0); 52 | else 53 | fColor = vec3 (0, 1, 0); 54 | // compute and output the vertex position 55 | // after view transformation and projection 56 | pos = projmat * pos; 57 | gl_Position = pos; 58 | } 59 | -------------------------------------------------------------------------------- /shaders/radixsort/addblocksum.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | // header is included here 23 | 24 | layout (local_size_x = BLOCKSIZE) in; 25 | 26 | layout (std430, binding = 0) buffer Data 27 | { 28 | uint data[]; 29 | }; 30 | 31 | layout (std430, binding = 1) readonly buffer BlockSums 32 | { 33 | uint blocksums[]; 34 | }; 35 | 36 | void main (void) 37 | { 38 | data[gl_GlobalInvocationID.x] += blocksums[gl_WorkGroupID.x]; 39 | } 40 | -------------------------------------------------------------------------------- /shaders/radixsort/blockscan.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | // header is included here 23 | 24 | layout (local_size_x = HALFBLOCKSIZE) in; 25 | 26 | layout (std430, binding = 0) buffer Data 27 | { 28 | uint data[]; 29 | }; 30 | 31 | layout (std430, binding = 1) writeonly buffer BlockSums 32 | { 33 | uint blocksums[]; 34 | }; 35 | 36 | #define NUM_BANKS 32 37 | #define LOG_NUM_BANKS 5 38 | #define CONFLICT_FREE_OFFSET(n) ((n) >> LOG_NUM_BANKS) 39 | 40 | shared uint temp[BLOCKSIZE + CONFLICT_FREE_OFFSET(BLOCKSIZE)]; 41 | 42 | const int n = BLOCKSIZE; 43 | 44 | void main (void) 45 | { 46 | int gid = int (gl_GlobalInvocationID.x); 47 | int lid = int (gl_LocalInvocationIndex); 48 | int offset = 1; 49 | 50 | int ai = lid; 51 | int bi = lid + (n/2); 52 | 53 | int bankOffsetA = CONFLICT_FREE_OFFSET(ai); 54 | int bankOffsetB = CONFLICT_FREE_OFFSET(bi); 55 | 56 | temp[ai + bankOffsetA] = data[gl_WorkGroupID.x * BLOCKSIZE + lid]; 57 | temp[bi + bankOffsetB] = data[gl_WorkGroupID.x * BLOCKSIZE + lid + (n/2)]; 58 | 59 | for (int d = n >> 1; d > 0; d >>= 1) 60 | { 61 | barrier (); 62 | memoryBarrierShared (); 63 | 64 | if (lid < d) 65 | { 66 | int ai = offset * (2 * lid + 1) - 1; 67 | int bi = offset * (2 * lid + 2) - 1; 68 | ai += CONFLICT_FREE_OFFSET(ai); 69 | bi += CONFLICT_FREE_OFFSET(bi); 70 | 71 | temp[bi] += temp[ai]; 72 | } 73 | offset *= 2; 74 | } 75 | 76 | if (lid == 0) 77 | { 78 | blocksums[gl_WorkGroupID.x] = temp[n - 1 + CONFLICT_FREE_OFFSET(n-1)]; 79 | temp[n - 1 + CONFLICT_FREE_OFFSET(n-1)] = 0; 80 | } 81 | 82 | for (int d = 1; d < n; d *= 2) 83 | { 84 | offset >>= 1; 85 | barrier (); 86 | memoryBarrierShared (); 87 | 88 | if (lid < d) 89 | { 90 | int ai = offset * (2 * lid + 1) - 1; 91 | int bi = offset * (2 * lid + 2) - 1; 92 | ai += CONFLICT_FREE_OFFSET(ai); 93 | bi += CONFLICT_FREE_OFFSET(bi); 94 | 95 | uint t = temp[ai]; 96 | temp[ai] = temp[bi]; 97 | temp[bi] += t; 98 | } 99 | } 100 | 101 | barrier (); 102 | memoryBarrierShared (); 103 | 104 | data[gl_WorkGroupID.x * BLOCKSIZE + lid] = temp[ai + bankOffsetA]; 105 | data[gl_WorkGroupID.x * BLOCKSIZE + lid + (n/2)] = temp[bi + bankOffsetB]; 106 | } 107 | -------------------------------------------------------------------------------- /shaders/radixsort/counting.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | // header is included here 23 | 24 | layout (local_size_x = HALFBLOCKSIZE) in; 25 | 26 | layout (std430, binding = 0) buffer Data 27 | { 28 | vec4 data[]; 29 | }; 30 | 31 | layout (std430, binding = 1) writeonly buffer PrefixSum 32 | { 33 | uint prefixsum[]; 34 | }; 35 | 36 | layout (std430, binding = 2) writeonly buffer BlockSum 37 | { 38 | uint blocksum[]; 39 | }; 40 | 41 | uniform uvec4 blocksumoffsets; 42 | 43 | #define NUM_BANKS 32 44 | #define LOG_NUM_BANKS 5 45 | #define CONFLICT_FREE_OFFSET(n) ((n) >> LOG_NUM_BANKS) 46 | 47 | shared uvec4 mask[BLOCKSIZE + CONFLICT_FREE_OFFSET(BLOCKSIZE)]; 48 | 49 | const int n = BLOCKSIZE; 50 | 51 | uniform int bitshift; 52 | 53 | uint GetHash (in vec3 pos) 54 | { 55 | ivec3 grid = ivec3 (clamp (pos.xyz, vec3 (0, 0, 0), GRID_SIZE)); 56 | return uint (dot (grid, GRID_HASHWEIGHTS)); 57 | } 58 | 59 | void main (void) 60 | { 61 | const int gid = int (gl_GlobalInvocationID.x); 62 | const int lid = int (gl_LocalInvocationIndex); 63 | 64 | int ai = lid; 65 | int bi = lid + (n/2); 66 | 67 | int bankOffsetA = CONFLICT_FREE_OFFSET(ai); 68 | int bankOffsetB = CONFLICT_FREE_OFFSET(bi); 69 | 70 | uint bits1 = bitfieldExtract (GetHash (data[gl_WorkGroupID.x * BLOCKSIZE + lid].xyz), bitshift, 2); 71 | uint bits2 = bitfieldExtract (GetHash (data[gl_WorkGroupID.x * BLOCKSIZE + lid + (n/2)].xyz), bitshift, 2); 72 | mask[ai + bankOffsetA] = uvec4 (equal (bits1 * uvec4 (1, 1, 1, 1), uvec4 (0, 1, 2, 3))); 73 | mask[bi + bankOffsetB] = uvec4 (equal (bits2 * uvec4 (1, 1, 1, 1), uvec4 (0, 1, 2, 3))); 74 | 75 | int offset = 1; 76 | for (int d = n >> 1; d > 0; d >>= 1) 77 | { 78 | barrier (); 79 | memoryBarrierShared (); 80 | 81 | if (lid < d) 82 | { 83 | int ai = offset * (2 * lid + 1) - 1; 84 | int bi = offset * (2 * lid + 2) - 1; 85 | ai += CONFLICT_FREE_OFFSET(ai); 86 | bi += CONFLICT_FREE_OFFSET(bi); 87 | 88 | mask[bi] += mask[ai]; 89 | } 90 | offset *= 2; 91 | } 92 | 93 | barrier (); 94 | memoryBarrierShared (); 95 | 96 | if (lid == 0) 97 | { 98 | for (int i = 0; i < 4; i++) 99 | { 100 | blocksum[blocksumoffsets[i] + gl_WorkGroupID.x] = uvec4 (mask[n - 1 + CONFLICT_FREE_OFFSET(n - 1)])[i]; 101 | } 102 | 103 | mask[n - 1 + CONFLICT_FREE_OFFSET(n - 1)] = uvec4 (0, 0, 0, 0); 104 | } 105 | 106 | 107 | for (int d = 1; d < n; d *= 2) 108 | { 109 | offset >>= 1; 110 | barrier (); 111 | memoryBarrierShared (); 112 | 113 | if (lid < d) 114 | { 115 | int ai = offset * (2 * lid + 1) - 1; 116 | int bi = offset * (2 * lid + 2) - 1; 117 | ai += CONFLICT_FREE_OFFSET(ai); 118 | bi += CONFLICT_FREE_OFFSET(bi); 119 | 120 | uvec4 tmp = mask[ai]; 121 | mask[ai] = mask[bi]; 122 | mask[bi] += tmp; 123 | } 124 | } 125 | 126 | barrier (); 127 | memoryBarrierShared (); 128 | 129 | prefixsum[gl_WorkGroupID.x * BLOCKSIZE + lid] = uvec4 (mask[ai + bankOffsetA])[bits1]; 130 | prefixsum[gl_WorkGroupID.x * BLOCKSIZE + lid + (n/2)] = uvec4 (mask[bi + bankOffsetB])[bits2]; 131 | } 132 | -------------------------------------------------------------------------------- /shaders/radixsort/globalsort.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | // header is included here 23 | 24 | layout (local_size_x = BLOCKSIZE) in; 25 | 26 | layout (std430, binding = 0) readonly buffer Data 27 | { 28 | vec4 data[]; 29 | }; 30 | 31 | layout (std430, binding = 1) readonly buffer PrefixSum 32 | { 33 | uint prefixsum[]; 34 | }; 35 | 36 | layout (std430, binding = 2) readonly buffer BlockSum 37 | { 38 | uint blocksum[]; 39 | }; 40 | 41 | layout (std430, binding = 3) writeonly buffer Result 42 | { 43 | vec4 result[]; 44 | }; 45 | 46 | uniform uvec4 blocksumoffsets; 47 | 48 | uniform int bitshift; 49 | 50 | uint GetHash (int id) 51 | { 52 | vec3 pos = data[id].xyz; 53 | ivec3 grid = ivec3 (clamp (pos, vec3 (0, 0, 0), GRID_SIZE)); 54 | return uint (dot (grid, GRID_HASHWEIGHTS)); 55 | } 56 | 57 | void main (void) 58 | { 59 | const int gid = int (gl_GlobalInvocationID.x); 60 | const int lid = int (gl_LocalInvocationIndex); 61 | 62 | uint bits = bitfieldExtract (GetHash (gid), bitshift, 2); 63 | 64 | result[blocksum[blocksumoffsets[bits] + gl_WorkGroupID.x] + prefixsum[gid]] = data[gid]; 65 | } 66 | -------------------------------------------------------------------------------- /shaders/selection/fragment.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // input from vertex shader 25 | flat in int particleid; 26 | in vec2 fTexcoord; 27 | in vec3 fPosition; 28 | layout (location = 0) out int outputid; 29 | 30 | // projection and view matrix 31 | layout (binding = 0, std140) uniform TransformationBlock { 32 | mat4 viewmat; 33 | mat4 projmat; 34 | }; 35 | 36 | void main (void) 37 | { 38 | float r = dot (fTexcoord, fTexcoord); 39 | if (r > 1.0) 40 | { 41 | discard; 42 | return; 43 | } 44 | 45 | vec3 normal = vec3 (fTexcoord, -sqrt (1 - r)); 46 | 47 | vec4 fPos = vec4 (fPosition - 0.1 * normal, 1.0); 48 | vec4 clipPos = projmat * fPos; 49 | gl_FragDepth = clipPos.z / clipPos.w; 50 | 51 | outputid = particleid; 52 | } 53 | -------------------------------------------------------------------------------- /shaders/selection/vertex.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // input vertex attributes 25 | layout (location = 0) in vec2 vPosition; 26 | layout (location = 1) in vec3 particlePosition; 27 | 28 | // projection and view matrix 29 | layout (binding = 0, std140) uniform TransformationBlock { 30 | mat4 viewmat; 31 | mat4 projmat; 32 | }; 33 | 34 | // output to the fragment shader 35 | flat out int particleid; 36 | out vec3 fPosition; 37 | out vec2 fTexcoord; 38 | 39 | void main (void) 40 | { 41 | // pass data to the fragment shader 42 | vec4 pos = viewmat * vec4 (0.2 * particlePosition + 0.2 * vec3 (-64, 1, -64), 1.0); 43 | pos.xy += vPosition * 0.1; 44 | fPosition = pos.xyz; 45 | particleid = int (gl_InstanceID); 46 | fTexcoord = vPosition * 0.5 + 0.5; 47 | // compute and output the vertex position 48 | // after view transformation and projection 49 | gl_Position = projmat * pos; 50 | } 51 | -------------------------------------------------------------------------------- /shaders/skybox/fragment.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // output color 25 | layout (location = 0) out vec4 color; 26 | 27 | // texture 28 | layout (binding = 0) uniform samplerCube tex; 29 | 30 | // input from vertex shader 31 | in vec3 fTexcoord; 32 | 33 | void main (void) 34 | { 35 | // fetch texture value and output resulting color 36 | color = texture (tex, fTexcoord); 37 | } 38 | -------------------------------------------------------------------------------- /shaders/skybox/vertex.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // input vertex attributes 25 | layout (location = 0) in vec3 vPosition; 26 | 27 | // projection and view matrix 28 | layout (binding = 0, std140) uniform TransformationBlock { 29 | mat4 viewmat; 30 | mat4 projmat; 31 | }; 32 | 33 | // output to the fragment shader 34 | out vec3 fTexcoord; 35 | 36 | void main (void) 37 | { 38 | // pass data to the fragment shader 39 | fTexcoord = vPosition; 40 | // compute and output the vertex position 41 | // after view transformation and projection 42 | gl_Position = projmat * vec4 (100 * mat3 (viewmat) * vPosition, 1); 43 | } 44 | -------------------------------------------------------------------------------- /shaders/sph/calclambda.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | // header is included here 23 | 24 | layout (local_size_x = BLOCKSIZE) in; 25 | 26 | struct ParticleKey { 27 | vec3 pos; 28 | int id; 29 | }; 30 | 31 | layout (std430, binding = 1) readonly buffer ParticleKeys 32 | { 33 | ParticleKey particlekeys[]; 34 | }; 35 | 36 | 37 | layout (binding = 2) uniform isamplerBuffer neighbourcelltexture; 38 | layout (binding = 0, r32f) uniform writeonly imageBuffer lambdatexture; 39 | 40 | 41 | float Wpoly6 (float r) 42 | { 43 | if (r > h) 44 | return 0; 45 | float tmp = h * h - r * r; 46 | return 1.56668147106 * tmp * tmp * tmp / (h*h*h*h*h*h*h*h*h); 47 | } 48 | 49 | float Wspiky (float r) 50 | { 51 | if (r > h) 52 | return 0; 53 | float tmp = h - r; 54 | return 4.774648292756860 * tmp * tmp * tmp / (h*h*h*h*h*h); 55 | } 56 | 57 | vec3 gradWspiky (vec3 r) 58 | { 59 | float l = length (r); 60 | if (l > h || l == 0) 61 | return vec3 (0, 0, 0); 62 | float tmp = h - l; 63 | return (-3 * 4.774648292756860 * tmp * tmp) * r / (l * h*h*h*h*h*h); 64 | } 65 | 66 | void main (void) 67 | { 68 | vec3 position = particlekeys[gl_GlobalInvocationID.x].pos; 69 | 70 | float sum_k_grad_Ci = 0; 71 | float rho = 0; 72 | 73 | vec3 grad_pi_Ci = vec3 (0, 0, 0); 74 | 75 | FOR_EACH_NEIGHBOUR(j) 76 | { 77 | vec3 position_j = particlekeys[j].pos; 78 | 79 | // compute rho_i (equation 2) 80 | float len = distance (position, position_j); 81 | float tmp = Wpoly6 (len); 82 | rho += tmp; 83 | 84 | // sum gradients of Ci (equation 8 and parts of equation 9) 85 | // use j as k so that we can stay in the same loop 86 | vec3 grad_pk_Ci = vec3 (0, 0, 0); 87 | grad_pk_Ci = gradWspiky (position - position_j); 88 | grad_pk_Ci *= one_over_rho_0; 89 | sum_k_grad_Ci += dot (grad_pk_Ci, grad_pk_Ci); 90 | 91 | // now use j as j again and accumulate grad_pi_Ci for the case k=i 92 | // from equation 8 93 | grad_pi_Ci += grad_pk_Ci; // = gradWspiky (particle.position - particles[j].position); 94 | } 95 | END_FOR_EACH_NEIGHBOUR(j) 96 | // add grad_pi_Ci to the sum 97 | sum_k_grad_Ci += dot (grad_pi_Ci, grad_pi_Ci); 98 | 99 | // compute lambda_i (equations 1 and 9) 100 | float C_i = rho * one_over_rho_0 - 1; 101 | float lambda = -C_i / (sum_k_grad_Ci + epsilon); 102 | imageStore (lambdatexture, int (gl_GlobalInvocationID.x), vec4 (lambda, 0, 0, 0)); 103 | } 104 | -------------------------------------------------------------------------------- /shaders/sph/clearhighlight.glsl: -------------------------------------------------------------------------------- 1 | layout (local_size_x = BLOCKSIZE) in; 2 | 3 | layout (binding = 0, r32ui) uniform uimageBuffer highlighttexture; 4 | 5 | void main (void) 6 | { 7 | imageAtomicAnd (highlighttexture, int (gl_GlobalInvocationID.x), uint (1)); 8 | } 9 | -------------------------------------------------------------------------------- /shaders/sph/foreachneighbour.glsl: -------------------------------------------------------------------------------- 1 | #define FOR_EACH_NEIGHBOUR(var) for (int o = 0; o < 3; o++) {\ 2 | ivec3 datav = texelFetch (neighbourcelltexture, int (gl_GlobalInvocationID.x * 3 + o)).xyz;\ 3 | for (int comp = 0; comp < 3; comp++) {\ 4 | int data = datav[comp];\ 5 | int entries = data >> 24;\ 6 | data = data & 0xFFFFFF;\ 7 | /*if (data == 0) continue;*/\ 8 | for (int var = data; var < data + entries; var++) {\ 9 | if (var != gl_GlobalInvocationID.x) { 10 | #define END_FOR_EACH_NEIGHBOUR(var) }}}} 11 | -------------------------------------------------------------------------------- /shaders/sph/highlight.glsl: -------------------------------------------------------------------------------- 1 | layout (local_size_x = BLOCKSIZE) in; 2 | 3 | struct ParticleKey { 4 | vec3 pos; 5 | int id; 6 | }; 7 | 8 | layout (std430, binding = 1) readonly buffer ParticleKeys 9 | { 10 | ParticleKey particlekeys[]; 11 | }; 12 | 13 | layout (binding = 2) uniform isamplerBuffer neighbourcelltexture; 14 | layout (binding = 0, r32ui) uniform uimageBuffer highlighttexture; 15 | 16 | void main (void) 17 | { 18 | int id = particlekeys[gl_GlobalInvocationID.x].id; 19 | 20 | uint flag = imageLoad (highlighttexture, id).x; 21 | 22 | if ((flag & 1) == 1) 23 | { 24 | FOR_EACH_NEIGHBOUR(j) 25 | { 26 | imageAtomicOr (highlighttexture, particlekeys[j].id, uint(2)); 27 | } 28 | END_FOR_EACH_NEIGHBOUR(j) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /shaders/sph/predictpos.glsl: -------------------------------------------------------------------------------- 1 | layout (local_size_x = BLOCKSIZE) in; 2 | 3 | struct ParticleKey { 4 | vec3 pos; 5 | int id; 6 | }; 7 | 8 | layout (std430, binding = 1) writeonly buffer ParticleKeys 9 | { 10 | ParticleKey particlekeys[]; 11 | }; 12 | 13 | layout (location = 0) uniform bool extforce; 14 | 15 | layout (binding = 0) uniform samplerBuffer positiontexture; 16 | layout (binding = 1) uniform samplerBuffer velocitytexture; 17 | 18 | void main (void) 19 | { 20 | ParticleKey key; 21 | key.id = int (gl_GlobalInvocationID.x); 22 | 23 | key.pos = texelFetch (positiontexture, key.id).xyz; 24 | vec3 velocity = texelFetch (velocitytexture, key.id).xyz; 25 | 26 | // optionally apply an additional external force to some particles 27 | if (extforce && key.pos.z > GRID_SIZE.z/2) 28 | velocity += 2 * gravity * vec3 (0, 0, -1) * timestep; 29 | 30 | // gravity 31 | //velocity += gravity * vec3 (n.x * 0.05, -1, n.y*0.05) * timestep; 32 | velocity += gravity * vec3 (0, -1, 0) * timestep; 33 | 34 | key.pos += timestep * velocity; 35 | 36 | // predict new position 37 | particlekeys[key.id] = key; 38 | } 39 | -------------------------------------------------------------------------------- /shaders/sph/update.glsl: -------------------------------------------------------------------------------- 1 | layout (local_size_x = BLOCKSIZE) in; 2 | 3 | struct ParticleKey { 4 | vec3 pos; 5 | int id; 6 | }; 7 | 8 | layout (std430, binding = 1) readonly buffer ParticleKeys 9 | { 10 | ParticleKey particlekeys[]; 11 | }; 12 | 13 | layout (binding = 0, rgba32f) uniform imageBuffer positiontexture; 14 | layout (binding = 1, rgba32f) uniform imageBuffer velocitytexture; 15 | 16 | void main (void) 17 | { 18 | ParticleKey key = particlekeys[gl_GlobalInvocationID.x]; 19 | 20 | vec3 oldposition = imageLoad (positiontexture, key.id).xyz; 21 | 22 | // calculate velocity 23 | vec3 velocity = (key.pos - oldposition) / timestep; 24 | 25 | // update position and velocity 26 | imageStore (positiontexture, key.id, vec4 (key.pos, 0)); 27 | imageStore (velocitytexture, key.id, vec4 (velocity, 0)); 28 | } 29 | -------------------------------------------------------------------------------- /shaders/sph/updatepos.glsl: -------------------------------------------------------------------------------- 1 | layout (local_size_x = BLOCKSIZE) in; 2 | 3 | struct ParticleKey { 4 | vec3 pos; 5 | int id; 6 | }; 7 | 8 | layout (std430, binding = 1) buffer ParticleKeys 9 | { 10 | ParticleKey particlekeys[]; 11 | }; 12 | 13 | layout (binding = 2) uniform isamplerBuffer neighbourcelltexture; 14 | layout (binding = 3) uniform samplerBuffer lambdatexture; 15 | layout (binding = 4) uniform sampler3D collisiontexture; 16 | 17 | float Wpoly6 (float r) 18 | { 19 | if (r > h) 20 | return 0; 21 | float tmp = h * h - r * r; 22 | return 1.56668147106 * tmp * tmp * tmp / (h*h*h*h*h*h*h*h*h); 23 | } 24 | 25 | float Wspiky (float r) 26 | { 27 | if (r > h) 28 | return 0; 29 | float tmp = h - r; 30 | return 4.774648292756860 * tmp * tmp * tmp / (h*h*h*h*h*h); 31 | } 32 | 33 | vec3 gradWspiky (vec3 r) 34 | { 35 | float l = length (r); 36 | if (l > h || l == 0) 37 | return vec3 (0, 0, 0); 38 | float tmp = h - l; 39 | return (-3 * 4.774648292756860 * tmp * tmp) * r / (l * h*h*h*h*h*h); 40 | } 41 | 42 | void main (void) 43 | { 44 | vec3 position = particlekeys[gl_GlobalInvocationID.x].pos; 45 | 46 | vec3 deltap = vec3 (0, 0, 0); 47 | 48 | //float lambda = lambdas[gl_GlobalInvocationID.x]; 49 | float lambda = texelFetch (lambdatexture, int (gl_GlobalInvocationID.x)).x; 50 | 51 | FOR_EACH_NEIGHBOUR(j) 52 | { 53 | // This might fetch an already updated position, 54 | // but that doesn't cause any harm. 55 | vec3 position_j = particlekeys[j].pos; 56 | 57 | float scorr = tensile_instability_scale * Wpoly6 (distance (position, position_j)); 58 | scorr *= scorr; 59 | scorr *= scorr; 60 | scorr = -tensile_instability_k * scorr; 61 | 62 | float lambda_j = texelFetch (lambdatexture, j).x; 63 | 64 | // accumulate position corrections (part of equation 12) 65 | deltap += (lambda + lambda_j + scorr) * gradWspiky (position - position_j); 66 | } 67 | END_FOR_EACH_NEIGHBOUR(j) 68 | 69 | /*deltap *= one_over_rho_0; 70 | 71 | float dist = length (deltap); 72 | int num_taps = int (floor (dist)) +1; 73 | float step = 1.0f / float (num_taps); 74 | 75 | for (int i = 0; i < num_taps; i++) { 76 | position += step * deltap; 77 | vec4 constraint = texture (collisiontexture, position / GRID_SIZE); 78 | //vec4 constraint = texelFetch (collisiontexture, ivec3 (position), 0); 79 | float epsilon = dot (position.xyz, constraint.xyz) - constraint.w; 80 | if (epsilon < 0) { 81 | position -= 2*epsilon * constraint.xyz; 82 | break; 83 | } 84 | }*/ 85 | position += one_over_rho_0 * deltap; 86 | 87 | 88 | /* // collision detection begin 89 | vec3 wall = vec3 (1, 1, 1); 90 | 91 | vec3 walldist = position - wall; 92 | 93 | position = wall + walldist * (vec3 (greaterThan (walldist, vec3 (0, 0, 0))) * 1.75 - 0.75); 94 | 95 | walldist = (GRID_SIZE - wall) - position; 96 | position = (GRID_SIZE - wall) - walldist * (vec3 (greaterThan (walldist, vec3 (0, 0, 0))) * 1.75 - 0.75);*/ 97 | 98 | vec3 wall = vec3 (16, 0, 16 ); 99 | 100 | position = clamp (position, vec3 (0, 0, 0) + wall, GRID_SIZE - wall); 101 | /*position = clamp (position, vec3 (-16, 0, -16), vec3 (16, 16, 16));*/ 102 | // collision detection end 103 | 104 | particlekeys[gl_GlobalInvocationID.x].pos = position; 105 | } 106 | -------------------------------------------------------------------------------- /shaders/sph/vorticity.glsl: -------------------------------------------------------------------------------- 1 | layout (local_size_x = BLOCKSIZE) in; 2 | 3 | layout (std430, binding = 1) buffer ParticleKeys 4 | { 5 | vec4 particlekeys[]; 6 | }; 7 | 8 | layout (std430, binding = 3) coherent buffer VorticityBuffer 9 | { 10 | float vorticities[]; 11 | }; 12 | 13 | layout (binding = 2) uniform isamplerBuffer neighbourcelltexture; 14 | 15 | layout (binding = 1, rgba32f) uniform imageBuffer velocitytexture; 16 | 17 | float Wpoly6 (float r) 18 | { 19 | if (r > h) 20 | return 0; 21 | float tmp = h * h - r * r; 22 | return 1.56668147106 * tmp * tmp * tmp / (h*h*h*h*h*h*h*h*h); 23 | } 24 | 25 | vec3 gradWspiky (vec3 r) 26 | { 27 | float l = length (r); 28 | if (l > h || l == 0) 29 | return vec3 (0, 0, 0); 30 | float tmp = h - l; 31 | return (-3 * 4.774648292756860 * tmp * tmp) * r / (l * h*h*h*h*h*h); 32 | } 33 | 34 | void main (void) 35 | { 36 | vec4 key = particlekeys[gl_GlobalInvocationID.x]; 37 | int particleid = floatBitsToInt (key.w); 38 | vec3 position = key.xyz; 39 | 40 | // fetch velocity 41 | vec3 velocity = imageLoad (velocitytexture, particleid).xyz; 42 | 43 | // calculate vorticity & apply XSPH viscosity 44 | vec3 v = vec3 (0, 0, 0); 45 | vec3 vorticity = vec3 (0, 0, 0); 46 | float rho = 0; 47 | FOR_EACH_NEIGHBOUR(j) 48 | { 49 | vec4 key_j = particlekeys[j]; 50 | vec3 v_ij = imageLoad (velocitytexture, floatBitsToInt (key_j.w)).xyz - velocity; 51 | vec3 p_ij = position - key_j.xyz; 52 | float tmp = Wpoly6 (length (p_ij)); 53 | rho += tmp; 54 | v += v_ij * tmp; 55 | vorticity += cross (v_ij, gradWspiky (p_ij)); 56 | } 57 | END_FOR_EACH_NEIGHBOUR(j) 58 | velocity += xsph_viscosity_c * v; 59 | 60 | vorticities[gl_GlobalInvocationID.x] = length (vorticity); 61 | 62 | barrier (); 63 | memoryBarrier (); 64 | 65 | // vorticity confinement 66 | vec3 gradVorticity = vec3 (0, 0, 0); 67 | FOR_EACH_NEIGHBOUR(j) 68 | { 69 | vec3 p_ij = position - particlekeys[j].xyz; 70 | // There is no real guarantee that vorticities[] contains the correct 71 | // values at this point, but there seem to be no issues in practice. 72 | gradVorticity += vorticities[j] * gradWspiky (p_ij); 73 | } 74 | END_FOR_EACH_NEIGHBOUR(j) 75 | 76 | float l = length (gradVorticity); 77 | if (l > 0) 78 | gradVorticity /= l; 79 | vec3 N = gradVorticity; 80 | 81 | // apply vorticity force 82 | velocity += timestep * vorticity_epsilon * cross (N, vorticity); 83 | 84 | // update particle information 85 | imageStore (velocitytexture, particleid, vec4 (velocity, 0)); 86 | } 87 | -------------------------------------------------------------------------------- /shaders/thickness/fragment.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // input from vertex shader 25 | in vec2 fTexcoord; 26 | in vec3 fPosition; 27 | flat in uint id; 28 | 29 | layout (location = 0) out float thickness; 30 | layout (location = 1) out vec3 noise; 31 | 32 | layout (binding = 0) uniform sampler2D depthtex; 33 | 34 | uniform bool usenoise; 35 | 36 | // projection and view matrix 37 | layout (binding = 0, std140) uniform TransformationBlock { 38 | mat4 viewmat; 39 | mat4 projmat; 40 | }; 41 | 42 | // 43 | // Description : Array and textureless GLSL 2D/3D/4D simplex 44 | // noise functions. 45 | // Author : Ian McEwan, Ashima Arts. 46 | // Maintainer : ijm 47 | // Lastmod : 20110822 (ijm) 48 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 49 | // Distributed under the MIT License. See LICENSE file. 50 | // https://github.com/ashima/webgl-noise 51 | // 52 | vec4 permute(vec4 x) { 53 | return mod (((x*34.0)+1.0)*x, 289.0); 54 | } 55 | 56 | float snoise(vec3 v) 57 | { 58 | // First corner 59 | vec3 i = floor(v + dot(v, vec3 (1.0/3.0, 1.0/3.0, 1.0/3.0)) ); 60 | vec3 x0 = v - i + dot(i, vec3 (1.0/6.0, 1.0/6.0, 1.0/6.0)) ; 61 | 62 | // Other corners 63 | vec3 g = step(x0.yzx, x0.xyz); 64 | vec3 l = 1.0 - g; 65 | vec3 i1 = min( g.xyz, l.zxy ); 66 | vec3 i2 = max( g.xyz, l.zxy ); 67 | 68 | vec3 x1 = x0 - i1 + 1.0 / 6.0; 69 | vec3 x2 = x0 - i2 + 1.0 / 3.0; 70 | vec3 x3 = x0 - 0.5; 71 | 72 | // Permutations 73 | i = mod (i, 289.0); 74 | vec4 p = permute( permute( permute( 75 | i.z + vec4(0.0, i1.z, i2.z, 1.0 )) 76 | + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) 77 | + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); 78 | 79 | // Gradients: 7x7 points over a square, mapped onto an octahedron. 80 | // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) 81 | 82 | vec4 j = mod (p, 49); 83 | 84 | vec4 x_ = floor(j / 7); 85 | vec4 y_ = mod (j, 7); 86 | 87 | vec4 x = x_ * 2.0 / 7.0 - 13.0 / 14.0; 88 | vec4 y = y_ * 2.0 / 7.0 - 13.0 / 14.0; 89 | vec4 h = 1.0 - abs(x) - abs(y); 90 | 91 | vec4 b0 = vec4( x.xy, y.xy ); 92 | vec4 b1 = vec4( x.zw, y.zw ); 93 | 94 | vec4 s0 = vec4(lessThan(b0,vec4 (0.0, 0.0, 0.0, 0.0)))*2.0 - 1.0; 95 | vec4 s1 = vec4(lessThan(b1,vec4 (0.0, 0.0, 0.0, 0.0)))*2.0 - 1.0; 96 | 97 | vec4 a0 = (b0 + s0).xzyw; 98 | vec4 a1 = (b1 + s1).xzyw; 99 | 100 | vec3 p0 = normalize(vec3(a0.xy,h.x)); 101 | vec3 p1 = normalize(vec3(a0.zw,h.y)); 102 | vec3 p2 = normalize(vec3(a1.xy,h.z)); 103 | vec3 p3 = normalize(vec3(a1.zw,h.w)); 104 | 105 | // Mix final noise value 106 | vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); 107 | m = m * m; 108 | return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), 109 | dot(p2,x2), dot(p3,x3) ) ); 110 | } 111 | 112 | // linearize a depth value in order to determine a meaningful difference 113 | float linearizeDepth (in float d) 114 | { 115 | const float f = 1000.0f; 116 | const float n = 1.0f; 117 | return (2 * n) / (f + n - d * (f - n)); 118 | } 119 | 120 | void main (void) 121 | { 122 | float r = dot (fTexcoord, fTexcoord); 123 | if (r > 1) 124 | discard; 125 | thickness = 1; 126 | if (usenoise) 127 | { 128 | vec3 normal = vec3 (fTexcoord, -sqrt (1 - r)); 129 | vec4 fPos = vec4 (fPosition - 0.1 * normal, 1.0); 130 | vec4 clipPos = projmat * fPos; 131 | float depth = linearizeDepth (clipPos.z / clipPos.w); 132 | 133 | float dd = depth - linearizeDepth (texture (depthtex, fTexcoord).x); 134 | noise = exp (-r - dd * dd) 135 | * vec3 (snoise (vec3 (fTexcoord + 1, 16.0 * float (id)) * 0.2), 136 | snoise (vec3 (fTexcoord + 3, 16.0 * float (id)) * 0.2), 137 | snoise (vec3 (fTexcoord + 5, 16.0 * float (id)) * 0.2)); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /shaders/thickness/vertex.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | //#version 430 core 23 | 24 | // input vertex attributes 25 | layout (location = 0) in vec2 vPosition; 26 | layout (location = 1) in vec3 particlePosition; 27 | 28 | // projection and view matrix 29 | layout (binding = 0, std140) uniform TransformationBlock { 30 | mat4 viewmat; 31 | mat4 projmat; 32 | }; 33 | 34 | out vec2 fTexcoord; 35 | out vec3 fPosition; 36 | flat out uint id; 37 | 38 | void main (void) 39 | { 40 | 41 | // pass data to the fragment shader 42 | vec4 pos = viewmat * vec4 (0.2 * particlePosition.xyz + 0.2 * vec3 (-64, 1, -64), 1.0) + vec4 (vPosition, 0, 1) * 0.1; 43 | fTexcoord = vPosition; 44 | fPosition = pos.xyz; 45 | id = gl_InstanceID; 46 | // compute and output the vertex position 47 | // after view transformation and projection 48 | gl_Position = projmat * pos; 49 | } 50 | -------------------------------------------------------------------------------- /src/Blur.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "Blur.h" 23 | 24 | Blur::Blur (void) 25 | { 26 | program.CompileShader (GL_FRAGMENT_SHADER, "shaders/blur/fragment.glsl"); 27 | program.CompileShader (GL_VERTEX_SHADER, "shaders/blur/vertex.glsl"); 28 | program.Link (); 29 | 30 | offsetscaleloc = program.GetUniformLocation ("offsetscale"); 31 | } 32 | 33 | Blur::~Blur (void) 34 | { 35 | } 36 | 37 | /** Compute blur weights. 38 | * Computes gaussian blur weights using binomial coefficients. 39 | * \param n n 40 | * \param k k 41 | */ 42 | float ComputeWeight (unsigned long n, unsigned long k) 43 | { 44 | long double tmp; 45 | /* scale down by the sum of all coefficients except the 46 | * two smallest */ 47 | tmp = 1.0 / (powl (2, n) - 2 * (1 + n)); 48 | /* multiply by the binomial coefficient */ 49 | for (int i = 1; i <= k; i++) 50 | { 51 | tmp *= (n - k + i); 52 | tmp /= i; 53 | } 54 | return tmp; 55 | } 56 | 57 | void Blur::ComputeWeights (const GLuint &target, float sigma) 58 | { 59 | GLuint size; 60 | 61 | size = sigma * 6; 62 | size &= ~3; 63 | size++; 64 | std::vector data; 65 | 66 | std::vector weights_data; 67 | 68 | /* computes binomial coefficients */ 69 | for (int i = 0; i < (size+1)/2; i++) 70 | { 71 | weights_data.push_back 72 | (ComputeWeight (size + 3, ((size - 1) / 2) - i + 2)); 73 | } 74 | 75 | /* push first weight and offset */ 76 | data.push_back (weights_data[0]); 77 | data.push_back (0); 78 | 79 | /* compute weights and offsets for linear sampling */ 80 | for (int i = 1; i <= weights_data.size() >> 1; i++) 81 | { 82 | float weight; 83 | /* compute and push combined weight */ 84 | weight = weights_data[i * 2 - 1] + 85 | weights_data[i * 2]; 86 | data.push_back (weight); 87 | /* compute and push combined offset */ 88 | data.push_back (((i * 2 - 1) /* discrete offset */ 89 | * weights_data[i * 2 - 1] /* discrete weight */ 90 | + i * 2 /* discrete offset */ 91 | * weights_data[i * 2]) /* discrete weight */ 92 | / weight); /* scale */ 93 | } 94 | 95 | glBufferData (target, sizeof (float) * data.size (), data.data (), GL_STATIC_DRAW); 96 | } 97 | 98 | void Blur::Apply (const glm::vec2 &offsetscale, const GLuint &weights) 99 | { 100 | glBindBufferBase (GL_SHADER_STORAGE_BUFFER, 0, weights); 101 | program.Use (); 102 | glProgramUniform2f (program.get (), offsetscaleloc, offsetscale.x, offsetscale.y); 103 | FullscreenQuad::Get ().Render (); 104 | } 105 | -------------------------------------------------------------------------------- /src/Blur.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef BLUR_H 23 | #define BLUR_H 24 | 25 | #include "common.h" 26 | #include "ShaderProgram.h" 27 | #include "FullscreenQuad.h" 28 | 29 | /** Blur class. 30 | * This class performs a Gaussian blur on a texture. 31 | */ 32 | class Blur 33 | { 34 | public: 35 | /** Constructor. 36 | */ 37 | Blur (void); 38 | /** Destructor. 39 | */ 40 | ~Blur (void); 41 | 42 | /** Compute weights. 43 | * Computes blur weights for a given sigma and stores them in the 44 | * buffer object currently bound to target. 45 | * \param target target of the buffer object to use 46 | * \param sigma blur sigma 47 | */ 48 | static void ComputeWeights (const GLuint &target, float sigma); 49 | 50 | /** Apply blur. 51 | * Applies the blur to the currently bound texture and renders 52 | * the result as a fullscreen quad (i.e. an appropriate framebuffer 53 | * object must be bound by the caller). 54 | * \param offsetscale Scale factor for the texture fetch offsets. 55 | * For a horizontal blur use (1/inputWidth,0) 56 | * and for a vertical blur use (0,1/inputHeight). 57 | * \param weights Weight buffer for the blur. A weight buffer 58 | * can be generated by ComputeWeights. 59 | */ 60 | void Apply (const glm::vec2 &offsetscale, const GLuint &weights); 61 | private: 62 | /** Shader program. 63 | * Shader program that performs the blur. 64 | */ 65 | ShaderProgram program; 66 | 67 | /** Offset scale uniform location. 68 | * Uniform location of the offset scale uniform variable. 69 | */ 70 | GLuint offsetscaleloc; 71 | }; 72 | 73 | #endif /* BLUR_H */ 74 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package (glfw3 REQUIRED) 2 | find_package (PNG REQUIRED) 3 | find_package (GLM REQUIRED) 4 | find_package (OpenGL REQUIRED) 5 | find_package (Threads REQUIRED) 6 | 7 | include_directories (${GLFW_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/glcorew ${PNG_INCLUDE_DIRS} ${GLM_INCLUDE_DIR}) 8 | 9 | if (WIN32) 10 | set (CMAKE_EXE_LINKER_FLAGS "-static") 11 | endif (WIN32) 12 | 13 | file (GLOB PBF_SOURCES *.cpp) 14 | 15 | add_executable (pbf ${PBF_SOURCES}) 16 | 17 | target_link_libraries (pbf glfw ${PNG_LIBRARIES} ${OPENGL_LIBRARIES} glcorew spdlog Threads::Threads) 18 | add_dependencies(pbf shaders-target textures-target) 19 | -------------------------------------------------------------------------------- /src/Camera.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "Camera.h" 23 | 24 | Camera::Camera (void) : xangle (0.0f), yangle (0.0f) 25 | { 26 | } 27 | 28 | Camera::~Camera (void) 29 | { 30 | } 31 | 32 | const glm::vec3 &Camera::GetPosition (void) const 33 | { 34 | return pos; 35 | } 36 | 37 | glm::mat4 Camera::GetViewMatrix (void) const 38 | { 39 | glm::vec3 dir = rot * glm::vec3 (0, 0, 1); 40 | glm::vec3 up = rot * glm::vec3 (0, 1, 0); 41 | glm::mat4 vmat = glm::lookAt (pos, pos + dir, up); 42 | return vmat; 43 | } 44 | 45 | void Camera::SetPosition (const glm::vec3 &_pos) 46 | { 47 | pos = _pos; 48 | } 49 | 50 | void Camera::Rotate (const float &_xangle, const float &_yangle) 51 | { 52 | xangle += _xangle; 53 | yangle += _yangle; 54 | 55 | rot = glm::rotate (glm::quat (), yangle * float (M_PI / 180.0f), glm::vec3 (0.0f, 1.0f, 0.0f)); 56 | rot = glm::rotate (rot, xangle * float (M_PI / 180.0f), glm::vec3 (1.0f, 0.0f, 0.0f)); 57 | } 58 | 59 | void Camera::Zoom (const float &value) 60 | { 61 | pos += 0.1f * value * (rot * glm::vec3 (0, 0, 1)); 62 | } 63 | 64 | void Camera::MoveX (const float &value) 65 | { 66 | pos += 0.05f * float (value) * (rot * glm::vec3 (1, 0, 0)); 67 | } 68 | 69 | void Camera::MoveY (const float &value) 70 | { 71 | pos += 0.05f * float (value) * (rot * glm::vec3 (0, 1, 0)); 72 | } 73 | -------------------------------------------------------------------------------- /src/Camera.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef CAMERA_H 23 | #define CAMERA_H 24 | 25 | #include "common.h" 26 | 27 | /** Camera class. 28 | * The camera class processes user input in order to create a view matrix for the scene. 29 | */ 30 | class Camera 31 | { 32 | public: 33 | /** Constructor. 34 | */ 35 | Camera (void); 36 | /** Destructor. 37 | */ 38 | ~Camera (void); 39 | 40 | /** Generate a view matrix. 41 | * Generates and returns a view matrix for the current camera position and orientation. 42 | * \returns the generated view matrix 43 | */ 44 | glm::mat4 GetViewMatrix (void) const; 45 | 46 | /** Get the camera position. 47 | * \returns the current position of the camera 48 | */ 49 | const glm::vec3 &GetPosition (void) const; 50 | 51 | /** Rotate the camera. 52 | * Rotates the camera around the specified angles. 53 | * \param xangle rotation around the x axis 54 | * \param yangle rotation around the y axis 55 | */ 56 | void Rotate (const float &xangle, const float &yangle); 57 | /** %Camera zoom. 58 | * Zooms the camera by the specified amount. 59 | * \param value the zoom factor 60 | */ 61 | void Zoom (const float &value); 62 | /** Move the camera in x direction. 63 | * Moves the camera in the direction of the x axis of its current coordinate system. 64 | * \param value distance to move 65 | */ 66 | void MoveX (const float &value); 67 | /** Move the camera in y direction. 68 | * Moves the camera in the direction of the y axis of its current coordinate system. 69 | * \param value distance to move 70 | */ 71 | void MoveY (const float &value); 72 | 73 | /** Set the camera position. 74 | * Specify the camera position. 75 | * \param pos new camera position 76 | */ 77 | void SetPosition (const glm::vec3 &pos); 78 | private: 79 | /** Current position of the camera. 80 | */ 81 | glm::vec3 pos; 82 | /** Current rotation of the camera. 83 | * Stores the current rotation of the camera as a quaternion. 84 | */ 85 | glm::quat rot; 86 | /** Rotation around the x axis. 87 | * Stores the current rotation of the camera around the x axis. 88 | */ 89 | float xangle; 90 | /** Rotation around the y axis. 91 | * Stores the current rotation of the camera around the y axis. 92 | */ 93 | float yangle; 94 | }; 95 | 96 | #endif /* CAMERA_H */ 97 | -------------------------------------------------------------------------------- /src/Font.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "Font.h" 23 | 24 | Font::Font (const std::string &filename) 25 | { 26 | // create and bind a vertex array 27 | glGenVertexArrays (1, &vertexarray); 28 | glBindVertexArray (vertexarray); 29 | 30 | // generate buffer objects 31 | glGenBuffers (2, buffers); 32 | 33 | // store vertices to the vertex buffer 34 | glBindBuffer (GL_ARRAY_BUFFER, vertexbuffer); 35 | const GLushort vertices[] = { 36 | 0, 0, 37 | 1, 0, 38 | 1, 1, 39 | 0, 1 40 | }; 41 | glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW); 42 | // define the vertices as vertex attribute 0 43 | glVertexAttribPointer (0, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, 0); 44 | glEnableVertexAttribArray (0); 45 | 46 | // store the indices to the index buffer 47 | glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexbuffer); 48 | const GLushort indices[] = { 49 | 1, 0, 2, 50 | 2, 0, 3 51 | }; 52 | glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices, GL_STATIC_DRAW); 53 | 54 | // load the texture (only the red channel needs to be stored internally) 55 | texture.Bind (GL_TEXTURE_2D); 56 | Texture::Load (GL_TEXTURE_2D, filename, GL_COMPRESSED_RED); 57 | // generate mipmap and activate trilinear filtering 58 | glGenerateMipmap (GL_TEXTURE_2D); 59 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 60 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 61 | 62 | // compile the shader program 63 | program.CompileShader (GL_VERTEX_SHADER, "shaders/font/vertex.glsl"); 64 | program.CompileShader (GL_FRAGMENT_SHADER, "shaders/font/fragment.glsl"); 65 | program.Link (); 66 | 67 | // get the uniform locations 68 | mat_location = program.GetUniformLocation ("mat"); 69 | charpos_location = program.GetUniformLocation ("charpos"); 70 | pos_location = program.GetUniformLocation ("pos"); 71 | 72 | // specify an orthographic transformation matrix 73 | glm::mat4 mat = glm::ortho (0.0f, 40.0f, 25.0f, 0.0f); 74 | glProgramUniformMatrix4fv (program.get (), mat_location, 1, GL_FALSE, glm::value_ptr (mat)); 75 | } 76 | 77 | Font::~Font (void) 78 | { 79 | // clean up 80 | glDeleteBuffers (2, buffers); 81 | glDeleteVertexArrays (1, &vertexarray); 82 | } 83 | 84 | void Font::PrintStr (const float &x, const float &y, const std::string &text) 85 | { 86 | // bind the shader program, texture, vertex array and index buffer 87 | program.Use (); 88 | texture.Bind (GL_TEXTURE_2D); 89 | glBindVertexArray (vertexarray); 90 | glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexbuffer); 91 | 92 | // enable additive blending 93 | glEnable (GL_BLEND); 94 | glBlendFunc (GL_SRC_ALPHA, GL_ONE); 95 | glBlendEquation (GL_FUNC_ADD); 96 | // disable depth testing 97 | glDisable (GL_DEPTH_TEST); 98 | 99 | // display the string 100 | for (size_t i = 0; i < text.length (); i++) 101 | { 102 | // calculate the position of the character in the font texture and pass it to the shader 103 | char c = text[i]; 104 | if (c < 0x20 || c > 0x7f) 105 | continue; 106 | c -= 0x20; 107 | glUniform2f (charpos_location, float (c & 0xF) / 16.0f, float (c>>4) / 8.0f); 108 | // pass the position at which to display the character to the shader 109 | glUniform2f (pos_location, x + float(i)/2, y); 110 | // draw the "square" 111 | glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); 112 | } 113 | // disable blending 114 | glDisable (GL_BLEND); 115 | // enable depth test 116 | glEnable (GL_DEPTH_TEST); 117 | } 118 | -------------------------------------------------------------------------------- /src/Font.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef FONT_H 23 | #define FONT_H 24 | 25 | #include "common.h" 26 | #include "Texture.h" 27 | #include "ShaderProgram.h" 28 | 29 | /** Font subsystem. 30 | * A simple class for displaying text using a font texture. 31 | */ 32 | class Font 33 | { 34 | public: 35 | /** Constructor. 36 | * \param filename the filename of the font texture to load 37 | */ 38 | Font (const std::string &filename); 39 | /** Destructor. 40 | */ 41 | ~Font (void); 42 | 43 | /** Print string. 44 | * Displays a string at the given position. 45 | * \param x x coordinate at which to display the text 46 | * \param y y coordinate at which to display the text 47 | * \param text text to display 48 | */ 49 | void PrintStr (const float &x, const float &y, const std::string &text); 50 | private: 51 | union { 52 | struct { 53 | /** Vertex buffer. 54 | * OpenGL buffer object storing the vertices of a square. 55 | */ 56 | GLuint vertexbuffer; 57 | /** Index buffer. 58 | * OpenGL buffer object storing the vertex indices. 59 | */ 60 | GLuint indexbuffer; 61 | }; 62 | /** Buffer objects. 63 | * The buffer objects are stored in a union, so that it is possible 64 | * to create/delete all buffer objects with a single OpenGL call. 65 | */ 66 | GLuint buffers[2]; 67 | }; 68 | /** Vertex array object. 69 | * OpenGL vertex array object used to store information about the layout and location 70 | * of the vertex attributes. 71 | */ 72 | GLuint vertexarray; 73 | /** Font texture. 74 | * Texture object to store the font texture. 75 | */ 76 | Texture texture; 77 | /** Matrix uniform location. 78 | * Uniform location of the transformation matrix. 79 | */ 80 | GLuint mat_location; 81 | /** Character position uniform location. 82 | * Uniform location of the character position, i.e. the position 83 | * of the character to be drawn within the font texture. 84 | */ 85 | GLuint charpos_location; 86 | /** Position uniform location. 87 | * Uniform location of the raster position at which a character should 88 | * be drawn. 89 | */ 90 | GLuint pos_location; 91 | /** Shader program. 92 | * Shader program for the shaders used to display the text. 93 | */ 94 | ShaderProgram program; 95 | }; 96 | 97 | #endif /* FONT_H */ 98 | -------------------------------------------------------------------------------- /src/Framing.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "Framing.h" 23 | 24 | Framing::Framing (void) 25 | { 26 | // load shader 27 | program.CompileShader (GL_VERTEX_SHADER, "shaders/framing/vertex.glsl"); 28 | program.CompileShader (GL_FRAGMENT_SHADER, "shaders/framing/fragment.glsl"); 29 | program.Link (); 30 | 31 | // create and bind a vertex array 32 | glGenVertexArrays (1, &vertexarray); 33 | glBindVertexArray (vertexarray); 34 | 35 | // generate buffer objects 36 | glGenBuffers (4, buffers); 37 | 38 | // store vertices to a buffer object 39 | glBindBuffer (GL_ARRAY_BUFFER, vertexbuffer); 40 | const GLfloat vertices[] = { 41 | -100, 0, 100, 42 | 100, 0, 100, 43 | 100, 0, -100, 44 | -100, 0, -100 45 | }; 46 | glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW); 47 | // define the vertices as vertex attribute 0 48 | glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, 0); 49 | glEnableVertexAttribArray (0); 50 | 51 | // store texture coordinates to a buffer object 52 | glBindBuffer (GL_ARRAY_BUFFER, texcoordbuffer); 53 | const GLushort texcoords[] = { 54 | 0, 10, 55 | 10, 10, 56 | 10, 0, 57 | 0, 0 58 | }; 59 | glBufferData (GL_ARRAY_BUFFER, sizeof (texcoords), texcoords, GL_STATIC_DRAW); 60 | // define texture coordinates as vertex attribute 1 61 | glVertexAttribPointer (1, 2, GL_UNSIGNED_SHORT, GL_FALSE, 0, 0); 62 | glEnableVertexAttribArray (1); 63 | 64 | // store normals to a buffer object 65 | glBindBuffer (GL_ARRAY_BUFFER, normalbuffer); 66 | const GLbyte normals[] = { 67 | 0, 127, 0, 0, 68 | 0, 127, 0, 0, 69 | 0, 127, 0, 0, 70 | 0, 127, 0, 0 71 | }; 72 | glBufferData (GL_ARRAY_BUFFER, sizeof (normals), normals, GL_STATIC_DRAW); 73 | // define normals as vertex attribute 2 74 | glVertexAttribPointer (2, 3, GL_BYTE, GL_TRUE, 4, 0); 75 | glEnableVertexAttribArray (2); 76 | 77 | // store indices to a buffer object 78 | glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexbuffer); 79 | const GLushort indices[] = { 80 | 0, 1, 2, 81 | 0, 2, 3 82 | }; 83 | glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices, GL_STATIC_DRAW); 84 | 85 | // load the texture 86 | texture.Bind (GL_TEXTURE_2D); 87 | Texture::Load (GL_TEXTURE_2D, "textures/framing.png", GL_COMPRESSED_RGB); 88 | // generate a mipmap and enable trilinear filtering 89 | glGenerateMipmap (GL_TEXTURE_2D); 90 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 91 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 92 | } 93 | 94 | Framing::~Framing (void) 95 | { 96 | // clean up 97 | glDeleteBuffers (4, buffers); 98 | glDeleteVertexArrays (1, &vertexarray); 99 | } 100 | 101 | void Framing::Render (void) 102 | { 103 | // activate shader program 104 | program.Use (); 105 | // bind texture, vertex array and index buffer 106 | texture.Bind (GL_TEXTURE_2D); 107 | glBindVertexArray (vertexarray); 108 | glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexbuffer); 109 | // render the framing 110 | glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); 111 | } 112 | -------------------------------------------------------------------------------- /src/Framing.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef FRAMING_H 23 | #define FRAMING_H 24 | 25 | #include "common.h" 26 | #include "Texture.h" 27 | #include "ShaderProgram.h" 28 | 29 | /** Scene framing. 30 | * This class renders a framing for the scene. 31 | */ 32 | class Framing 33 | { 34 | public: 35 | /** Constructor. 36 | */ 37 | Framing (void); 38 | /** Destructor. 39 | */ 40 | ~Framing (void); 41 | /** Render. 42 | * Renders the framing. 43 | */ 44 | void Render (void); 45 | private: 46 | /** Shader program. 47 | * Shader program for displaying the surrounding scene. 48 | */ 49 | ShaderProgram program; 50 | 51 | union { 52 | struct { 53 | /** Vertex buffer. 54 | * OpenGL buffer object storing the vertices of the framing. 55 | */ 56 | GLuint vertexbuffer; 57 | /** Normal buffer. 58 | * OpenGL buffer object storing the normals of the framing. 59 | */ 60 | GLuint normalbuffer; 61 | /** Texture coordinate buffer. 62 | * OpenGL buffer object storing the texture coordinates of the framing. 63 | */ 64 | GLuint texcoordbuffer; 65 | /** Index buffer. 66 | * OpenGL buffer object storing the vertex indices. 67 | */ 68 | GLuint indexbuffer; 69 | }; 70 | /** Buffer objects. 71 | * The buffer objects are stored in a union, so that it is possible 72 | * to create/delete all buffer objects with a single OpenGL call. 73 | */ 74 | GLuint buffers[4]; 75 | }; 76 | /** Vertex array object. 77 | * OpenGL vertex array object used to store information about the layout and location 78 | * of the vertex attributes. 79 | */ 80 | GLuint vertexarray; 81 | /** Texture. 82 | * Texture object storing the texture used on the framing. 83 | */ 84 | Texture texture; 85 | }; 86 | 87 | #endif /* FRAMING_H */ 88 | -------------------------------------------------------------------------------- /src/FullscreenQuad.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "FullscreenQuad.h" 23 | 24 | FullscreenQuad *FullscreenQuad::object = NULL; 25 | 26 | const FullscreenQuad &FullscreenQuad::Get (void) 27 | { 28 | if (object == NULL) 29 | object = new FullscreenQuad (); 30 | return *object; 31 | } 32 | 33 | void FullscreenQuad::Release (void) 34 | { 35 | if (object != NULL) 36 | { 37 | delete object; 38 | object = NULL; 39 | } 40 | } 41 | 42 | FullscreenQuad::FullscreenQuad (void) 43 | { 44 | // create and bind a vertex array 45 | glGenVertexArrays (1, &vertexarray); 46 | glBindVertexArray (vertexarray); 47 | 48 | // generate buffer objects 49 | glGenBuffers (2, buffers); 50 | 51 | // store vertices to a buffer object 52 | glBindBuffer (GL_ARRAY_BUFFER, vertexbuffer); 53 | const GLshort vertices[] = { 54 | -32767, 32767, 55 | 32767, 32767, 56 | 32767, -32767, 57 | -32767,-32767 58 | }; 59 | glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW); 60 | // define the vertices as vertex attribute 0 61 | glVertexAttribPointer (0, 2, GL_SHORT, GL_TRUE, 0, 0); 62 | glEnableVertexAttribArray (0); 63 | 64 | // store indices to a buffer object 65 | glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexbuffer); 66 | const GLushort indices[] = { 67 | 2, 1, 0, 68 | 3, 2, 0 69 | }; 70 | glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices, GL_STATIC_DRAW); 71 | } 72 | 73 | FullscreenQuad::~FullscreenQuad (void) 74 | { 75 | // clean up 76 | glDeleteBuffers (2, buffers); 77 | glDeleteVertexArrays (1, &vertexarray); 78 | } 79 | 80 | void FullscreenQuad::Render (void) const 81 | { 82 | // bind vertex array and index buffer 83 | glBindVertexArray (vertexarray); 84 | glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexbuffer); 85 | // render the framing 86 | glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); 87 | } 88 | -------------------------------------------------------------------------------- /src/FullscreenQuad.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef FULLSCREENQUAD_H 23 | #define FULLSCREENQUAD_H 24 | 25 | #include "common.h" 26 | #include "Texture.h" 27 | 28 | /** Fullscreen quad. 29 | * This class renders a full screen quad. 30 | */ 31 | class FullscreenQuad 32 | { 33 | public: 34 | /** Obtain class instance. 35 | * FullscreenQuad is a singleton class, so it can't be constructed, 36 | * but this function is called to obtain a reference to a global object. 37 | * \returns a reference to the global fullscreen quad object 38 | * 39 | */ 40 | static const FullscreenQuad &Get (void); 41 | /** Release global object. 42 | * FullscreenQuad is a singleton class, so there is a global object that 43 | * is created on demand. On application termination this object has to be 44 | * released by calling this function. 45 | */ 46 | static void Release (void); 47 | /** Render. 48 | * Renders the framing. 49 | */ 50 | void Render (void) const; 51 | private: 52 | /** Global object. 53 | * The FullscreenQuad is a singleton class, so there exists only one global instance 54 | * of this class at any time, which is stored in this static variable. 55 | * 56 | */ 57 | static FullscreenQuad *object; 58 | /** Private constructor. 59 | * As FullscreenQuad is a singleton class the constructor is private and only used internally 60 | * to create the global object. 61 | */ 62 | FullscreenQuad (void); 63 | /** Destructor. 64 | * As FullscreenQuad is a singleton class the destructor is private and only used internally 65 | * to release the global object. 66 | */ 67 | ~FullscreenQuad (void); 68 | union { 69 | struct { 70 | /** Vertex buffer. 71 | * OpenGL buffer object storing the vertices of the framing. 72 | */ 73 | GLuint vertexbuffer; 74 | /** Index buffer. 75 | * OpenGL buffer object storing the vertex indices. 76 | */ 77 | GLuint indexbuffer; 78 | }; 79 | /** Buffer objects. 80 | * The buffer objects are stored in a union, so that it is possible 81 | * to create/delete all buffer objects with a single OpenGL call. 82 | */ 83 | GLuint buffers[2]; 84 | }; 85 | /** Vertex array object. 86 | * OpenGL vertex array object used to store information about the layout and location 87 | * of the vertex attributes. 88 | */ 89 | GLuint vertexarray; 90 | }; 91 | 92 | #endif /* FULLSCREENQUAD_H */ 93 | -------------------------------------------------------------------------------- /src/NeighbourCellFinder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "NeighbourCellFinder.h" 23 | 24 | NeighbourCellFinder::NeighbourCellFinder (const GLuint &_numparticles, const glm::ivec3 &_gridsize) 25 | : numparticles (_numparticles), gridsize (_gridsize) 26 | { 27 | std::stringstream stream; 28 | stream << "const vec3 GRID_SIZE = vec3 (" << gridsize.x << ", " << gridsize.y << ", " << gridsize.z << ");" << std::endl 29 | << "const ivec3 GRID_HASHWEIGHTS = ivec3 (1, " << gridsize.x * gridsize.z << ", " << gridsize.x << ");" << std::endl 30 | << "#define BLOCKSIZE 256" << std::endl; 31 | 32 | 33 | findcells.CompileShader (GL_COMPUTE_SHADER, "shaders/neighbourcellfinder/findcells.glsl", stream.str ()); 34 | findcells.Link (); 35 | 36 | neighbourcells.CompileShader (GL_COMPUTE_SHADER, "shaders/neighbourcellfinder/neighbourcells.glsl", stream.str ()); 37 | neighbourcells.Link (); 38 | 39 | // create buffer objects 40 | glGenBuffers (1, buffers); 41 | 42 | // allocate grid clear buffer 43 | // (only needed if GL_ARB_clear_texture is not available) 44 | GLuint tmpbuffer; 45 | if (!GLEXTS.ARB_clear_texture) 46 | { 47 | glGenBuffers (1, &tmpbuffer); 48 | glBindBuffer (GL_PIXEL_UNPACK_BUFFER, tmpbuffer); 49 | glBufferData (GL_PIXEL_UNPACK_BUFFER, sizeof (GLint) * gridsize.x * gridsize.y * gridsize.z, NULL, GL_STATIC_DRAW); 50 | { 51 | GLint v = -1; 52 | glClearBufferData (GL_PIXEL_UNPACK_BUFFER, GL_R32I, GL_RED_INTEGER, GL_INT, &v); 53 | } 54 | gridcleartexture.Bind (GL_TEXTURE_3D); 55 | glTexImage3D (GL_TEXTURE_3D, 0, GL_R32I, gridsize.x, gridsize.y, gridsize.z, 0, GL_RED_INTEGER, GL_INT, NULL); 56 | } 57 | 58 | // allocate grid texture 59 | gridtexture.Bind (GL_TEXTURE_3D); 60 | glTexImage3D (GL_TEXTURE_3D, 0, GL_R32I, gridsize.x, gridsize.y, gridsize.z, 0, GL_RED_INTEGER, GL_INT, NULL); 61 | glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 62 | glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 63 | glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); 64 | glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); 65 | glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); 66 | { 67 | GLint border[] = { -1, -1, -1, -1 }; 68 | glTexParameterIiv (GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, border); 69 | } 70 | 71 | // clear grid texture 72 | if (!GLEXTS.ARB_clear_texture) 73 | { 74 | glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); 75 | glDeleteBuffers (1, &tmpbuffer); 76 | } 77 | else 78 | { 79 | GLint v = -1; 80 | glClearTexImage (gridtexture.get (), 0, GL_RED_INTEGER, GL_INT, &v); 81 | } 82 | 83 | // allocate grid end texture 84 | gridendtexture.Bind (GL_TEXTURE_3D); 85 | glTexImage3D (GL_TEXTURE_3D, 0, GL_R32I, gridsize.x, gridsize.y, gridsize.z, 0, GL_RED_INTEGER, GL_INT, NULL); 86 | glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 87 | glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 88 | glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 89 | glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 90 | glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 91 | 92 | // allocate neighbour cell buffer 93 | glBindBuffer (GL_SHADER_STORAGE_BUFFER, neighbourcellbuffer); 94 | glBufferData (GL_SHADER_STORAGE_BUFFER, sizeof (GLuint) * 12 * numparticles, NULL, GL_DYNAMIC_COPY); 95 | 96 | // create neighbour cell texture 97 | neighbourcelltexture.Bind (GL_TEXTURE_BUFFER); 98 | glTexBuffer (GL_TEXTURE_BUFFER, GL_RGBA32I, neighbourcellbuffer); 99 | 100 | } 101 | 102 | NeighbourCellFinder::~NeighbourCellFinder (void) 103 | { 104 | // cleanup 105 | glDeleteBuffers (1, buffers); 106 | } 107 | 108 | const Texture &NeighbourCellFinder::GetResult (void) const 109 | { 110 | return neighbourcelltexture; 111 | } 112 | 113 | void NeighbourCellFinder::FindNeighbourCells (const GLuint &particlebuffer) 114 | { 115 | // clear grid buffer 116 | if (GLEXTS.ARB_clear_texture) 117 | { 118 | GLint v = -1; 119 | glClearTexImage (gridtexture.get (), 0, GL_RED_INTEGER, GL_INT, &v); 120 | } 121 | else 122 | { 123 | glCopyImageSubData (gridcleartexture.get (), GL_TEXTURE_3D, 0, 0, 0, 0, 124 | gridtexture.get (), GL_TEXTURE_3D, 0, 0, 0, 0, 125 | gridsize.x, gridsize.y, gridsize.z); 126 | } 127 | 128 | glBindBufferBase (GL_SHADER_STORAGE_BUFFER, 0, particlebuffer); 129 | 130 | // find grid cells 131 | glBindImageTexture (0, gridtexture.get (), 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32I); 132 | glBindImageTexture (1, gridendtexture.get (), 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32I); 133 | findcells.Use (); 134 | glDispatchCompute (numparticles >> 8, 1, 1); 135 | glMemoryBarrier (GL_SHADER_STORAGE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 136 | 137 | // grid and flag textures as input 138 | gridtexture.Bind (GL_TEXTURE_3D); 139 | glActiveTexture (GL_TEXTURE1); 140 | gridendtexture.Bind (GL_TEXTURE_3D); 141 | glActiveTexture (GL_TEXTURE0); 142 | 143 | // find neighbour cells for each particle 144 | glBindImageTexture (0, neighbourcelltexture.get (), 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32I); 145 | neighbourcells.Use (); 146 | glDispatchCompute (numparticles >> 8, 1, 1); 147 | glMemoryBarrier (GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 148 | } 149 | -------------------------------------------------------------------------------- /src/NeighbourCellFinder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef NEIGHBOURCELLFINDER_H 23 | #define NEIGHBOURCELLFINDER_H 24 | 25 | #include "common.h" 26 | #include "ShaderProgram.h" 27 | #include "RadixSort.h" 28 | #include "Texture.h" 29 | 30 | /** Neighbour cell finder class. 31 | * This class is responsible for finding the grid cell id of the neighbouring 32 | * particles of each particle. 33 | * 34 | */ 35 | class NeighbourCellFinder 36 | { 37 | public: 38 | /** Constructor. 39 | * \param numparticles number of particles to process 40 | * \param gridsize size of the particle grid 41 | */ 42 | NeighbourCellFinder (const GLuint &numparticles, const glm::ivec3 &gridsize); 43 | /** Destructor. 44 | */ 45 | ~NeighbourCellFinder (void); 46 | 47 | /** Find neighbour cells. 48 | * Finds neighbour cells for the particles in the specified particle buffer. 49 | * \param particlebuffer particle buffer to process 50 | */ 51 | void FindNeighbourCells (const GLuint &particlebuffer); 52 | 53 | /** Get result. 54 | * Returns a buffer texture containing 9 entries for each particle each consisting 55 | * of the neighbour cell id and the number of entries in the cell. 56 | * \returns the buffer texture containing the found neighbour cells 57 | */ 58 | const Texture &GetResult (void) const; 59 | private: 60 | /** Simulation step shader program. 61 | * Shader program for the simulation step that finds grid cells in the 62 | * sorted particle array. 63 | */ 64 | ShaderProgram findcells; 65 | 66 | /** Grid size. 67 | * Size of the particle grid. 68 | */ 69 | const glm::ivec3 gridsize; 70 | 71 | /** Neighbour cell program. 72 | * Shader program for finding neighbouring cells for a particle. 73 | */ 74 | ShaderProgram neighbourcells; 75 | 76 | union { 77 | struct { 78 | /** Neighbour cell buffer. 79 | * Buffer used to store neighbouring cells for each particle. 80 | */ 81 | GLuint neighbourcellbuffer; 82 | 83 | }; 84 | /** Buffer objects. 85 | * The buffer objects are stored in a union, so that it is possible 86 | * to create/delete all buffer objects with a single OpenGL call. 87 | */ 88 | GLuint buffers[1]; 89 | }; 90 | 91 | /** Grid clear texture. 92 | * Texture used to clear the grid texture if GL_ARB_clear_texture is not available. 93 | */ 94 | Texture gridcleartexture; 95 | 96 | /** Grid texture. 97 | * Texture in which the offset of the first particle for each grid is stored. 98 | */ 99 | Texture gridtexture; 100 | 101 | /** Grid end texture. 102 | * Texture in which the offset of the last particle for each grid is stored. 103 | */ 104 | Texture gridendtexture; 105 | 106 | /** Neighbour cell texture. 107 | * Texture through which the neighbour cell buffer is accessed. 108 | */ 109 | Texture neighbourcelltexture; 110 | 111 | /** Number of particles. 112 | * Stores the number of particles in the simulation. 113 | */ 114 | const GLuint numparticles; 115 | }; 116 | 117 | #endif /* NEIGHBOURCELLFINDER_H */ 118 | -------------------------------------------------------------------------------- /src/PointSprite.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "PointSprite.h" 23 | 24 | PointSprite::PointSprite (void) 25 | { 26 | // create and bind a vertex array 27 | glGenVertexArrays (1, &vertexarray); 28 | glBindVertexArray (vertexarray); 29 | 30 | // generate buffer objects 31 | glGenBuffers (2, buffers); 32 | 33 | GLshort vertices[] = { 34 | -32767, 32767, 35 | 32767, 32767, 36 | 32767,-32767, 37 | -32767,-32767 38 | }; 39 | 40 | // store vertices to a buffer object 41 | glBindBuffer (GL_ARRAY_BUFFER, vertexbuffer); 42 | glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW); 43 | // define the vertices as vertex attribute 0 44 | glVertexAttribPointer (0, 2, GL_SHORT, GL_TRUE, 0, 0); 45 | glEnableVertexAttribArray (0); 46 | 47 | const GLushort indices[] = { 48 | 0, 2, 1, 49 | 2, 0, 3 50 | }; 51 | 52 | // store indices to a buffer object 53 | glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexbuffer); 54 | glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices, GL_STATIC_DRAW); 55 | } 56 | 57 | PointSprite::~PointSprite (void) 58 | { 59 | // cleanup 60 | glDeleteBuffers (2, buffers); 61 | glDeleteVertexArrays (1, &vertexarray); 62 | } 63 | 64 | void PointSprite::SetPositionBuffer (GLuint buffer, GLsizei stride, GLintptr offset) 65 | { 66 | // bind the vertex array and the position buffer 67 | glBindVertexArray (vertexarray); 68 | glBindBuffer (GL_ARRAY_BUFFER, buffer); 69 | // define the per-instance vertex attribute 70 | glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, stride, (const GLvoid*) offset); 71 | glEnableVertexAttribArray (1); 72 | glVertexAttribDivisor (1, 1); 73 | } 74 | 75 | void PointSprite::SetHighlightBuffer (GLuint buffer, GLsizei stride, GLintptr offset) 76 | { 77 | // bind the vertex array and the position buffer 78 | glBindVertexArray (vertexarray); 79 | glBindBuffer (GL_ARRAY_BUFFER, buffer); 80 | // define the per-instance vertex attribute 81 | glVertexAttribIPointer (2, 1, GL_UNSIGNED_INT, stride, (const GLvoid*) offset); 82 | glEnableVertexAttribArray (2); 83 | glVertexAttribDivisor (2, 1); 84 | } 85 | 86 | void PointSprite::Render (GLuint instances) const 87 | { 88 | // bind vertex array and index buffer 89 | glBindVertexArray (vertexarray); 90 | glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexbuffer); 91 | // render the framing 92 | glDrawElementsInstanced (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0, instances); 93 | } 94 | -------------------------------------------------------------------------------- /src/PointSprite.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef PONTSPRITE_H 23 | #define PONTSPRITE_H 24 | 25 | #include "common.h" 26 | 27 | /** PointSprite class. 28 | * This class renders point sprites that can be used for rendering particles. 29 | */ 30 | class PointSprite 31 | { 32 | public: 33 | /** Constructor. 34 | */ 35 | PointSprite (void); 36 | /** Destructor 37 | */ 38 | ~PointSprite (void); 39 | 40 | /** Specify a position buffer. 41 | * Specifies a buffer containing the positions for the point sprites. 42 | * \param buffer the buffer object containing the position data 43 | * \param stride number of bytes between consecutive positions or 0 for tightly packed positions 44 | * \param offset byte offset of the position data in the buffer object 45 | */ 46 | void SetPositionBuffer (GLuint buffer, GLsizei stride = 0, GLintptr offset = 0); 47 | 48 | /** Specify a highlight buffer. 49 | * Specifies a buffer containing the highlighting information for the point sprites. 50 | * \param buffer the buffer object containing the highlighting information. 51 | * \param stride number of bytes between consecutive positions or 0 for tightly packed positions 52 | * \param offset byte offset of the position data in the buffer object 53 | */ 54 | void SetHighlightBuffer (GLuint buffer, GLsizei stride = 0, GLintptr offset = 0); 55 | 56 | /** Render the point sprites. 57 | * \param instances number of instances to render. 58 | */ 59 | void Render (GLuint instances) const; 60 | private: 61 | union { 62 | struct { 63 | /** Vertex buffer. 64 | * OpenGL buffer object storing the vertices of the point sprites. 65 | */ 66 | GLuint vertexbuffer; 67 | /** Index buffer. 68 | * OpenGL buffer object storing the vertex indices. 69 | */ 70 | GLuint indexbuffer; 71 | }; 72 | /** Buffer objects. 73 | * The buffer objects are stored in a union, so that it is possible 74 | * to create/delete all buffer objects with a single OpenGL call. 75 | */ 76 | GLuint buffers[2]; 77 | }; 78 | /** Vertex array object. 79 | * OpenGL vertex array object used to store information about the layout and location 80 | * of the vertex attributes. 81 | */ 82 | GLuint vertexarray; 83 | }; 84 | 85 | #endif /* SPHERE_H */ 86 | -------------------------------------------------------------------------------- /src/RadixSort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "RadixSort.h" 23 | 24 | unsigned int count_sortbits (uint64_t v) 25 | { 26 | unsigned int r = 1; 27 | while (v >>= 1) 28 | r++; 29 | return r; 30 | } 31 | 32 | RadixSort::RadixSort (GLuint _blocksize, GLuint _numblocks, const glm::ivec3 &gridsize) 33 | : blocksize (_blocksize), numblocks (_numblocks) 34 | { 35 | std::stringstream stream; 36 | stream << "const vec3 GRID_SIZE = vec3 (" << gridsize.x << ", " << gridsize.y << ", " << gridsize.z << ");" << std::endl 37 | << "const ivec3 GRID_HASHWEIGHTS = ivec3 (1, " << gridsize.x * gridsize.z << ", " << gridsize.x << ");" << std::endl 38 | << "#define BLOCKSIZE " << blocksize << std::endl 39 | << "#define HALFBLOCKSIZE " << (blocksize / 2) << std::endl; 40 | 41 | if (blocksize & 1) 42 | throw std::logic_error ("The block size for sorting has to be even."); 43 | 44 | numbits = count_sortbits (uint64_t (gridsize.x) * uint64_t (gridsize.y) * uint64_t (gridsize.z) - 1); 45 | 46 | // load shaders 47 | counting.CompileShader (GL_COMPUTE_SHADER, "shaders/radixsort/counting.glsl", stream.str ()); 48 | counting.Link (); 49 | blockscan.CompileShader (GL_COMPUTE_SHADER, "shaders/radixsort/blockscan.glsl", stream.str ()); 50 | blockscan.Link (); 51 | globalsort.CompileShader (GL_COMPUTE_SHADER, "shaders/radixsort/globalsort.glsl", stream.str ()); 52 | globalsort.Link (); 53 | addblocksum.CompileShader (GL_COMPUTE_SHADER, "shaders/radixsort/addblocksum.glsl", stream.str ()); 54 | addblocksum.Link (); 55 | 56 | // create buffer objects 57 | glGenBuffers (3, buffers); 58 | 59 | // allocate input buffer 60 | glBindBuffer (GL_SHADER_STORAGE_BUFFER, buffer); 61 | glBufferData (GL_SHADER_STORAGE_BUFFER, sizeof (glm::vec4) * blocksize * numblocks, NULL, GL_DYNAMIC_COPY); 62 | 63 | // allocate prefix sum buffer 64 | glBindBuffer (GL_SHADER_STORAGE_BUFFER, prefixsums); 65 | glBufferData (GL_SHADER_STORAGE_BUFFER, sizeof (uint32_t) * blocksize * numblocks, NULL, GL_DYNAMIC_COPY); 66 | 67 | // create block sum buffers 68 | uint32_t numblocksums = 4 * numblocks; 69 | { 70 | int n = ceil (log (((numblocksums + blocksize - 1) / blocksize) * blocksize) / log (blocksize)); 71 | n++; 72 | blocksums.resize (n); 73 | glGenBuffers (n, &blocksums[0]); 74 | } 75 | for (int i = 0; i < blocksums.size (); i++) 76 | { 77 | GLuint &blocksum = blocksums[i]; 78 | // allocate a single block sum buffer 79 | glBindBuffer (GL_SHADER_STORAGE_BUFFER, blocksum); 80 | numblocksums = ((numblocksums + blocksize - 1) / blocksize) * blocksize; 81 | if (numblocksums < 1) 82 | numblocksums = 1; 83 | glBufferData (GL_SHADER_STORAGE_BUFFER, sizeof (uint32_t) * numblocksums, NULL, GL_DYNAMIC_COPY); 84 | numblocksums /= blocksize; 85 | } 86 | 87 | // allocate output buffer 88 | glBindBuffer (GL_SHADER_STORAGE_BUFFER, result); 89 | glBufferData (GL_SHADER_STORAGE_BUFFER, sizeof (glm::vec4) * blocksize * numblocks, NULL, GL_DYNAMIC_COPY); 90 | 91 | // pass block sum offsets to the shader programs 92 | glm::uvec4 blocksumoffsets (0, numblocks, numblocks * 2, numblocks * 3); 93 | glProgramUniform4uiv (counting.get (), counting.GetUniformLocation ("blocksumoffsets"), 1, 94 | glm::value_ptr (blocksumoffsets)); 95 | glProgramUniform4uiv (globalsort.get (), globalsort.GetUniformLocation ("blocksumoffsets"), 1, 96 | glm::value_ptr (blocksumoffsets)); 97 | 98 | // query uniform locations 99 | counting_bitshift = counting.GetUniformLocation ("bitshift"); 100 | globalsort_bitshift = globalsort.GetUniformLocation ("bitshift"); 101 | 102 | // clear block sum buffers 103 | for (int i = 0; i < blocksums.size (); i++) 104 | { 105 | unsigned int &blocksum = blocksums[i]; 106 | glBindBuffer (GL_SHADER_STORAGE_BUFFER, blocksum); 107 | glClearBufferData (GL_SHADER_STORAGE_BUFFER, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, NULL); 108 | } 109 | } 110 | 111 | RadixSort::~RadixSort (void) 112 | { 113 | // cleanup 114 | glDeleteBuffers (blocksums.size (), &blocksums[0]); 115 | glDeleteBuffers (3, buffers); 116 | } 117 | 118 | GLuint RadixSort::GetBuffer (void) const 119 | { 120 | // return the current input buffer 121 | return buffer; 122 | } 123 | 124 | void RadixSort::Run (void) 125 | { 126 | // sort bits from least to most significant 127 | for (int i = 0; i < (numbits + 1) >> 1; i++) 128 | { 129 | SortBits (2 * i); 130 | // swap the buffer objects 131 | std::swap (result, buffer); 132 | } 133 | } 134 | 135 | /** Integer power. 136 | * Calculates an integer power. 137 | * \param x base 138 | * \param y exponent 139 | * \returns x to the power of y 140 | */ 141 | uint32_t intpow (uint32_t x, uint32_t y) 142 | { 143 | uint32_t r = 1; 144 | while (y) 145 | { 146 | if (y & 1) 147 | r *= x; 148 | y >>= 1; 149 | x *= x; 150 | } 151 | return r; 152 | } 153 | 154 | void RadixSort::SortBits (int bits) 155 | { 156 | // pass current bit shift to the shader programs 157 | glProgramUniform1i (counting.get (), counting_bitshift, bits); 158 | glProgramUniform1i (globalsort.get (), globalsort_bitshift, bits); 159 | 160 | // set buffer bindings 161 | { 162 | GLuint bufs[4] = { buffer, prefixsums, blocksums.front (), result }; 163 | glBindBuffersBase (GL_SHADER_STORAGE_BUFFER, 0, 4, bufs); 164 | } 165 | 166 | // counting 167 | counting.Use (); 168 | glDispatchCompute (numblocks, 1, 1); 169 | glMemoryBarrier (GL_SHADER_STORAGE_BARRIER_BIT); 170 | 171 | // create block sums level by level 172 | blockscan.Use (); 173 | uint32_t numblocksums = (4 * numblocks) / blocksize; 174 | for (int i = 0; i < blocksums.size () - 1; i++) 175 | { 176 | glBindBuffersBase (GL_SHADER_STORAGE_BUFFER, 0, 2, &blocksums[i]); 177 | glDispatchCompute (numblocksums > 0 ? numblocksums : 1, 1, 1); 178 | numblocksums /= blocksize; 179 | glMemoryBarrier (GL_SHADER_STORAGE_BARRIER_BIT); 180 | } 181 | 182 | // add block sums level by level (in reversed order) 183 | addblocksum.Use (); 184 | for (int i = blocksums.size () - 3; i >= 0; i--) 185 | { 186 | uint32_t numblocksums = (4 * numblocks) / intpow (blocksize, i + 1); 187 | glBindBuffersBase (GL_SHADER_STORAGE_BUFFER, 0, 2, &blocksums[i]); 188 | glDispatchCompute (numblocksums > 0 ? numblocksums : 1, 1, 1); 189 | glMemoryBarrier (GL_SHADER_STORAGE_BARRIER_BIT); 190 | } 191 | 192 | // map values to their global position in the output buffer 193 | { 194 | GLuint bufs[2] = { buffer, prefixsums }; 195 | glBindBuffersBase (GL_SHADER_STORAGE_BUFFER, 0, 2, bufs); 196 | } 197 | globalsort.Use (); 198 | glDispatchCompute (numblocks, 1, 1); 199 | glMemoryBarrier (GL_SHADER_STORAGE_BARRIER_BIT); 200 | } 201 | -------------------------------------------------------------------------------- /src/RadixSort.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef RADIXSORT_H 23 | #define RADIXSORT_H 24 | 25 | #include "common.h" 26 | #include "ShaderProgram.h" 27 | 28 | /** Radix sort class. 29 | * This class is responsible for sorting the particle buffer 30 | * with respect to their grid id that is computed from their 31 | * position. 32 | */ 33 | class RadixSort 34 | { 35 | public: 36 | /** Constructor. 37 | * \param blocksize Block size used for sortig the particles. 38 | * \param numblocks Number of blocks of values to sort. 39 | * \param gridsize size of the particle grid 40 | */ 41 | RadixSort (GLuint blocksize, GLuint numblocks, const glm::ivec3 &gridsize); 42 | /** Destuctor. 43 | */ 44 | ~RadixSort (void); 45 | /** Get content buffer. 46 | * Returns the internal buffer object. 47 | * Warning: As two buffer objects are used internally (the data is swapped 48 | * between them while sorting) the returned value is not always the same! 49 | * Note: This function is guaranteed to return the correct buffer object 50 | * that is valid until the next call of Run(...). 51 | * \returns the internal buffer object. 52 | */ 53 | GLuint GetBuffer (void) const; 54 | /** Sort the buffer. 55 | * Sorts the buffer. 56 | */ 57 | void Run (void); 58 | private: 59 | /** Sort bits. 60 | * Sorts the internal buffer with respect to two bits. 61 | * \param bits specifies less significant bit with respect to which to sort 62 | */ 63 | void SortBits (int bits); 64 | 65 | /** Number of relevant bits. 66 | * Number of relevant bits that have to be sorted. 67 | */ 68 | unsigned int numbits; 69 | 70 | /** Counting shader program. 71 | * Shader program used to count the key bits and thereby generate a prefix sum. 72 | */ 73 | ShaderProgram counting; 74 | /** Block scan shader program. 75 | * Shader program used to create a prefix sum of a block of data. 76 | */ 77 | ShaderProgram blockscan; 78 | /** Global sort shader program. 79 | * Shader program used to map the values to their correct global position. 80 | */ 81 | ShaderProgram globalsort; 82 | /** Add block sum shader program. 83 | * Shader program used to add the (separately computed) sum of all preceding blocks 84 | * to some blocks. 85 | */ 86 | ShaderProgram addblocksum; 87 | union { 88 | struct { 89 | /** Source buffer. 90 | * This buffer is used as the input for the next sorting operation. 91 | * During each sorting oparation this value is swapped with result. 92 | */ 93 | GLuint buffer; 94 | /** Prefix sum buffer. 95 | * This buffer stores the prefix sums used to determine the global positions. 96 | */ 97 | GLuint prefixsums; 98 | /** Destination buffer. 99 | * This buffer is used as the output for the next sorting operation. 100 | * During each sorting operation this value is swapped with buffer. 101 | */ 102 | GLuint result; 103 | }; 104 | /** Buffer objects. 105 | * The buffer objects are stored in a union, so that it is possible 106 | * to create/delete all buffer objects with a single OpenGL call. 107 | */ 108 | GLuint buffers[3]; 109 | }; 110 | /** Blocksums array. 111 | * Stores the number of blocks to sum up at each level. 112 | */ 113 | std::vector blocksums; 114 | 115 | /** Block size. 116 | * Stores the size of one block. 117 | */ 118 | const uint32_t blocksize; 119 | /** Number of blocks. 120 | * Stores the number of blocks to be sorted. 121 | */ 122 | const uint32_t numblocks; 123 | /** Bit shift uniform location (counting shader). 124 | * Uniform location for the bit shift variable in the counting shader. 125 | */ 126 | int counting_bitshift; 127 | /** Bit shift uniform location (global sort shader). 128 | * Uniform location for the bit shift variable in the global sort shader. 129 | */ 130 | int globalsort_bitshift; 131 | }; 132 | 133 | #endif /* !defined RADIXSORT_H */ 134 | -------------------------------------------------------------------------------- /src/Selection.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "Selection.h" 23 | 24 | Selection::Selection (void) 25 | { 26 | // load shaders 27 | selectionprogram.CompileShader (GL_VERTEX_SHADER, "shaders/selection/vertex.glsl"); 28 | selectionprogram.CompileShader (GL_FRAGMENT_SHADER, "shaders/selection/fragment.glsl"); 29 | selectionprogram.Link (); 30 | 31 | // create depth texture 32 | depthtexture.Bind (GL_TEXTURE_2D); 33 | glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 34 | 35 | // create selection texture 36 | selectiontexture.Bind (GL_TEXTURE_2D); 37 | glTexImage2D (GL_TEXTURE_2D, 0, GL_R32I, 1, 1, 0, GL_RED_INTEGER, GL_INT, NULL); 38 | 39 | // create framebuffer object 40 | glGenFramebuffers (1, framebuffers); 41 | 42 | // setup framebuffer 43 | glBindFramebuffer (GL_FRAMEBUFFER, selectionfb); 44 | glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthtexture.get (), 0); 45 | glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, selectiontexture.get (), 0); 46 | glBindFramebuffer (GL_FRAMEBUFFER, 0); 47 | } 48 | 49 | Selection::~Selection (void) 50 | { 51 | // cleanup 52 | glDeleteFramebuffers (1, framebuffers); 53 | } 54 | 55 | GLint Selection::GetParticle (GLuint positionbuffer, GLuint numparticles, float xpos, float ypos) 56 | { 57 | // setup viewport according to the specified position 58 | int width, height; 59 | glfwGetFramebufferSize (window, &width, &height); 60 | glBindFramebuffer (GL_FRAMEBUFFER, selectionfb); 61 | { 62 | GLenum buffers[] = { GL_COLOR_ATTACHMENT0 }; 63 | glDrawBuffers (1, buffers); 64 | const GLint v[] = { -1, -1, -1, -1 }; 65 | glClearBufferiv (GL_COLOR, 0, &v[0]); 66 | } 67 | glViewport (-xpos, ypos - height, width, height); 68 | 69 | // pass the position buffer to the point sprite class 70 | pointsprite.SetPositionBuffer (positionbuffer, 4 * sizeof (float), 0); 71 | 72 | // clear depth buffer 73 | glClear (GL_DEPTH_BUFFER_BIT); 74 | 75 | // render the spheres and write the particle id to the texture. 76 | selectionprogram.Use (); 77 | pointsprite.Render (numparticles); 78 | glBindFramebuffer (GL_FRAMEBUFFER, 0); 79 | 80 | // query and return the result 81 | selectiontexture.Bind (GL_TEXTURE_2D); 82 | GLint id; 83 | glGetTexImage (GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_INT, &id); 84 | return id; 85 | } 86 | -------------------------------------------------------------------------------- /src/Selection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef SELECTION_H 23 | #define SELECTION_H 24 | 25 | #include "common.h" 26 | #include "ShaderProgram.h" 27 | #include "Texture.h" 28 | #include "PointSprite.h" 29 | 30 | /** Selection class. 31 | * This class is responsible for determining which particle is located at a given screen position. 32 | */ 33 | class Selection 34 | { 35 | public: 36 | /** Constructor. 37 | */ 38 | Selection (void); 39 | /** Destruction. 40 | */ 41 | ~Selection (void); 42 | 43 | /** Get particle from screen position. 44 | * Determines the particle at the given screen coordinates, if any. 45 | * \param positionbuffer buffer object storing the particle positions 46 | * \param numparticles number of particles in the buffer 47 | * \param x x coordinate 48 | * \param y y coordinate 49 | * \returns the particle id or -1 if there is no particle at the given position 50 | */ 51 | GLint GetParticle (GLuint positionbuffer, GLuint numparticles, float x, float y); 52 | private: 53 | /** Selection shader program. 54 | * Shader program for selecting particles. 55 | */ 56 | ShaderProgram selectionprogram; 57 | 58 | /** Depth texture. 59 | * Texture for the depth buffer of the selection framebuffer. 60 | */ 61 | Texture depthtexture; 62 | 63 | /** Selection texture. 64 | * Texture for the selection framebuffer. 65 | */ 66 | Texture selectiontexture; 67 | 68 | union { 69 | struct { 70 | /** Selection framebuffer. 71 | * Framebuffer object used to determine which object resides at a specific screen 72 | * space position. 73 | */ 74 | GLuint selectionfb; 75 | }; 76 | /** Framebuffer objects. 77 | * The framebuffer objects are stored in a union, so that it is possible 78 | * to create/delete all texture objects with a single OpenGL call. 79 | */ 80 | GLuint framebuffers[1]; 81 | }; 82 | 83 | /** Point sprite object. 84 | * This is used to render point sprites for the particles. 85 | */ 86 | PointSprite pointsprite; 87 | }; 88 | 89 | #endif /* SELECTION_H */ 90 | -------------------------------------------------------------------------------- /src/ShaderProgram.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "ShaderProgram.h" 23 | 24 | ShaderProgram::ShaderProgram(void) : program(glCreateProgram()) { 25 | } 26 | 27 | ShaderProgram::~ShaderProgram(void) { 28 | glDeleteProgram(program); 29 | } 30 | 31 | void ShaderProgram::Link(void) { 32 | // attempt to link the program 33 | glLinkProgram(program); 34 | 35 | // check for errors and throw the error log as exception on failure 36 | GLint status; 37 | glGetProgramiv(program, GL_LINK_STATUS, &status); 38 | if (status == GL_FALSE) { 39 | GLint length; 40 | std::vector log; 41 | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); 42 | log.resize(length); 43 | glGetProgramInfoLog(program, length, NULL, &log[0]); 44 | throw std::runtime_error(std::string("Failed to link shader program: ") + std::string(&log[0], length)); 45 | } 46 | } 47 | 48 | void ShaderProgram::Use(void) const { 49 | glUseProgram(program); 50 | } 51 | 52 | GLint ShaderProgram::GetUniformLocation(const char *name) const { 53 | return glGetUniformLocation(program, name); 54 | } 55 | 56 | void 57 | ShaderProgram::CompileShader(GLenum type, std::initializer_list filenames, const std::string &header) { 58 | GLuint shader; 59 | 60 | std::vector data; 61 | GLint length = 0; 62 | 63 | // prepend #version statement 64 | const char version[] = "#version 430 core\n"; 65 | data.assign(version, version + (sizeof(version) / sizeof(version[0]) - 1)); 66 | 67 | // prepend header 68 | data.insert(data.end(), header.begin(), header.end()); 69 | 70 | // fix line count 71 | const std::string linedef = "\n#line 1\n"; 72 | data.insert(data.end(), linedef.begin(), linedef.end()); 73 | 74 | // load shader source 75 | length = static_cast(data.size()); 76 | for (const auto &filename : filenames) { 77 | size_t len; 78 | std::ifstream f(filename.c_str(), std::ios_base::in); 79 | if (!f.is_open()) 80 | throw std::runtime_error(std::string("Cannot load shader: ") + filename); 81 | 82 | f.seekg(0, std::ios_base::end); 83 | len = static_cast(f.tellg()); 84 | f.seekg(0, std::ios_base::beg); 85 | 86 | data.resize(length + len); 87 | f.read(&data[length], len); 88 | len = static_cast(f.gcount()); 89 | 90 | if (f.bad()) 91 | throw std::runtime_error(std::string("Cannot load shader: ") + filename); 92 | length += len; 93 | } 94 | 95 | // create a shader, specify the source and attempt to compile it 96 | shader = glCreateShader(type); 97 | const GLchar *src = (const GLchar *) &data[0]; 98 | glShaderSource(shader, 1, &src, &length); 99 | glCompileShader(shader); 100 | 101 | // check the compilation status and throw the error log as exception on failure 102 | GLint status; 103 | glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 104 | if (status == GL_FALSE) { 105 | glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); 106 | data.resize(length); 107 | glGetShaderInfoLog(shader, length, NULL, &data[0]); 108 | glDeleteShader(shader); 109 | std::string names; 110 | for (const auto &fname : filenames) { 111 | if (names.size() > 0) { 112 | names += ", "; 113 | } 114 | names += "\"" + fname + "\""; 115 | } 116 | throw std::runtime_error(fmt::format("Cannot compile shader {}: {}", names, std::string(&data[0], length))); 117 | } 118 | 119 | // attach the shader object to the program 120 | glAttachShader(program, shader); 121 | // delete the shader object (it is internally stored as long as the program is not deleted) 122 | glDeleteShader(shader); 123 | } 124 | -------------------------------------------------------------------------------- /src/ShaderProgram.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef SHADERPROGRAM_H 23 | #define SHADERPROGRAM_H 24 | 25 | #include "common.h" 26 | 27 | /** Shader program. 28 | * A class to create and store an OpenGL shader program. 29 | */ 30 | class ShaderProgram { 31 | public: 32 | /** Constructor. 33 | */ 34 | ShaderProgram(void); 35 | 36 | /** Destructor. 37 | */ 38 | ~ShaderProgram(void); 39 | 40 | /** Compile a shader. 41 | * Compiles a shader of given type and attaches it to the shader program. 42 | * \param type type of the shader to attach 43 | * \param filename path to the shader source 44 | * \param header optional header to include at the top of the file 45 | */ 46 | void CompileShader(GLenum type, const std::string &filename, const std::string &header = std::string()) { 47 | CompileShader(type, {filename}, header); 48 | } 49 | 50 | /** Compile a shader. 51 | * Compiles a shader of given type and attaches it to the shader program. 52 | * \param type type of the shader to attach 53 | * \param filename path to the shader source 54 | * \param header optional header to include at the top of the file 55 | */ 56 | void 57 | CompileShader(GLenum type, std::initializer_list filenames, const std::string &header = std::string()); 58 | 59 | /** Link the shader program. 60 | * Links the shader program. 61 | */ 62 | void Link(void); 63 | 64 | /** Use the shader program. 65 | * Installs the program as part of the current rendering state. 66 | */ 67 | void Use(void) const; 68 | 69 | /** Get a uniform location. 70 | * Obtains the location of a uniform of the shader program. 71 | * \param name name of the uniform variable 72 | * \returns the uniform location 73 | */ 74 | GLint GetUniformLocation(const char *name) const; 75 | 76 | /** Get the program object. 77 | * \returns the OpenGL shader program object. 78 | */ 79 | const GLuint &get(void) const { 80 | return program; 81 | } 82 | 83 | private: 84 | /** Program object. 85 | * OpenGL shader program object. 86 | */ 87 | GLuint program; 88 | }; 89 | 90 | #endif /* SHADERPROGRAM_H */ 91 | -------------------------------------------------------------------------------- /src/Simulation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef SIMULATION_H 23 | #define SIMULATION_H 24 | 25 | #include "common.h" 26 | #include "Camera.h" 27 | #include "ShaderProgram.h" 28 | #include "Framing.h" 29 | #include "Font.h" 30 | #include "FullscreenQuad.h" 31 | #include "PointSprite.h" 32 | #include "SPH.h" 33 | #include "SurfaceReconstruction.h" 34 | #include "Skybox.h" 35 | #include "Selection.h" 36 | 37 | /** Simulation class. 38 | * This is the main class which takes care of the whole simulation. 39 | */ 40 | class Simulation 41 | { 42 | public: 43 | /** Constructor. 44 | */ 45 | Simulation (void); 46 | /** Destructor. 47 | */ 48 | ~Simulation (void); 49 | 50 | /** Mouse movement event. 51 | * Handles mouse movement events. 52 | * \param x relative movement of the cursor in x direction 53 | * \param y relative movement of the cursor in y direction 54 | */ 55 | void OnMouseMove (const double &x, const double &y); 56 | 57 | /** Mouse button event. 58 | * Handles mouse button events. 59 | * \param button button that was pressed. 60 | */ 61 | void OnMouseDown (const int &button); 62 | 63 | /** Mouse button event. 64 | * Handles mouse button events. 65 | * \param button button that was released. 66 | */ 67 | void OnMouseUp (const int &button); 68 | 69 | /** Reset particle buffer. 70 | * Resets the particle buffer containing the particle information. 71 | */ 72 | void ResetParticleBuffer (void); 73 | 74 | /** Key up event. 75 | * Handles key release events. 76 | * \param key key that was released 77 | */ 78 | void OnKeyUp (int key); 79 | 80 | /** Key down event. 81 | * Handles key press events. 82 | * \param key key that was pressed 83 | */ 84 | void OnKeyDown (int key); 85 | 86 | /** Resize event. 87 | * Handles window resize event. 88 | * \param width new framebuffer width 89 | * \param height new framebuffer height 90 | */ 91 | void Resize (const unsigned int &width, const unsigned int &height); 92 | 93 | /** Get number of particles. 94 | * Obtains the number of particles in the simulation. 95 | * \returns the number of particles in the simulation. 96 | */ 97 | const unsigned int GetNumberOfParticles (void) const; 98 | 99 | /** Animation loop. 100 | * This function is called every frame and performs the actual simulation. 101 | * \returns True, if there were no errors, false otherwise. 102 | */ 103 | bool Frame (void); 104 | private: 105 | /** Transformation buffer layout. 106 | * Structure representing the memory layout of the uniform buffer 107 | * containing the transformation information. 108 | */ 109 | typedef struct transformationbuffer { 110 | /** View matrix. 111 | * The view matrix. 112 | */ 113 | glm::mat4 viewmat; 114 | /** Projection matrix. 115 | * The projection matrix. 116 | */ 117 | glm::mat4 projmat; 118 | /** Inverse view matrix. 119 | * Inverse of the view matrix. 120 | */ 121 | glm::mat4 invviewmat; 122 | } transformationbuffer_t; 123 | 124 | /** Lighting parameter layout. 125 | * Structure representing the memory layout of the uniform buffer 126 | * containing the lighting parameters. 127 | */ 128 | typedef struct lightparams { 129 | /** Light position. 130 | * Position of the light source. 131 | */ 132 | glm::vec3 lightpos; 133 | /** Padding. 134 | * Padding to create the correct memory layout. 135 | */ 136 | float padding; 137 | /** Spot direction. 138 | * Direction of the spot light. 139 | */ 140 | glm::vec3 spotdir; 141 | /** Padding. 142 | * Padding to create the correct memory layout. 143 | */ 144 | float padding2; 145 | /** Eye position. 146 | * Eye/camera position used for specular lighting. 147 | */ 148 | glm::vec3 eyepos; 149 | /** Spot exponent. 150 | * Spot exponent used to calculate the spot light falloff. 151 | */ 152 | float spotexponent; 153 | /** Light intensity. 154 | * Intensity of the light source. 155 | */ 156 | float lightintensity; 157 | } lightparams_t; 158 | 159 | /** Update view matrix. 160 | * Called whenever the view matrix is changed. 161 | */ 162 | void UpdateViewMatrix (void); 163 | /** Camera. 164 | * Used to handle input events and create a view matrix. 165 | */ 166 | Camera camera; 167 | 168 | /** Particle shader program. 169 | * Shader program for displaying the particles. 170 | */ 171 | ShaderProgram particleprogram; 172 | 173 | /** Skybox. 174 | * Takes care of rendering a sky box for the scene. 175 | */ 176 | Skybox skybox; 177 | 178 | /** Framing. 179 | * Takes care of rendering a framing for the scene. 180 | */ 181 | Framing framing; 182 | 183 | /** Point Sprite. 184 | * Takes care of rendering particles as point sprites. 185 | */ 186 | PointSprite pointsprite; 187 | 188 | /** SPH class. 189 | * Takes care of the SPH simulation. 190 | */ 191 | SPH sph; 192 | 193 | /** Environment map. 194 | * Optional environment map containing a texture for the sky box. 195 | */ 196 | Texture *envmap; 197 | 198 | /** Sky box flag. 199 | * Flag indicating whether to use a sky box. 200 | */ 201 | bool useskybox; 202 | 203 | /** Noise flag. 204 | * Flag indicating whether to use noise. 205 | */ 206 | bool usenoise; 207 | 208 | /** Surface reconstruction class. 209 | * Takes care of surface reconstruction and rendering. 210 | */ 211 | SurfaceReconstruction surfacereconstruction; 212 | 213 | /** Running flag 214 | * Flag indicating whether the simulation is running. 215 | */ 216 | bool running; 217 | 218 | /** Surface reconstruction flag. 219 | * flag indicating whether the particles should be rendered 220 | * as spheres or whether a reconstructed water surface should 221 | * be rendered. 222 | */ 223 | bool usesurfacereconstruction; 224 | 225 | union { 226 | struct { 227 | /** Transformation uniform buffer. 228 | * Buffer object to store the projection and view matrix. 229 | */ 230 | GLuint transformationbuffer; 231 | 232 | /** Lighting uniform buffer. 233 | * Buffer object to store the lighting parameters. 234 | */ 235 | GLuint lightingbuffer; 236 | }; 237 | /** Buffer objects. 238 | * The buffer objects are stored in a union, so that it is possible 239 | * to create/delete all buffer objects with a single OpenGL call. 240 | */ 241 | GLuint buffers[2]; 242 | }; 243 | 244 | /** Selection subsystem. 245 | * Takes care of determining particle ids from screen positions. Used for particle highlighting. 246 | */ 247 | Selection selection; 248 | 249 | /** Font subsystem. 250 | * Takes care of displaying text. 251 | */ 252 | Font font; 253 | 254 | /** Rendering query object. 255 | * Query object to record the time spent in the rendering phase. 256 | */ 257 | GLuint renderingquery; 258 | 259 | /** Projection matrix. 260 | * Matrix describing the perspective projection. 261 | */ 262 | glm::mat4 projmat; 263 | 264 | /** Framebuffer width. 265 | * Width of the current display framebuffer. 266 | */ 267 | unsigned int width; 268 | /** Framebuffer height. 269 | * Height of the current display framebuffer. 270 | */ 271 | unsigned int height; 272 | 273 | /** Last frame time. 274 | * Stores the time when the rendering of the last frame took place. 275 | */ 276 | float last_time; 277 | 278 | /** Last FPS time. 279 | * Stores the last time the fps count was updated. 280 | */ 281 | float last_fps_time; 282 | 283 | /** GUI timer. 284 | * Timer storing the time left to display GUI information in seconds. 285 | */ 286 | float guitimer; 287 | 288 | /** Enum type for gui states. 289 | */ 290 | typedef enum guistate { 291 | GUISTATE_REST_DENSITY = 0, 292 | GUISTATE_CFM_EPSILON, 293 | GUISTATE_GRAVITY, 294 | GUISTATE_TIMESTEP, 295 | GUISTATE_NUM_SOLVER_ITERATIONS, 296 | GUISTATE_TENSILE_INSTABILITY_K, 297 | GUISTATE_TENSILE_INSTABILITY_SCALE, 298 | GUISTATE_XSPH_VISCOSITY, 299 | GUISTATE_VORTICITY_EPSILON, 300 | GUISTATE_NUM_STATES, 301 | } guistate_t; 302 | 303 | /** Gui states. 304 | * Stores the current state of the gui. 305 | */ 306 | guistate_t guistate; 307 | /** Frame counter. 308 | * Frame counter used to determine the frames per second. 309 | */ 310 | unsigned int framecount; 311 | /** Frames per second. 312 | * The number of frames rendered in the last second. 313 | */ 314 | unsigned int fps; 315 | }; 316 | 317 | #endif /* SIMULATION_H */ 318 | -------------------------------------------------------------------------------- /src/Skybox.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "Skybox.h" 23 | 24 | Skybox::Skybox (void) 25 | { 26 | // load shader 27 | program.CompileShader (GL_VERTEX_SHADER, "shaders/skybox/vertex.glsl"); 28 | program.CompileShader (GL_FRAGMENT_SHADER, "shaders/skybox/fragment.glsl"); 29 | program.Link (); 30 | 31 | // create and bind a vertex array 32 | glGenVertexArrays (1, &vertexarray); 33 | glBindVertexArray (vertexarray); 34 | 35 | // generate buffer objects 36 | glGenBuffers (4, buffers); 37 | 38 | // store vertices to a buffer object 39 | glBindBuffer (GL_ARRAY_BUFFER, vertexbuffer); 40 | const GLfloat vertices[] = { 41 | -1, -1, 1, 42 | 1, -1, 1, 43 | 1, -1, -1, 44 | -1, -1, -1, 45 | 46 | -1, 1, 1, 47 | 1, 1, 1, 48 | 1, 1, -1, 49 | -1, 1, -1, 50 | }; 51 | glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW); 52 | // define the vertices as vertex attribute 0 53 | glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, 0); 54 | glEnableVertexAttribArray (0); 55 | 56 | // store indices to a buffer object 57 | glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexbuffer); 58 | const GLushort indices[] = { 59 | 0, 1, 2, 60 | 0, 2, 3, 61 | 62 | 6, 5, 4, 63 | 7, 6, 4, 64 | 65 | 1, 0, 4, 66 | 1, 4, 5, 67 | 68 | 2, 1, 6, 69 | 1, 5, 6, 70 | 71 | 3, 2, 6, 72 | 3, 6, 7, 73 | 74 | 0, 3, 7, 75 | 0, 7, 4 76 | }; 77 | glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices, GL_STATIC_DRAW); 78 | } 79 | 80 | Skybox::~Skybox (void) 81 | { 82 | // clean up 83 | glDeleteBuffers (4, buffers); 84 | glDeleteVertexArrays (1, &vertexarray); 85 | } 86 | 87 | void Skybox::Render (const Texture &envmap) 88 | { 89 | // activate shader program 90 | program.Use (); 91 | // bind texture, vertex array and index buffer 92 | envmap.Bind (GL_TEXTURE_CUBE_MAP); 93 | glBindVertexArray (vertexarray); 94 | glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexbuffer); 95 | // render the framing 96 | glDrawElements (GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); 97 | } 98 | -------------------------------------------------------------------------------- /src/Skybox.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef SKYBOX_H 23 | #define SKYBOX_H 24 | 25 | #include "common.h" 26 | #include "Texture.h" 27 | #include "ShaderProgram.h" 28 | 29 | /** Sky box. 30 | * This class renders a sky box for the scene. 31 | */ 32 | class Skybox 33 | { 34 | public: 35 | /** Constructor. 36 | */ 37 | Skybox (void); 38 | /** Destructor. 39 | */ 40 | ~Skybox (void); 41 | /** Render. 42 | * Renders the skybox. 43 | * \param envmap Environment map to use on the sky box. 44 | */ 45 | void Render (const Texture &envmap); 46 | private: 47 | /** Shader program. 48 | * Shader program for displaying the sky box. 49 | */ 50 | ShaderProgram program; 51 | 52 | union { 53 | struct { 54 | /** Vertex buffer. 55 | * OpenGL buffer object storing the vertices of the sky box. 56 | */ 57 | GLuint vertexbuffer; 58 | /** Normal buffer. 59 | * OpenGL buffer object storing the normals of the sky box. 60 | */ 61 | GLuint normalbuffer; 62 | /** Texture coordinate buffer. 63 | * OpenGL buffer object storing the texture coordinates of the sky box. 64 | */ 65 | GLuint texcoordbuffer; 66 | /** Index buffer. 67 | * OpenGL buffer object storing the vertex indices. 68 | */ 69 | GLuint indexbuffer; 70 | }; 71 | /** Buffer objects. 72 | * The buffer objects are stored in a union, so that it is possible 73 | * to create/delete all buffer objects with a single OpenGL call. 74 | */ 75 | GLuint buffers[4]; 76 | }; 77 | /** Vertex array object. 78 | * OpenGL vertex array object used to store information about the layout and location 79 | * of the vertex attributes. 80 | */ 81 | GLuint vertexarray; 82 | }; 83 | 84 | #endif /* SKYBOX_H */ 85 | -------------------------------------------------------------------------------- /src/SurfaceReconstruction.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef SURFACERECONSTRUCTION_H 23 | #define SURFACERECONSTRUCTION_H 24 | 25 | #include "common.h" 26 | #include "PointSprite.h" 27 | #include "ShaderProgram.h" 28 | #include "FullscreenQuad.h" 29 | #include "Blur.h" 30 | 31 | /** Surface reconstruction class. 32 | * This class is responsible for the surface reconstruction. 33 | */ 34 | class SurfaceReconstruction 35 | { 36 | public: 37 | /** Constuctor. 38 | */ 39 | SurfaceReconstruction (void); 40 | /** Destructor. 41 | */ 42 | ~SurfaceReconstruction (void); 43 | /** Render surface. 44 | * Renders the surface of the particles stored in the given buffer. 45 | * \param positionbuffer Buffer object storing particle positions. 46 | * \param numparticles Number of particles. 47 | * \param width Framebuffer width. 48 | * \param height Framebuffer height. 49 | */ 50 | void Render (const GLuint &positionbuffer, const GLuint &numparticles, const GLuint &width, const GLuint &height); 51 | /** Set environment map. 52 | * Sets an environment map used for reflection rendering. 53 | * \param envmap the environment map or NULL to disable reflections 54 | */ 55 | void SetEnvironmentMap (const Texture *envmap); 56 | /** Enable noise. 57 | * Enable noise for rendering. 58 | */ 59 | void EnableNoise (void); 60 | /** Disable noise. 61 | * Disable noise for rendering. 62 | */ 63 | void DisableNoise (void); 64 | private: 65 | 66 | /** Particle depth shader program. 67 | * Shader program for rendering the particle depths only. 68 | */ 69 | ShaderProgram particledepthprogram; 70 | 71 | /** Fullscreen quad shader program. 72 | * Shader program for rendering the fullscreen quad. 73 | */ 74 | ShaderProgram fsquadprog; 75 | 76 | /** Depth blur shader program. 77 | * Shader program for blurring the particle depth texture. 78 | */ 79 | ShaderProgram depthblurprog; 80 | 81 | /** Thickness program. 82 | * Shader program for storing the particle thickness. 83 | */ 84 | ShaderProgram thicknessprog; 85 | 86 | /** Depth blur offset scale uniform location. 87 | * Uniform location for the uniform variable storing the offset scale for the depth blur. 88 | */ 89 | GLuint depthbluroffsetscale; 90 | 91 | /** Point Sprite. 92 | * Takes care of rendering particles as point sprites. 93 | */ 94 | PointSprite pointsprite; 95 | 96 | /** Thickness blur. 97 | * Takes care of blurring the thickness image. 98 | */ 99 | Blur thicknessblur; 100 | 101 | /** Noise flag. 102 | * Flag indicating whether to use noise. 103 | */ 104 | bool usenoise; 105 | 106 | union { 107 | struct { 108 | /** Thickness blur weights. 109 | * Weights used for blurring the thickness texture. 110 | */ 111 | GLuint thicknessblurweights; 112 | 113 | /** Depth blur weights. 114 | * Weights used for blurring the depth texture. 115 | */ 116 | GLuint depthblurweights; 117 | }; 118 | /** Buffer objects. 119 | * The buffer objects are stored in a union, so that it is possible 120 | * to create/delete all buffer objects with a single OpenGL call. 121 | */ 122 | GLuint buffers[2]; 123 | }; 124 | 125 | union { 126 | struct { 127 | /** Depth framebuffer. 128 | * Framebuffer object used to store the particle depths. 129 | */ 130 | GLuint depthfb; 131 | /** Horizontal depth blur framebuffer. 132 | * Framebuffer object used for blurring the particle depths horizontally. 133 | */ 134 | GLuint depthhblurfb; 135 | /** Vertical depth blur framebuffer. 136 | * Framebuffer object used for blurring the particle depths vertically. 137 | */ 138 | GLuint depthvblurfb; 139 | /** Thickness framebuffer. 140 | * Framebuffer object used for rendering to the thickness texture. 141 | */ 142 | GLuint thicknessfb; 143 | /** Thickness blur framebuffer. 144 | * Framebuffer object used for blurring the thickness texture. 145 | */ 146 | GLuint thicknessblurfb; 147 | }; 148 | /** Framebuffer objects. 149 | * The framebuffer objects are stored in a union, so that it is possible 150 | * to create/delete all texture objects with a single OpenGL call. 151 | */ 152 | GLuint framebuffers[5]; 153 | }; 154 | 155 | /** Particle depth texture. 156 | * Texture to store the particle depths. 157 | */ 158 | Texture depthtexture; 159 | 160 | /** Temporary blur texture. 161 | * Texture to store temporary steps during blurring. 162 | */ 163 | Texture blurtexture; 164 | /** Thickness texture. 165 | * Texture in which the water thickness is stored. 166 | */ 167 | Texture thicknesstexture; 168 | /** Thickness blur texture. 169 | * Temporary texture used for blurring the water thickness. 170 | */ 171 | Texture thicknessblurtexture; 172 | 173 | /** Noise texture. 174 | * Texture used to store the generated noise. 175 | */ 176 | Texture noisetexture; 177 | 178 | /** Environment map. 179 | * Pointer to an environment map texture. 180 | */ 181 | const Texture *envmap; 182 | 183 | /** Offscreen framebuffer width. 184 | * Width of the offscreen framebuffer. 185 | */ 186 | unsigned int offscreen_width; 187 | /** Offscreen framebuffer height. 188 | * Height of the offscreen framebuffer. 189 | */ 190 | unsigned int offscreen_height; 191 | 192 | }; 193 | 194 | #endif /* SURFACERECONSTRUCTION_H */ 195 | -------------------------------------------------------------------------------- /src/Texture.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "Texture.h" 23 | #include 24 | 25 | Texture::Texture (void) 26 | { 27 | glGenTextures (1, &texture); 28 | } 29 | 30 | Texture::~Texture (void) 31 | { 32 | glDeleteTextures (1, &texture); 33 | } 34 | 35 | void Texture::Bind (GLenum target) const 36 | { 37 | glBindTexture (target, texture); 38 | } 39 | 40 | /** libpng I/O helper callback. 41 | * File I/O callback helper for using libpng with STL file streams. 42 | * \param png_ptr libpng handle 43 | * \param data memory to which to put the data 44 | * \param length number of bytes to read 45 | * 46 | */ 47 | void _PngReadFn (png_structp png_ptr, png_bytep data, png_size_t length) 48 | { 49 | std::ifstream *file = reinterpret_cast (png_get_io_ptr (png_ptr)); 50 | file->read (reinterpret_cast (data), length); 51 | if (file->fail ()) 52 | png_error (png_ptr, "I/O error."); 53 | } 54 | 55 | void Texture::Load (const GLenum &target, const std::string &filename, GLuint internalformat) 56 | { 57 | // open the file 58 | std::ifstream file (filename.c_str (), std::ios_base::in|std::ios_base::binary); 59 | if (!file.is_open ()) 60 | throw std::runtime_error (std::string ("Cannot open texture: ") + filename); 61 | 62 | png_structp png_ptr; 63 | png_infop info_ptr; 64 | 65 | // initialize libpng 66 | png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 67 | NULL, NULL, NULL); 68 | if (!png_ptr) 69 | throw std::runtime_error ("Cannot create png read struct"); 70 | info_ptr = png_create_info_struct (png_ptr); 71 | if (!info_ptr) 72 | { 73 | png_destroy_read_struct (&png_ptr, NULL, NULL); 74 | throw std::runtime_error ("Cannot create png info struct."); 75 | } 76 | 77 | // long jump error handling 78 | if (setjmp (png_jmpbuf (png_ptr))) 79 | { 80 | png_destroy_read_struct (&png_ptr, &info_ptr, NULL); 81 | throw std::runtime_error ("libpng error."); 82 | } 83 | 84 | // set I/O callback 85 | png_set_read_fn (png_ptr, &file, _PngReadFn); 86 | 87 | // read header information and request a usable format 88 | png_read_info (png_ptr, info_ptr); 89 | png_set_packing (png_ptr); 90 | png_set_expand (png_ptr); 91 | if (png_get_bit_depth (png_ptr, info_ptr) == 16) 92 | png_set_swap (png_ptr); 93 | png_read_update_info (png_ptr, info_ptr); 94 | 95 | // obtain information about the image 96 | int rowbytes = png_get_rowbytes (png_ptr, info_ptr); 97 | int channels= png_get_channels (png_ptr, info_ptr); 98 | int width = png_get_image_width (png_ptr, info_ptr); 99 | int height = png_get_image_height (png_ptr, info_ptr); 100 | int depth = png_get_bit_depth (png_ptr, info_ptr); 101 | 102 | // assure a valid pixel depth 103 | if (depth != 8 && depth != 16 && depth != 32) 104 | { 105 | png_destroy_read_struct (&png_ptr, &info_ptr, NULL); 106 | throw std::runtime_error (std::string ("Invalid bit depth in ") + filename); 107 | } 108 | 109 | // convert depth to OpenGL data type 110 | const GLuint types[] = { 111 | GL_UNSIGNED_BYTE, 112 | GL_UNSIGNED_SHORT, 113 | 0, 114 | GL_UNSIGNED_INT 115 | }; 116 | GLuint type = types [(depth / 8) - 1]; 117 | 118 | // assure a valid number of channels 119 | if (channels < 1 || channels > 4) 120 | { 121 | png_destroy_read_struct (&png_ptr, &info_ptr, NULL); 122 | throw std::runtime_error (std::string ("Invalid number of channels.") + filename); 123 | } 124 | 125 | // convert the number of channels to an OpenGL format 126 | const GLuint formats[] = { 127 | GL_RED, GL_RG, GL_RGB, GL_RGBA 128 | }; 129 | GLuint format = formats[channels - 1]; 130 | 131 | // read the image data 132 | std::vector data; 133 | data.resize (rowbytes * height); 134 | int i; 135 | for (i = 0; i < height; i++) 136 | { 137 | png_read_row (png_ptr, &data[i * rowbytes], NULL); 138 | } 139 | 140 | // cleanup libpng 141 | png_destroy_read_struct (&png_ptr, &info_ptr, NULL); 142 | 143 | // pass the image data to OpenGL 144 | glTexImage2D (target, 0, internalformat, width, height, 0, format, type, &data[0]); 145 | } 146 | -------------------------------------------------------------------------------- /src/Texture.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef TEXTURE_H 23 | #define TEXTURE_H 24 | 25 | #include "common.h" 26 | 27 | /** Texture class. 28 | * This class stores an OpenGL texture object and is capably of loading png images. 29 | */ 30 | class Texture 31 | { 32 | public: 33 | /** Constructor. 34 | */ 35 | Texture (void); 36 | /** Destructor. 37 | */ 38 | ~Texture (void); 39 | 40 | /** Bind the texture. 41 | * Bind the texture to the specified texturing target. 42 | * \param target texturing target to which to bind the texture 43 | */ 44 | void Bind (GLenum target) const; 45 | 46 | /** Load a png image. 47 | * Loads a png image and stores it in the texture bound to the specified target. 48 | * \param target specifies the texture target 49 | * \param filename path to the image to load 50 | * \param internalformat internal format used to store the texture 51 | */ 52 | static void Load (const GLenum &target, const std::string &filename, GLuint internalformat = GL_RGBA8); 53 | 54 | /** Get the texture object. 55 | * \returns the OpenGL texture object 56 | */ 57 | const GLuint &get (void) const { 58 | return texture; 59 | } 60 | 61 | private: 62 | /** Texture object. 63 | * The OpenGL texture object managed by this class. 64 | */ 65 | GLuint texture; 66 | }; 67 | 68 | #endif /* TEXTURE_H */ 69 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Daniel Kirchner 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE ANDNONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #ifndef COMMON_H 23 | #define COMMON_H 24 | 25 | #define GLFW_INCLUDE_NONE 26 | #include 27 | #include 28 | #include 29 | #include 30 | #define GLM_FORCE_SWIZZLE 31 | #define GLM_FORCE_RADIANS 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #ifndef M_PI 46 | #define M_PI 3.14159265358979323846 47 | #endif 48 | #ifndef M_PI_2 49 | #define M_PI_2 1.57079632679489661923 50 | #endif 51 | 52 | #include "spdlog/spdlog.h" 53 | 54 | extern GLFWwindow *window; 55 | 56 | /** Check for OpenGL extension. 57 | * Checks whether an OpenGL extension is supported. 58 | * \param name Name of the extension. 59 | * \returns True, if the extension is supported, false, if not. 60 | */ 61 | bool IsExtensionSupported (const std::string &name); 62 | 63 | /** OpenGL extension support flags. 64 | * Type of a structure that contains flags indicating whether 65 | * specific OpenGL extensions are supported or not. 66 | */ 67 | typedef struct glextflags { 68 | /** ARB_clear_texture support. 69 | * True if ARB_clear_texture is supported, false otherwise. 70 | */ 71 | bool ARB_clear_texture; 72 | } glextflags_t; 73 | 74 | extern glextflags_t GLEXTS; 75 | 76 | #endif /* !defined COMMON_H */ 77 | -------------------------------------------------------------------------------- /textures/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set (textures_files font.png framing.png 2 | sky/skybox_negx.png sky/skybox_negy.png sky/skybox_negz.png 3 | sky/skybox_posx.png sky/skybox_posy.png sky/skybox_posz.png) 4 | 5 | foreach(item IN ITEMS ${textures_files}) 6 | list(APPEND textures_out "${CMAKE_CURRENT_BINARY_DIR}/${item}") 7 | add_custom_command( 8 | OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${item}" 9 | COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${item}" "${CMAKE_CURRENT_BINARY_DIR}/${item}" 10 | DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${item}" 11 | ) 12 | endforeach() 13 | 14 | message(STATUS "${textures_out}") 15 | 16 | add_custom_target(textures-target DEPENDS "${textures_out}") 17 | -------------------------------------------------------------------------------- /textures/font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ekpyron/pbf/19cb7773468411dd55561a0db2e1ab5f7b5f9c91/textures/font.png -------------------------------------------------------------------------------- /textures/framing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ekpyron/pbf/19cb7773468411dd55561a0db2e1ab5f7b5f9c91/textures/framing.png -------------------------------------------------------------------------------- /textures/sky/readme.txt: -------------------------------------------------------------------------------- 1 | Author 2 | ====== 3 | 4 | This is the work of Emil Persson, aka Humus. 5 | http://www.humus.name 6 | 7 | 8 | 9 | License 10 | ======= 11 | 12 | This work is licensed under a Creative Commons Attribution 3.0 Unported License. 13 | http://creativecommons.org/licenses/by/3.0/ 14 | -------------------------------------------------------------------------------- /textures/sky/skybox_negx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ekpyron/pbf/19cb7773468411dd55561a0db2e1ab5f7b5f9c91/textures/sky/skybox_negx.png -------------------------------------------------------------------------------- /textures/sky/skybox_negy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ekpyron/pbf/19cb7773468411dd55561a0db2e1ab5f7b5f9c91/textures/sky/skybox_negy.png -------------------------------------------------------------------------------- /textures/sky/skybox_negz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ekpyron/pbf/19cb7773468411dd55561a0db2e1ab5f7b5f9c91/textures/sky/skybox_negz.png -------------------------------------------------------------------------------- /textures/sky/skybox_posx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ekpyron/pbf/19cb7773468411dd55561a0db2e1ab5f7b5f9c91/textures/sky/skybox_posx.png -------------------------------------------------------------------------------- /textures/sky/skybox_posy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ekpyron/pbf/19cb7773468411dd55561a0db2e1ab5f7b5f9c91/textures/sky/skybox_posy.png -------------------------------------------------------------------------------- /textures/sky/skybox_posz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ekpyron/pbf/19cb7773468411dd55561a0db2e1ab5f7b5f9c91/textures/sky/skybox_posz.png --------------------------------------------------------------------------------