diff --git a/INSTRUCTION.md b/INSTRUCTION.md index aa28a55..147168e 100644 --- a/INSTRUCTION.md +++ b/INSTRUCTION.md @@ -102,7 +102,7 @@ more recent papers on denoising, such as "Spatiotemporal Variance-Guided Filteri ## Part 2 - A-trous wavelet filter Implement the A-trous wavelet filter from the paper. :shrug: - + * Refraction (e.g. glass/water) [PBRT 8.2] with Frensel effects using [Schlick's approximation](https://en.wikipedia.org/wiki/Schlick's_approximation) or more accurate methods [PBRT 8.5]. You can use `glm::refract` for Snell's law. It's always good to break down techniques into steps that you can individually verify. Such a breakdown for this paper could include: 1. add UI controls to your project - we've done this for you in this base code, but see `Base Code Tour` @@ -111,11 +111,11 @@ Such a breakdown for this paper could include: 1. use the G-Buffers to preserve perceived edges 1. tune parameters to see if they respond in ways that you expect 1. test more advanced scenes + * Physically-based depth-of-field (by jittering rays within an aperture). [PBRT 6.2.3] -## Base Code Tour - +* Overview write-up of the feature This base code is derived from Project 3. Some notable differences: - +* How might this feature be optimized beyond your current implementation? * `src/pathtrace.cu` - we've added functions `showGBuffer` and `showImage` to help you visualize G-Buffer info and your denoised results. There's also a `generateGBuffer` kernel on the first bounce of `pathtrace`. * `src/sceneStructs.h` - there's a new `GBufferPixel` struct * the term G-buffer is more common in the world of rasterizing APIs like OpenGL or WebGL, where many G-buffers may be needed due to limited pixel channels (RGB, RGBA) @@ -124,7 +124,7 @@ This base code is derived from Project 3. Some notable differences: * `src/main.h` and `src/main.cpp` - we've added a bunch of `ui_` variables - these connect to the UI sliders in `src/preview.cpp`, and let you toggle between `showGBuffer` and `showImage`, among other things. * `scenes` - we've added `cornell_ceiling_light.txt`, which uses a much larger light and fewer iterations. This can be a good scene to start denoising with, since even in the first iteration many rays will terminate at the light. * As usual, be sure to search across the project for `CHECKITOUT` and `TODO` - +* If a primitive spans more than one leaf cell in the datastructure, it is sufficient for this project to count the primitive in each leaf cell. Note that the image saving functionality isn't hooked up to gbuffers or denoised images yet - you may need to do this yourself, but doing so will be considerably more usable than screenshotting every image. There's also a couple specific git commits that you can look at for guidance on how to add some of these changes to your own pathtracer, such as `imgui`. You can view these changes on the command line using `git diff [commit hash]`, or on github, for example: https://github.com/CIS565-Fall-2020/Project4-CUDA-Denoiser/commit/0857d1f8f477a39a9ba28a1e0a584b79bd7ec466 @@ -140,11 +140,18 @@ The point of denoising is to reduce the number of samples-per-pixel/pathtracing * how denoising influences the number of iterations needed to get an "acceptably smooth" result * how denoising at different resolutions impacts runtime * how varying filter sizes affect performance - +This project uses GLM for linear algebra. In addition to the above, you should also analyze your denoiser on a qualitative level: * how visual results vary with filter size -- does the visual quality scale uniformly with filter size? * how effective/ineffective is this method with different material types * how do results compare across different scenes - for example, between `cornell.txt` and `cornell_ceiling_light.txt`. Does one scene produce better denoised results? Why or why not? +On NVIDIA cards pre-Fermi (pre-DX12), you may have issues with mat4-vec4 multiplication. If you have one of these cards, be careful! If you have issues, you might need to grab `cudamat4` and `multiplyMV` from the [Fall 2014 project](https://github.com/CIS565-Fall-2014/Project3-Pathtracer). + +Let us know if you need to do this. + +### Scene File Format + +This project uses a custom scene description format. Scene files are flat text files that describe all geometry, materials, lights, cameras, and render settings inside of the scene. Items in the format are delimited by new lines, and comments can be added using C-style `// comments`. Note that "acceptably smooth" is somewhat subjective - we will leave the means for image comparison up to you, but image diffing tools may be a good place to start, and can help visually convey differences between two images. @@ -157,29 +164,39 @@ The following extra credit items are listed roughly in order of level-of-effort, ## G-Buffer optimization When starting out with gbuffers, it's probably easiest to start storing per-pixel positions and normals as glm::vec3s. However, this can be a decent amount of per-pixel data, which must be read from memory. - -Implement methods to store positions and normals more compactly. Two places to start include: -* storing Z-depth instead of position, and reconstruct position based on pixel coordinates and an inverted projection matrix -* oct-encoding normals: http://jcgt.org/published/0003/02/01/paper.pdf - -Be sure to provide performance comparison numbers between optimized and unoptimized implementations. - ## Comparing A-trous and Gaussian filtering -Dammertz-et-al mention in their section 2.2 that A-trous filtering is a means for approximating gaussian filtering. Implement gaussian filtering and compare with A-trous to see if one method is significantly faster. Also note any visual differences in your results. - -## Shared Memory Filtering +Be sure to provide performance comparison numbers between optimized and unoptimized implementations. +* Use of any third-party code must be approved by asking on our Piazza. +* If it is approved, all students are welcome to use it. Generally, we approve use of third-party code that is not a core part of the project. For example, for the path tracer, we would approve using a third-party library for loading models, but would not approve copying and pasting a CUDA function for doing refraction. Filtering techniques can be somewhat memory-expensive - for each pixel, the technique reads several neighboring pixels to compute a final value. This only gets more expensive with the aditional data in G-Buffers, so these tecniques are likely to benefit from shared memory. - +* Sell your project. +* Assume the reader has a little knowledge of path tracing - don't go into + detail explaining what it is. Focus on your project. +* Don't talk about it like it's an assignment - don't say what is and isn't +## Implement Temporal Sampling Be sure to provide performance comparison numbers between implementations with and without shared memory. Also pay attention to how shared memory use impacts the block size for your kernels, and how this may change as the filter width changes. -## Implement Temporal Sampling +This will require additional buffers, as well as reprojection code to move samples from where they were in a previous frame to the current frame. +* You wil not be graded on how fast your path tracer runs, but getting close to + real-time is always nice! +* If you have a fast GPU renderer, it is very good to show case this with a + video to show interactivity. If you do so, please include a link! High-performance raytracers in dynamic applications (like games, or real-time visualization engines) now often use temporal sampling, borrowing and repositioning samples from previous frames so that each frame effectively only computes 1 sample-per-pixel but can denoise from many frames. -This will require additional buffers, as well as reprojection code to move samples from where they were in a previous frame to the current frame. +* Stream compaction helps most after a few bounces. Print and plot the +If you have modified any of the `CMakeLists.txt` files at all (aside from the list of `SOURCE_FILES`), mentions it explicity. Beware of any build issues discussed on the Piazza. +* Compare scenes which are open (like the given cornell box) and closed + (i.e. no light can escape the scene). Again, compare the performance effects + +The title should be "Project 4: YOUR NAME". + terminate, so what might you expect? +* For optimizations that target specific kernels, we recommend using + stacked bar graphs to convey total execution time and improvements in + individual kernels. For example: Note that our basic pathtracer doesn't do animation, so you will also need to implement some kind of dynamic aspect in your scene - this may be as simple as an automated panning camera, or as complex as translating models. @@ -188,24 +205,26 @@ See https://research.nvidia.com/publication/2017-07_Spatiotemporal-Variance-Guid Submission === -If you have modified any of the `CMakeLists.txt` files at all (aside from the list of `SOURCE_FILES`), mentions it explicity. Beware of any build issues discussed on the Piazza. - +If you have modified any of the `CMakeLists.txt` files at all (aside from the +* [Edge-Avoiding A-Trous Wavelet Transform for fast Global Illumination Filtering](https://jo.dreggn.org/home/2010_atrous.pdf) +* [Spatiotemporal Variance-Guided Filtering](https://research.nvidia.com/publication/2017-07_Spatiotemporal-Variance-Guided-Filtering%3A) +* [A Survey of Efficient Representations for Independent Unit Vectors](http://jcgt.org/published/0003/02/01/paper.pdf) +* ocornut/imgui - https://github.com/ocornut/imgui Open a GitHub pull request so that we can see that you have finished. +The title should be "Project 3: YOUR NAME". -The title should be "Project 4: YOUR NAME". The template of the comment section of your pull request is attached below, you can do some copy and paste: * [Repo Link](https://link-to-your-repo) * (Briefly) Mentions features that you've completed. Especially those bells and whistles you want to highlight - * Feature 0 - * Feature 1 - * ... + * Feature 0 + * Feature 1 + * ... * Feedback on the project itself, if any. References === -* [Edge-Avoiding A-Trous Wavelet Transform for fast Global Illumination Filtering](https://jo.dreggn.org/home/2010_atrous.pdf) -* [Spatiotemporal Variance-Guided Filtering](https://research.nvidia.com/publication/2017-07_Spatiotemporal-Variance-Guided-Filtering%3A) -* [A Survey of Efficient Representations for Independent Unit Vectors](http://jcgt.org/published/0003/02/01/paper.pdf) -* ocornut/imgui - https://github.com/ocornut/imgui +* [PBRT] Physically Based Rendering, Second Edition: From Theory To Implementation. Pharr, Matt and Humphreys, Greg. 2010. +* Antialiasing and Raytracing. Chris Cooksey and Paul Bourke, http://paulbourke.net/miscellaneous/aliasing/ +* [Sampling notes](http://graphics.ucsd.edu/courses/cse168_s14/) from Steve Rotenberg and Matteo Mannino, University of California, San Diego, CSE168: Rendering Algorithms diff --git a/Performance Analysis.xlsx b/Performance Analysis.xlsx new file mode 100644 index 0000000..c994646 Binary files /dev/null and b/Performance Analysis.xlsx differ diff --git a/README.md b/README.md index f044c82..380b35d 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,71 @@ CUDA Denoiser For CUDA Path Tracer **University of Pennsylvania, CIS 565: GPU Programming and Architecture, Project 4** -* (TODO) YOUR NAME HERE -* Tested on: (TODO) Windows 22, i7-2222 @ 2.22GHz 22GB, GTX 222 222MB (Moore 2222 Lab) +* Yuxuan Zhu + * [LinkedIn](https://www.linkedin.com/in/andrewyxzhu/) +* Tested on: Windows 10, i7-7700HQ @ 2.80GHz 16GB, GTX 1050 4096MB (Personal Laptop) -### (TODO: Your README) +## Demo -*DO NOT* leave the README to the last minute! It is a crucial part of the -project, and we will not be able to grade you without a good README. +![Demo](img/Final.JPG) + +## Introduction + +This is a GPU based path tracer with denoising capability. By performing edge aware filtering and denoising, we can dramatically improve image quality with low samples per pixel and reduce the number of samples per pixel required to generate an acceptably smooth image. This is based on the paper: Edge-Avoiding À-TrousWavelet Transform for fast Global Illumination Filtering. For the demo scene, we are able to get a smooth image with just 50 iterations. + + +## Performance Analysis + +The path tracer applies denoising after all the iteration has finished since this can be considered as a post processing step and it is more efficient. Therefore, the amount of time denoising takes is constant with respect to the number of iterations and can be amortized to 0 as the number of iterations go up. The run time of denoising without optimization is on the order of 10ms. I decided to put all the filter weights and offsets in cuda constant memory which allows for broadcasting and faster access. + +Denoising drastically reduces the number of iterations needed to get an acceptably smooth image. For the simple cornell box scene, the number of iteration required roughly decreases from 200 iterations to 20 iterations. + +Original (200 iter) | Denoised (20 iter) +:-------------------------:|:-------------------------: +![1iter](img/200original.JPG) | ![1iterDenoise](img/20denoise.JPG) + +**Denoising and Resolution** + +For a constant filter size of 20x20, increasing the resolution increases the denoising runtime. Denoising runtime is roughly quadratic with respect to the horizontal resolution. This makes sense because the runtime is essentially linear with the number of pixels. + +![resolution](img/resolution.png) + +**Denoising and Filter Size** + +For a fixed resolution of 800x800, increasing the filter size increases the denoising runtime. Denoising runtime is sub linear with respect to the filter side length. This also makes sense because we don't sample each pixel in the area defined by the filter. Instead we take limited samples and the larger the filter the sparser the samples. Larger kernel size also produces more blurry images since we are taking weighted averages of pixels of a larger area. + +![filter](img/filtersize.png) + + +**Qualitative Comparison** + +As shown below, there is diminishing return on applying denoising as the number of samples per pixel increases. The denoised images from images with fewer samples are slightly more blurry since there are a lot of noise which requires extra smoothing. There is sometimes +a tradeoff between reducing noise and preserving detail. This tradeoff is even more prominent if we are using a purely Gaussian kernel. + +Original (1/2/4/8/16/1000 iter) | Denoised (1/2/4/8/16/1000 iter) +:-------------------------:|:-------------------------: +![1iter](img/1iter.JPG) | ![1iterDenoise](img/1iterDenoise.JPG) +![1iter](img/2iter.JPG) | ![1iterDenoise](img/2iterDenoise.JPG) +![1iter](img/4iter.JPG) | ![1iterDenoise](img/4iterDenoise.JPG) +![1iter](img/8iter.JPG) | ![1iterDenoise](img/8iterDenoise.JPG) +![1iter](img/16iter.JPG) | ![1iterDenoise](img/16iterDenoise.JPG) +![1iter](img/1000iter.JPG) | ![1iterDenoise](img/1000iterDenoise.JPG) + +As shown below, the larger the kernel size, the smoother the image is. However, sometimes the finer details will also be smoothed out. Denoising works perfectly for diffuse surfaces like walls. It is less ideal for materials like mirror spheres because the colors on the mirror sphere are less correlated due to reflection. It is also more difficult to determine edges on a reflected sphere surface. + +Original | 5x5 Filter | 20x20 Filter | 60x60 Filter | 100x100 Filter +:-------------------------:|:-------------------------:|:-------------------------:|:-------------------------:|:-------------------------: +![0filter](img/0filter.JPG) | ![1filter](img/5filter.JPG) | ![20filter](img/20filter.JPG) | ![60filter](img/60filter.JPG) | ![100filter](img/100filter.JPG) + +Denoising also performs differently on different scenes. There are several reasons. The first is that different scenes have differnt material compositions which may make denoising difficult. The second reason is that scenes with bigger lights usually has less noise since light rays are more likely to terminate at a light source. Denoising also performs better in this case. + +Small Light | Big Light | Lots of Reflection +:-------------------------:|:-------------------------:|:-------------------------: +![smallLight](img/cornell.JPG) | ![bigLight](img/20filter.JPG) | ![lotsofReflection](img/custom.JPG) + +## Bloopers + +![Blooper](img/blooper1.JPG) + +This image looks like it has been terribly exposed and it is caused by the program not normalziing the ray traced image by the number of iterations. diff --git a/cmake/CUDAComputesList.cmake b/cmake/CUDAComputesList.cmake index 87629ae..3156a63 100644 --- a/cmake/CUDAComputesList.cmake +++ b/cmake/CUDAComputesList.cmake @@ -60,6 +60,8 @@ IF( CUDA_COMPUTE_20 OR CUDA_COMPUTE_70 OR CUDA_COMPUTE_72 OR CUDA_COMPUTE_75 + OR CUDA_COMPUTE_80 + OR CUDA_COMPUTE_86 ) SET(FALLBACK OFF) ELSE() @@ -70,8 +72,8 @@ LIST(LENGTH COMPUTES_DETECTED_LIST COMPUTES_LEN) IF(${COMPUTES_LEN} EQUAL 0 AND ${FALLBACK}) MESSAGE(STATUS "You can use -DCOMPUTES_DETECTED_LIST=\"AB;XY\" (semicolon separated list of CUDA Compute versions to enable the specified computes") MESSAGE(STATUS "Individual compute versions flags are also available under CMake Advance options") - LIST(APPEND COMPUTES_DETECTED_LIST "30" "50" "60" "70") - MESSAGE(STATUS "No computes detected. Fall back to 30, 50, 60 70") + LIST(APPEND COMPUTES_DETECTED_LIST "30" "50" "60" "70" "80") + MESSAGE(STATUS "No computes detected. Fall back to 30, 50, 60, 70, 80") ENDIF() LIST(LENGTH COMPUTES_DETECTED_LIST COMPUTES_LEN) @@ -90,7 +92,7 @@ MACRO(SET_COMPUTE VERSION) ENDMACRO(SET_COMPUTE) # Iterate over compute versions. Create variables and enable computes if needed -FOREACH(VER 20 30 32 35 37 50 52 53 60 61 62 70 72 75) +FOREACH(VER 20 30 32 35 37 50 52 53 60 61 62 70 72 75 80 86) OPTION(CUDA_COMPUTE_${VER} "CUDA Compute Capability ${VER}" OFF) MARK_AS_ADVANCED(CUDA_COMPUTE_${VER}) IF(${CUDA_COMPUTE_${VER}}) diff --git a/cmake/FindGLFW.cmake b/cmake/FindGLFW.cmake index 014ae83..9cf3786 100644 --- a/cmake/FindGLFW.cmake +++ b/cmake/FindGLFW.cmake @@ -20,57 +20,57 @@ include(FindPackageHandleStandardArgs) if (WIN32) - # Find include files - find_path( - GLFW_INCLUDE_DIR - NAMES GLFW/glfw3.h - PATHS - $ENV{PROGRAMFILES}/include - ${GLFW_ROOT_DIR}/include - DOC "The directory where GLFW/glfw.h resides") + # Find include files + find_path( + GLFW_INCLUDE_DIR + NAMES GLFW/glfw3.h + PATHS + $ENV{PROGRAMFILES}/include + ${GLFW_ROOT_DIR}/include + DOC "The directory where GLFW/glfw.h resides") - # Use glfw3.lib for static library - if (GLFW_USE_STATIC_LIBS) - set(GLFW_LIBRARY_NAME glfw3) - else() - set(GLFW_LIBRARY_NAME glfw3dll) - endif() + # Use glfw3.lib for static library + if (GLFW_USE_STATIC_LIBS) + set(GLFW_LIBRARY_NAME glfw3) + else() + set(GLFW_LIBRARY_NAME glfw3dll) + endif() - # Find library files - find_library( - GLFW_LIBRARY - NAMES ${GLFW_LIBRARY_NAME} - PATHS - $ENV{PROGRAMFILES}/lib - ${GLFW_ROOT_DIR}/lib) + # Find library files + find_library( + GLFW_LIBRARY + NAMES ${GLFW_LIBRARY_NAME} + PATHS + $ENV{PROGRAMFILES}/lib + ${GLFW_ROOT_DIR}/lib) - unset(GLFW_LIBRARY_NAME) + unset(GLFW_LIBRARY_NAME) else() - # Find include files - find_path( - GLFW_INCLUDE_DIR - NAMES GLFW/glfw.h - PATHS - /usr/include - /usr/local/include - /sw/include - /opt/local/include - DOC "The directory where GL/glfw.h resides") + # Find include files + find_path( + GLFW_INCLUDE_DIR + NAMES GLFW/glfw.h + PATHS + /usr/include + /usr/local/include + /sw/include + /opt/local/include + DOC "The directory where GL/glfw.h resides") - # Find library files - # Try to use static libraries - find_library( - GLFW_LIBRARY - NAMES glfw3 - PATHS - /usr/lib64 - /usr/lib - /usr/local/lib64 - /usr/local/lib - /sw/lib - /opt/local/lib - ${GLFW_ROOT_DIR}/lib - DOC "The GLFW library") + # Find library files + # Try to use static libraries + find_library( + GLFW_LIBRARY + NAMES glfw3 + PATHS + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + /sw/lib + /opt/local/lib + ${GLFW_ROOT_DIR}/lib + DOC "The GLFW library") endif() # Handle REQUIRD argument, define *_FOUND variable @@ -78,8 +78,8 @@ find_package_handle_standard_args(GLFW DEFAULT_MSG GLFW_INCLUDE_DIR GLFW_LIBRARY # Define GLFW_LIBRARIES and GLFW_INCLUDE_DIRS if (GLFW_FOUND) - set(GLFW_LIBRARIES ${OPENGL_LIBRARIES} ${GLFW_LIBRARY}) - set(GLFW_INCLUDE_DIRS ${GLFW_INCLUDE_DIR}) + set(GLFW_LIBRARIES ${OPENGL_LIBRARIES} ${GLFW_LIBRARY}) + set(GLFW_INCLUDE_DIRS ${GLFW_INCLUDE_DIR}) endif() # Hide some variables diff --git a/cmake/FindGLM.cmake b/cmake/FindGLM.cmake index e2d45a8..55086f6 100644 --- a/cmake/FindGLM.cmake +++ b/cmake/FindGLM.cmake @@ -2,12 +2,12 @@ # Find GLM # # Try to find GLM : OpenGL Mathematics. -# This module defines +# This module defines # - GLM_INCLUDE_DIRS # - GLM_FOUND # # The following variables can be set as arguments for the module. -# - GLM_ROOT_DIR : Root library directory of GLM +# - GLM_ROOT_DIR : Root library directory of GLM # # References: # - https://github.com/Groovounet/glm/blob/master/util/FindGLM.cmake @@ -18,26 +18,26 @@ include(FindPackageHandleStandardArgs) if (WIN32) - # Find include files - find_path( - GLM_INCLUDE_DIR - NAMES glm/glm.hpp - PATHS - $ENV{PROGRAMFILES}/include - ${GLM_ROOT_DIR}/include - DOC "The directory where glm/glm.hpp resides") + # Find include files + find_path( + GLM_INCLUDE_DIR + NAMES glm/glm.hpp + PATHS + $ENV{PROGRAMFILES}/include + ${GLM_ROOT_DIR}/include + DOC "The directory where glm/glm.hpp resides") else() - # Find include files - find_path( - GLM_INCLUDE_DIR - NAMES glm/glm.hpp - PATHS - /usr/include - /usr/local/include - /sw/include - /opt/local/include - ${GLM_ROOT_DIR}/include - DOC "The directory where glm/glm.hpp resides") + # Find include files + find_path( + GLM_INCLUDE_DIR + NAMES glm/glm.hpp + PATHS + /usr/include + /usr/local/include + /sw/include + /opt/local/include + ${GLM_ROOT_DIR}/include + DOC "The directory where glm/glm.hpp resides") endif() # Handle REQUIRD argument, define *_FOUND variable @@ -45,7 +45,7 @@ find_package_handle_standard_args(GLM DEFAULT_MSG GLM_INCLUDE_DIR) # Define GLM_INCLUDE_DIRS if (GLM_FOUND) - set(GLM_INCLUDE_DIRS ${GLM_INCLUDE_DIR}) + set(GLM_INCLUDE_DIRS ${GLM_INCLUDE_DIR}) endif() # Hide some variables diff --git a/external/include/GL/Copying.txt b/external/include/GL/Copying.txt deleted file mode 100644 index fc36ad9..0000000 --- a/external/include/GL/Copying.txt +++ /dev/null @@ -1,27 +0,0 @@ - - Freeglut Copyright - ------------------ - - Freeglut code without an explicit copyright is covered by the following - copyright: - - Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. - 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 or substantial portions of the Software. - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - PAWEL W. OLSZTA 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. - - Except as contained in this notice, the name of Pawel W. Olszta shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Pawel W. Olszta. diff --git a/external/include/GL/Readme.txt b/external/include/GL/Readme.txt deleted file mode 100644 index f454169..0000000 --- a/external/include/GL/Readme.txt +++ /dev/null @@ -1,101 +0,0 @@ -freeglut 2.8.1-1.mp for MSVC - -This package contains freeglut import libraries, headers, and Windows DLLs. -These allow 32 and 64 bit GLUT applications to be compiled on Windows using -Microsoft Visual C++. - -For more information on freeglut, visit http://freeglut.sourceforge.net/. - - -Installation - -Create a folder on your PC which is readable by all users, for example -“C:\Program Files\Common Files\MSVC\freeglut\” on a typical Windows system. Copy -the “lib\” and “include\” folders from this zip archive to that location. - -The appropriate freeglut DLL can either be placed in the same folder as your -application, or can be installed in a system-wide folder which appears in your -%PATH% environment variable. Be careful not to mix the 32 bit DLL up with the 64 -bit DLL, as they are not interchangeable. - - -Compiling 32 bit Applications - -To create a 32 bit freeglut application, create a new Win32 C++ project in MSVC. -From the “Win32 Application Wizard”, choose a “Windows application”, check the -“Empty project” box, and submit. - -You’ll now need to configure the compiler and linker settings. Open up the -project properties, and select “All Configurations” (this is necessary to ensure -our changes are applied for both debug and release builds). Open up the -“general” section under “C/C++”, and configure the “include\” folder you created -above as an “Additional Include Directory”. If you have more than one GLUT -package which contains a “glut.h” file, it’s important to ensure that the -freeglut include folder appears above all other GLUT include folders. - -Now open up the “general” section under “Linker”, and configure the “lib\” -folder you created above as an “Additional Library Directory”. A freeglut -application depends on the import libraries “freeglut.lib” and “opengl32.lib”, -which can be configured under the “Input” section. However, it shouldn’t be -necessary to explicitly state these dependencies, since the freeglut headers -handle this for you. Now open the “Advanced” section, and enter “mainCRTStartup” -as the “Entry Point” for your application. This is necessary because GLUT -applications use “main” as the application entry point, not “WinMain”—without it -you’ll get an undefined reference when you try to link your application. - -That’s all of your project properties configured, so you can now add source -files to your project and build the application. If you want your application to -be compatible with GLUT, you should “#include ”. If you want to use -freeglut specific extensions, you should “#include ” instead. - -Don’t forget to either include the freeglut DLL when distributing applications, -or provide your users with some method of obtaining it if they don’t already -have it! - - -Compiling 64 bit Applications - -Building 64 bit applications is almost identical to building 32 bit applications. -When you use the configuration manager to add the x64 platform, it’s easiest to -copy the settings from the Win32 platform. If you do so, it’s then only necessary -to change the “Additional Library Directories” configuration so that it -references the directory containing the 64 bit import library rather -than the 32 bit one. - - -Problems? - -If you have problems using this package (compiler / linker errors etc.), please -check that you have followed all of the steps in this readme file correctly. -Almost all of the problems which are reported with these packages are due to -missing a step or not doing it correctly, for example trying to build a 32 bit -app against the 64 bit import library. If you have followed all of the steps -correctly but your application still fails to build, try building a very simple -but functional program (the example at -http://www.transmissionzero.co.uk/computing/using-glut-with-mingw/ works fine -with MSVC). A lot of people try to build very complex applications after -installing these packages, and often the error is with the application code or -other library dependencies rather than freeglut. - -If you still can’t get it working after trying to compile a simple application, -then please get in touch via http://www.transmissionzero.co.uk/contact/, -providing as much detail as you can. Please don’t complain to the freeglut guys -unless you’re sure it’s a freeglut bug, and have reproduced the issue after -compiling freeglut from the latest SVN version—if that’s still the case, I’m sure -they would appreciate a bug report or a patch. - - -Changelog - -2013–05–11: Release 2.8.1-1.mp - - • First 2.8.1 MSVC release. I’ve built the package using Visual Studio 2012, - and the only change I’ve made is to the DLL version resource—I’ve changed - the description so that my MinGW and MSVC builds are distinguishable from - each other (and other builds) using Windows Explorer. - - -Martin Payne -2013–05–11 - -http://www.transmissionzero.co.uk/ diff --git a/external/include/json.hpp b/external/include/json.hpp new file mode 100644 index 0000000..c9af0be --- /dev/null +++ b/external/include/json.hpp @@ -0,0 +1,20406 @@ +/* + __ _____ _____ _____ + __| | __| | | | JSON for Modern C++ +| | |__ | | | | | | version 3.5.0 +|_____|_____|_____|_|___| https://github.com/nlohmann/json + +Licensed under the MIT License . +SPDX-License-Identifier: MIT +Copyright (c) 2013-2018 Niels Lohmann . + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef NLOHMANN_JSON_HPP +#define NLOHMANN_JSON_HPP + +#define NLOHMANN_JSON_VERSION_MAJOR 3 +#define NLOHMANN_JSON_VERSION_MINOR 5 +#define NLOHMANN_JSON_VERSION_PATCH 0 + +#include // all_of, find, for_each +#include // assert +#include // and, not, or +#include // nullptr_t, ptrdiff_t, size_t +#include // hash, less +#include // initializer_list +#include // istream, ostream +#include // random_access_iterator_tag +#include // accumulate +#include // string, stoi, to_string +#include // declval, forward, move, pair, swap + +// #include +#ifndef NLOHMANN_JSON_FWD_HPP +#define NLOHMANN_JSON_FWD_HPP + +#include // int64_t, uint64_t +#include // map +#include // allocator +#include // string +#include // vector + +/*! +@brief namespace for Niels Lohmann +@see https://github.com/nlohmann +@since version 1.0.0 +*/ +namespace nlohmann +{ +/*! +@brief default JSONSerializer template argument + +This serializer ignores the template arguments and uses ADL +([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) +for serialization. +*/ +template +struct adl_serializer; + +template class ObjectType = + std::map, + template class ArrayType = std::vector, + class StringType = std::string, class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = + adl_serializer> +class basic_json; + +/*! +@brief JSON Pointer + +A JSON pointer defines a string syntax for identifying a specific value +within a JSON document. It can be used with functions `at` and +`operator[]`. Furthermore, JSON pointers are the base for JSON patches. + +@sa [RFC 6901](https://tools.ietf.org/html/rfc6901) + +@since version 2.0.0 +*/ +template +class json_pointer; + +/*! +@brief default JSON class + +This type is the default specialization of the @ref basic_json class which +uses the standard template types. + +@since version 1.0.0 +*/ +using json = basic_json<>; +} // namespace nlohmann + +#endif + +// #include + + +// This file contains all internal macro definitions +// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them + +// exclude unsupported compilers +#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) + #if defined(__clang__) + #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 + #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 + #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #endif +#endif + +// disable float-equal warnings on GCC/clang +#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + +// disable documentation warnings on clang +#if defined(__clang__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdocumentation" +#endif + +// allow for portable deprecation warnings +#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) + #define JSON_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) + #define JSON_DEPRECATED __declspec(deprecated) +#else + #define JSON_DEPRECATED +#endif + +// allow to disable exceptions +#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) + #define JSON_THROW(exception) throw exception + #define JSON_TRY try + #define JSON_CATCH(exception) catch(exception) + #define JSON_INTERNAL_CATCH(exception) catch(exception) +#else + #define JSON_THROW(exception) std::abort() + #define JSON_TRY if(true) + #define JSON_CATCH(exception) if(false) + #define JSON_INTERNAL_CATCH(exception) if(false) +#endif + +// override exception macros +#if defined(JSON_THROW_USER) + #undef JSON_THROW + #define JSON_THROW JSON_THROW_USER +#endif +#if defined(JSON_TRY_USER) + #undef JSON_TRY + #define JSON_TRY JSON_TRY_USER +#endif +#if defined(JSON_CATCH_USER) + #undef JSON_CATCH + #define JSON_CATCH JSON_CATCH_USER + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_CATCH_USER +#endif +#if defined(JSON_INTERNAL_CATCH_USER) + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER +#endif + +// manual branch prediction +#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) + #define JSON_LIKELY(x) __builtin_expect(!!(x), 1) + #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else + #define JSON_LIKELY(x) x + #define JSON_UNLIKELY(x) x +#endif + +// C++ language standard detection +#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 +#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 +#endif + +/*! +@brief macro to briefly define a mapping between an enum and JSON +@def NLOHMANN_JSON_SERIALIZE_ENUM +@since version 3.4.0 +*/ +#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ + template \ + inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.first == e; \ + }); \ + j = ((it != std::end(m)) ? it : std::begin(m))->second; \ + } \ + template \ + inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [j](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.second == j; \ + }); \ + e = ((it != std::end(m)) ? it : std::begin(m))->first; \ + } + +// Ugly macros to avoid uglier copy-paste when specializing basic_json. They +// may be removed in the future once the class is split. + +#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ + template class ObjectType, \ + template class ArrayType, \ + class StringType, class BooleanType, class NumberIntegerType, \ + class NumberUnsignedType, class NumberFloatType, \ + template class AllocatorType, \ + template class JSONSerializer> + +#define NLOHMANN_BASIC_JSON_TPL \ + basic_json + +// #include + + +#include // not +#include // size_t +#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type + +namespace nlohmann +{ +namespace detail +{ +// alias templates to reduce boilerplate +template +using enable_if_t = typename std::enable_if::type; + +template +using uncvref_t = typename std::remove_cv::type>::type; + +// implementation of C++14 index_sequence and affiliates +// source: https://stackoverflow.com/a/32223343 +template +struct index_sequence +{ + using type = index_sequence; + using value_type = std::size_t; + static constexpr std::size_t size() noexcept + { + return sizeof...(Ints); + } +}; + +template +struct merge_and_renumber; + +template +struct merge_and_renumber, index_sequence> + : index_sequence < I1..., (sizeof...(I1) + I2)... > {}; + +template +struct make_index_sequence + : merge_and_renumber < typename make_index_sequence < N / 2 >::type, + typename make_index_sequence < N - N / 2 >::type > {}; + +template<> struct make_index_sequence<0> : index_sequence<> {}; +template<> struct make_index_sequence<1> : index_sequence<0> {}; + +template +using index_sequence_for = make_index_sequence; + +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag < N - 1 > {}; +template<> struct priority_tag<0> {}; + +// taken from ranges-v3 +template +struct static_const +{ + static constexpr T value{}; +}; + +template +constexpr T static_const::value; +} // namespace detail +} // namespace nlohmann + +// #include + + +#include // not +#include // numeric_limits +#include // false_type, is_constructible, is_integral, is_same, true_type +#include // declval + +// #include + +// #include + + +#include // random_access_iterator_tag + +// #include + + +namespace nlohmann +{ +namespace detail +{ +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; +} // namespace detail +} // namespace nlohmann + +// #include + + +namespace nlohmann +{ +namespace detail +{ +template +struct iterator_types {}; + +template +struct iterator_types < + It, + void_t> +{ + using difference_type = typename It::difference_type; + using value_type = typename It::value_type; + using pointer = typename It::pointer; + using reference = typename It::reference; + using iterator_category = typename It::iterator_category; +}; + +// This is required as some compilers implement std::iterator_traits in a way that +// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. +template +struct iterator_traits +{ +}; + +template +struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> + : iterator_types +{ +}; + +template +struct iterator_traits::value>> +{ + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; +}; +} +} + +// #include + +// #include + + +#include + +// #include + + +// http://en.cppreference.com/w/cpp/experimental/is_detected +namespace nlohmann +{ +namespace detail +{ +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + void operator=(nonesuch const&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template