├── .gitignore ├── .vscode ├── c_cpp_properties.json ├── launch.json ├── settings.json └── tasks.json ├── 3rdparty ├── flythrough_camera │ ├── LICENSE │ ├── README.md │ └── flythrough_camera.h ├── tinygltf │ ├── json.hpp │ ├── stb_image.h │ ├── stb_image_write.h │ ├── tiny_gltf.cc │ └── tiny_gltf.h ├── tinyobjloader │ ├── tiny_obj_loader.cc │ └── tiny_obj_loader.h ├── ufbx │ ├── LICENSE │ ├── README.md │ ├── ufbx.c │ └── ufbx.h ├── vox │ ├── read_vox.cpp │ └── read_vox.h └── yocto │ ├── CMakeLists.txt │ ├── ext │ ├── json.hpp │ ├── stb_image.cpp │ ├── stb_image.h │ ├── stb_image_resize.h │ ├── stb_image_write.h │ ├── tinyexr.cpp │ └── tinyexr.h │ ├── yocto_bvh.cpp │ ├── yocto_bvh.h │ ├── yocto_cli.h │ ├── yocto_color.h │ ├── yocto_geometry.h │ ├── yocto_image.cpp │ ├── yocto_image.h │ ├── yocto_math.h │ ├── yocto_mesh.cpp │ ├── yocto_mesh.h │ ├── yocto_modelio.cpp │ ├── yocto_modelio.h │ ├── yocto_noise.h │ ├── yocto_parallel.h │ ├── yocto_sampling.h │ ├── yocto_scene.cpp │ ├── yocto_scene.h │ ├── yocto_sceneio.cpp │ ├── yocto_sceneio.h │ ├── yocto_shading.h │ ├── yocto_shape.cpp │ ├── yocto_shape.h │ ├── yocto_trace.cpp │ └── yocto_trace.h ├── LICENSE ├── README.md ├── assets ├── CathedralIrradiance.dds ├── CathedralRadiance.dds ├── SkyBox.frag ├── SkyBox.vert ├── common.glsl ├── pbr.frag ├── pbr.vert ├── pbr │ ├── LICENSE.md │ ├── README.md │ ├── animation.glsl │ ├── brdf.glsl │ ├── cubemap.frag │ ├── cubemap.vert │ ├── functions.glsl │ ├── ibl.glsl │ ├── lut_charlie.png │ ├── lut_ggx.png │ ├── lut_thin_film.png │ ├── pbr.frag │ ├── primitive.vert │ ├── punctual.glsl │ ├── run.bat │ ├── textures.glsl │ └── tonemapping.glsl ├── postprocess │ ├── FXAA3_11.h │ ├── SMAA.h │ ├── fxaa.frag │ ├── fxaa.vert │ ├── smaa.frag │ └── smaa.vert ├── shadow_mapping.frag ├── shadow_mapping.vert └── unlit.frag ├── cinderblock.png ├── cinderblock.xml ├── doc ├── README.md └── figures │ ├── BRDFs.png │ ├── BTDFs.png │ ├── Fresnel_Conductor.JPG │ ├── Fresnel_Dielectric.JPG │ ├── Interreflection.jpg │ ├── Masking.png │ ├── Shadowing.png │ └── Snells_Law.JPG ├── include ├── FirstPersonCamera.h ├── GltfNode.h ├── Node.h ├── NodeExt.h ├── SkyNode.h ├── cigltf.h ├── ciobj.h ├── civox.h ├── melo.h └── postprocess │ ├── FXAA.h │ └── SMAA.h ├── melo.code-workspace ├── samples ├── AnimToCSV │ ├── include │ │ ├── Resources.h │ │ └── item.def │ ├── resources │ │ └── cinder_app_icon.ico │ ├── src │ │ └── AnimToCSVApp.cpp │ └── vc2019 │ │ ├── AnimToCSV.sln │ │ ├── AnimToCSV.vcxproj │ │ ├── AnimToCSV.vcxproj.filters │ │ └── Resources.rc ├── MeshViewer │ ├── .gitignore │ ├── assets │ │ ├── Box │ │ │ ├── README.md │ │ │ ├── glTF-Binary │ │ │ │ └── Box.glb │ │ │ ├── glTF-Draco │ │ │ │ ├── 0.bin │ │ │ │ └── Box.gltf │ │ │ ├── glTF-Embedded │ │ │ │ └── Box.gltf │ │ │ ├── glTF-pbrSpecularGlossiness │ │ │ │ ├── Box.gltf │ │ │ │ └── Box0.bin │ │ │ ├── glTF │ │ │ │ ├── Box.gltf │ │ │ │ └── Box0.bin │ │ │ └── screenshot │ │ │ │ └── screenshot.png │ │ ├── InterpolationTest │ │ │ └── InterpolationTest.glb │ │ ├── oc-five │ │ │ ├── five-shape-ao.jpg │ │ │ ├── five-shape-basecolor.jpg │ │ │ ├── five-shape-height.png │ │ │ ├── five-shape-roughness.png │ │ │ ├── five.bin │ │ │ └── five.gltf │ │ ├── shibainu │ │ │ ├── shibainu.mtl │ │ │ └── shibainu.obj │ │ └── vox │ │ │ ├── monu1.vox │ │ │ └── teapot.vox │ ├── build-vs2015.bat │ ├── include │ │ ├── Resources.h │ │ └── item.def │ ├── resources │ │ ├── CinderApp.icns │ │ ├── CinderApp_ios.png │ │ └── cinder_app_icon.ico │ ├── src │ │ ├── MeshViewerApp.cpp │ │ ├── ShadowMap.h │ │ └── vfspp │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── include │ │ │ ├── CFileInfo.h │ │ │ ├── CMemoryFile.h │ │ │ ├── CMemoryFileSystem.h │ │ │ ├── CNativeFile.h │ │ │ ├── CNativeFileSystem.h │ │ │ ├── CVirtualFileSystem.h │ │ │ ├── CZipFile.h │ │ │ ├── CZipFileSystem.h │ │ │ ├── IFile.h │ │ │ ├── IFileSystem.h │ │ │ ├── VFS.h │ │ │ └── dirent.h │ │ │ └── src │ │ │ ├── CFileInfo.cpp │ │ │ ├── CMemoryFile.cpp │ │ │ ├── CMemoryFileSystem.cpp │ │ │ ├── CNativeFile.cpp │ │ │ ├── CNativeFileSystem.cpp │ │ │ ├── CStringUtilsVFS.cpp │ │ │ ├── CStringUtilsVFS.h │ │ │ ├── CVirtualFileSystem.cpp │ │ │ ├── CZipFile.cpp │ │ │ ├── CZipFileSystem.cpp │ │ │ ├── miniz.c │ │ │ └── miniz.h │ ├── vc2015 │ │ ├── MeloViewer.sln │ │ ├── MeshViewer.vcxproj │ │ ├── MeshViewer.vcxproj.filters │ │ └── Resources.rc │ ├── xcode │ │ ├── Info.plist │ │ ├── MeloViewer.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ ├── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcuserdata │ │ │ │ │ └── vinjn.xcuserdatad │ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ └── xcuserdata │ │ │ │ └── vinjn.xcuserdatad │ │ │ │ ├── xcdebugger │ │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── MeloViewer_Prefix.pch │ └── xcode_ios │ │ ├── Images.xcassets │ │ └── LaunchImage.launchimage │ │ │ ├── Contents.json │ │ │ ├── Default-568h@2x.png │ │ │ ├── Default-667@2x.png │ │ │ └── Default-736h@3x~iphone.png │ │ ├── Info.plist │ │ ├── LaunchScreen.xib │ │ ├── MeshViewer.xcodeproj │ │ └── project.pbxproj │ │ └── MeshViewer_Prefix.pch ├── SimpleSceneGraphApp │ ├── include │ │ ├── Resources.h │ │ └── license.txt │ ├── src │ │ └── SimpleSceneGraphApp.cpp │ └── vc2015 │ │ ├── Resources.rc │ │ ├── SimpleSceneGraph.sln │ │ ├── SimpleSceneGraph.vcxproj │ │ ├── SimpleSceneGraph.vcxproj.filters │ │ └── cinder_app_icon.ico └── XRoom │ ├── .gitignore │ ├── build-vs2019.bat │ ├── include │ ├── Resources.h │ └── item.def │ ├── resources │ └── cinder_app_icon.ico │ ├── src │ └── XRoomApp.cpp │ └── vs2019 │ ├── Resources.rc │ ├── XRoom.sln │ ├── XRoom.vcxproj │ └── XRoom.vcxproj.filters └── src ├── GltfNode.cpp ├── Node.cpp ├── NodeExt.cpp ├── SceneIO.cpp ├── SkyNode.cpp ├── cigltf.cpp ├── ciobj.cpp ├── melo.cpp └── postprocess ├── AreaTex.h ├── FXAA.cpp ├── SMAA.cpp └── SearchTex.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | # *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | # *.pch 13 | 14 | *.ilk 15 | *.opendb 16 | 17 | # Compiled Dynamic libraries 18 | *.so 19 | *.dylib 20 | *.dll 21 | 22 | *.pyc 23 | *.7z 24 | 25 | # Fortran module files 26 | *.mod 27 | *.smod 28 | 29 | # Compiled Static libraries 30 | *.lai 31 | *.la 32 | *.a 33 | *.lib 34 | 35 | # Executables 36 | *.exe 37 | *.out 38 | *.app 39 | 40 | *.suo 41 | *.user 42 | *.pdb 43 | *.db 44 | 45 | x64 46 | .vs 47 | MiniConfig.xml 48 | 49 | bin/ 50 | Debug/ 51 | Release/ -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Win32", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "${workspaceFolder}/../Cinder/include/cinder/**", 8 | "${workspaceFolder}/../Cinder/src/cinder/**", 9 | "${workspaceFolder}/../Cinder/blocks/**" 10 | ], 11 | "defines": [ 12 | "_DEBUG", 13 | "UNICODE", 14 | "_UNICODE" 15 | ], 16 | "windowsSdkVersion": "10.0.17134.0", 17 | "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.14.26428/bin/Hostx64/x64/cl.exe", 18 | "cStandard": "c11", 19 | "cppStandard": "c++17", 20 | "intelliSenseMode": "msvc-x64" 21 | } 22 | ], 23 | "version": 4 24 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [{ 7 | "name": "(Windows) Launch", 8 | "type": "cppvsdbg", 9 | "request": "launch", 10 | "program": "${workspaceFolder}/bin/${workspaceFolderBasename}-d.exe", 11 | "args": [], 12 | "stopAtEntry": false, 13 | "cwd": "${workspaceFolder}", 14 | "environment": [], 15 | "externalConsole": true 16 | }] 17 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.clang_format_style": "{PointerBindsToType: true, ColumnLimit: 100, IndentWidth: 4, UseTab: Never, NamespaceIndentation: All, BreakBeforeBraces: Allman}", 3 | "editor.formatOnSave": true 4 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [{ 6 | "label": "msbuild", 7 | "type": "shell", 8 | "command": "msbuild", 9 | "args": [ 10 | // Ask msbuild to generate full paths for file names. 11 | "${workspaceFolder}/vc2015/${workspaceFolderBasename}.sln", 12 | "/property:GenerateFullPaths=true", 13 | "/t:build" 14 | ], 15 | "group": "build", 16 | "presentation": { 17 | // Reveal the output only if unrecognized errors occur. 18 | "reveal": "silent" 19 | }, 20 | // Use the standard MS compiler pattern to detect errors, warnings and infos 21 | "problemMatcher": "$msCompile" 22 | }, 23 | { 24 | "label": "xcode", 25 | "type": "shell", 26 | "command": "xcodebuild", 27 | "args": [ 28 | "-project", 29 | "${workspaceFolder}/xcode/${workspaceFolderBasename}.xcodeproj", 30 | "-configuration", 31 | "Debug" 32 | ], 33 | "group": "build", 34 | "presentation": { 35 | // Reveal the output only if unrecognized errors occur. 36 | "reveal": "silent" 37 | }, 38 | // Use the standard MS compiler pattern to detect errors, warnings and infos 39 | "problemMatcher": "$gcc" 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /3rdparty/flythrough_camera/LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /3rdparty/tinygltf/tiny_gltf.cc: -------------------------------------------------------------------------------- 1 | #define TINYGLTF_IMPLEMENTATION 2 | 3 | //#define STB_IMAGE_IMPLEMENTATION 4 | //#define STB_IMAGE_WRITE_IMPLEMENTATION 5 | #define TINYGLTF_NO_EXTERNAL_IMAGE 6 | //#define TINYGLTF_USE_RAPIDJSON 7 | //#define TINYGLTF_NO_STB_IMAGE 8 | //#define TINYGLTF_NO_STB_IMAGE_WRITE 9 | 10 | #include "tiny_gltf.h" 11 | -------------------------------------------------------------------------------- /3rdparty/tinyobjloader/tiny_obj_loader.cc: -------------------------------------------------------------------------------- 1 | #define TINYOBJLOADER_IMPLEMENTATION 2 | #include "tiny_obj_loader.h" 3 | -------------------------------------------------------------------------------- /3rdparty/ufbx/LICENSE: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | This software is available under 2 licenses -- choose whichever you prefer. 3 | ------------------------------------------------------------------------------ 4 | ALTERNATIVE A - MIT License 5 | Copyright (c) 2020 Samuli Raivio 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 10 | of the Software, and to permit persons to whom the Software is furnished to do 11 | so, subject to the following conditions: 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 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 THE 20 | SOFTWARE. 21 | ------------------------------------------------------------------------------ 22 | ALTERNATIVE B - Public Domain (www.unlicense.org) 23 | This is free and unencumbered software released into the public domain. 24 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 25 | software, either in source code form or as a compiled binary, for any purpose, 26 | commercial or non-commercial, and by any means. 27 | In jurisdictions that recognize copyright laws, the author or authors of this 28 | software dedicate any and all copyright interest in the software to the public 29 | domain. We make this dedication for the benefit of the public at large and to 30 | the detriment of our heirs and successors. We intend this dedication to be an 31 | overt act of relinquishment in perpetuity of all present and future rights to 32 | this software under copyright law. 33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 34 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 35 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 36 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 37 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 38 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 39 | ---------------------------------------- 40 | -------------------------------------------------------------------------------- /3rdparty/ufbx/README.md: -------------------------------------------------------------------------------- 1 | # ufbx [![Build Status](https://travis-ci.org/bqqbarbhg/ufbx.svg?branch=master)](https://travis-ci.org/bqqbarbhg/ufbx) [![codecov](https://codecov.io/gh/bqqbarbhg/ufbx/branch/master/graph/badge.svg)](https://codecov.io/gh/bqqbarbhg/ufbx) 2 | 3 | Single source file FBX reader. Supports both ASCII and binary files starting from version 6100. 4 | 5 | ## Usage 6 | 7 | ```c 8 | ufbx_load_opts opts = { }; // Optional, pass NULL for defaults 9 | ufbx_error error; // Optional, pass NULL if you don't care about errors 10 | ufbx_scene *scene = ufbx_load_file("thing.fbx", &opts, &error); 11 | if (!scene) { do_fail(&error); exit(1); } 12 | 13 | // Use and inspect `scene`, it's just plain data! 14 | 15 | // Geometry is always stored in a consistent indexed format: 16 | ufbx_mesh *cube = ufbx_find_mesh(scene, "Cube"); 17 | for (size_t face_ix = 0; face_ix < cube->num_faces; face_ix++) { 18 | ufbx_face face = cube->faces[face_ix]; 19 | for (size_t vertex_ix = 0; vertex_ix < face.num_indices; vertex_ix++) { 20 | size_t index = face.index_begin + vertex_ix; 21 | ufbx_vec3 position = cube->vertex_position.data[cube->vertex_position.indices[index]]; 22 | ufbx_vec3 normal = ufbx_get_vertex_vec3(&cube->vertex_normal, index); // Equivalent utility function 23 | push_vertex(&position, &normal); 24 | } 25 | } 26 | 27 | // There's also helper functions for evaluating animations: 28 | ufbx_anim_stack *anim = ufbx_find_anim_stack(scene, "Animation"); 29 | for (double time = 0.0; time <= 1.0; time += 1.0/60.0) { 30 | ufbx_transform transform = ufbx_evaluate_transform(scene, cube, anim, time); 31 | ufbx_matrix matrix = ufbx_get_transform_matrix(&transform); 32 | push_pose(&matrix); 33 | } 34 | 35 | // Don't forget to free the allocation! 36 | ufbx_free_scene(scene); 37 | ``` 38 | 39 | ## WIP 40 | 41 | This library is still a work in progress, but most of the implemented features are quite 42 | usable as the library is heavily tested and fuzzed. 43 | 44 | The API might change in the future, especially materials and evaluating animations. 45 | 46 | ## License 47 | 48 | ``` 49 | ------------------------------------------------------------------------------ 50 | This software is available under 2 licenses -- choose whichever you prefer. 51 | ------------------------------------------------------------------------------ 52 | ALTERNATIVE A - MIT License 53 | Copyright (c) 2020 Samuli Raivio 54 | Permission is hereby granted, free of charge, to any person obtaining a copy of 55 | this software and associated documentation files (the "Software"), to deal in 56 | the Software without restriction, including without limitation the rights to 57 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 58 | of the Software, and to permit persons to whom the Software is furnished to do 59 | so, subject to the following conditions: 60 | The above copyright notice and this permission notice shall be included in all 61 | copies or substantial portions of the Software. 62 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 63 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 64 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 65 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 66 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 67 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 68 | SOFTWARE. 69 | ------------------------------------------------------------------------------ 70 | ALTERNATIVE B - Public Domain (www.unlicense.org) 71 | This is free and unencumbered software released into the public domain. 72 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 73 | software, either in source code form or as a compiled binary, for any purpose, 74 | commercial or non-commercial, and by any means. 75 | In jurisdictions that recognize copyright laws, the author or authors of this 76 | software dedicate any and all copyright interest in the software to the public 77 | domain. We make this dedication for the benefit of the public at large and to 78 | the detriment of our heirs and successors. We intend this dedication to be an 79 | overt act of relinquishment in perpetuity of all present and future rights to 80 | this software under copyright law. 81 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 82 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 83 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 84 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 85 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 86 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 87 | ---------------------------------------- 88 | ``` 89 | -------------------------------------------------------------------------------- /3rdparty/vox/read_vox.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of NVIDIA CORPORATION nor the names of its 13 | * contributors may be used to endorse or promote products derived 14 | * from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 24 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | 34 | using namespace ci; 35 | 36 | struct VoxelModel { 37 | int dims[3]; 38 | std::vector< uvec4 > voxels; 39 | }; 40 | 41 | void read_vox( const char* filename, std::vector< VoxelModel >& models, uvec4 palette[256] ); 42 | 43 | 44 | -------------------------------------------------------------------------------- /3rdparty/yocto/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(yocto 2 | yocto_math.h yocto_color.h yocto_geometry.h 3 | yocto_noise.h yocto_sampling.h yocto_shading.h 4 | yocto_modelio.h yocto_modelio.cpp 5 | yocto_bvh.h yocto_bvh.cpp 6 | yocto_shape.h yocto_shape.cpp 7 | yocto_mesh.h yocto_mesh.cpp 8 | yocto_image.h yocto_image.cpp 9 | yocto_scene.h yocto_scene.cpp 10 | yocto_trace.h yocto_trace.cpp 11 | yocto_sceneio.h yocto_sceneio.cpp 12 | yocto_cli.h 13 | ext/stb_image.h ext/stb_image_resize.h ext/stb_image_write.h ext/stb_image.cpp 14 | ext/json.hpp 15 | ext/tinyexr.h ext/tinyexr.cpp 16 | ) 17 | 18 | set_target_properties(yocto PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES) 19 | 20 | if(UNIX AND NOT APPLE) 21 | find_package(Threads REQUIRED) 22 | target_link_libraries(yocto Threads::Threads) 23 | endif(UNIX AND NOT APPLE) 24 | 25 | if(YOCTO_EMBREE) 26 | target_compile_definitions(yocto PUBLIC -DYOCTO_EMBREE) 27 | if(APPLE) 28 | target_include_directories(yocto PUBLIC /usr/local/include) 29 | target_link_libraries(yocto /usr/local/lib/libembree3.dylib) 30 | endif(APPLE) 31 | if(MSVC) 32 | target_include_directories(yocto PUBLIC "/Program Files/Intel/Embree3 X64/include" "C:/Program Files/Intel/Embree3 X64/include") 33 | link_directories("/Program Files/Intel/Embree3 X64/lib" "C:/Program Files/Intel/Embree3 X64/lib") 34 | target_link_libraries(yocto embree3 tbb tbbmalloc) 35 | endif(MSVC) 36 | if(UNIX AND NOT APPLE) 37 | target_link_libraries(yocto embree3) 38 | endif() 39 | endif(YOCTO_EMBREE) 40 | 41 | # warning flags 42 | if(APPLE) 43 | target_compile_options(yocto PUBLIC -Wall -Wconversion -Wno-sign-conversion -Wno-implicit-float-conversion) 44 | endif(APPLE) 45 | if(MSVC) 46 | target_compile_options(yocto PUBLIC /D_CRT_SECURE_NO_WARNINGS /wd4018 /wd4244 /wd4305 /wd4800 /wd4267) 47 | target_compile_options(yocto PUBLIC /EHsc) 48 | endif(MSVC) -------------------------------------------------------------------------------- /3rdparty/yocto/ext/stb_image.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Snippet to compile stb_image libraries. 3 | // 4 | 5 | // 6 | // LICENSE: 7 | // 8 | // Copyright (c) 2016 -- 2019 Fabio Pellacini 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | // SOFTWARE. 27 | // 28 | 29 | #if !defined(_WIN32) && !defined(_WIN64) 30 | #pragma GCC diagnostic push 31 | #pragma GCC diagnostic ignored "-Wunused-function" 32 | #pragma GCC diagnostic ignored "-Wunused-variable" 33 | #ifndef __clang__ 34 | #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 35 | #endif 36 | #endif 37 | 38 | // #ifndef _clang_analyzer__ 39 | 40 | #define STB_IMAGE_IMPLEMENTATION 41 | #include "stb_image.h" 42 | 43 | #define STB_IMAGE_WRITE_IMPLEMENTATION 44 | #include "stb_image_write.h" 45 | 46 | #define STB_IMAGE_RESIZE_IMPLEMENTATION 47 | #include "stb_image_resize.h" 48 | 49 | // #endif 50 | 51 | #if !defined(_WIN32) && !defined(_WIN64) 52 | #pragma GCC diagnostic pop 53 | #endif 54 | -------------------------------------------------------------------------------- /3rdparty/yocto/ext/tinyexr.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Snippet to compile stb_image libraries. 3 | // 4 | 5 | // 6 | // LICENSE: 7 | // 8 | // Copyright (c) 2016 -- 2019 Fabio Pellacini 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | // SOFTWARE. 27 | // 28 | 29 | #if !defined(_WIN32) && !defined(_WIN64) 30 | #pragma GCC diagnostic push 31 | #pragma GCC diagnostic ignored "-Wunused-function" 32 | #pragma GCC diagnostic ignored "-Wunused-variable" 33 | #ifndef __clang__ 34 | #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 35 | #endif 36 | #endif 37 | 38 | // #ifndef _clang_analyzer__ 39 | 40 | #if defined(_WIN32) 41 | #ifndef NOMINMAX 42 | #define NOMINMAX 43 | #endif 44 | #endif 45 | 46 | #define TINYEXR_IMPLEMENTATION 47 | #include "tinyexr.h" 48 | 49 | // #endif 50 | 51 | #if !defined(_WIN32) && !defined(_WIN64) 52 | #pragma GCC diagnostic pop 53 | #endif 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 - 2019 Jing Interactive | 静动 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # melo 2 | melo is mesh loader for OBJ, glTF2 and PLY, also includes a `Cinder` based mesh viewer on Windows and macOS. 3 | 4 | # Features 5 | 6 | - Support Windows and macOS 7 | - Can be used outside of Cinder 8 | - Loading OBJ meshes through [syoyo/tinyobjloader](https://github.com/syoyo/tinyobjloader) 9 | - Loading glTF2 meshes through [syoyo/tinygltf](https://github.com/syoyo/tinygltf) 10 | - PBR rendering w/ modified shaders from [KhronosGroup/glTF-WebGL-PBR](https://github.com/KhronosGroup/glTF-WebGL-PBR/tree/master/shaders) 11 | 12 | # TODO 13 | - Implement skinning animation 14 | - Implement morph animation 15 | - Support Linux / Android / iOS 16 | - Support Sketchfab download API 17 | - FrameGraph 18 | 19 | # To build `samples/MeshViewer`, you need: 20 | 21 | * [Cinder](https://github.com/cinder/Cinder) 22 | * [Cinder-VNM](https://github.com/jing-interactive/Cinder-VNM) 23 | 24 | The folder structure should appear like this: 25 | 26 | ``` 27 | Cinder/ 28 | blocks/ 29 | Cinder-VNM/ 30 | melo/ 31 | samples/MeshViewer/vc2015/MeshViewer.sln 32 | assets/ 33 | Cube/ 34 | Cube.gltf 35 | cerberus/ 36 | Cerberus.obj 37 | Awesome-gltf-files/ 38 | scene.gltf 39 | scene.bin 40 | Symbolic-links-are-also-supported 41 | include/ 42 | ``` 43 | 44 | # PBR shader macros 45 | 46 | ## vertex inputs 47 | 48 | - HAS_NORMALS 49 | - HAS_TANGENTS 50 | - HAS_VERTEX_COLOR_VEC4 51 | - HAS_UV_SET1 52 | - HAS_UV_SET2 53 | 54 | - USE_MORPHING 55 | - USE_SKINNING 56 | 57 | - HAS_TARGET_POSITION0 58 | - HAS_TARGET_POSITION1 59 | - HAS_TARGET_POSITION2 60 | - HAS_TARGET_POSITION3 61 | - HAS_TARGET_POSITION4 62 | - HAS_TARGET_POSITION5 63 | - HAS_TARGET_POSITION6 64 | - HAS_TARGET_POSITION7 65 | - HAS_TARGET_NORMAL0 66 | - HAS_TARGET_NORMAL1 67 | - HAS_TARGET_NORMAL2 68 | - HAS_TARGET_NORMAL3 69 | - HAS_TARGET_NORMAL4 70 | - HAS_TARGET_TANGENT0 71 | - HAS_TARGET_TANGENT1 72 | - HAS_TARGET_TANGENT2 73 | - HAS_TARGET_TANGENT3 74 | - HAS_TARGET_TANGENT4 75 | - HAS_JOINT_SET1 76 | - HAS_JOINT_SET2 77 | - HAS_JOINT_SET3 78 | - HAS_JOINT_SET4 79 | - HAS_WEIGHT_SET1 80 | - HAS_WEIGHT_SET2 81 | 82 | 83 | ## material types 84 | - MATERIAL_SPECULARGLOSSINESS 85 | - MATERIAL_METALLICROUGHNESS 86 | - MATERIAL_UNLIT 87 | - MATERIAL_ANISOTROPY 88 | - MATERIAL_SUBSURFACE 89 | - MATERIAL_THIN_FILM 90 | - MATERIAL_THICKNESS 91 | - MATERIAL_ABSORPTION 92 | - MATERIAL_IOR 93 | - MATERIAL_TRANSMISSION 94 | 95 | ## texture maps 96 | - HAS_BASE_COLOR_MAP 97 | - HAS_NORMAL_MAP 98 | - HAS_METALLIC_ROUGHNESS_MAP 99 | - HAS_OCCLUSION_MAP 100 | - HAS_EMISSIVE_MAP 101 | - HAS_SUBSURFACE_COLOR_MAP 102 | - HAS_SUBSURFACE_THICKNESS_MAP 103 | - HAS_ANISOTROPY_MAP 104 | - HAS_ANISOTROPY_DIRECTION_MAP 105 | - HAS_SPECULAR_GLOSSINESS_MAP 106 | - HAS_METALLICROUGHNESS_SPECULAROVERRIDE_MAP 107 | - HAS_SHEEN_COLOR_INTENSITY_MAP 108 | - HAS_THIN_FILM_MAP 109 | - HAS_THIN_FILM_THICKNESS_MAP 110 | - HAS_THICKNESS_MAP 111 | - HAS_CLEARCOAT_TEXTURE_MAP 112 | - HAS_CLEARCOAT_ROUGHNESS_MAP 113 | - HAS_CLEARCOAT_NORMAL_MAP 114 | 115 | ## alpha mode 116 | - ALPHAMODE_OPAQUE 117 | - ALPHAMODE_MASK 118 | 119 | ## use misc 120 | - USE_IBL 121 | - USE_PUNCTUAL 122 | 123 | ## debug 124 | 125 | - DEBUG_BASECOLOR 126 | - DEBUG_ALPHA 127 | - DEBUG_NORMAL 128 | - DEBUG_TANGENT 129 | - DEBUG_METALLIC 130 | - DEBUG_ROUGHNESS 131 | - DEBUG_BITANGENT 132 | - DEBUG_OCCLUSION 133 | - DEBUG_F0 134 | - DEBUG_FEMISSIVE 135 | - DEBUG_FSPECULAR 136 | - DEBUG_FDIFFUSE 137 | - DEBUG_FSHEEN 138 | - DEBUG_FCLEARCOAT 139 | - DEBUG_FSUBSURFACE 140 | - DEBUG_THICKNESS 141 | - DEBUG_FTRANSMISSION 142 | -------------------------------------------------------------------------------- /assets/CathedralIrradiance.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/assets/CathedralIrradiance.dds -------------------------------------------------------------------------------- /assets/CathedralRadiance.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/assets/CathedralRadiance.dds -------------------------------------------------------------------------------- /assets/SkyBox.frag: -------------------------------------------------------------------------------- 1 | #include "common.glsl" 2 | 3 | uniform samplerCube uCubeMapTex; 4 | uniform float uExposure; 5 | uniform float uGamma; 6 | 7 | in vec3 vDirection; 8 | 9 | out vec4 oColor; 10 | 11 | void main( void ) 12 | { 13 | vec3 color = pow( texture( uCubeMapTex, vDirection ).rgb, vec3( 2.2f ) ); 14 | 15 | // apply the tone-mapping 16 | color = Uncharted2Tonemap( color * uExposure ); 17 | // white balance 18 | color = color * ( 1.0f / Uncharted2Tonemap( vec3( 20.0f ) ) ); 19 | 20 | // gamma correction 21 | color = pow( color, vec3( 1.0f / uGamma ) ); 22 | oColor = vec4( color, 1.0 ); 23 | } -------------------------------------------------------------------------------- /assets/SkyBox.vert: -------------------------------------------------------------------------------- 1 | uniform mat4 ciViewMatrix; 2 | uniform mat4 ciProjectionMatrix; 3 | 4 | in vec4 ciPosition; 5 | 6 | out vec3 vDirection; 7 | 8 | void main( void ) 9 | { 10 | vDirection = vec3( ciPosition ); 11 | mat4 rotMat = mat4(mat3(ciViewMatrix)); 12 | gl_Position = ciProjectionMatrix * rotMat * ciPosition; 13 | gl_Position.w = gl_Position.z; 14 | } 15 | -------------------------------------------------------------------------------- /assets/common.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision mediump float; 3 | #endif 4 | 5 | const float M_PI = 3.141592653589793; 6 | const float c_MinRoughness = 0.04; 7 | 8 | // Filmic tonemapping from 9 | // http://filmicgames.com/archives/75 10 | 11 | const float A = 0.15; 12 | const float B = 0.50; 13 | const float C = 0.10; 14 | const float D = 0.20; 15 | const float E = 0.02; 16 | const float F = 0.30; 17 | 18 | vec3 Uncharted2Tonemap( vec3 x ) 19 | { 20 | return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; 21 | } 22 | 23 | 24 | // https://www.unrealengine.com/blog/physically-based-shading-on-mobile 25 | vec3 EnvBRDFApprox( vec3 SpecularColor, float Roughness, float NoV ) 26 | { 27 | const vec4 c0 = vec4( -1, -0.0275, -0.572, 0.022 ); 28 | const vec4 c1 = vec4( 1, 0.0425, 1.04, -0.04 ); 29 | vec4 r = Roughness * c0 + c1; 30 | float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y; 31 | vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; 32 | return SpecularColor * AB.x + AB.y; 33 | } 34 | 35 | 36 | // http://the-witness.net/news/2012/02/seamless-cube-map-filtering/ 37 | vec3 fix_cube_lookup( vec3 v, float cube_size, float lod ) { 38 | float M = max(max(abs(v.x), abs(v.y)), abs(v.z)); 39 | float scale = 1.0 - exp2(lod) / cube_size; 40 | if (abs(v.x) != M) v.x *= scale; 41 | if (abs(v.y) != M) v.y *= scale; 42 | if (abs(v.z) != M) v.z *= scale; 43 | return v; 44 | } 45 | 46 | // Normal Blending 47 | // Source adapted from http://blog.selfshadow.com/publications/blending-in-detail/ 48 | vec3 blendNormalsUnity( vec3 baseNormal, vec3 detailsNormal ) 49 | { 50 | vec3 n1 = baseNormal; 51 | vec3 n2 = detailsNormal; 52 | mat3 nBasis = mat3( 53 | vec3(n1.z, n1.y, -n1.x), // +90 degree rotation around y axis 54 | vec3(n1.x, n1.z, -n1.y), // -90 degree rotation around x axis 55 | vec3(n1.x, n1.y, n1.z)); 56 | return normalize(n2.x*nBasis[0] + n2.y*nBasis[1] + n2.z*nBasis[2]); 57 | } 58 | 59 | vec4 SRGBtoLINEAR(vec4 srgbIn) 60 | { 61 | #ifdef MANUAL_SRGB 62 | #ifdef SRGB_FAST_APPROXIMATION 63 | vec3 linOut = pow(srgbIn.xyz,vec3(2.2)); 64 | #else //SRGB_FAST_APPROXIMATION 65 | vec3 bLess = step(vec3(0.04045),srgbIn.xyz); 66 | vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess ); 67 | #endif //SRGB_FAST_APPROXIMATION 68 | return vec4(linOut,srgbIn.w);; 69 | #else //MANUAL_SRGB 70 | return srgbIn; 71 | #endif //MANUAL_SRGB 72 | } 73 | 74 | // Gets metallic factor from specular glossiness workflow inputs 75 | float convertMetallic(vec3 diffuse, vec3 specular, float maxSpecular) { 76 | float perceivedDiffuse = sqrt(0.299 * diffuse.r * diffuse.r + 0.587 * diffuse.g * diffuse.g + 0.114 * diffuse.b * diffuse.b); 77 | float perceivedSpecular = sqrt(0.299 * specular.r * specular.r + 0.587 * specular.g * specular.g + 0.114 * specular.b * specular.b); 78 | if (perceivedSpecular < c_MinRoughness) { 79 | return 0.0; 80 | } 81 | float a = c_MinRoughness; 82 | float b = perceivedDiffuse * (1.0 - maxSpecular) / (1.0 - c_MinRoughness) + perceivedSpecular - 2.0 * c_MinRoughness; 83 | float c = c_MinRoughness - perceivedSpecular; 84 | float D = max(b * b - 4.0 * a * c, 0.0); 85 | return clamp((-b + sqrt(D)) / (2.0 * a), 0.0, 1.0); 86 | } 87 | -------------------------------------------------------------------------------- /assets/pbr.vert: -------------------------------------------------------------------------------- 1 | in vec4 ciPosition; 2 | #ifdef HAS_NORMALS 3 | in vec4 ciNormal; 4 | #endif 5 | #ifdef HAS_TANGENTS 6 | in vec4 ciTangent; 7 | #endif 8 | #ifdef HAS_UV 9 | in vec2 ciTexCoord0; 10 | #endif 11 | #ifdef HAS_COLOR 12 | in vec4 ciColor; 13 | #endif 14 | 15 | uniform mat4 ciModelViewProjection; 16 | uniform mat4 ciModelMatrix; 17 | 18 | // shadow mapping 19 | uniform mat4 uShadowMatrix; 20 | out vec4 vShadowCoord; 21 | 22 | out vec3 v_Position; // in world space 23 | out vec2 v_UV; 24 | 25 | uniform bool u_flipV; 26 | 27 | #ifdef HAS_NORMALS 28 | #ifdef HAS_TANGENTS 29 | out mat3 v_TBN; 30 | #else 31 | out vec3 v_Normal; 32 | #endif 33 | #endif 34 | #ifdef HAS_COLOR 35 | out vec4 v_Color; 36 | #endif 37 | 38 | const mat4 biasMatrix = mat4( 0.5, 0.0, 0.0, 0.0, 39 | 0.0, 0.5, 0.0, 0.0, 40 | 0.0, 0.0, 0.5, 0.0, 41 | 0.5, 0.5, 0.5, 1.0 ); 42 | 43 | void main() 44 | { 45 | vec4 pos = ciModelMatrix * ciPosition; 46 | v_Position = vec3(pos.xyz) / pos.w; 47 | vShadowCoord = ( biasMatrix * uShadowMatrix * ciModelMatrix ) * ciPosition; 48 | 49 | #ifdef HAS_NORMALS 50 | #ifdef HAS_TANGENTS 51 | vec3 normalW = normalize(vec3(ciModelMatrix * vec4(ciNormal.xyz, 0.0))); 52 | vec3 tangentW = normalize(vec3(ciModelMatrix * vec4(ciTangent.xyz, 0.0))); 53 | vec3 bitangentW = cross(normalW, tangentW) * ciTangent.w; 54 | v_TBN = mat3(tangentW, bitangentW, normalW); 55 | #else // HAS_TANGENTS != 1 56 | v_Normal = normalize(vec3(ciModelMatrix * vec4(ciNormal.xyz, 0.0))); 57 | #endif 58 | #endif 59 | 60 | #ifdef HAS_UV 61 | v_UV = ciTexCoord0; 62 | if (u_flipV) { 63 | v_UV.t = 1.0 - v_UV.t; 64 | } 65 | #else 66 | v_UV = vec2(0.,0.); 67 | #endif 68 | #ifdef HAS_COLOR 69 | v_Color = ciColor; 70 | #endif 71 | gl_Position = ciModelViewProjection * ciPosition; // needs w for proper perspective correction 72 | } 73 | -------------------------------------------------------------------------------- /assets/pbr/animation.glsl: -------------------------------------------------------------------------------- 1 | #ifdef HAS_TARGET_POSITION0 2 | in vec3 a_Target_Position0; 3 | #endif 4 | 5 | #ifdef HAS_TARGET_POSITION1 6 | in vec3 a_Target_Position1; 7 | #endif 8 | 9 | #ifdef HAS_TARGET_POSITION2 10 | in vec3 a_Target_Position2; 11 | #endif 12 | 13 | #ifdef HAS_TARGET_POSITION3 14 | in vec3 a_Target_Position3; 15 | #endif 16 | 17 | #ifdef HAS_TARGET_POSITION4 18 | in vec3 a_Target_Position4; 19 | #endif 20 | 21 | #ifdef HAS_TARGET_POSITION5 22 | in vec3 a_Target_Position5; 23 | #endif 24 | 25 | #ifdef HAS_TARGET_POSITION6 26 | in vec3 a_Target_Position6; 27 | #endif 28 | 29 | #ifdef HAS_TARGET_POSITION7 30 | in vec3 a_Target_Position7; 31 | #endif 32 | 33 | #ifdef HAS_TARGET_NORMAL0 34 | in vec3 a_Target_Normal0; 35 | #endif 36 | 37 | #ifdef HAS_TARGET_NORMAL1 38 | in vec3 a_Target_Normal1; 39 | #endif 40 | 41 | #ifdef HAS_TARGET_NORMAL2 42 | in vec3 a_Target_Normal2; 43 | #endif 44 | 45 | #ifdef HAS_TARGET_NORMAL3 46 | in vec3 a_Target_Normal3; 47 | #endif 48 | 49 | #ifdef HAS_TARGET_TANGENT0 50 | in vec3 a_Target_Tangent0; 51 | #endif 52 | 53 | #ifdef HAS_TARGET_TANGENT1 54 | in vec3 a_Target_Tangent1; 55 | #endif 56 | 57 | #ifdef HAS_TARGET_TANGENT2 58 | in vec3 a_Target_Tangent2; 59 | #endif 60 | 61 | #ifdef HAS_TARGET_TANGENT3 62 | in vec3 a_Target_Tangent3; 63 | #endif 64 | 65 | #ifdef USE_MORPHING 66 | uniform float u_morphWeights[WEIGHT_COUNT]; 67 | #endif 68 | 69 | #ifdef HAS_JOINT_SET1 70 | in vec4 a_Joint1; 71 | #endif 72 | 73 | #ifdef HAS_JOINT_SET2 74 | in vec4 a_Joint2; 75 | #endif 76 | 77 | #ifdef HAS_WEIGHT_SET1 78 | in vec4 a_Weight1; 79 | #endif 80 | 81 | #ifdef HAS_WEIGHT_SET2 82 | in vec4 a_Weight2; 83 | #endif 84 | 85 | #ifdef USE_SKINNING 86 | uniform mat4 u_jointMatrix[JOINT_COUNT]; 87 | uniform mat4 u_jointNormalMatrix[JOINT_COUNT]; 88 | #endif 89 | 90 | #ifdef USE_SKINNING 91 | mat4 getSkinningMatrix() 92 | { 93 | mat4 skin = mat4(0); 94 | 95 | #if defined(HAS_WEIGHT_SET1) && defined(HAS_JOINT_SET1) 96 | skin += 97 | a_Weight1.x * u_jointMatrix[int(a_Joint1.x)] + 98 | a_Weight1.y * u_jointMatrix[int(a_Joint1.y)] + 99 | a_Weight1.z * u_jointMatrix[int(a_Joint1.z)] + 100 | a_Weight1.w * u_jointMatrix[int(a_Joint1.w)]; 101 | #endif 102 | 103 | #if defined(HAS_WEIGHT_SET2) && defined(HAS_JOINT_SET2) 104 | skin += 105 | a_Weight2.x * u_jointMatrix[int(a_Joint2.x)] + 106 | a_Weight2.y * u_jointMatrix[int(a_Joint2.y)] + 107 | a_Weight2.z * u_jointMatrix[int(a_Joint2.z)] + 108 | a_Weight2.w * u_jointMatrix[int(a_Joint2.w)]; 109 | #endif 110 | 111 | return skin; 112 | } 113 | 114 | mat4 getSkinningNormalMatrix() 115 | { 116 | mat4 skin = mat4(0); 117 | 118 | #if defined(HAS_WEIGHT_SET1) && defined(HAS_JOINT_SET1) 119 | skin += 120 | a_Weight1.x * u_jointNormalMatrix[int(a_Joint1.x)] + 121 | a_Weight1.y * u_jointNormalMatrix[int(a_Joint1.y)] + 122 | a_Weight1.z * u_jointNormalMatrix[int(a_Joint1.z)] + 123 | a_Weight1.w * u_jointNormalMatrix[int(a_Joint1.w)]; 124 | #endif 125 | 126 | #if defined(HAS_WEIGHT_SET2) && defined(HAS_JOINT_SET2) 127 | skin += 128 | a_Weight2.x * u_jointNormalMatrix[int(a_Joint2.x)] + 129 | a_Weight2.y * u_jointNormalMatrix[int(a_Joint2.y)] + 130 | a_Weight2.z * u_jointNormalMatrix[int(a_Joint2.z)] + 131 | a_Weight2.w * u_jointNormalMatrix[int(a_Joint2.w)]; 132 | #endif 133 | 134 | return skin; 135 | } 136 | #endif // !USE_SKINNING 137 | 138 | #ifdef USE_MORPHING 139 | vec4 getTargetPosition() 140 | { 141 | vec4 pos = vec4(0); 142 | 143 | #ifdef HAS_TARGET_POSITION0 144 | pos.xyz += u_morphWeights[0] * a_Target_Position0; 145 | #endif 146 | 147 | #ifdef HAS_TARGET_POSITION1 148 | pos.xyz += u_morphWeights[1] * a_Target_Position1; 149 | #endif 150 | 151 | #ifdef HAS_TARGET_POSITION2 152 | pos.xyz += u_morphWeights[2] * a_Target_Position2; 153 | #endif 154 | 155 | #ifdef HAS_TARGET_POSITION3 156 | pos.xyz += u_morphWeights[3] * a_Target_Position3; 157 | #endif 158 | 159 | #ifdef HAS_TARGET_POSITION4 160 | pos.xyz += u_morphWeights[4] * a_Target_Position4; 161 | #endif 162 | 163 | return pos; 164 | } 165 | 166 | vec3 getTargetNormal() 167 | { 168 | vec3 normal = vec3(0); 169 | 170 | #ifdef HAS_TARGET_NORMAL0 171 | normal += u_morphWeights[0] * a_Target_Normal0; 172 | #endif 173 | 174 | #ifdef HAS_TARGET_NORMAL1 175 | normal += u_morphWeights[1] * a_Target_Normal1; 176 | #endif 177 | 178 | #ifdef HAS_TARGET_NORMAL2 179 | normal += u_morphWeights[2] * a_Target_Normal2; 180 | #endif 181 | 182 | #ifdef HAS_TARGET_NORMAL3 183 | normal += u_morphWeights[3] * a_Target_Normal3; 184 | #endif 185 | 186 | #ifdef HAS_TARGET_NORMAL4 187 | normal += u_morphWeights[4] * a_Target_Normal4; 188 | #endif 189 | 190 | return normal; 191 | } 192 | 193 | vec3 getTargetTangent() 194 | { 195 | vec3 tangent = vec3(0); 196 | 197 | #ifdef HAS_TARGET_TANGENT0 198 | tangent += u_morphWeights[0] * a_Target_Tangent0; 199 | #endif 200 | 201 | #ifdef HAS_TARGET_TANGENT1 202 | tangent += u_morphWeights[1] * a_Target_Tangent1; 203 | #endif 204 | 205 | #ifdef HAS_TARGET_TANGENT2 206 | tangent += u_morphWeights[2] * a_Target_Tangent2; 207 | #endif 208 | 209 | #ifdef HAS_TARGET_TANGENT3 210 | tangent += u_morphWeights[3] * a_Target_Tangent3; 211 | #endif 212 | 213 | #ifdef HAS_TARGET_TANGENT4 214 | tangent += u_morphWeights[4] * a_Target_Tangent4; 215 | #endif 216 | 217 | return tangent; 218 | } 219 | 220 | #endif // !USE_MORPHING 221 | -------------------------------------------------------------------------------- /assets/pbr/brdf.glsl: -------------------------------------------------------------------------------- 1 | // 2 | // Fresnel 3 | // 4 | // http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html 5 | // https://github.com/wdas/brdf/tree/master/src/brdfs 6 | // https://google.github.io/filament/Filament.md.html 7 | // 8 | 9 | // The following equation models the Fresnel reflectance term of the spec equation (aka F()) 10 | // Implementation of fresnel from [4], Equation 15 11 | vec3 F_Schlick(vec3 f0, vec3 f90, float VdotH) 12 | { 13 | return f0 + (f90 - f0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0); 14 | } 15 | 16 | // Smith Joint GGX 17 | // Note: Vis = G / (4 * NdotL * NdotV) 18 | // see Eric Heitz. 2014. Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs. Journal of Computer Graphics Techniques, 3 19 | // see Real-Time Rendering. Page 331 to 336. 20 | // see https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/geometricshadowing(specularg) 21 | float V_GGX(float NdotL, float NdotV, float alphaRoughness) 22 | { 23 | float alphaRoughnessSq = alphaRoughness * alphaRoughness; 24 | 25 | float GGXV = NdotL * sqrt(NdotV * NdotV * (1.0 - alphaRoughnessSq) + alphaRoughnessSq); 26 | float GGXL = NdotV * sqrt(NdotL * NdotL * (1.0 - alphaRoughnessSq) + alphaRoughnessSq); 27 | 28 | float GGX = GGXV + GGXL; 29 | if (GGX > 0.0) 30 | { 31 | return 0.5 / GGX; 32 | } 33 | return 0.0; 34 | } 35 | 36 | // The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D()) 37 | // Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz 38 | // Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3. 39 | float D_GGX(float NdotH, float alphaRoughness) 40 | { 41 | float alphaRoughnessSq = alphaRoughness * alphaRoughness; 42 | float f = (NdotH * NdotH) * (alphaRoughnessSq - 1.0) + 1.0; 43 | return alphaRoughnessSq / (M_PI * f * f); 44 | } 45 | 46 | float lambdaSheenNumericHelper(float x, float alphaG) 47 | { 48 | float oneMinusAlphaSq = (1.0 - alphaG) * (1.0 - alphaG); 49 | float a = mix(21.5473, 25.3245, oneMinusAlphaSq); 50 | float b = mix(3.82987, 3.32435, oneMinusAlphaSq); 51 | float c = mix(0.19823, 0.16801, oneMinusAlphaSq); 52 | float d = mix(-1.97760, -1.27393, oneMinusAlphaSq); 53 | float e = mix(-4.32054, -4.85967, oneMinusAlphaSq); 54 | return a / (1.0 + b * pow(x, c)) + d * x + e; 55 | } 56 | 57 | float lambdaSheen(float cosTheta, float alphaG) 58 | { 59 | if(abs(cosTheta) < 0.5) 60 | { 61 | return exp(lambdaSheenNumericHelper(cosTheta, alphaG)); 62 | } 63 | else 64 | { 65 | return exp(2.0 * lambdaSheenNumericHelper(0.5, alphaG) - lambdaSheenNumericHelper(1.0 - cosTheta, alphaG)); 66 | } 67 | } 68 | 69 | float V_Sheen(float NdotL, float NdotV, float sheenRoughness) 70 | { 71 | sheenRoughness = max(sheenRoughness, 0.000001); //clamp (0,1] 72 | float alphaG = sheenRoughness * sheenRoughness; 73 | 74 | return clamp(1.0 / ((1.0 + lambdaSheen(NdotV, alphaG) + lambdaSheen(NdotL, alphaG)) * 75 | (4.0 * NdotV * NdotL)), 0.0, 1.0); 76 | } 77 | 78 | //Sheen implementation------------------------------------------------------------------------------------- 79 | // See https://github.com/sebavan/glTF/tree/KHR_materials_sheen/extensions/2.0/Khronos/KHR_materials_sheen 80 | 81 | // Estevez and Kulla http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf 82 | float D_Charlie(float sheenRoughness, float NdotH) 83 | { 84 | sheenRoughness = max(sheenRoughness, 0.000001); //clamp (0,1] 85 | float alphaG = sheenRoughness * sheenRoughness; 86 | float invR = 1.0 / alphaG; 87 | float cos2h = NdotH * NdotH; 88 | float sin2h = 1.0 - cos2h; 89 | return (2.0 + invR) * pow(sin2h, invR * 0.5) / (2.0 * M_PI); 90 | } 91 | 92 | //https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#acknowledgments AppendixB 93 | vec3 BRDF_lambertian(vec3 f0, vec3 f90, vec3 diffuseColor, float specularWeight, float VdotH) 94 | { 95 | // see https://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ 96 | return (1.0 - specularWeight * F_Schlick(f0, f90, VdotH)) * (diffuseColor / M_PI); 97 | } 98 | 99 | // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#acknowledgments AppendixB 100 | vec3 BRDF_specularGGX(vec3 f0, vec3 f90, float alphaRoughness, float specularWeight, float VdotH, float NdotL, float NdotV, float NdotH) 101 | { 102 | vec3 F = F_Schlick(f0, f90, VdotH); 103 | float Vis = V_GGX(NdotL, NdotV, alphaRoughness); 104 | float D = D_GGX(NdotH, alphaRoughness); 105 | 106 | return specularWeight * F * Vis * D; 107 | } 108 | 109 | // f_sheen 110 | vec3 BRDF_specularSheen(vec3 sheenColor, float sheenRoughness, float NdotL, float NdotV, float NdotH) 111 | { 112 | float sheenDistribution = D_Charlie(sheenRoughness, NdotH); 113 | float sheenVisibility = V_Sheen(NdotL, NdotV, sheenRoughness); 114 | return sheenColor * sheenDistribution * sheenVisibility; 115 | } 116 | -------------------------------------------------------------------------------- /assets/pbr/cubemap.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | #include 4 | 5 | uniform samplerCube u_specularEnvSampler; 6 | uniform float u_envBlurNormalized; 7 | uniform int u_MipCount; 8 | 9 | out vec4 FragColor; 10 | in vec3 TexCoords; 11 | 12 | void main() 13 | { 14 | vec4 color = textureLod(u_specularEnvSampler, TexCoords, u_envBlurNormalized * float(u_MipCount - 1)); 15 | FragColor = vec4(toneMap(color.rgb), color.a); 16 | } 17 | -------------------------------------------------------------------------------- /assets/pbr/cubemap.vert: -------------------------------------------------------------------------------- 1 | in vec3 a_position; 2 | out vec3 TexCoords; 3 | 4 | uniform mat4 u_ViewProjectionMatrix; 5 | uniform mat3 u_envRotation; 6 | 7 | void main() 8 | { 9 | TexCoords = u_envRotation * a_position; 10 | mat4 mat = u_ViewProjectionMatrix; 11 | mat[3] = vec4(0.0, 0.0, 0.0, 0.1); 12 | vec4 pos = mat * vec4(a_position, 1.0); 13 | gl_Position = pos.xyww; 14 | } 15 | -------------------------------------------------------------------------------- /assets/pbr/functions.glsl: -------------------------------------------------------------------------------- 1 | // textures.glsl needs to be included 2 | 3 | const float M_PI = 3.141592653589793; 4 | 5 | in vec3 v_Position; 6 | 7 | #ifdef HAS_NORMALS 8 | #ifdef HAS_TANGENTS 9 | in mat3 v_TBN; 10 | #else 11 | in vec3 v_Normal; 12 | #endif 13 | #endif 14 | 15 | #ifdef HAS_VERTEX_COLOR_VEC3 16 | in vec3 v_Color; 17 | #endif 18 | #ifdef HAS_VERTEX_COLOR_VEC4 19 | in vec4 v_Color; 20 | #endif 21 | 22 | vec4 getVertexColor() 23 | { 24 | vec4 color = vec4(1.0, 1.0, 1.0, 1.0); 25 | 26 | #ifdef HAS_VERTEX_COLOR_VEC3 27 | color.rgb = v_Color.rgb; 28 | #endif 29 | #ifdef HAS_VERTEX_COLOR_VEC4 30 | color = v_Color; 31 | #endif 32 | 33 | return color; 34 | } 35 | 36 | struct NormalInfo { 37 | vec3 ng; // Geometric normal 38 | vec3 n; // Pertubed normal 39 | vec3 t; // Pertubed tangent 40 | vec3 b; // Pertubed bitangent 41 | }; 42 | 43 | float clampedDot(vec3 x, vec3 y) 44 | { 45 | return clamp(dot(x, y), 0.0, 1.0); 46 | } 47 | 48 | float max3(vec3 v) 49 | { 50 | return max(max(v.x, v.y), v.z); 51 | } 52 | 53 | 54 | float applyIorToRoughness(float roughness, float ior) 55 | { 56 | // Scale roughness with IOR so that an IOR of 1.0 results in no microfacet refraction and 57 | // an IOR of 1.5 results in the default amount of microfacet refraction. 58 | return roughness * clamp(ior * 2.0 - 2.0, 0.0, 1.0); 59 | } 60 | -------------------------------------------------------------------------------- /assets/pbr/ibl.glsl: -------------------------------------------------------------------------------- 1 | vec3 getDiffuseLight(vec3 n) 2 | { 3 | return texture(u_LambertianEnvSampler, u_envRotation * n).rgb; 4 | } 5 | 6 | vec4 getSpecularSample(vec3 reflection, float lod) 7 | { 8 | return textureLod(u_GGXEnvSampler, u_envRotation * reflection, lod); 9 | } 10 | 11 | vec4 getSheenSample(vec3 reflection, float lod) 12 | { 13 | return textureLod(u_CharlieEnvSampler, u_envRotation * reflection, lod); 14 | } 15 | 16 | vec3 getIBLRadianceGGX(vec3 n, vec3 v, float roughness, vec3 F0, float specularWeight) 17 | { 18 | float NdotV = clampedDot(n, v); 19 | float lod = roughness * float(u_MipCount - 1); 20 | vec3 reflection = normalize(reflect(-v, n)); 21 | 22 | vec2 brdfSamplePoint = clamp(vec2(NdotV, roughness), vec2(0.0, 0.0), vec2(1.0, 1.0)); 23 | vec2 f_ab = texture(u_GGXLUT, brdfSamplePoint).rg; 24 | vec4 specularSample = getSpecularSample(reflection, lod); 25 | 26 | vec3 specularLight = specularSample.rgb; 27 | 28 | // see https://bruop.github.io/ibl/#single_scattering_results at Single Scattering Results 29 | // Roughness dependent fresnel, from Fdez-Aguera 30 | vec3 Fr = max(vec3(1.0 - roughness), F0) - F0; 31 | vec3 k_S = F0 + Fr * pow(1.0 - NdotV, 5.0); 32 | vec3 FssEss = k_S * f_ab.x + f_ab.y; 33 | 34 | return specularWeight * specularLight * FssEss; 35 | } 36 | 37 | vec3 getTransmissionSample(vec2 fragCoord, float roughness, float ior) 38 | { 39 | float framebufferLod = log2(float(u_TransmissionFramebufferSize.x)) * applyIorToRoughness(roughness, ior); 40 | vec3 transmittedLight = textureLod(u_TransmissionFramebufferSampler, fragCoord.xy, framebufferLod).rgb; 41 | transmittedLight = sRGBToLinear(transmittedLight); 42 | return transmittedLight; 43 | } 44 | 45 | 46 | vec3 getIBLVolumeRefraction(vec3 n, vec3 v, float perceptualRoughness, vec3 baseColor, vec3 f0, vec3 f90, 47 | vec3 position, mat4 modelMatrix, mat4 viewMatrix, mat4 projMatrix, float ior, float thickness, vec3 attenuationColor, float attenuationDistance) 48 | { 49 | vec3 transmissionRay = getVolumeTransmissionRay(n, v, thickness, ior, modelMatrix); 50 | vec3 refractedRayExit = position + transmissionRay; 51 | 52 | // Project refracted vector on the framebuffer, while mapping to normalized device coordinates. 53 | vec4 ndcPos = projMatrix * viewMatrix * vec4(refractedRayExit, 1.0); 54 | vec2 refractionCoords = ndcPos.xy / ndcPos.w; 55 | refractionCoords += 1.0; 56 | refractionCoords /= 2.0; 57 | 58 | // Sample framebuffer to get pixel the refracted ray hits. 59 | vec3 transmittedLight = getTransmissionSample(refractionCoords, perceptualRoughness, ior); 60 | 61 | vec3 attenuatedColor = applyVolumeAttenuation(transmittedLight, length(transmissionRay), attenuationColor, attenuationDistance); 62 | 63 | // Sample GGX LUT to get the specular component. 64 | float NdotV = clampedDot(n, v); 65 | vec2 brdfSamplePoint = clamp(vec2(NdotV, perceptualRoughness), vec2(0.0, 0.0), vec2(1.0, 1.0)); 66 | vec2 brdf = texture(u_GGXLUT, brdfSamplePoint).rg; 67 | vec3 specularColor = f0 * brdf.x + f90 * brdf.y; 68 | 69 | return (1.0 - specularColor) * attenuatedColor * baseColor; 70 | } 71 | 72 | // specularWeight is introduced with KHR_materials_specular 73 | vec3 getIBLRadianceLambertian(vec3 n, vec3 v, float roughness, vec3 diffuseColor, vec3 F0, float specularWeight) 74 | { 75 | float NdotV = clampedDot(n, v); 76 | vec2 brdfSamplePoint = clamp(vec2(NdotV, roughness), vec2(0.0, 0.0), vec2(1.0, 1.0)); 77 | vec2 f_ab = texture(u_GGXLUT, brdfSamplePoint).rg; 78 | 79 | vec3 irradiance = getDiffuseLight(n); 80 | 81 | // see https://bruop.github.io/ibl/#single_scattering_results at Single Scattering Results 82 | // Roughness dependent fresnel, from Fdez-Aguera 83 | 84 | vec3 Fr = max(vec3(1.0 - roughness), F0) - F0; 85 | vec3 k_S = F0 + Fr * pow(1.0 - NdotV, 5.0); 86 | vec3 FssEss = specularWeight * k_S * f_ab.x + f_ab.y; // <--- GGX / specular light contribution (scale it down if the specularWeight is low) 87 | 88 | // Multiple scattering, from Fdez-Aguera 89 | float Ems = (1.0 - (f_ab.x + f_ab.y)); 90 | vec3 F_avg = specularWeight * (F0 + (1.0 - F0) / 21.0); 91 | vec3 FmsEms = Ems * FssEss * F_avg / (1.0 - F_avg * Ems); 92 | vec3 k_D = diffuseColor * (1.0 - FssEss + FmsEms); // we use +FmsEms as indicated by the formula in the blog post (might be a typo in the implementation) 93 | 94 | return (FmsEms + k_D) * irradiance; 95 | } 96 | 97 | vec3 getIBLRadianceCharlie(vec3 n, vec3 v, float sheenRoughness, vec3 sheenColor) 98 | { 99 | float NdotV = clampedDot(n, v); 100 | float lod = sheenRoughness * float(u_MipCount - 1); 101 | vec3 reflection = normalize(reflect(-v, n)); 102 | 103 | vec2 brdfSamplePoint = clamp(vec2(NdotV, sheenRoughness), vec2(0.0, 0.0), vec2(1.0, 1.0)); 104 | float brdf = texture(u_CharlieLUT, brdfSamplePoint).b; 105 | vec4 sheenSample = getSheenSample(reflection, lod); 106 | 107 | vec3 sheenLight = sheenSample.rgb; 108 | return sheenLight * sheenColor * brdf; 109 | } 110 | -------------------------------------------------------------------------------- /assets/pbr/lut_charlie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/assets/pbr/lut_charlie.png -------------------------------------------------------------------------------- /assets/pbr/lut_ggx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/assets/pbr/lut_ggx.png -------------------------------------------------------------------------------- /assets/pbr/lut_thin_film.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/assets/pbr/lut_thin_film.png -------------------------------------------------------------------------------- /assets/pbr/primitive.vert: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | in vec3 a_Position; 4 | out vec3 v_Position; 5 | 6 | #ifdef HAS_NORMALS 7 | in vec3 a_Normal; 8 | #endif 9 | 10 | #ifdef HAS_TANGENTS 11 | in vec4 a_Tangent; 12 | #endif 13 | 14 | #ifdef HAS_NORMALS 15 | #ifdef HAS_TANGENTS 16 | out mat3 v_TBN; 17 | #else 18 | out vec3 v_Normal; 19 | #endif 20 | #endif 21 | 22 | #ifdef HAS_UV_SET1 23 | in vec2 a_UV1; 24 | #endif 25 | 26 | #ifdef HAS_UV_SET2 27 | in vec2 a_UV2; 28 | #endif 29 | 30 | out vec2 v_UVCoord1; 31 | out vec2 v_UVCoord2; 32 | 33 | #ifdef HAS_VERTEX_COLOR_VEC3 34 | in vec3 a_Color; 35 | out vec3 v_Color; 36 | #endif 37 | 38 | #ifdef HAS_VERTEX_COLOR_VEC4 39 | in vec4 a_Color; 40 | out vec4 v_Color; 41 | #endif 42 | 43 | uniform mat4 u_ViewProjectionMatrix; 44 | uniform mat4 u_ModelMatrix; 45 | uniform mat4 u_NormalMatrix; 46 | 47 | vec4 getPosition() 48 | { 49 | vec4 pos = vec4(a_Position, 1.0); 50 | 51 | #ifdef USE_MORPHING 52 | pos += getTargetPosition(); 53 | #endif 54 | 55 | #ifdef USE_SKINNING 56 | pos = getSkinningMatrix() * pos; 57 | #endif 58 | 59 | return pos; 60 | } 61 | 62 | #ifdef HAS_NORMALS 63 | vec3 getNormal() 64 | { 65 | vec3 normal = a_Normal; 66 | 67 | #ifdef USE_MORPHING 68 | normal += getTargetNormal(); 69 | #endif 70 | 71 | #ifdef USE_SKINNING 72 | normal = mat3(getSkinningNormalMatrix()) * normal; 73 | #endif 74 | 75 | return normalize(normal); 76 | } 77 | #endif 78 | 79 | #ifdef HAS_TANGENTS 80 | vec3 getTangent() 81 | { 82 | vec3 tangent = a_Tangent.xyz; 83 | 84 | #ifdef USE_MORPHING 85 | tangent += getTargetTangent(); 86 | #endif 87 | 88 | #ifdef USE_SKINNING 89 | tangent = mat3(getSkinningMatrix()) * tangent; 90 | #endif 91 | 92 | return normalize(tangent); 93 | } 94 | #endif 95 | 96 | void main() 97 | { 98 | vec4 pos = u_ModelMatrix * getPosition(); 99 | v_Position = vec3(pos.xyz) / pos.w; 100 | 101 | #ifdef HAS_NORMALS 102 | #ifdef HAS_TANGENTS 103 | vec3 tangent = getTangent(); 104 | vec3 normalW = normalize(vec3(u_ModelMatrix * vec4(getNormal(), 0.0))); 105 | vec3 tangentW = normalize(vec3(u_ModelMatrix * vec4(tangent, 0.0))); 106 | vec3 bitangentW = cross(normalW, tangentW) * a_Tangent.w; 107 | v_TBN = mat3(tangentW, bitangentW, normalW); 108 | #else // !HAS_TANGENTS 109 | v_Normal = normalize(vec3(u_ModelMatrix * vec4(getNormal(), 0.0))); 110 | #endif 111 | #endif // !HAS_NORMALS 112 | 113 | v_UVCoord1 = vec2(0.0, 0.0); 114 | v_UVCoord2 = vec2(0.0, 0.0); 115 | 116 | #ifdef HAS_UV_SET1 117 | v_UVCoord1 = a_UV1; 118 | #endif 119 | 120 | #ifdef HAS_UV_SET2 121 | v_UVCoord2 = a_UV2; 122 | #endif 123 | 124 | #if defined(HAS_VERTEX_COLOR_VEC3) || defined(HAS_VERTEX_COLOR_VEC4) 125 | v_Color = a_Color; 126 | #endif 127 | 128 | gl_Position = u_ViewProjectionMatrix * pos; 129 | } 130 | -------------------------------------------------------------------------------- /assets/pbr/punctual.glsl: -------------------------------------------------------------------------------- 1 | // KHR_lights_punctual extension. 2 | // see https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual 3 | struct Light 4 | { 5 | vec3 direction; 6 | float range; 7 | 8 | vec3 color; 9 | float intensity; 10 | 11 | vec3 position; 12 | float innerConeCos; 13 | 14 | float outerConeCos; 15 | int type; 16 | float padding1; 17 | float padding2; 18 | }; 19 | 20 | const int LightType_Directional = 0; 21 | const int LightType_Point = 1; 22 | const int LightType_Spot = 2; 23 | 24 | // https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md#range-property 25 | float getRangeAttenuation(float range, float distance) 26 | { 27 | if (range <= 0.0) 28 | { 29 | // negative range means unlimited 30 | return 1.0 / pow(distance, 2.0); 31 | } 32 | return max(min(1.0 - pow(distance / range, 4.0), 1.0), 0.0) / pow(distance, 2.0); 33 | } 34 | 35 | // https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md#inner-and-outer-cone-angles 36 | float getSpotAttenuation(vec3 pointToLight, vec3 spotDirection, float outerConeCos, float innerConeCos) 37 | { 38 | float actualCos = dot(normalize(spotDirection), normalize(-pointToLight)); 39 | if (actualCos > outerConeCos) 40 | { 41 | if (actualCos < innerConeCos) 42 | { 43 | return smoothstep(outerConeCos, innerConeCos, actualCos); 44 | } 45 | return 1.0; 46 | } 47 | return 0.0; 48 | } 49 | 50 | vec3 getLighIntensity(Light light, vec3 pointToLight) 51 | { 52 | float rangeAttenuation = 1.0; 53 | float spotAttenuation = 1.0; 54 | 55 | if (light.type != LightType_Directional) 56 | { 57 | rangeAttenuation = getRangeAttenuation(light.range, length(pointToLight)); 58 | } 59 | if (light.type == LightType_Spot) 60 | { 61 | spotAttenuation = getSpotAttenuation(pointToLight, light.direction, light.outerConeCos, light.innerConeCos); 62 | } 63 | 64 | return rangeAttenuation * spotAttenuation * light.intensity * light.color; 65 | } 66 | 67 | vec3 getPunctualRadianceTransmission(vec3 normal, vec3 view, vec3 pointToLight, float alphaRoughness, 68 | vec3 f0, vec3 f90, float transmissionPercentage, vec3 baseColor, float ior) 69 | { 70 | float transmissionRougness = applyIorToRoughness(alphaRoughness, ior); 71 | 72 | vec3 n = normalize(normal); // Outward direction of surface point 73 | vec3 v = normalize(view); // Direction from surface point to view 74 | vec3 l = normalize(pointToLight); 75 | vec3 l_mirror = normalize(l + 2.0*n*dot(-l, n)); // Mirror light reflection vector on surface 76 | vec3 h = normalize(l_mirror + v); // Halfway vector between transmission light vector and v 77 | 78 | float D = D_GGX(clamp(dot(n, h), 0.0, 1.0), transmissionRougness); 79 | vec3 F = F_Schlick(f0, f90, clamp(dot(v, h), 0.0, 1.0)); 80 | float T = transmissionPercentage; 81 | float Vis = V_GGX(clamp(dot(n, l_mirror), 0.0, 1.0), clamp(dot(n, v), 0.0, 1.0), transmissionRougness); 82 | 83 | // Transmission BTDF 84 | return (1.0 - F) * baseColor * D * Vis; 85 | } 86 | 87 | vec3 getPunctualRadianceClearCoat(vec3 clearcoatNormal, vec3 v, vec3 l, vec3 h, float VdotH, vec3 f0, vec3 f90, float clearcoatRoughness) 88 | { 89 | float NdotL = clampedDot(clearcoatNormal, l); 90 | float NdotV = clampedDot(clearcoatNormal, v); 91 | float NdotH = clampedDot(clearcoatNormal, h); 92 | return NdotL * BRDF_specularGGX(f0, f90, clearcoatRoughness * clearcoatRoughness, 1.0, VdotH, NdotL, NdotV, NdotH); 93 | } 94 | 95 | vec3 getPunctualRadianceSheen(vec3 sheenColor, float sheenRoughness, float NdotL, float NdotV, float NdotH) 96 | { 97 | return NdotL * BRDF_specularSheen(sheenColor, sheenRoughness, NdotL, NdotV, NdotH); 98 | } 99 | 100 | // Compute attenuated light as it travels through a volume. 101 | vec3 applyVolumeAttenuation(vec3 radiance, float transmissionDistance, vec3 attenuationColor, float attenuationDistance) 102 | { 103 | if (attenuationDistance == 0.0) 104 | { 105 | // Attenuation distance is +∞ (which we indicate by zero), i.e. the transmitted color is not attenuated at all. 106 | return radiance; 107 | } 108 | else 109 | { 110 | // Compute light attenuation using Beer's law. 111 | vec3 attenuationCoefficient = -log(attenuationColor) / attenuationDistance; 112 | vec3 transmittance = exp(-attenuationCoefficient * transmissionDistance); // Beer's law 113 | return transmittance * radiance; 114 | } 115 | } 116 | 117 | vec3 getVolumeTransmissionRay(vec3 n, vec3 v, float thickness, float ior, mat4 modelMatrix) 118 | { 119 | // Direction of refracted light. 120 | vec3 refractionVector = refract(-v, normalize(n), 1.0 / ior); 121 | 122 | // Compute rotation-independant scaling of the model matrix. 123 | vec3 modelScale; 124 | modelScale.x = length(vec3(modelMatrix[0].xyz)); 125 | modelScale.y = length(vec3(modelMatrix[1].xyz)); 126 | modelScale.z = length(vec3(modelMatrix[2].xyz)); 127 | 128 | // The thickness is specified in local space. 129 | return normalize(refractionVector) * thickness * modelScale; 130 | } 131 | -------------------------------------------------------------------------------- /assets/pbr/run.bat: -------------------------------------------------------------------------------- 1 | glslc -o output.txt -DHAS_NORMALS -DHAS_UV_SET1 -DMATERIAL_METALLICROUGHNESS -DHAS_BASE_COLOR_MAP -DUSE_PUNCTUAL -DLIGHT_COUNT=1 -DHAS_METALLIC_ROUGHNESS_MAP -DHAS_NORMAL_MAP -vertex primitive.vert -fragment pbr.frag -------------------------------------------------------------------------------- /assets/pbr/tonemapping.glsl: -------------------------------------------------------------------------------- 1 | uniform float u_Exposure; 2 | 3 | const float GAMMA = 2.2; 4 | const float INV_GAMMA = 1.0 / GAMMA; 5 | 6 | // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT 7 | const mat3 ACESInputMat = mat3 8 | ( 9 | 0.59719, 0.07600, 0.02840, 10 | 0.35458, 0.90834, 0.13383, 11 | 0.04823, 0.01566, 0.83777 12 | ); 13 | 14 | // ODT_SAT => XYZ => D60_2_D65 => sRGB 15 | const mat3 ACESOutputMat = mat3 16 | ( 17 | 1.60475, -0.10208, -0.00327, 18 | -0.53108, 1.10813, -0.07276, 19 | -0.07367, -0.00605, 1.07602 20 | ); 21 | 22 | // linear to sRGB approximation 23 | // see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 24 | vec3 linearTosRGB(vec3 color) 25 | { 26 | return pow(color, vec3(INV_GAMMA)); 27 | } 28 | 29 | // sRGB to linear approximation 30 | // see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html 31 | vec3 sRGBToLinear(vec3 srgbIn) 32 | { 33 | return vec3(pow(srgbIn.xyz, vec3(GAMMA))); 34 | } 35 | 36 | vec4 sRGBToLinear(vec4 srgbIn) 37 | { 38 | return vec4(sRGBToLinear(srgbIn.xyz), srgbIn.w); 39 | } 40 | 41 | // ACES tone map (faster approximation) 42 | // see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ 43 | vec3 toneMapACES_Narkowicz(vec3 color) 44 | { 45 | const float A = 2.51; 46 | const float B = 0.03; 47 | const float C = 2.43; 48 | const float D = 0.59; 49 | const float E = 0.14; 50 | return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0); 51 | } 52 | 53 | // ACES filmic tone map approximation 54 | // see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl 55 | vec3 RRTAndODTFit(vec3 color) 56 | { 57 | vec3 a = color * (color + 0.0245786) - 0.000090537; 58 | vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081; 59 | return a / b; 60 | } 61 | // tone mapping 62 | vec3 toneMapACES_Hill(vec3 color) 63 | { 64 | color = ACESInputMat * color; 65 | 66 | // Apply RRT and ODT 67 | color = RRTAndODTFit(color); 68 | 69 | color = ACESOutputMat * color; 70 | 71 | // Clamp to [0, 1] 72 | color = clamp(color, 0.0, 1.0); 73 | 74 | return color; 75 | } 76 | 77 | vec3 toneMap(vec3 color) 78 | { 79 | color *= u_Exposure; 80 | 81 | #ifdef TONEMAP_ACES_NARKOWICZ 82 | color = toneMapACES_Narkowicz(color); 83 | #endif 84 | 85 | #ifdef TONEMAP_ACES_HILL 86 | color = toneMapACES_Hill(color); 87 | #endif 88 | 89 | #ifdef TONEMAP_ACES_HILL_EXPOSURE_BOOST 90 | // boost exposure as discussed in https://github.com/mrdoob/three.js/pull/19621 91 | // this factor is based on the exposure correction of Krzysztof Narkowicz in his 92 | // implemetation of ACES tone mapping 93 | color /= 0.6; 94 | 95 | color = toneMapACES_Hill(color); 96 | #endif 97 | 98 | return linearTosRGB(color); 99 | } 100 | -------------------------------------------------------------------------------- /assets/postprocess/fxaa.frag: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | #ifdef GL_ARB_gpu_shader5 4 | #extension GL_ARB_gpu_shader5 : enable 5 | #else 6 | #extension GL_EXT_gpu_shader4 : enable 7 | #define FXAA_FAST_PIXEL_OFFSET 0 8 | #endif 9 | 10 | #define FXAA_PC 1 11 | #define FXAA_GLSL_130 1 12 | #define FXAA_QUALITY__PRESET 39 13 | #define FXAA_GREEN_AS_LUMA 0 14 | 15 | #include "FXAA3_11.h" 16 | 17 | uniform sampler2D uTexture; 18 | uniform vec4 uExtents; 19 | 20 | out vec4 oColor; 21 | 22 | void main( void ) 23 | { 24 | FxaaFloat2 fxaaQualityRcpFrame; 25 | fxaaQualityRcpFrame.x = uExtents.x; 26 | fxaaQualityRcpFrame.y = uExtents.y; 27 | 28 | FxaaFloat2 uv = gl_FragCoord.xy * uExtents.xy; 29 | 30 | FxaaFloat4 ConsolePosPos = FxaaFloat4(0.0,0.0,0.0,0.0); 31 | FxaaFloat4 ConsoleRcpFrameOpt = FxaaFloat4(0.0,0.0,0.0,0.0); 32 | FxaaFloat4 ConsoleRcpFrameOpt2 = FxaaFloat4(0.0,0.0,0.0,0.0); 33 | FxaaFloat4 Console360RcpFrameOpt2 = FxaaFloat4(0.0,0.0,0.0,0.0); 34 | 35 | // Only used on FXAA Quality. 36 | // Choose the amount of sub-pixel aliasing removal. 37 | // This can effect sharpness. 38 | // 1.00 - upper limit (softer) 39 | // 0.75 - default amount of filtering 40 | // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) 41 | // 0.25 - almost off 42 | // 0.00 - completely off 43 | FxaaFloat QualitySubpix = 0.75; 44 | 45 | // The minimum amount of local contrast required to apply algorithm. 46 | // 0.333 - too little (faster) 47 | // 0.250 - low quality 48 | // 0.166 - default 49 | // 0.125 - high quality 50 | // 0.033 - very high quality (slower) 51 | FxaaFloat QualityEdgeThreshold = 0.033; 52 | 53 | // You dont need to touch theses variables it have no visible effect 54 | FxaaFloat QualityEdgeThresholdMin = 0.0; 55 | FxaaFloat ConsoleEdgeSharpness = 8.0; 56 | FxaaFloat ConsoleEdgeThreshold = 0.125; 57 | FxaaFloat ConsoleEdgeThresholdMin = 0.05; 58 | FxaaFloat4 Console360ConstDir = FxaaFloat4(1.0, -1.0, 0.25, -0.25); 59 | 60 | oColor = FxaaPixelShader(uv, ConsolePosPos, uTexture, uTexture, uTexture, fxaaQualityRcpFrame, 61 | ConsoleRcpFrameOpt, ConsoleRcpFrameOpt2, Console360RcpFrameOpt2, 62 | QualitySubpix, QualityEdgeThreshold, QualityEdgeThresholdMin, 63 | ConsoleEdgeSharpness, ConsoleEdgeThreshold, ConsoleEdgeThresholdMin, Console360ConstDir); 64 | } 65 | -------------------------------------------------------------------------------- /assets/postprocess/fxaa.vert: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | uniform mat4 ciModelViewProjection; 4 | 5 | in vec4 ciPosition; 6 | 7 | void main() 8 | { 9 | gl_Position = ciModelViewProjection * ciPosition; 10 | } 11 | -------------------------------------------------------------------------------- /assets/postprocess/smaa.frag: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | // Pass in the render target metrics as a uniform 4 | uniform vec4 SMAA_RT_METRICS; // (1/w, 1/h, w, h) 5 | 6 | #define SMAA_INCLUDE_VS 0 7 | #define SMAA_INCLUDE_PS 1 8 | #include "SMAA.h" 9 | 10 | noperspective in vec2 texcoord; 11 | noperspective in vec2 pixcoord; 12 | noperspective in vec4 offset[3]; 13 | 14 | // Additional shader inputs 15 | uniform sampler2D uColorTex; // 1st and 3rd pass 16 | uniform sampler2D uEdgesTex; // 2nd pass only 17 | uniform sampler2D uAreaTex; // 2nd pass only 18 | uniform sampler2D uSearchTex; // 2nd pass only 19 | uniform sampler2D uBlendTex; // 3rd pass only 20 | 21 | out vec4 fragColor; 22 | 23 | void main() 24 | { 25 | #if SMAA_PASS == 1 26 | fragColor = vec4( SMAALumaEdgeDetectionPS( texcoord, offset, uColorTex ), 0.0, 0.0 ); 27 | #elif SMAA_PASS == 2 28 | ivec4 subsampleIndices = ivec4(0, 0, 0, 0); 29 | fragColor = SMAABlendingWeightCalculationPS( texcoord, pixcoord, offset, 30 | uEdgesTex, uAreaTex, uSearchTex, subsampleIndices ); 31 | #elif SMAA_PASS == 3 32 | fragColor = SMAANeighborhoodBlendingPS( texcoord, offset[0], uColorTex, uBlendTex ); 33 | #endif 34 | } -------------------------------------------------------------------------------- /assets/postprocess/smaa.vert: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | // Pass in the render target metrics as a uniform 4 | uniform vec4 SMAA_RT_METRICS; // (1/w, 1/h, w, h) 5 | 6 | #define SMAA_INCLUDE_VS 1 7 | #define SMAA_INCLUDE_PS 0 8 | #include "SMAA.h" 9 | 10 | uniform mat4 ciModelViewProjection; 11 | 12 | in vec4 ciPosition; 13 | in vec4 ciTexCoord0; 14 | 15 | noperspective out vec2 texcoord; 16 | noperspective out vec2 pixcoord; 17 | noperspective out vec4 offset[3]; 18 | 19 | void main() 20 | { 21 | texcoord = pixcoord = ciTexCoord0.st; 22 | 23 | #if SMAA_PASS == 1 24 | SMAAEdgeDetectionVS( texcoord, offset ); 25 | #elif SMAA_PASS == 2 26 | SMAABlendingWeightCalculationVS( texcoord, pixcoord, offset ); 27 | #elif SMAA_PASS == 3 28 | SMAANeighborhoodBlendingVS( texcoord, offset[0] ); 29 | #endif 30 | 31 | gl_Position = ciModelViewProjection * ciPosition; 32 | } -------------------------------------------------------------------------------- /assets/shadow_mapping.frag: -------------------------------------------------------------------------------- 1 | #version 410 2 | 3 | uniform float ciElapsedSeconds; 4 | 5 | in vec4 vColor; 6 | in vec4 vPosition; 7 | in vec3 vNormal; 8 | in vec4 vModelPosition; 9 | in vec3 vModelNormal; 10 | in vec4 vShadowCoord; 11 | 12 | 13 | uniform vec3 uLightPos; 14 | uniform bool uIsTeapot; 15 | 16 | uniform sampler2DShadow uShadowMap; 17 | uniform mat4 uShadowMatrix; 18 | uniform int uShadowTechnique; 19 | uniform float uDepthBias; 20 | uniform bool uOnlyShadowmap; 21 | uniform float uRandomOffset; 22 | uniform bool uEnableNormSlopeOffset; 23 | uniform int uNumRandomSamples; 24 | 25 | out vec4 fragColor; 26 | 27 | float rand( vec2 seed ) { 28 | return fract( sin(dot(seed.xy ,vec2( 12.9898, 78.233 ))) * 43758.5453 ); 29 | } 30 | 31 | float rand( vec4 seed ) 32 | { 33 | float dot_product = dot(seed, vec4(12.9898,78.233, 45.164, 94.673)); 34 | return fract(sin(dot_product) * 43758.5453); 35 | } 36 | 37 | vec4 getRandomOffset( int i ) { 38 | float indexA = rand(vec4(gl_FragCoord.xyx, ciElapsedSeconds*i)) - 0.5; 39 | float indexB = rand(vec4(gl_FragCoord.yxy * i, ciElapsedSeconds*i)) - 0.5; 40 | return vec4( vec2(indexA, indexB), 0, 0); 41 | } 42 | 43 | vec2 getNormSlopeBias( vec3 N, vec3 L ) { 44 | 45 | float cos_alpha = clamp(dot(N, L), 0.0, 1.0 ); 46 | float offset_scale_N = sqrt(1 - cos_alpha * cos_alpha); // sin(acos(L·N)) 47 | float offset_scale_L = offset_scale_N / cos_alpha; // tan(acos(L·N)) 48 | return vec2(offset_scale_N, min(2.0, offset_scale_L)); 49 | } 50 | 51 | float sampleBasic( vec4 sc ) { 52 | return textureProj( uShadowMap, sc ); 53 | } 54 | 55 | float samplePCF3x3( vec4 sc ) 56 | { 57 | const int s = 2; 58 | 59 | float shadow = 0.0; 60 | shadow += textureProjOffset( uShadowMap, sc, ivec2(-s,-s) ); 61 | shadow += textureProjOffset( uShadowMap, sc, ivec2(-s, 0) ); 62 | shadow += textureProjOffset( uShadowMap, sc, ivec2(-s, s) ); 63 | shadow += textureProjOffset( uShadowMap, sc, ivec2( 0,-s) ); 64 | shadow += textureProjOffset( uShadowMap, sc, ivec2( 0, 0) ); 65 | shadow += textureProjOffset( uShadowMap, sc, ivec2( 0, s) ); 66 | shadow += textureProjOffset( uShadowMap, sc, ivec2( s,-s) ); 67 | shadow += textureProjOffset( uShadowMap, sc, ivec2( s, 0) ); 68 | shadow += textureProjOffset( uShadowMap, sc, ivec2( s, s) ); 69 | return shadow/9.0;; 70 | } 71 | 72 | float samplePCF4x4( vec4 sc ) 73 | { 74 | const int r = 2; 75 | const int s = 2 * r; 76 | 77 | float shadow = 0.0; 78 | shadow += textureProjOffset( uShadowMap, sc, ivec2(-s,-s) ); 79 | shadow += textureProjOffset( uShadowMap, sc, ivec2(-r,-s) ); 80 | shadow += textureProjOffset( uShadowMap, sc, ivec2( r,-s) ); 81 | shadow += textureProjOffset( uShadowMap, sc, ivec2( s,-s) ); 82 | 83 | shadow += textureProjOffset( uShadowMap, sc, ivec2(-s,-r) ); 84 | shadow += textureProjOffset( uShadowMap, sc, ivec2(-r,-r) ); 85 | shadow += textureProjOffset( uShadowMap, sc, ivec2( r,-r) ); 86 | shadow += textureProjOffset( uShadowMap, sc, ivec2( s,-r) ); 87 | 88 | shadow += textureProjOffset( uShadowMap, sc, ivec2(-s, r) ); 89 | shadow += textureProjOffset( uShadowMap, sc, ivec2(-r, r) ); 90 | shadow += textureProjOffset( uShadowMap, sc, ivec2( r, r) ); 91 | shadow += textureProjOffset( uShadowMap, sc, ivec2( s, r) ); 92 | 93 | shadow += textureProjOffset( uShadowMap, sc, ivec2(-s, s) ); 94 | shadow += textureProjOffset( uShadowMap, sc, ivec2(-r, s) ); 95 | shadow += textureProjOffset( uShadowMap, sc, ivec2( r, s) ); 96 | shadow += textureProjOffset( uShadowMap, sc, ivec2( s, s) ); 97 | 98 | return shadow/16.0; 99 | } 100 | 101 | float sampleRandom( vec4 sc, vec2 normSlopeBias ) 102 | { 103 | float shadow = 0.0; 104 | for( int i = 0; i< uNumRandomSamples; i++ ) { 105 | vec4 off = getRandomOffset( i ); 106 | off.xy *= normSlopeBias; 107 | shadow += textureProj( uShadowMap, sc + off ); 108 | } 109 | return shadow / float( uNumRandomSamples ); 110 | } 111 | 112 | void main() 113 | { 114 | // Normal in view space 115 | vec3 N = normalize( vNormal ); 116 | // Light direction 117 | vec3 L = normalize( uLightPos - vPosition.xyz ); 118 | // To camera vector 119 | vec3 C = normalize( -vPosition.xyz ); 120 | // Surface reflection vector 121 | vec3 R = normalize( -reflect( L, N ) ); 122 | 123 | // Modulated ambient (with fake red indirect lighting coming from the sphere) 124 | vec3 sphereGlow = vec3( 0.6, 0.15, 0.15 ); 125 | vec3 indirectGlow = vec3( clamp( dot( 0.8 * normalize(vModelNormal), -normalize(vModelPosition.xyz) ), 0.0, 0.55 ), 0.0, 0.0 ); 126 | vec3 A = mix( sphereGlow, indirectGlow, float(uIsTeapot) ) + vec3( 0.07, 0.05, 0.1 ); 127 | // Diffuse factor 128 | float NdotL = max( dot( N, L ), 0.0 ); 129 | vec3 D = vec3( NdotL ); 130 | // Specular factor 131 | vec3 S = pow( max( dot( R, C ), 0.0 ), 50.0 ) * vec3(1.0); 132 | 133 | // Sample the shadowmap to compute the shadow value 134 | float shadow = 1.0f; 135 | vec4 sc = vShadowCoord; 136 | sc.z += uDepthBias; 137 | 138 | if( uShadowTechnique == 0 ) { 139 | shadow = sampleBasic( sc ); 140 | } 141 | else if( uShadowTechnique == 1 ) { 142 | shadow = samplePCF3x3( sc ); 143 | } 144 | else if ( uShadowTechnique == 2 ) { 145 | shadow = samplePCF4x4( sc ); 146 | } 147 | else if ( uShadowTechnique == 3 ) { 148 | vec2 offset = mix( vec2(uRandomOffset), getNormSlopeBias( N, L ), float(uEnableNormSlopeOffset) ); 149 | shadow = sampleRandom( sc, offset ); 150 | } 151 | 152 | fragColor.rgb = mix( ( ( D + S ) * shadow + A ) * vColor.rgb, vec3(shadow), float(uOnlyShadowmap) ); 153 | fragColor.a = 1.0; 154 | } 155 | -------------------------------------------------------------------------------- /assets/shadow_mapping.vert: -------------------------------------------------------------------------------- 1 | #version 410 2 | 3 | in vec4 ciPosition; 4 | in vec3 ciNormal; 5 | in vec4 ciColor; 6 | 7 | uniform mat4 ciModelMatrix; 8 | uniform mat4 ciModelView; 9 | uniform mat3 ciNormalMatrix; 10 | uniform mat4 ciModelViewProjection; 11 | 12 | // ShadowMatrix converts from modeling coordinates to shadow map coordinates. 13 | uniform mat4 uShadowMatrix; 14 | 15 | out vec4 vColor; 16 | out vec4 vPosition; 17 | out vec3 vNormal; 18 | out vec4 vModelPosition; 19 | out vec3 vModelNormal; 20 | out vec2 vTexCoord0; 21 | // Coordinate to be used for shadow map lookup 22 | out vec4 vShadowCoord; 23 | 24 | /* Bias matrix alters the clip coordinates so that x & y 25 | * lie between 0.0 and 1.0 for texture sampling. */ 26 | const mat4 biasMat = mat4( 0.5, 0.0, 0.0, 0.0, 27 | 0.0, 0.5, 0.0, 0.0, 28 | 0.0, 0.0, 0.5, 0.0, 29 | 0.5, 0.5, 0.5, 1.0 ); 30 | void main() { 31 | vColor = ciColor; 32 | vPosition = ciModelView * ciPosition; 33 | vModelPosition = ciModelMatrix * ciPosition; 34 | vModelNormal = (ciModelMatrix * vec4(ciNormal, 0.0)).xyz; 35 | vNormal = normalize( ciNormalMatrix * ciNormal ); 36 | 37 | vShadowCoord = (biasMat * uShadowMatrix * ciModelMatrix) * ciPosition; 38 | gl_Position = ciModelViewProjection * ciPosition; 39 | } -------------------------------------------------------------------------------- /assets/unlit.frag: -------------------------------------------------------------------------------- 1 | #include "common.glsl" 2 | 3 | #ifdef HAS_BASECOLORMAP 4 | uniform sampler2D u_BaseColorSampler; 5 | #endif 6 | uniform vec4 u_BaseColorFactor; 7 | in vec2 v_UV; 8 | #ifdef HAS_COLOR 9 | in vec4 v_Color; 10 | #endif 11 | 12 | out vec4 oColor; 13 | 14 | void main() 15 | { 16 | #ifdef HAS_BASECOLORMAP 17 | vec4 baseColor = SRGBtoLINEAR(texture(u_BaseColorSampler, v_UV)) * u_BaseColorFactor; 18 | #elif defined(HAS_COLOR) 19 | vec4 baseColor = v_Color * u_BaseColorFactor; 20 | #else 21 | vec4 baseColor = u_BaseColorFactor; 22 | #endif 23 | oColor = vec4(pow(baseColor.rgb, vec3(1.0/2.2)), baseColor.a); 24 | } 25 | -------------------------------------------------------------------------------- /cinderblock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/cinderblock.png -------------------------------------------------------------------------------- /cinderblock.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | assets/brdfLUT.png 12 | assets/CathedralIrradiance.dds 13 | assets/CathedralRadiance.dds 14 | 15 | assets/common.glsl 16 | assets/pbr.frag 17 | assets/pbr.vert 18 | assets/shadow_mapping.frag 19 | assets/shadow_mapping.vert 20 | assets/SkyBox.frag 21 | assets/SkyBox.vert 22 | assets/unlit.frag 23 | 24 | include 25 | 3rdparty/rapidjson 26 | 27 | src/*.cpp 28 | 3rdparty/tinygltf/*.cc 29 | 3rdparty/tinyobjloader/*.cc 30 | include/*.* 31 | 3rdparty/tinygltf/*.h 32 | 3rdparty/tinyobjloader/*.h 33 | 34 | 35 | -------------------------------------------------------------------------------- /doc/figures/BRDFs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/doc/figures/BRDFs.png -------------------------------------------------------------------------------- /doc/figures/BTDFs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/doc/figures/BTDFs.png -------------------------------------------------------------------------------- /doc/figures/Fresnel_Conductor.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/doc/figures/Fresnel_Conductor.JPG -------------------------------------------------------------------------------- /doc/figures/Fresnel_Dielectric.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/doc/figures/Fresnel_Dielectric.JPG -------------------------------------------------------------------------------- /doc/figures/Interreflection.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/doc/figures/Interreflection.jpg -------------------------------------------------------------------------------- /doc/figures/Masking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/doc/figures/Masking.png -------------------------------------------------------------------------------- /doc/figures/Shadowing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/doc/figures/Shadowing.png -------------------------------------------------------------------------------- /doc/figures/Snells_Law.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/doc/figures/Snells_Law.JPG -------------------------------------------------------------------------------- /include/FirstPersonCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cinder/app/App.h" 4 | 5 | #define FLYTHROUGH_CAMERA_IMPLEMENTATION 6 | #include "../3rdparty/flythrough_camera/flythrough_camera.h" 7 | 8 | using namespace ci; 9 | using namespace ci::app; 10 | 11 | struct CameraPersp2 : CameraPersp 12 | { 13 | mat4& getViewMatrixReference() 14 | { 15 | mModelViewCached = true; 16 | return mViewMatrix; 17 | } 18 | }; 19 | 20 | struct FirstPersonCamera : public CameraPersp2 21 | { 22 | //vec3 eye = { 3.0f, 3.0f, 3.0f }; 23 | //vec3 look = { 0.0f, 0.0f, 1.0f }; 24 | //const vec3 up = { 0.0f, 1.0f, 0.0f }; 25 | float move_speed = 3.0f; 26 | float rotate_speed = 0.2f; 27 | float max_pitch_rotation_degrees = 80.0f; 28 | 29 | void setActive(bool flag) 30 | { 31 | activated = flag; 32 | } 33 | 34 | void setup() 35 | { 36 | mWorldUp = { 0.0f, 1.0f, 0.0f }; 37 | mViewDirection = { 0.0f, 0.0f, 1.0f }; 38 | mElapsedSeconds = getElapsedSeconds(); 39 | // mCam.lookAt(aabb.getMax() * 2.0f, aabb.getCenter()); 40 | 41 | // flythrough_camera_look_to(pos, look, up, glm::value_ptr(mViewMatrix), 0); 42 | 43 | getWindow()->getSignalResize().connect([&] { setAspectRatio(getWindowAspectRatio()); }); 44 | 45 | getWindow()->getSignalKeyDown().connect( 46 | [&](KeyEvent& event) { mIsKeyPressed[event.getCode()] = true; }); 47 | 48 | getWindow()->getSignalKeyUp().connect( 49 | [&](KeyEvent& event) { mIsKeyPressed[event.getCode()] = false; }); 50 | 51 | getWindow()->getSignalMouseDown().connect( 52 | [&](MouseEvent& ev) { mIsRMousePressed = ev.isRight(); }); 53 | 54 | getWindow()->getSignalMouseUp().connect([&](MouseEvent& ev) { mIsRMousePressed = false; }); 55 | 56 | getWindow()->getSignalMouseMove().connect([&](MouseEvent& ev) { 57 | mIsRMousePressed = ev.isRight(); 58 | mMousePos = ev.getPos(); 59 | }); 60 | 61 | AppBase::get()->getSignalUpdate().connect([&] { 62 | float delta_time_sec = getElapsedSeconds() - mElapsedSeconds; 63 | mElapsedSeconds = getElapsedSeconds(); 64 | 65 | if (activated) 66 | { 67 | flythrough_camera_update( 68 | glm::value_ptr(mEyePoint), glm::value_ptr(mViewDirection), glm::value_ptr(mWorldUp), 69 | glm::value_ptr(mViewMatrix), delta_time_sec, 70 | move_speed * (mIsKeyPressed[KeyEvent::KEY_LSHIFT] ? 2.0f : 1.0f) * activated, 71 | rotate_speed, max_pitch_rotation_degrees, mMousePos.x - mPrevMousePos.x, 72 | mMousePos.y - mPrevMousePos.y, 73 | mIsKeyPressed[KeyEvent::KEY_UP], mIsKeyPressed[KeyEvent::KEY_LEFT], mIsKeyPressed[KeyEvent::KEY_DOWN], mIsKeyPressed[KeyEvent::KEY_RIGHT], 74 | false /*mIsKeyPressed[KeyEvent::KEY_SPACE]*/, 75 | mIsKeyPressed[KeyEvent::KEY_LCTRL], 0); 76 | 77 | float* view = glm::value_ptr(mViewMatrix); 78 | #if 0 79 | printf("\n"); 80 | printf("pos: %f, %f, %f\n", mEyePoint[0], mEyePoint[1], mEyePoint[2]); 81 | printf("look: %f, %f, %f\n", mViewDirection[0], mViewDirection[1], mViewDirection[2]); 82 | printf("view: %f %f %f %f\n" 83 | " %f %f %f %f\n" 84 | " %f %f %f %f\n" 85 | " %f %f %f %f\n", 86 | view[0], view[1], view[2], view[3], view[4], view[5], view[6], view[7], 87 | view[8], view[9], view[10], view[11], view[12], view[13], view[14], 88 | view[15]); 89 | #endif 90 | mModelViewCached = true; 91 | } 92 | mPrevMousePos = mMousePos; 93 | }); 94 | } 95 | 96 | private: 97 | double mElapsedSeconds; 98 | ivec2 mMousePos, mPrevMousePos; 99 | 100 | bool mIsKeyPressed[KeyEvent::KEY_LAST] = { false }; 101 | bool mIsRMousePressed = false; 102 | 103 | bool activated = true; 104 | }; 105 | -------------------------------------------------------------------------------- /include/GltfNode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #undef near 4 | #undef far 5 | #include "../3rdparty/yocto/yocto_sceneio.h" 6 | #include "../include/Node.h" 7 | #include 8 | #include 9 | 10 | namespace fs = std::filesystem; 11 | 12 | typedef std::shared_ptr GltfSceneRef; 13 | 14 | const int LightType_Directional = 0; 15 | const int LightType_Point = 1; 16 | const int LightType_Spot = 2; 17 | 18 | #define DebugTypeList \ 19 | ENTRY(DEBUG_NONE, None) \ 20 | ENTRY(DEBUG_BASECOLOR, BaseColor) \ 21 | ENTRY(DEBUG_ALPHA, Alpha) \ 22 | ENTRY(DEBUG_NORMAL, Normal) \ 23 | ENTRY(DEBUG_TANGENT, Tangent) \ 24 | ENTRY(DEBUG_BITANGENT, Bitangent) \ 25 | ENTRY(DEBUG_METALLIC, Metallic) \ 26 | ENTRY(DEBUG_ROUGHNESS, Roughness) \ 27 | ENTRY(DEBUG_OCCLUSION, Occulussion) \ 28 | ENTRY(DEBUG_F0, F0) \ 29 | ENTRY(DEBUG_FEMISSIVE, Emissive) \ 30 | ENTRY(DEBUG_FSPECULAR, Specular) \ 31 | ENTRY(DEBUG_FDIFFUSE, Diffuse) \ 32 | ENTRY(DEBUG_FSHEEN, Sheen) \ 33 | ENTRY(DEBUG_FCLEARCOAT, ClearCoat) \ 34 | ENTRY(DEBUG_FSUBSURFACE, Subsurface) \ 35 | ENTRY(DEBUG_THICKNESS, Thickness) \ 36 | ENTRY(DEBUG_FTRANSMISSION, Transmission) 37 | 38 | #define ENTRY(flag, name) flag, 39 | enum DebugType 40 | { 41 | DebugTypeList 42 | 43 | DEBUG_COUNT, 44 | }; 45 | #undef ENTRY 46 | 47 | struct GltfLight 48 | { 49 | glm::vec3 direction = { 0,1.0f, 0 }; 50 | float range = { 999 }; 51 | 52 | glm::vec3 color = { 1, 1, 1 }; 53 | float intensity = 10; 54 | 55 | glm::vec3 position; 56 | float innerConeCos = 0.1; 57 | 58 | float outerConeCos = 0.5; 59 | int type = LightType_Directional; 60 | 61 | glm::vec2 padding; 62 | }; 63 | 64 | struct GltfMaterial 65 | { 66 | typedef std::shared_ptr Ref; 67 | static Ref create(GltfScene* scene, yocto::scene_material& property, DebugType debugType = DEBUG_NONE); 68 | 69 | yocto::scene_material property; 70 | 71 | ci::gl::Texture2dRef emission_tex; 72 | ci::gl::Texture2dRef color_tex; 73 | ci::gl::Texture2dRef roughness_tex; 74 | ci::gl::Texture2dRef scattering_tex; 75 | ci::gl::Texture2dRef normal_tex; 76 | ci::gl::Texture2dRef occulusion_tex; 77 | 78 | void bind(); 79 | 80 | void unbind(); 81 | 82 | ci::gl::GlslProgRef glsl; 83 | }; 84 | 85 | struct GltfNode : melo::Node 86 | { 87 | typedef std::shared_ptr Ref; 88 | static Ref create(GltfScene* scene, yocto::scene_instance& property); 89 | 90 | ci::gl::VboMeshRef mesh; 91 | GltfMaterial::Ref material; 92 | 93 | void draw(melo::DrawOrder order) override; 94 | void reloadMaterial(); 95 | 96 | GltfScene* scene; 97 | yocto::scene_instance property; 98 | }; 99 | 100 | struct GltfScene : melo::Node 101 | { 102 | static void progress_callback(const std::string& message, int current, int total); 103 | 104 | static GltfSceneRef create(const fs::path& path); 105 | 106 | fs::path path; 107 | 108 | GltfLight lights[1] = {}; 109 | std::vector meshes; 110 | std::vector textures; 111 | std::vector materials; 112 | 113 | yocto::scene_scene property; 114 | 115 | static ci::gl::TextureCubeMapRef radianceTexture; 116 | static ci::gl::TextureCubeMapRef irradianceTexture; 117 | static ci::gl::Texture2dRef brdfLUTTexture; 118 | 119 | void createMaterials(DebugType debugType = DEBUG_NONE); 120 | 121 | ci::gl::Texture2dRef getTexture(yocto::texture_handle handle) 122 | { 123 | if (handle == yocto::invalid_handle) return {}; 124 | return textures[handle]; 125 | } 126 | 127 | ci::gl::VboMeshRef getMesh(yocto::shape_handle handle) 128 | { 129 | if (handle == yocto::invalid_handle) return {}; 130 | return meshes[handle]; 131 | } 132 | 133 | GltfMaterial::Ref getMaterial(yocto::material_handle handle) 134 | { 135 | if (handle == yocto::invalid_handle) return {}; 136 | return materials[handle]; 137 | } 138 | 139 | void update(double elapsed) override; 140 | 141 | void predraw(melo::DrawOrder order) override; 142 | 143 | void postdraw(melo::DrawOrder order) override; 144 | 145 | bool isMaterialDirty = false; 146 | 147 | private: 148 | 149 | ci::gl::Texture2dRef createTexture(const yocto::scene_texture& texture); 150 | 151 | ci::gl::VboMeshRef createMesh(const yocto::scene_shape& shape); 152 | }; -------------------------------------------------------------------------------- /include/NodeExt.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010-2012, Paul Houx - All rights reserved. 3 | This code is intended for use with the Cinder C++ library: http://libcinder.org 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted 6 | provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions 9 | and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions 11 | and the following disclaimer in the documentation and/or other materials provided with the 12 | distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 15 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 17 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 20 | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 21 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | */ 23 | 24 | #pragma once 25 | 26 | #include "Node.h" 27 | #include "cinder/gl/gl.h" 28 | 29 | namespace cinder { 30 | namespace geom { 31 | class Source; 32 | } 33 | typedef std::shared_ptr TriMeshRef; 34 | } 35 | 36 | namespace melo 37 | { 38 | using namespace ci; 39 | 40 | struct DirectionalLightNode : public Node 41 | { 42 | typedef std::shared_ptr Ref; 43 | static Ref create(float radius = 5, Color color = { 1,1,1 }); 44 | 45 | void draw(DrawOrder order) override; 46 | 47 | float radius; 48 | Color color; 49 | }; 50 | 51 | struct GridNode : public Node 52 | { 53 | typedef std::shared_ptr Ref; 54 | 55 | gl::VertBatchRef vertBatch; 56 | gl::GlslProgRef shader; 57 | float mMeters; 58 | 59 | static Ref create(float meters = 10.0f); 60 | 61 | GridNode(float meters = 10.0f); 62 | 63 | void draw(DrawOrder order) override; 64 | }; 65 | 66 | struct MeshNode : public Node 67 | { 68 | typedef std::shared_ptr Ref; 69 | 70 | gl::VboMeshRef vboMesh; 71 | gl::GlslProgRef shader; 72 | 73 | static Ref create(TriMeshRef triMesh); 74 | 75 | static Ref create(const geom::Source& source); 76 | MeshNode(TriMeshRef triMesh); 77 | 78 | void draw(DrawOrder order) override; 79 | }; 80 | } // namespace nodes -------------------------------------------------------------------------------- /include/SkyNode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Node.h" 4 | #include 5 | 6 | namespace melo 7 | { 8 | struct SkyNode : Node 9 | { 10 | typedef std::shared_ptr Ref; 11 | 12 | static Ref create(const std::string& skyTexturePath); 13 | 14 | void predraw(DrawOrder order) override; 15 | void draw(DrawOrder order) override; 16 | 17 | ci::gl::TextureCubeMapRef mSkyTex; 18 | ci::gl::BatchRef mSkyBoxBatch; 19 | ci::gl::GlslProgRef skyBoxShader; 20 | }; 21 | } -------------------------------------------------------------------------------- /include/ciobj.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../3rdparty/tinyobjloader/tiny_obj_loader.h" 4 | 5 | #include "Node.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | typedef std::shared_ptr ModelObjRef; 12 | 13 | using namespace ci; 14 | 15 | struct MaterialObj 16 | { 17 | typedef std::shared_ptr Ref; 18 | std::string name; 19 | tinyobj::material_t property; 20 | ModelObjRef modelObj; 21 | 22 | gl::Texture2dRef diffuseTexture; 23 | gl::Texture2dRef normalTexture; 24 | 25 | glm::vec4 diffuseFactor = glm::vec4(1); 26 | glm::vec3 ambientFactor = glm::vec3(1); 27 | glm::vec3 specularFactor = glm::vec3(1); 28 | glm::vec3 emissiveFactor = glm::vec3(1); 29 | glm::vec3 transmittanceFactor = glm::vec3(0); 30 | float glossinessFactor = 1.0f; 31 | float ior = 1.0f; 32 | int dissolve = 1; 33 | int illum = 0; 34 | 35 | gl::GlslProgRef ciShader; 36 | 37 | melo::MaterialType materialType; 38 | 39 | static Ref create(ModelObjRef modelObj, const tinyobj::material_t& property); 40 | void recreate(const tinyobj::material_t& property); 41 | void predraw(); 42 | void postdraw(); 43 | }; 44 | 45 | struct MeshObj : public melo::Node 46 | { 47 | typedef std::shared_ptr Ref; 48 | tinyobj::shape_t property; 49 | 50 | struct SubMesh 51 | { 52 | // very stupid design of OBJ spec... 53 | gl::VboMeshRef vboMesh; 54 | MaterialObj::Ref material; 55 | glm::vec3 boundBoxMin, boundBoxMax; 56 | 57 | // these are scratch data, keep them here for easier life... 58 | std::vector positions; 59 | std::vector normals; 60 | std::vector texcoords; 61 | std::vector colors; 62 | std::vector indexArray; 63 | 64 | void setup(); 65 | void draw(); 66 | }; 67 | 68 | std::unordered_map submeshes; 69 | 70 | static Ref create(ModelObjRef modelObj, const tinyobj::shape_t& property); 71 | 72 | void draw(melo::DrawOrder order) override; 73 | void predraw(melo::DrawOrder order) override; 74 | void postdraw(melo::DrawOrder order) override; 75 | }; 76 | 77 | struct ModelObj : public MeshObj 78 | { 79 | static ModelObjRef create(const fs::path& meshPath, std::string* loadingError = nullptr); 80 | 81 | fs::path meshPath; 82 | fs::path baseDir; 83 | 84 | bool flipV = true; 85 | 86 | std::vector materials; 87 | tinyobj::attrib_t attrib; 88 | }; 89 | -------------------------------------------------------------------------------- /include/civox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // TODO -------------------------------------------------------------------------------- /include/melo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../include/Node.h" 4 | #include 5 | #include 6 | 7 | namespace melo 8 | { 9 | NodeRef create(const std::string& typeName); 10 | bool isMeshPathSupported(const cinder::fs::path& meshPath); 11 | 12 | NodeRef createRootNode(); 13 | NodeRef createMeshNode(const cinder::fs::path& meshPath); 14 | NodeRef createGridNode(float meters = 100.0f); 15 | NodeRef createSkyNode(const std::string& skyTexturePath); 16 | 17 | NodeRef loadScene(const std::string& filename); 18 | bool writeScene(NodeRef scene, const std::string& filename); 19 | 20 | void drawBoundingBox(NodeRef node, const ci::Color& color = { 1, 1, 0 }); 21 | 22 | NodeRef pick(NodeRef parentNode, const ci::CameraPersp& camera, const glm::ivec2& screenPos, uint32_t rayMask = 0xFFFFFF); 23 | NodeRef pick(NodeRef parentNode, const ci::Ray& ray, uint32_t rayMask = 0xFFFFFF); 24 | }; 25 | -------------------------------------------------------------------------------- /include/postprocess/FXAA.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014, Paul Houx - All rights reserved. 3 | This code is intended for use with the Cinder C++ library: http://libcinder.org 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that 6 | the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and 9 | the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 11 | the following disclaimer in the documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 14 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 15 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 17 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 18 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 19 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20 | POSSIBILITY OF SUCH DAMAGE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "cinder/gl/gl.h" 26 | #include "cinder/gl/Batch.h" 27 | #include "cinder/gl/Fbo.h" 28 | #include "cinder/gl/Texture.h" 29 | 30 | class FXAA { 31 | public: 32 | FXAA(); 33 | 34 | void draw( const ci::gl::TextureRef &source, const ci::Area &bounds ); 35 | void apply( const ci::gl::FboRef &destination, const ci::gl::FboRef &source ); 36 | private: 37 | ci::gl::BatchRef mBatch; 38 | }; -------------------------------------------------------------------------------- /include/postprocess/SMAA.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014, Paul Houx - All rights reserved. 3 | This code is intended for use with the Cinder C++ library: http://libcinder.org 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that 6 | the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and 9 | the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 11 | the following disclaimer in the documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 14 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 15 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 17 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 18 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 19 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20 | POSSIBILITY OF SUCH DAMAGE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "cinder/gl/gl.h" 26 | #include "cinder/gl/Batch.h" 27 | #include "cinder/gl/Fbo.h" 28 | #include "cinder/gl/Texture.h" 29 | 30 | class SMAA { 31 | public: 32 | SMAA(); 33 | 34 | void draw( const ci::gl::Texture2dRef &source, const ci::Area &bounds ); 35 | void apply( const ci::gl::FboRef &destination, const ci::gl::FboRef &source ); 36 | 37 | ci::gl::Texture2dRef getEdgePass(); 38 | ci::gl::Texture2dRef getBlendPass(); 39 | 40 | private: 41 | ci::gl::Fbo::Format mFboFormat; 42 | ci::gl::FboRef mFboEdgePass; 43 | ci::gl::FboRef mFboBlendPass; 44 | 45 | ci::gl::BatchRef mBatchFirstPass; // edge detection 46 | ci::gl::BatchRef mBatchSecondPass; // blending weight calculation 47 | ci::gl::BatchRef mBatchThirdPass; // neighborhood blending 48 | 49 | // These textures contain look-up tables that speed up the SMAA process. 50 | ci::gl::Texture2dRef mAreaTex; 51 | ci::gl::Texture2dRef mSearchTex; 52 | 53 | // Size of our buffers, to be passed to the shaders. 54 | ci::vec4 mMetrics; 55 | 56 | void createBuffers( int width, int height ); 57 | 58 | void doEdgePass( const ci::gl::Texture2dRef &source ); 59 | void doBlendPass(); 60 | }; -------------------------------------------------------------------------------- /melo.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [{ 3 | "path": "." 4 | }, 5 | { 6 | "path": "../../include/cinder" 7 | }, 8 | { 9 | "path": "../../src/cinder" 10 | }, 11 | { 12 | "path": "../../blocks" 13 | }, 14 | ], 15 | "settings": { 16 | "files.associations": { 17 | "*.gltf": "json", 18 | "xiosbase": "cpp", 19 | "array": "cpp", 20 | "tuple": "cpp", 21 | "utility": "cpp", 22 | "functional": "cpp" 23 | }, 24 | "git.ignoreLimitWarning": true 25 | } 26 | } -------------------------------------------------------------------------------- /samples/AnimToCSV/include/Resources.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cinder/CinderResources.h" 3 | 4 | //#define RES_MY_RES CINDER_RESOURCE( ../resources/, image_name.png, 128, IMAGE ) 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /samples/AnimToCSV/include/item.def: -------------------------------------------------------------------------------- 1 | ITEM_DEF(int, APP_WIDTH, 1024) 2 | ITEM_DEF(int, APP_HEIGHT, 768) 3 | -------------------------------------------------------------------------------- /samples/AnimToCSV/resources/cinder_app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/AnimToCSV/resources/cinder_app_icon.ico -------------------------------------------------------------------------------- /samples/AnimToCSV/vc2019/AnimToCSV.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 16 3 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AnimToCSV", "AnimToCSV.vcxproj", "{9B9E5F13-7358-46D5-8587-682B7A86D2DB}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|x64 = Debug|x64 8 | Release|x64 = Release|x64 9 | EndGlobalSection 10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 11 | {9B9E5F13-7358-46D5-8587-682B7A86D2DB}.Debug|x64.ActiveCfg = Debug|x64 12 | {9B9E5F13-7358-46D5-8587-682B7A86D2DB}.Debug|x64.Build.0 = Debug|x64 13 | {9B9E5F13-7358-46D5-8587-682B7A86D2DB}.Release|x64.ActiveCfg = Release|x64 14 | {9B9E5F13-7358-46D5-8587-682B7A86D2DB}.Release|x64.Build.0 = Release|x64 15 | EndGlobalSection 16 | GlobalSection(SolutionProperties) = preSolution 17 | HideSolutionNode = FALSE 18 | EndGlobalSection 19 | EndGlobal 20 | -------------------------------------------------------------------------------- /samples/AnimToCSV/vc2019/Resources.rc: -------------------------------------------------------------------------------- 1 | #include "../include/Resources.h" 2 | 3 | 1 ICON "..\\resources\\cinder_app_icon.ico" 4 | -------------------------------------------------------------------------------- /samples/MeshViewer/.gitignore: -------------------------------------------------------------------------------- 1 | assets 2 | -------------------------------------------------------------------------------- /samples/MeshViewer/assets/Box/README.md: -------------------------------------------------------------------------------- 1 | # Box 2 | ## Screenshot 3 | 4 | ![screenshot](screenshot/screenshot.png) 5 | 6 | ## License Information 7 | 8 | Donated by [Cesium](http://cesiumjs.org/) for glTF testing. -------------------------------------------------------------------------------- /samples/MeshViewer/assets/Box/glTF-Binary/Box.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/Box/glTF-Binary/Box.glb -------------------------------------------------------------------------------- /samples/MeshViewer/assets/Box/glTF-Draco/0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/Box/glTF-Draco/0.bin -------------------------------------------------------------------------------- /samples/MeshViewer/assets/Box/glTF-Draco/Box.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "asset": { 3 | "generator": "COLLADA2GLTF", 4 | "version": "2.0" 5 | }, 6 | "scene": 0, 7 | "scenes": [ 8 | { 9 | "nodes": [ 10 | 0 11 | ] 12 | } 13 | ], 14 | "nodes": [ 15 | { 16 | "children": [ 17 | 1 18 | ], 19 | "matrix": [ 20 | 1, 21 | 0, 22 | 0, 23 | 0, 24 | 0, 25 | 0, 26 | -1, 27 | 0, 28 | 0, 29 | 1, 30 | 0, 31 | 0, 32 | 0, 33 | 0, 34 | 0, 35 | 1 36 | ] 37 | }, 38 | { 39 | "mesh": 0 40 | } 41 | ], 42 | "meshes": [ 43 | { 44 | "primitives": [ 45 | { 46 | "attributes": { 47 | "NORMAL": 1, 48 | "POSITION": 2 49 | }, 50 | "indices": 0, 51 | "mode": 4, 52 | "material": 0, 53 | "extensions": { 54 | "KHR_draco_mesh_compression": { 55 | "bufferView": 0, 56 | "attributes": { 57 | "NORMAL": 0, 58 | "POSITION": 1 59 | } 60 | } 61 | } 62 | } 63 | ], 64 | "name": "Mesh" 65 | } 66 | ], 67 | "accessors": [ 68 | { 69 | "componentType": 5123, 70 | "count": 36, 71 | "max": [ 72 | 23 73 | ], 74 | "min": [ 75 | 0 76 | ], 77 | "type": "SCALAR" 78 | }, 79 | { 80 | "componentType": 5126, 81 | "count": 24, 82 | "max": [ 83 | 1, 84 | 1, 85 | 1 86 | ], 87 | "min": [ 88 | -1, 89 | -1, 90 | -1 91 | ], 92 | "type": "VEC3" 93 | }, 94 | { 95 | "componentType": 5126, 96 | "count": 24, 97 | "max": [ 98 | 0.5, 99 | 0.5, 100 | 0.5 101 | ], 102 | "min": [ 103 | -0.5, 104 | -0.5, 105 | -0.5 106 | ], 107 | "type": "VEC3" 108 | } 109 | ], 110 | "materials": [ 111 | { 112 | "pbrMetallicRoughness": { 113 | "baseColorFactor": [ 114 | 0.800000011920929, 115 | 0, 116 | 0, 117 | 1 118 | ], 119 | "metallicFactor": 0 120 | }, 121 | "name": "Red" 122 | } 123 | ], 124 | "bufferViews": [ 125 | { 126 | "buffer": 0, 127 | "byteOffset": 0, 128 | "byteLength": 118 129 | } 130 | ], 131 | "buffers": [ 132 | { 133 | "byteLength": 118, 134 | "uri": "0.bin" 135 | } 136 | ], 137 | "extensionsRequired": [ 138 | "KHR_draco_mesh_compression" 139 | ], 140 | "extensionsUsed": [ 141 | "KHR_draco_mesh_compression" 142 | ] 143 | } 144 | -------------------------------------------------------------------------------- /samples/MeshViewer/assets/Box/glTF-Embedded/Box.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "asset": { 3 | "generator": "COLLADA2GLTF", 4 | "version": "2.0" 5 | }, 6 | "scene": 0, 7 | "scenes": [ 8 | { 9 | "nodes": [ 10 | 0 11 | ] 12 | } 13 | ], 14 | "nodes": [ 15 | { 16 | "children": [ 17 | 1 18 | ], 19 | "matrix": [ 20 | 1.0, 21 | 0.0, 22 | 0.0, 23 | 0.0, 24 | 0.0, 25 | 0.0, 26 | -1.0, 27 | 0.0, 28 | 0.0, 29 | 1.0, 30 | 0.0, 31 | 0.0, 32 | 0.0, 33 | 0.0, 34 | 0.0, 35 | 1.0 36 | ] 37 | }, 38 | { 39 | "mesh": 0 40 | } 41 | ], 42 | "meshes": [ 43 | { 44 | "primitives": [ 45 | { 46 | "attributes": { 47 | "NORMAL": 1, 48 | "POSITION": 2 49 | }, 50 | "indices": 0, 51 | "mode": 4, 52 | "material": 0 53 | } 54 | ], 55 | "name": "Mesh" 56 | } 57 | ], 58 | "accessors": [ 59 | { 60 | "bufferView": 0, 61 | "byteOffset": 0, 62 | "componentType": 5123, 63 | "count": 36, 64 | "max": [ 65 | 23 66 | ], 67 | "min": [ 68 | 0 69 | ], 70 | "type": "SCALAR" 71 | }, 72 | { 73 | "bufferView": 1, 74 | "byteOffset": 0, 75 | "componentType": 5126, 76 | "count": 24, 77 | "max": [ 78 | 1.0, 79 | 1.0, 80 | 1.0 81 | ], 82 | "min": [ 83 | -1.0, 84 | -1.0, 85 | -1.0 86 | ], 87 | "type": "VEC3" 88 | }, 89 | { 90 | "bufferView": 1, 91 | "byteOffset": 288, 92 | "componentType": 5126, 93 | "count": 24, 94 | "max": [ 95 | 0.5, 96 | 0.5, 97 | 0.5 98 | ], 99 | "min": [ 100 | -0.5, 101 | -0.5, 102 | -0.5 103 | ], 104 | "type": "VEC3" 105 | } 106 | ], 107 | "materials": [ 108 | { 109 | "pbrMetallicRoughness": { 110 | "baseColorFactor": [ 111 | 0.800000011920929, 112 | 0.0, 113 | 0.0, 114 | 1.0 115 | ], 116 | "metallicFactor": 0.0 117 | }, 118 | "name": "Red" 119 | } 120 | ], 121 | "bufferViews": [ 122 | { 123 | "buffer": 0, 124 | "byteOffset": 576, 125 | "byteLength": 72, 126 | "target": 34963 127 | }, 128 | { 129 | "buffer": 0, 130 | "byteOffset": 0, 131 | "byteLength": 576, 132 | "byteStride": 12, 133 | "target": 34962 134 | } 135 | ], 136 | "buffers": [ 137 | { 138 | "byteLength": 648, 139 | "uri": "data:application/octet-stream;base64,AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA" 140 | } 141 | ] 142 | } 143 | -------------------------------------------------------------------------------- /samples/MeshViewer/assets/Box/glTF-pbrSpecularGlossiness/Box.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "asset": { 3 | "generator": "COLLADA2GLTF", 4 | "version": "2.0" 5 | }, 6 | "scene": 0, 7 | "scenes": [ 8 | { 9 | "nodes": [ 10 | 0 11 | ] 12 | } 13 | ], 14 | "nodes": [ 15 | { 16 | "children": [ 17 | 1 18 | ], 19 | "matrix": [ 20 | 1.0, 21 | 0.0, 22 | 0.0, 23 | 0.0, 24 | 0.0, 25 | 0.0, 26 | -1.0, 27 | 0.0, 28 | 0.0, 29 | 1.0, 30 | 0.0, 31 | 0.0, 32 | 0.0, 33 | 0.0, 34 | 0.0, 35 | 1.0 36 | ] 37 | }, 38 | { 39 | "mesh": 0 40 | } 41 | ], 42 | "meshes": [ 43 | { 44 | "primitives": [ 45 | { 46 | "attributes": { 47 | "NORMAL": 1, 48 | "POSITION": 2 49 | }, 50 | "indices": 0, 51 | "mode": 4, 52 | "material": 0 53 | } 54 | ], 55 | "name": "Mesh" 56 | } 57 | ], 58 | "accessors": [ 59 | { 60 | "bufferView": 0, 61 | "byteOffset": 0, 62 | "componentType": 5123, 63 | "count": 36, 64 | "max": [ 65 | 23 66 | ], 67 | "min": [ 68 | 0 69 | ], 70 | "type": "SCALAR" 71 | }, 72 | { 73 | "bufferView": 1, 74 | "byteOffset": 0, 75 | "componentType": 5126, 76 | "count": 24, 77 | "max": [ 78 | 1.0, 79 | 1.0, 80 | 1.0 81 | ], 82 | "min": [ 83 | -1.0, 84 | -1.0, 85 | -1.0 86 | ], 87 | "type": "VEC3" 88 | }, 89 | { 90 | "bufferView": 1, 91 | "byteOffset": 288, 92 | "componentType": 5126, 93 | "count": 24, 94 | "max": [ 95 | 0.5, 96 | 0.5, 97 | 0.5 98 | ], 99 | "min": [ 100 | -0.5, 101 | -0.5, 102 | -0.5 103 | ], 104 | "type": "VEC3" 105 | } 106 | ], 107 | "materials": [ 108 | { 109 | "pbrMetallicRoughness": { 110 | "baseColorFactor": [ 111 | 0.800000011920929, 112 | 0.0, 113 | 0.0, 114 | 1.0 115 | ], 116 | "metallicFactor": 0.0 117 | }, 118 | "extensions": { 119 | "KHR_materials_pbrSpecularGlossiness": { 120 | "diffuseFactor": [ 121 | 0.800000011920929, 122 | 0.0, 123 | 0.0, 124 | 1.0 125 | ], 126 | "specularFactor": [ 127 | 0.20000000298023225, 128 | 0.20000000298023225, 129 | 0.20000000298023225 130 | ], 131 | "glossinessFactor": 1.0 132 | } 133 | }, 134 | "name": "Red" 135 | } 136 | ], 137 | "bufferViews": [ 138 | { 139 | "buffer": 0, 140 | "byteOffset": 576, 141 | "byteLength": 72, 142 | "target": 34963 143 | }, 144 | { 145 | "buffer": 0, 146 | "byteOffset": 0, 147 | "byteLength": 576, 148 | "byteStride": 12, 149 | "target": 34962 150 | } 151 | ], 152 | "buffers": [ 153 | { 154 | "byteLength": 648, 155 | "uri": "Box0.bin" 156 | } 157 | ], 158 | "extensionsUsed": [ 159 | "KHR_materials_pbrSpecularGlossiness" 160 | ] 161 | } 162 | -------------------------------------------------------------------------------- /samples/MeshViewer/assets/Box/glTF-pbrSpecularGlossiness/Box0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/Box/glTF-pbrSpecularGlossiness/Box0.bin -------------------------------------------------------------------------------- /samples/MeshViewer/assets/Box/glTF/Box.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "asset": { 3 | "generator": "COLLADA2GLTF", 4 | "version": "2.0" 5 | }, 6 | "scene": 0, 7 | "scenes": [ 8 | { 9 | "nodes": [ 10 | 0 11 | ] 12 | } 13 | ], 14 | "nodes": [ 15 | { 16 | "children": [ 17 | 1 18 | ], 19 | "matrix": [ 20 | 1.0, 21 | 0.0, 22 | 0.0, 23 | 0.0, 24 | 0.0, 25 | 0.0, 26 | -1.0, 27 | 0.0, 28 | 0.0, 29 | 1.0, 30 | 0.0, 31 | 0.0, 32 | 0.0, 33 | 0.0, 34 | 0.0, 35 | 1.0 36 | ] 37 | }, 38 | { 39 | "mesh": 0 40 | } 41 | ], 42 | "meshes": [ 43 | { 44 | "primitives": [ 45 | { 46 | "attributes": { 47 | "NORMAL": 1, 48 | "POSITION": 2 49 | }, 50 | "indices": 0, 51 | "mode": 4, 52 | "material": 0 53 | } 54 | ], 55 | "name": "Mesh" 56 | } 57 | ], 58 | "accessors": [ 59 | { 60 | "bufferView": 0, 61 | "byteOffset": 0, 62 | "componentType": 5123, 63 | "count": 36, 64 | "max": [ 65 | 23 66 | ], 67 | "min": [ 68 | 0 69 | ], 70 | "type": "SCALAR" 71 | }, 72 | { 73 | "bufferView": 1, 74 | "byteOffset": 0, 75 | "componentType": 5126, 76 | "count": 24, 77 | "max": [ 78 | 1.0, 79 | 1.0, 80 | 1.0 81 | ], 82 | "min": [ 83 | -1.0, 84 | -1.0, 85 | -1.0 86 | ], 87 | "type": "VEC3" 88 | }, 89 | { 90 | "bufferView": 1, 91 | "byteOffset": 288, 92 | "componentType": 5126, 93 | "count": 24, 94 | "max": [ 95 | 0.5, 96 | 0.5, 97 | 0.5 98 | ], 99 | "min": [ 100 | -0.5, 101 | -0.5, 102 | -0.5 103 | ], 104 | "type": "VEC3" 105 | } 106 | ], 107 | "materials": [ 108 | { 109 | "pbrMetallicRoughness": { 110 | "baseColorFactor": [ 111 | 0.800000011920929, 112 | 0.0, 113 | 0.0, 114 | 1.0 115 | ], 116 | "metallicFactor": 0.0 117 | }, 118 | "name": "Red" 119 | } 120 | ], 121 | "bufferViews": [ 122 | { 123 | "buffer": 0, 124 | "byteOffset": 576, 125 | "byteLength": 72, 126 | "target": 34963 127 | }, 128 | { 129 | "buffer": 0, 130 | "byteOffset": 0, 131 | "byteLength": 576, 132 | "byteStride": 12, 133 | "target": 34962 134 | } 135 | ], 136 | "buffers": [ 137 | { 138 | "byteLength": 648, 139 | "uri": "Box0.bin" 140 | } 141 | ] 142 | } 143 | -------------------------------------------------------------------------------- /samples/MeshViewer/assets/Box/glTF/Box0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/Box/glTF/Box0.bin -------------------------------------------------------------------------------- /samples/MeshViewer/assets/Box/screenshot/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/Box/screenshot/screenshot.png -------------------------------------------------------------------------------- /samples/MeshViewer/assets/InterpolationTest/InterpolationTest.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/InterpolationTest/InterpolationTest.glb -------------------------------------------------------------------------------- /samples/MeshViewer/assets/oc-five/five-shape-ao.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/oc-five/five-shape-ao.jpg -------------------------------------------------------------------------------- /samples/MeshViewer/assets/oc-five/five-shape-basecolor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/oc-five/five-shape-basecolor.jpg -------------------------------------------------------------------------------- /samples/MeshViewer/assets/oc-five/five-shape-height.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/oc-five/five-shape-height.png -------------------------------------------------------------------------------- /samples/MeshViewer/assets/oc-five/five-shape-roughness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/oc-five/five-shape-roughness.png -------------------------------------------------------------------------------- /samples/MeshViewer/assets/oc-five/five.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/oc-five/five.bin -------------------------------------------------------------------------------- /samples/MeshViewer/assets/shibainu/shibainu.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 3 3 | 4 | newmtl Shiba_Brown 5 | Ns 96.078431 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.679543 0.263325 0.040479 8 | Ks 0.250000 0.250000 0.250000 9 | Ke 0.000000 0.000000 0.000000 10 | Ni 1.000000 11 | d 1.000000 12 | illum 2 13 | 14 | newmtl Shiba_Nose 15 | Ns 96.078431 16 | Ka 1.000000 1.000000 1.000000 17 | Kd 0.004896 0.004896 0.004896 18 | Ks 0.057292 0.057292 0.057292 19 | Ke 0.000000 0.000000 0.000000 20 | Ni 1.000000 21 | d 1.000000 22 | illum 2 23 | 24 | newmtl Shiba_white 25 | Ns 96.078431 26 | Ka 1.000000 1.000000 1.000000 27 | Kd 0.715694 0.693872 0.644480 28 | Ks 0.250000 0.250000 0.250000 29 | Ke 0.000000 0.000000 0.000000 30 | Ni 1.000000 31 | d 1.000000 32 | illum 2 33 | -------------------------------------------------------------------------------- /samples/MeshViewer/assets/vox/monu1.vox: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/vox/monu1.vox -------------------------------------------------------------------------------- /samples/MeshViewer/assets/vox/teapot.vox: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/assets/vox/teapot.vox -------------------------------------------------------------------------------- /samples/MeshViewer/build-vs2015.bat: -------------------------------------------------------------------------------- 1 | cd %~dp0\vc2015 2 | set proj=MeloViewer.sln 3 | set msbuild="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\amd64\MSBuild.exe" 4 | set msbuild2="D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\amd64\MSBuild.exe" 5 | REM msbuild %proj% /p:Configuration=Debug /p:Platform=x64 /v:minimal /m 6 | %msbuild% %proj% /p:Configuration=Release /p:Platform=x64 /v:minimal /m 7 | %msbuild2% %proj% /p:Configuration=Release /p:Platform=x64 /v:minimal /m 8 | REM msbuild %proj% /p:Configuration=Debug_Shared /p:Platform=x64 /v:minimal /m 9 | REM msbuild %proj% /p:Configuration=Release_Shared /p:Platform=x64 /v:minimal /m 10 | cd .. -------------------------------------------------------------------------------- /samples/MeshViewer/include/Resources.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cinder/CinderResources.h" 3 | 4 | //#define RES_MY_RES CINDER_RESOURCE( ../resources/, image_name.png, 128, IMAGE ) 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /samples/MeshViewer/include/item.def: -------------------------------------------------------------------------------- 1 | GROUP_DEF(App) 2 | ITEM_DEF(int, APP_WIDTH, 1024) 3 | ITEM_DEF(int, APP_HEIGHT, 768) 4 | ITEM_DEF(bool, GUI_VISIBLE, true) 5 | ITEM_DEF(bool, ENV_VISIBLE, true) 6 | ITEM_DEF(bool, XYZ_VISIBLE, false) 7 | ITEM_DEF(bool, WIRE_FRAME, false) 8 | ITEM_DEF(bool, FLIP_V, true) 9 | ITEM_DEF(bool, FPS_CAMERA, false) 10 | ITEM_DEF(bool, CONSOLE_ENABLED, false) 11 | ITEM_DEF(bool, RENDER_DOC_ENABLED, false) 12 | ITEM_DEF(bool, PROFILE_NODE_DRAW, false) 13 | ITEM_DEF(bool, _REMOTERY_ENABLED, false) 14 | 15 | GROUP_DEF(Scene) 16 | ITEM_DEF(string, IRRADIANCE_TEX, "CathedralIrradiance.dds") 17 | ITEM_DEF(string, RADIANCE_TEX, "CathedralRadiance.dds") 18 | ITEM_DEF(string, BRDF_LUT_TEX, "pbr/lut_ggx.png") 19 | ITEM_DEF(bool, IS_SMAA, true) 20 | ITEM_DEF_MINMAX(float, POINT_SIZE, 1, 0.001, 10) 21 | ITEM_DEF_MINMAX(float, EXPOSURE, 1, 0.01, 10) 22 | ITEM_DEF_MINMAX(int, IBL_MIP, 0, 0, 10) 23 | 24 | GROUP_DEF(Camera) 25 | ITEM_DEF(float, CAM_POS_X, 10) 26 | ITEM_DEF(float, CAM_POS_Y, 10) 27 | ITEM_DEF(float, CAM_POS_Z, 10) 28 | ITEM_DEF(float, CAM_DIR_X, 0) 29 | ITEM_DEF(float, CAM_DIR_Y, 0) 30 | ITEM_DEF(float, CAM_DIR_Z, 0) 31 | ITEM_DEF(float, CAM_Z_NEAR, 0.1) 32 | ITEM_DEF(float, CAM_Z_FAR, 1000) 33 | 34 | GROUP_DEF(Light0) 35 | ITEM_DEF_MINMAX(float, LIGHT0_INTENSITY, 1, 0.01, 20) 36 | 37 | 38 | -------------------------------------------------------------------------------- /samples/MeshViewer/resources/CinderApp.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/resources/CinderApp.icns -------------------------------------------------------------------------------- /samples/MeshViewer/resources/CinderApp_ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/resources/CinderApp_ios.png -------------------------------------------------------------------------------- /samples/MeshViewer/resources/cinder_app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/resources/cinder_app_icon.ico -------------------------------------------------------------------------------- /samples/MeshViewer/src/ShadowMap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef std::shared_ptr ShadowMapRef; 4 | 5 | class ShadowMap { 6 | public: 7 | static ShadowMapRef create(int size) { return ShadowMapRef(new ShadowMap{ size }); } 8 | ShadowMap(int size) 9 | { 10 | reset(size); 11 | } 12 | 13 | void reset(int size) 14 | { 15 | gl::Texture2d::Format depthFormat; 16 | depthFormat.setInternalFormat(GL_DEPTH_COMPONENT32F); 17 | depthFormat.setMagFilter(GL_LINEAR); 18 | depthFormat.setMinFilter(GL_LINEAR); 19 | depthFormat.setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); 20 | depthFormat.setCompareMode(GL_COMPARE_REF_TO_TEXTURE); 21 | depthFormat.setCompareFunc(GL_LEQUAL); 22 | mTextureShadowMap = gl::Texture2d::create(size, size, depthFormat); 23 | 24 | gl::Fbo::Format fboFormat; 25 | fboFormat.attachment(GL_DEPTH_ATTACHMENT, mTextureShadowMap); 26 | mShadowMap = gl::Fbo::create(size, size, fboFormat); 27 | } 28 | 29 | const gl::FboRef& getFbo() const { return mShadowMap; } 30 | const gl::Texture2dRef& getTexture() const { return mTextureShadowMap; } 31 | 32 | float getAspectRatio() const { return mShadowMap->getAspectRatio(); } 33 | ivec2 getSize() const { return mShadowMap->getSize(); } 34 | private: 35 | gl::FboRef mShadowMap; 36 | gl::Texture2dRef mTextureShadowMap; 37 | }; 38 | 39 | struct LightData { 40 | bool toggleViewpoint; 41 | float distanceRadius; 42 | float fov; 43 | CameraPersp camera; 44 | vec3 viewpoint; 45 | vec3 target; 46 | }; 47 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Yev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/README.md: -------------------------------------------------------------------------------- 1 | # vfspp 2 | 3 | vfspp - C++ Virtual File System that allow to manipulate with files from memory, zip archives or native filesystems like it is just native filesystem. It is useful for game developers to use resources in native filesystem during development and then pack their to the archive in distribution build. 4 | 5 | ```C++ 6 | // Register native filesystem during developnment or zip for distribution build 7 | IFileSystemPtr root_fs = nullptr; 8 | #if !defined(DISTRIBUTION_BUILD) 9 | root_fs.reset(new CNativeFileSystem(GetBundlePath() + "resources/")); 10 | #else 11 | root_fs.reset(new CZipFileSystem("Resources.zip", "/")); 12 | #endif 13 | 14 | root_fs->Initialize(); 15 | vfs_get_global()->AddFileSystem("/", root_fs); 16 | ``` 17 | 18 | Sometimes useful to have several mounted filesystem, like "/" - is your root native filesystem, "/tmp" - memory filesystem, which allow to work with temporary files without disk operations, "/resources" - zip filesystem with game resources. 19 | 20 | ```C++ 21 | std::string zipPassword = "123"; 22 | 23 | IFileSystemPtr root_fs(new CNativeFileSystem(GetBundlePath() + "Documents/")); 24 | IFileSystemPtr zip_fs(new CZipFileSystem("Resources.zip", "/", false, zipPassword)); 25 | IFileSystemPtr mem_fs(new CMemoryFileSystem()); 26 | 27 | root_fs->Initialize(); 28 | zip_fs->Initialize(); 29 | mem_fs->Initialize(); 30 | 31 | CVirtualFileSystemPtr vfs = vfs_get_global(); 32 | vfs->AddFileSystem("/", root_fs); 33 | vfs->AddFileSystem("/resources", zip_fs); 34 | vfs->AddFileSystem("/tmp", mem_fs); 35 | 36 | IFilePtr saveFile = vfs->openFile(CFileInfo("/savefile.sav"), IFile::In); 37 | if (saveFile && saveFile->IsOpened()) 38 | { 39 | // Parse game save 40 | ... 41 | } 42 | 43 | IFilePtr userAvatarFile = vfs->openFile(CFileInfo("/tmp/avatar.jpg"), IFile::ReadWrite); 44 | if (userAvatarFile && userAvatarFile->IsOpened()) 45 | { 46 | // Load avatar from network and store it in memory 47 | ... 48 | userAvatarFile->Write(&data[0], data.size()); 49 | userAvatarFile->Close(); 50 | } 51 | 52 | IFilePtr textureFile = vfs->openFile(CFileInfo("/resources/background.pvr"), IFile::In); 53 | if (textureFile && textureFile->IsOpened()) 54 | { 55 | // Create texture 56 | ... 57 | } 58 | ``` 59 | 60 | # How To Build # 61 | 62 | Specify platform by setting PLATFORM variable. Supported: Windows, Linux, Android, macOS, iOS, tvOS, watchOS 63 | ``` 64 | cmake . -DPLATFORM=macOS 65 | make 66 | ``` 67 | 68 | Use CMAKE_INSTALL_PREFIX to change installation directory 69 | 70 | ``` 71 | cmake -DCMAKE_INSTALL_PREFIX=/usr -DPLATFORM=macOS 72 | make 73 | make install 74 | ``` 75 | 76 | To generate project file use -G option 77 | 78 | ``` 79 | cmake -G Xcode . -DPLATFORM=iOS 80 | or 81 | cmake -G "Visual Studio 14 2015 Win64" . -DPLATFORM=Windows 82 | ``` 83 | 84 | Add parameter WITH_EXAMPLES to build with example project 85 | 86 | ``` 87 | cmake -G Xcode . -DCMAKE_INSTALL_PREFIX=./build -DPLATFORM=macOS -DWITH_EXAMPLES=1 88 | ``` -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/include/CFileInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // CFileInfo.h 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/30/16. 6 | // 7 | // 8 | 9 | #ifndef CFILEINFO_H 10 | #define CFILEINFO_H 11 | 12 | #include "VFS.h" 13 | 14 | namespace vfspp 15 | { 16 | 17 | class CFileInfo final 18 | { 19 | public: 20 | CFileInfo(); 21 | ~CFileInfo(); 22 | 23 | CFileInfo(const std::string& filePath); 24 | CFileInfo(const std::string& basePath, const std::string& fileName, bool isDir); 25 | 26 | /* 27 | * 28 | */ 29 | void Initialize(const std::string& basePath, const std::string& fileName, bool isDir); 30 | 31 | /* 32 | * Get file name 33 | */ 34 | const std::string& Name() const; 35 | 36 | /* 37 | * Get file name without extension 38 | */ 39 | const std::string& BaseName() const; 40 | 41 | /* 42 | * Get file extension 43 | */ 44 | const std::string& Extension() const; 45 | 46 | /* 47 | * Get absolute file path 48 | */ 49 | const std::string& absolutePath() const; 50 | 51 | /* 52 | * Directory where file locates 53 | */ 54 | const std::string& basePath() const; 55 | 56 | /* 57 | * Is a directory 58 | */ 59 | bool IsDir() const; 60 | 61 | /* 62 | * 63 | */ 64 | bool IsValid() const; 65 | 66 | private: 67 | std::string m_Name; 68 | std::string m_BaseName; 69 | std::string m_Extension; 70 | std::string m_absolutePath; 71 | std::string m_basePath; 72 | bool m_IsDir; 73 | }; 74 | 75 | inline bool operator ==(const CFileInfo& fi1, const CFileInfo& fi2) 76 | { 77 | return fi1.absolutePath() == fi2.absolutePath(); 78 | } 79 | 80 | inline bool operator <(const CFileInfo& fi1, const CFileInfo& fi2) 81 | { 82 | return fi1.absolutePath() < fi2.absolutePath(); 83 | } 84 | 85 | }; // namespace vfspp 86 | 87 | #endif /* CFILEINFO_H */ 88 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/include/CMemoryFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // CMemoryFile.h 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/23/16. 6 | // 7 | // 8 | 9 | #ifndef CMEMORYFILE_H 10 | #define CMEMORYFILE_H 11 | 12 | #include "IFile.h" 13 | 14 | namespace vfspp 15 | { 16 | CLASS_PTR(IFile) 17 | 18 | class CMemoryFile final : public IFile 19 | { 20 | friend class CMemoryFileSystem; 21 | public: 22 | CMemoryFile(const CFileInfo& fileInfo); 23 | ~CMemoryFile(); 24 | 25 | /* 26 | * Get file information 27 | */ 28 | virtual const CFileInfo& FileInfo() const override; 29 | 30 | /* 31 | * Returns file size 32 | */ 33 | virtual uint64_t Size() override; 34 | 35 | /* 36 | * Check is readonly filesystem 37 | */ 38 | virtual bool isReadOnly() const override; 39 | 40 | /* 41 | * Open file for reading/writing 42 | */ 43 | virtual void Open(int mode) override; 44 | 45 | /* 46 | * Close file 47 | */ 48 | virtual void Close() override; 49 | 50 | /* 51 | * Check is file ready for reading/writing 52 | */ 53 | virtual bool IsOpened() const override; 54 | 55 | /* 56 | * Seek on a file 57 | */ 58 | virtual uint64_t Seek(uint64_t offset, Origin origin) override; 59 | /* 60 | * Returns offset in file 61 | */ 62 | virtual uint64_t Tell() override; 63 | 64 | /* 65 | * Read data from file to buffer 66 | */ 67 | virtual uint64_t Read(uint8_t* buffer, uint64_t size) override; 68 | /* 69 | * Write buffer data to file 70 | */ 71 | virtual uint64_t Write(const uint8_t* buffer, uint64_t size) override; 72 | 73 | private: 74 | std::vector m_Data; 75 | CFileInfo m_FileInfo; 76 | bool m_isReadOnly; 77 | bool m_IsOpened; 78 | uint64_t m_SeekPos; 79 | int m_Mode; 80 | }; 81 | 82 | } // namespace vfspp 83 | 84 | #endif /* CMEMORYFILE_H */ 85 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/include/CMemoryFileSystem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CMemoryFileSystem.h 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/23/16. 6 | // 7 | // 8 | 9 | #ifndef CMEMORYFILESYSTEM_H 10 | #define CMEMORYFILESYSTEM_H 11 | 12 | #include "IFileSystem.h" 13 | 14 | namespace vfspp 15 | { 16 | CLASS_PTR(CMemoryFile); 17 | 18 | class CMemoryFileSystem final : public IFileSystem 19 | { 20 | public: 21 | CMemoryFileSystem(); 22 | ~CMemoryFileSystem(); 23 | 24 | /* 25 | * Initialize filesystem with a base path 26 | */ 27 | virtual void Initialize() override; 28 | /* 29 | * Shutdown filesystem 30 | */ 31 | virtual void Shutdown() override; 32 | 33 | /* 34 | * Check if filesystem is initialized 35 | */ 36 | virtual bool IsInitialized() const override; 37 | 38 | /* 39 | * Get base path 40 | */ 41 | virtual const std::string& basePath() const override; 42 | 43 | /* 44 | * Retrieve file list according filter 45 | */ 46 | virtual const TFileList& FileList() const override; 47 | 48 | /* 49 | * Check is readonly filesystem 50 | */ 51 | virtual bool isReadOnly() const override; 52 | 53 | /* 54 | * Open existing file for reading, if not exists return null 55 | */ 56 | virtual IFilePtr openFile(const CFileInfo& filePath, int mode) override; 57 | 58 | /* 59 | * Close file 60 | */ 61 | virtual void closeFile(IFilePtr file) override; 62 | 63 | /* 64 | * Create file on writeable filesystem. Return true if file already exists 65 | */ 66 | virtual bool createFile(const CFileInfo& filePath) override; 67 | 68 | /* 69 | * Remove existing file on writable filesystem 70 | */ 71 | virtual bool removeFile(const CFileInfo& filePath) override; 72 | 73 | /* 74 | * Copy existing file on writable filesystem 75 | */ 76 | virtual bool copyFile(const CFileInfo& src, const CFileInfo& dest) override; 77 | 78 | /* 79 | * Rename existing file on writable filesystem 80 | */ 81 | virtual bool RenameFile(const CFileInfo& src, const CFileInfo& dest) override; 82 | 83 | /* 84 | * Check if file exists on filesystem 85 | */ 86 | virtual bool isFileExists(const CFileInfo& filePath) const override; 87 | 88 | /* 89 | * Check is file 90 | */ 91 | virtual bool IsFile(const CFileInfo& filePath) const override; 92 | 93 | /* 94 | * Check is dir 95 | */ 96 | virtual bool IsDir(const CFileInfo& dirPath) const override; 97 | 98 | private: 99 | IFilePtr FindFile(const CFileInfo& fileInfo) const; 100 | 101 | private: 102 | bool m_IsInitialized; 103 | TFileList m_FileList; 104 | }; 105 | 106 | } // namespace vfspp 107 | 108 | #endif /* CMEMORYFILESYSTEM_H */ 109 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/include/CNativeFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // CNativeFile.h 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/23/16. 6 | // 7 | // 8 | 9 | #ifndef CNATIVEFILE_H 10 | #define CNATIVEFILE_H 11 | 12 | #include "IFile.h" 13 | 14 | namespace vfspp 15 | { 16 | 17 | class CNativeFile final : public IFile 18 | { 19 | public: 20 | CNativeFile(const CFileInfo& fileInfo); 21 | ~CNativeFile(); 22 | 23 | /* 24 | * Get file information 25 | */ 26 | virtual const CFileInfo& FileInfo() const override; 27 | 28 | /* 29 | * Returns file size 30 | */ 31 | virtual uint64_t Size() override; 32 | 33 | /* 34 | * Check is readonly filesystem 35 | */ 36 | virtual bool isReadOnly() const override; 37 | 38 | /* 39 | * Open file for reading/writting 40 | */ 41 | virtual void Open(int mode) override; 42 | 43 | /* 44 | * Close file 45 | */ 46 | virtual void Close() override; 47 | 48 | /* 49 | * Check is file ready for reading/writing 50 | */ 51 | virtual bool IsOpened() const override; 52 | 53 | /* 54 | * Seek on a file 55 | */ 56 | virtual uint64_t Seek(uint64_t offset, Origin origin) override; 57 | /* 58 | * Returns offset in file 59 | */ 60 | virtual uint64_t Tell() override; 61 | 62 | /* 63 | * Read data from file to buffer 64 | */ 65 | virtual uint64_t Read(uint8_t* buffer, uint64_t size) override; 66 | /* 67 | * Write buffer data to file 68 | */ 69 | virtual uint64_t Write(const uint8_t* buffer, uint64_t size) override; 70 | 71 | private: 72 | CFileInfo m_FileInfo; 73 | std::fstream m_Stream; 74 | bool m_isReadOnly; 75 | int m_Mode; 76 | }; 77 | 78 | } // namespace vfspp 79 | 80 | #endif /* CNATIVEFILE_H */ 81 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/include/CNativeFileSystem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CNativeFileSystem.h 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/23/16. 6 | // 7 | // 8 | 9 | #ifndef CNATIVEFILESYSTEM_H 10 | #define CNATIVEFILESYSTEM_H 11 | 12 | #include "IFileSystem.h" 13 | 14 | struct SDir; 15 | 16 | namespace vfspp 17 | { 18 | CLASS_PTR(CNativeFile) 19 | 20 | class CNativeFileSystem final : public IFileSystem 21 | { 22 | public: 23 | /* 24 | * Constructor, create with a base path 25 | */ 26 | CNativeFileSystem(const std::string& basePath); 27 | ~CNativeFileSystem(); 28 | /* 29 | * Initialize filesystem 30 | */ 31 | virtual void Initialize() override; 32 | /* 33 | * Shutdown filesystem 34 | */ 35 | virtual void Shutdown() override; 36 | 37 | /* 38 | * Check if filesystem is initialized 39 | */ 40 | virtual bool IsInitialized() const override; 41 | 42 | /* 43 | * Get base path 44 | */ 45 | virtual const std::string& basePath() const override; 46 | 47 | /* 48 | * Retrieve file list according filter 49 | */ 50 | virtual const TFileList& FileList() const override; 51 | 52 | /* 53 | * Check is readonly filesystem 54 | */ 55 | virtual bool isReadOnly() const override; 56 | 57 | /* 58 | * Open existing file for reading, if not exists return null 59 | */ 60 | virtual IFilePtr openFile(const CFileInfo& filePath, int mode) override; 61 | 62 | /* 63 | * Close file 64 | */ 65 | virtual void closeFile(IFilePtr file) override; 66 | 67 | /* 68 | * Create file on writeable filesystem. Return true if file already exists 69 | */ 70 | virtual bool createFile(const CFileInfo& filePath) override; 71 | 72 | /* 73 | * Remove existing file on writable filesystem 74 | */ 75 | virtual bool removeFile(const CFileInfo& filePath) override; 76 | 77 | /* 78 | * Copy existing file on writable filesystem 79 | */ 80 | virtual bool copyFile(const CFileInfo& src, const CFileInfo& dest) override; 81 | 82 | /* 83 | * Rename existing file on writable filesystem 84 | */ 85 | virtual bool RenameFile(const CFileInfo& src, const CFileInfo& dest) override; 86 | 87 | /* 88 | * Check if file exists on filesystem 89 | */ 90 | virtual bool isFileExists(const CFileInfo& filePath) const override; 91 | 92 | /* 93 | * Check is file 94 | */ 95 | virtual bool IsFile(const CFileInfo& filePath) const override; 96 | 97 | /* 98 | * Check is dir 99 | */ 100 | virtual bool IsDir(const CFileInfo& dirPath) const override; 101 | 102 | private: 103 | IFilePtr FindFile(const CFileInfo& fileInfo) const; 104 | void BuildFilelist(SDir* dir, std::string basePath, TFileList& outFileList); 105 | 106 | private: 107 | std::string m_basePath; 108 | bool m_IsInitialized; 109 | TFileList m_FileList; 110 | }; 111 | 112 | } // namespace vfspp 113 | 114 | #endif /* CNATIVEFILESYSTEM_H */ 115 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/include/CVirtualFileSystem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CVirtualFileSystem.h 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/23/16. 6 | // 7 | // 8 | 9 | #ifndef CVIRTUALFILESYSTEM_H 10 | #define CVIRTUALFILESYSTEM_H 11 | 12 | #include "IFileSystem.h" 13 | #include "IFile.h" 14 | 15 | namespace vfspp 16 | { 17 | CLASS_PTR(IFile) 18 | CLASS_PTR(IFileSystem) 19 | CLASS_PTR(CVirtualFileSystem) 20 | 21 | extern void vfs_initialize(); 22 | extern void vfs_shutdown(); 23 | extern CVirtualFileSystemPtr vfs_get_global(); 24 | 25 | class CVirtualFileSystem final 26 | { 27 | public: 28 | typedef std::list TFileSystemList; 29 | typedef std::unordered_map TFileSystemMap; 30 | 31 | struct SSortedAlias 32 | { 33 | std::string alias; 34 | IFileSystemPtr filesystem; 35 | 36 | SSortedAlias(const std::string& a, 37 | IFileSystemPtr fs) 38 | : alias(a) 39 | , filesystem(fs) 40 | {} 41 | }; 42 | typedef std::list TSortedAliasList; 43 | 44 | public: 45 | CVirtualFileSystem(); 46 | ~CVirtualFileSystem(); 47 | 48 | /* 49 | * Register new filesystem. Alias is base prefix to file access. 50 | * For ex. registered filesystem has base path '/home/media', but registered 51 | * with alias '/', so it possible to access files with path '/filename' 52 | * instead of '/home/media/filename 53 | */ 54 | void AddFileSystem(const std::string& alias, IFileSystemPtr filesystem); 55 | 56 | /* 57 | * Remove registered filesystem 58 | */ 59 | void removeFileSystem(const std::string& alias); 60 | 61 | /* 62 | * Check if filesystem with 'alias' registered 63 | */ 64 | bool IsFileSystemExists(const std::string& alias) const; 65 | 66 | /* 67 | * Get filesystem with 'alias' 68 | */ 69 | IFileSystemPtr GetFilesystem(const std::string& alias); 70 | 71 | /* 72 | * Iterate over all registered filesystems and find first ocurrences of file 73 | */ 74 | IFilePtr openFile(const CFileInfo& filePath, IFile::FileMode mode); 75 | 76 | /* 77 | * Close opened file if it was opened via OpenFirstFile(..) 78 | */ 79 | void closeFile(IFilePtr file); 80 | 81 | private: 82 | TFileSystemMap m_FileSystem; 83 | TSortedAliasList m_SortedAlias; 84 | std::unordered_map m_OpenedFiles; 85 | }; 86 | 87 | }; // namespace vfspp 88 | 89 | #endif /* CVIRTUALFILESYSTEM_H */ 90 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/include/CZipFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // CZipFile.h 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/23/16. 6 | // 7 | // 8 | 9 | #ifndef CZIPFILE_H 10 | #define CZIPFILE_H 11 | 12 | #include "IFile.h" 13 | 14 | namespace vfspp 15 | { 16 | CLASS_PTR(CZip); 17 | 18 | class CZip 19 | { 20 | public: 21 | CZip(const std::string& zipPath); 22 | ~CZip(); 23 | 24 | bool MapFile(const std::string& filename, std::vector& data); 25 | const std::string& FileName() const; 26 | 27 | bool isReadOnly() const; 28 | 29 | private: 30 | std::string m_FileName; 31 | void* m_ZipArchive; 32 | typedef std::map> TEntriesMap; 33 | static TEntriesMap s_Entries; 34 | }; 35 | 36 | 37 | class CZipFile final : public IFile 38 | { 39 | friend class CZipFileSystem; 40 | public: 41 | CZipFile(const CFileInfo& fileInfo, CZipPtr zipFile); 42 | ~CZipFile(); 43 | 44 | /* 45 | * Get file information 46 | */ 47 | virtual const CFileInfo& FileInfo() const override; 48 | 49 | /* 50 | * Returns file size 51 | */ 52 | virtual uint64_t Size() override; 53 | 54 | /* 55 | * Check is readonly filesystem 56 | */ 57 | virtual bool isReadOnly() const override; 58 | 59 | /* 60 | * Open existing file for reading, if not exists return null 61 | */ 62 | virtual void Open(int mode) override; 63 | 64 | /* 65 | * Close file 66 | */ 67 | virtual void Close() override; 68 | 69 | /* 70 | * Check is file ready for reading/writing 71 | */ 72 | virtual bool IsOpened() const override; 73 | 74 | /* 75 | * Seek on a file 76 | */ 77 | virtual uint64_t Seek(uint64_t offset, Origin origin) override; 78 | 79 | /* 80 | * Returns offset in file 81 | */ 82 | virtual uint64_t Tell() override; 83 | 84 | /* 85 | * Read data from file to buffer 86 | */ 87 | virtual uint64_t Read(uint8_t* buffer, uint64_t size) override; 88 | 89 | /* 90 | * Write buffer data to file 91 | */ 92 | virtual uint64_t Write(const uint8_t* buffer, uint64_t size) override; 93 | 94 | private: 95 | CZipPtr m_ZipArchive; 96 | std::vector m_Data; 97 | CFileInfo m_FileInfo; 98 | bool m_isReadOnly; 99 | bool m_IsOpened; 100 | bool m_HasChanges; 101 | uint64_t m_SeekPos; 102 | int m_Mode; 103 | }; 104 | 105 | } // namespace vfspp 106 | 107 | #endif /* CZIPFILE_H */ 108 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/include/CZipFileSystem.h: -------------------------------------------------------------------------------- 1 | // 2 | // CZipFileSystem.h 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/23/16. 6 | // 7 | // 8 | 9 | #ifndef CZIPFILESYSTEM_H 10 | #define CZIPFILESYSTEM_H 11 | 12 | #include "IFileSystem.h" 13 | 14 | struct SDir; 15 | 16 | namespace vfspp 17 | { 18 | CLASS_PTR(CZip); 19 | CLASS_PTR(CZipFile); 20 | 21 | class CZipFileSystem final : public IFileSystem 22 | { 23 | public: 24 | /* 25 | * Constructor, create with a path to .zip file and base path in zip. 26 | * Optional parameter createIfNotExist will allow to create empty .zip file 27 | * Setup password to keep files in zip archive with ecryption 28 | */ 29 | CZipFileSystem(const std::string& zipPath, const std::string& basePath); 30 | ~CZipFileSystem(); 31 | 32 | /* 33 | * Initialize filesystem 34 | */ 35 | virtual void Initialize() override; 36 | 37 | /* 38 | * Shutdown filesystem 39 | */ 40 | virtual void Shutdown() override; 41 | 42 | /* 43 | * Check if filesystem is initialized 44 | */ 45 | virtual bool IsInitialized() const override; 46 | 47 | /* 48 | * Get base path 49 | */ 50 | virtual const std::string& basePath() const override; 51 | 52 | /* 53 | * Retrieve file list according filter 54 | */ 55 | virtual const TFileList& FileList() const override; 56 | 57 | /* 58 | * Check is readonly filesystem 59 | */ 60 | virtual bool isReadOnly() const override; 61 | 62 | /* 63 | * Open existing file for reading, if not exists return null 64 | */ 65 | virtual IFilePtr openFile(const CFileInfo& filePath, int mode) override; 66 | 67 | /* 68 | * Close file 69 | */ 70 | virtual void closeFile(IFilePtr file) override; 71 | 72 | /* 73 | * Create file on writeable filesystem. Return true if file already exists 74 | */ 75 | virtual bool createFile(const CFileInfo& filePath) override; 76 | 77 | /* 78 | * Remove existing file on writable filesystem 79 | */ 80 | virtual bool removeFile(const CFileInfo& filePath) override; 81 | 82 | /* 83 | * Copy existing file on writable filesystem 84 | */ 85 | virtual bool copyFile(const CFileInfo& src, const CFileInfo& dest) override; 86 | 87 | /* 88 | * Rename existing file on writable filesystem 89 | */ 90 | virtual bool RenameFile(const CFileInfo& src, const CFileInfo& dest) override; 91 | 92 | /* 93 | * Check if file exists on filesystem 94 | */ 95 | virtual bool isFileExists(const CFileInfo& filePath) const override; 96 | 97 | /* 98 | * Check is file 99 | */ 100 | virtual bool IsFile(const CFileInfo& filePath) const override; 101 | 102 | /* 103 | * Check is dir 104 | */ 105 | virtual bool IsDir(const CFileInfo& dirPath) const override; 106 | 107 | private: 108 | IFilePtr FindFile(const CFileInfo& fileInfo) const; 109 | 110 | private: 111 | std::string m_ZipPath; 112 | CZipPtr m_Zip; 113 | std::string m_basePath; 114 | bool m_IsInitialized; 115 | TFileList m_FileList; 116 | 117 | std::mutex m_Mutex; 118 | static std::unordered_map s_OpenedZips; 119 | }; 120 | 121 | } // namespace vfspp 122 | 123 | #endif /* CZIPFILESYSTEM_H */ 124 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/include/IFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // IFile.h 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/22/16. 6 | // 7 | // 8 | 9 | #ifndef IFILE_H 10 | #define IFILE_H 11 | 12 | #include "CFileInfo.h" 13 | 14 | namespace vfspp 15 | { 16 | 17 | class IFile 18 | { 19 | public: 20 | /* 21 | * Seek modes 22 | */ 23 | enum Origin 24 | { 25 | Begin, 26 | End, 27 | Set 28 | }; 29 | 30 | /* 31 | * Open file mode 32 | */ 33 | enum FileMode 34 | { 35 | In = 0x01, 36 | Out = 0x02, 37 | ReadWrite = In | Out, 38 | Append = 0x04, 39 | Truncate = 0x08 40 | }; 41 | 42 | public: 43 | IFile() = default; 44 | ~IFile() = default; 45 | 46 | /* 47 | * Get file information 48 | */ 49 | virtual const CFileInfo& FileInfo() const = 0; 50 | 51 | /* 52 | * Returns file size 53 | */ 54 | virtual uint64_t Size() = 0; 55 | 56 | /* 57 | * Check is readonly filesystem 58 | */ 59 | virtual bool isReadOnly() const = 0; 60 | 61 | /* 62 | * Open file for reading/writing 63 | */ 64 | virtual void Open(int mode) = 0; 65 | 66 | /* 67 | * Close file 68 | */ 69 | virtual void Close() = 0; 70 | 71 | /* 72 | * Check is file ready for reading/writing 73 | */ 74 | virtual bool IsOpened() const = 0; 75 | 76 | /* 77 | * Seek on a file 78 | */ 79 | virtual uint64_t Seek(uint64_t offset, Origin origin) = 0; 80 | /* 81 | * Returns offset in file 82 | */ 83 | virtual uint64_t Tell() = 0; 84 | 85 | /* 86 | * Read data from file to buffer 87 | */ 88 | virtual uint64_t Read(uint8_t* buffer, uint64_t size) = 0; 89 | /* 90 | * Write buffer data to file 91 | */ 92 | virtual uint64_t Write(const uint8_t* buffer, uint64_t size) = 0; 93 | 94 | /* 95 | * Templated alternative to Read 96 | */ 97 | template 98 | bool Read(T& value) 99 | { 100 | return (Read(&value, sizeof(value)) == sizeof(value)); 101 | } 102 | 103 | /* 104 | * Templated alternative to Write 105 | */ 106 | template 107 | uint64_t Write(const T& value) 108 | { 109 | return (Write(&value, sizeof(value)) == sizeof(value)); 110 | } 111 | }; 112 | 113 | inline bool operator ==(const IFile& f1, const IFile& f2) 114 | { 115 | return f1.FileInfo() == f2.FileInfo(); 116 | } 117 | 118 | inline bool operator ==(std::shared_ptr f1, std::shared_ptr f2) 119 | { 120 | if (!f1 || !f2) 121 | { 122 | return false; 123 | } 124 | 125 | return f1->FileInfo() == f2->FileInfo(); 126 | } 127 | 128 | } // namespace vfspp 129 | 130 | #endif /* IFILE_H */ 131 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/include/IFileSystem.h: -------------------------------------------------------------------------------- 1 | // 2 | // IFileSystem.h 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/22/16. 6 | // 7 | // 8 | 9 | #ifndef IFILESYSTEM_H 10 | #define IFILESYSTEM_H 11 | 12 | #include "IFile.h" 13 | 14 | namespace vfspp 15 | { 16 | CLASS_PTR(IFile) 17 | 18 | class IFileSystem 19 | { 20 | public: 21 | typedef std::set TFileList; 22 | 23 | public: 24 | IFileSystem() = default; 25 | ~IFileSystem() = default; 26 | 27 | /* 28 | * Initialize filesystem, call this method as soon as possible 29 | */ 30 | virtual void Initialize() = 0; 31 | /* 32 | * Shutdown filesystem 33 | */ 34 | virtual void Shutdown() = 0; 35 | 36 | /* 37 | * Check if filesystem is initialized 38 | */ 39 | virtual bool IsInitialized() const = 0; 40 | 41 | /* 42 | * Get base path 43 | */ 44 | virtual const std::string& basePath() const = 0; 45 | 46 | /* 47 | * Retrieve file list according filter 48 | */ 49 | virtual const TFileList& FileList() const = 0; 50 | 51 | /* 52 | * Check is readonly filesystem 53 | */ 54 | virtual bool isReadOnly() const = 0; 55 | 56 | /* 57 | * Open existing file for reading, if not exists return null 58 | */ 59 | virtual IFilePtr openFile(const CFileInfo& filePath, int mode) = 0; 60 | 61 | /* 62 | * Close file 63 | */ 64 | virtual void closeFile(IFilePtr file) = 0; 65 | 66 | /* 67 | * Create file on writeable filesystem. Return true if file already exists 68 | */ 69 | virtual bool createFile(const CFileInfo& filePath) = 0; 70 | 71 | /* 72 | * Remove existing file on writable filesystem 73 | */ 74 | virtual bool removeFile(const CFileInfo& filePath) = 0; 75 | 76 | /* 77 | * Copy existing file on writable filesystem 78 | */ 79 | virtual bool copyFile(const CFileInfo& src, const CFileInfo& dest) = 0; 80 | 81 | /* 82 | * Rename existing file on writable filesystem 83 | */ 84 | virtual bool RenameFile(const CFileInfo& src, const CFileInfo& dest) = 0; 85 | 86 | /* 87 | * Check if file exists on filesystem 88 | */ 89 | virtual bool isFileExists(const CFileInfo& filePath) const = 0; 90 | 91 | /* 92 | * Check is file 93 | */ 94 | virtual bool IsFile(const CFileInfo& filePath) const = 0; 95 | 96 | /* 97 | * Check is dir 98 | */ 99 | virtual bool IsDir(const CFileInfo& dirPath) const = 0; 100 | }; 101 | 102 | 103 | 104 | }; // namespace vfspp 105 | 106 | #endif /* IFILESYSTEM_H */ 107 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/include/VFS.h: -------------------------------------------------------------------------------- 1 | // 2 | // Global.h 3 | // OpenJam 4 | // 5 | // Created by Yevgeniy Logachev 6 | // Copyright (c) 2014 Yevgeniy Logachev. All rights reserved. 7 | // 8 | #ifndef VFSPP_GLOBAL_H 9 | #define VFSPP_GLOBAL_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | namespace vfspp 28 | { 29 | 30 | #define CLASS_PTR(_class) typedef std::shared_ptr _class##Ptr;\ 31 | typedef std::weak_ptr _class##Weak; 32 | 33 | #if VFS_LOGS_ENABLED 34 | # define VFS_LOG(...) printf(__VA_ARGS__) 35 | #else 36 | # define VFS_LOG(...) 37 | #endif 38 | 39 | }; // namespace vfspp 40 | 41 | #endif // VFSPP_GLOBAL_H 42 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/src/CFileInfo.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CFileInfo.cpp 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/23/16. 6 | // 7 | // 8 | 9 | #include "CFileInfo.h" 10 | #include "CStringUtilsVFS.h" 11 | 12 | using namespace vfspp; 13 | 14 | // ***************************************************************************** 15 | // Constants 16 | // ***************************************************************************** 17 | 18 | // ***************************************************************************** 19 | // Public Methods 20 | // ***************************************************************************** 21 | 22 | CFileInfo::CFileInfo() 23 | { 24 | 25 | } 26 | 27 | CFileInfo::~CFileInfo() 28 | { 29 | 30 | } 31 | 32 | CFileInfo::CFileInfo(const std::string& basePath, const std::string& fileName, bool isDir) 33 | { 34 | Initialize(basePath, fileName, isDir); 35 | } 36 | 37 | CFileInfo::CFileInfo(const std::string& filePath) 38 | { 39 | std::size_t found = filePath.rfind("/"); 40 | if (found != std::string::npos) 41 | { 42 | const std::string basePath = filePath.substr(0, found + 1); 43 | std::string fileName; 44 | if (found != filePath.length()) 45 | { 46 | fileName = filePath.substr(found + 1, filePath.length() - found - 1); 47 | } 48 | 49 | Initialize(basePath, fileName, false); 50 | } 51 | } 52 | 53 | void CFileInfo::Initialize(const std::string& basePath, const std::string& fileName, bool isDir) 54 | { 55 | m_basePath = basePath; 56 | m_Name = fileName; 57 | m_IsDir = isDir; 58 | 59 | if (!CStringUtils::EndsWith(m_basePath, "/")) 60 | { 61 | m_basePath += "/"; 62 | } 63 | 64 | if (isDir && !CStringUtils::EndsWith(m_Name, "/")) 65 | { 66 | m_Name += "/"; 67 | } 68 | 69 | if (CStringUtils::StartsWith(m_Name, "/")) 70 | { 71 | m_Name = m_Name.substr(1, m_Name.length() - 1); 72 | } 73 | 74 | m_absolutePath = m_basePath + m_Name; 75 | 76 | size_t dotsNum = std::count(m_Name.begin(), m_Name.end(), '.'); 77 | bool isDotOrDotDot = (dotsNum == m_Name.length() && isDir); 78 | 79 | if (!isDotOrDotDot) 80 | { 81 | std::size_t found = m_Name.rfind("."); 82 | if (found != std::string::npos) 83 | { 84 | m_BaseName = m_Name.substr(0, found); 85 | if (found < m_Name.length()) 86 | { 87 | m_Extension = m_Name.substr(found, m_Name.length() - found); 88 | } 89 | } 90 | } 91 | } 92 | 93 | const std::string& CFileInfo::Name() const 94 | { 95 | return m_Name; 96 | } 97 | 98 | const std::string& CFileInfo::BaseName() const 99 | { 100 | return m_BaseName; 101 | } 102 | 103 | const std::string& CFileInfo::Extension() const 104 | { 105 | return m_Extension; 106 | } 107 | 108 | const std::string& CFileInfo::absolutePath() const 109 | { 110 | return m_absolutePath; 111 | } 112 | 113 | const std::string& CFileInfo::basePath() const 114 | { 115 | return m_basePath; 116 | } 117 | 118 | bool CFileInfo::IsDir() const 119 | { 120 | return m_IsDir; 121 | } 122 | 123 | bool CFileInfo::IsValid() const 124 | { 125 | return !m_absolutePath.empty(); 126 | } 127 | 128 | // ***************************************************************************** 129 | // Protected Methods 130 | // ***************************************************************************** 131 | 132 | // ***************************************************************************** 133 | // Private Methods 134 | // ***************************************************************************** 135 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/src/CMemoryFile.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CMemoryFile.cpp 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/23/16. 6 | // 7 | // 8 | 9 | #include "CMemoryFile.h" 10 | #include 11 | 12 | using namespace vfspp; 13 | 14 | // ***************************************************************************** 15 | // Constants 16 | // ***************************************************************************** 17 | 18 | // ***************************************************************************** 19 | // Public Methods 20 | // ***************************************************************************** 21 | 22 | CMemoryFile::CMemoryFile(const CFileInfo& fileInfo) 23 | : m_FileInfo(fileInfo) 24 | , m_isReadOnly(true) 25 | , m_IsOpened(false) 26 | , m_SeekPos(0) 27 | , m_Mode(0) 28 | { 29 | 30 | } 31 | 32 | CMemoryFile::~CMemoryFile() 33 | { 34 | Close(); 35 | } 36 | 37 | const CFileInfo& CMemoryFile::FileInfo() const 38 | { 39 | return m_FileInfo; 40 | } 41 | 42 | uint64_t CMemoryFile::Size() 43 | { 44 | if (IsOpened()) 45 | { 46 | return m_Data.size(); 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | bool CMemoryFile::isReadOnly() const 53 | { 54 | return m_isReadOnly; 55 | } 56 | 57 | void CMemoryFile::Open(int mode) 58 | { 59 | if (IsOpened() && m_Mode == mode) 60 | { 61 | Seek(0, IFile::Begin); 62 | return; 63 | } 64 | 65 | m_Mode = mode; 66 | m_SeekPos = 0; 67 | m_isReadOnly = true; 68 | 69 | if (mode & (int)IFile::Out) 70 | { 71 | m_isReadOnly = false; 72 | } 73 | if (mode & (int)IFile::Append) 74 | { 75 | m_isReadOnly = false; 76 | m_SeekPos = Size() > 0 ? Size() - 1 : 0; 77 | } 78 | if (mode & (int)IFile::Truncate) 79 | { 80 | m_Data.clear(); 81 | } 82 | 83 | m_IsOpened = true; 84 | } 85 | 86 | void CMemoryFile::Close() 87 | { 88 | m_isReadOnly = true; 89 | m_IsOpened = false; 90 | m_SeekPos = 0; 91 | } 92 | 93 | bool CMemoryFile::IsOpened() const 94 | { 95 | return m_IsOpened; 96 | } 97 | 98 | uint64_t CMemoryFile::Seek(uint64_t offset, Origin origin) 99 | { 100 | if (!IsOpened()) 101 | { 102 | return 0; 103 | } 104 | 105 | if (origin == IFile::Begin) 106 | { 107 | m_SeekPos = offset; 108 | } 109 | else if (origin == IFile::End) 110 | { 111 | m_SeekPos = Size() - offset; 112 | } 113 | else 114 | { 115 | m_SeekPos += offset; 116 | } 117 | m_SeekPos = std::min(m_SeekPos, Size() - 1); 118 | 119 | return Tell(); 120 | } 121 | 122 | uint64_t CMemoryFile::Tell() 123 | { 124 | return m_SeekPos; 125 | } 126 | 127 | uint64_t CMemoryFile::Read(uint8_t* buffer, uint64_t size) 128 | { 129 | if (!IsOpened()) 130 | { 131 | return 0; 132 | } 133 | 134 | uint64_t bufferSize = Size() - Tell(); 135 | uint64_t maxSize = std::min(size, bufferSize); 136 | if (maxSize > 0) 137 | { 138 | memcpy(buffer, m_Data.data(), (size_t)maxSize); 139 | } 140 | else 141 | { 142 | return 0; 143 | } 144 | 145 | return maxSize; 146 | } 147 | 148 | uint64_t CMemoryFile::Write(const uint8_t* buffer, uint64_t size) 149 | { 150 | if (!IsOpened() || isReadOnly()) 151 | { 152 | return 0; 153 | } 154 | 155 | uint64_t bufferSize = Size() - Tell(); 156 | if (size > bufferSize) 157 | { 158 | m_Data.resize((size_t)(m_Data.size() + (size - bufferSize))); 159 | } 160 | memcpy(m_Data.data() + Tell(), buffer, (size_t)size); 161 | 162 | return size; 163 | } 164 | 165 | // ***************************************************************************** 166 | // Protected Methods 167 | // ***************************************************************************** 168 | 169 | // ***************************************************************************** 170 | // Private Methods 171 | // ***************************************************************************** 172 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/src/CNativeFile.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CNativeFile.cpp 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/23/16. 6 | // 7 | // 8 | 9 | #include "CNativeFile.h" 10 | 11 | using namespace vfspp; 12 | 13 | // ***************************************************************************** 14 | // Constants 15 | // ***************************************************************************** 16 | 17 | // ***************************************************************************** 18 | // Public Methods 19 | // ***************************************************************************** 20 | 21 | CNativeFile::CNativeFile(const CFileInfo& fileInfo) 22 | : m_FileInfo(fileInfo) 23 | , m_isReadOnly(true) 24 | , m_Mode(0) 25 | { 26 | } 27 | 28 | CNativeFile::~CNativeFile() 29 | { 30 | Close(); 31 | } 32 | 33 | const CFileInfo& CNativeFile::FileInfo() const 34 | { 35 | return m_FileInfo; 36 | } 37 | 38 | uint64_t CNativeFile::Size() 39 | { 40 | if (IsOpened()) 41 | { 42 | uint64_t curPos = Tell(); 43 | Seek(0, End); 44 | uint64_t size = Tell(); 45 | Seek(curPos, Begin); 46 | 47 | return size; 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | bool CNativeFile::isReadOnly() const 54 | { 55 | return m_isReadOnly; 56 | } 57 | 58 | void CNativeFile::Open(int mode) 59 | { 60 | if (IsOpened() && m_Mode == mode) 61 | { 62 | Seek(0, IFile::Begin); 63 | return; 64 | } 65 | 66 | m_Mode = mode; 67 | m_isReadOnly = true; 68 | 69 | std::ios_base::openmode open_mode = (std::ios_base::openmode)0x00; 70 | if (mode & IFile::In) 71 | { 72 | open_mode |= std::fstream::in; 73 | } 74 | if (mode & IFile::Out) 75 | { 76 | m_isReadOnly = false; 77 | open_mode |= std::fstream::out; 78 | } 79 | if (mode & IFile::Append) 80 | { 81 | m_isReadOnly = false; 82 | open_mode |= std::fstream::app; 83 | } 84 | if (mode & IFile::Truncate) 85 | { 86 | open_mode |= std::fstream::trunc; 87 | } 88 | 89 | m_Stream.open(FileInfo().absolutePath().c_str(), open_mode); 90 | } 91 | 92 | void CNativeFile::Close() 93 | { 94 | m_Stream.close(); 95 | } 96 | 97 | bool CNativeFile::IsOpened() const 98 | { 99 | return m_Stream.is_open(); 100 | } 101 | 102 | uint64_t CNativeFile::Seek(uint64_t offset, Origin origin) 103 | { 104 | if (!IsOpened()) 105 | { 106 | return 0; 107 | } 108 | 109 | std::ios_base::seekdir way; 110 | if (origin == Begin) 111 | { 112 | way = std::ios_base::beg; 113 | } 114 | else if (origin == End) 115 | { 116 | way = std::ios_base::end; 117 | } 118 | else 119 | { 120 | way = std::ios_base::cur; 121 | } 122 | 123 | m_Stream.seekg(offset, way); 124 | m_Stream.seekp(offset, way); 125 | 126 | return Tell(); 127 | } 128 | 129 | uint64_t CNativeFile::Tell() 130 | { 131 | return static_cast(m_Stream.tellg()); 132 | } 133 | 134 | uint64_t CNativeFile::Read(uint8_t* buffer, uint64_t size) 135 | { 136 | if (!IsOpened()) 137 | { 138 | return 0; 139 | } 140 | 141 | m_Stream.read (reinterpret_cast(buffer), (std::streamsize)size); 142 | if (m_Stream) 143 | { 144 | return size; 145 | } 146 | 147 | return static_cast(m_Stream.gcount()); 148 | } 149 | 150 | uint64_t CNativeFile::Write(const uint8_t* buffer, uint64_t size) 151 | { 152 | if (!IsOpened() || isReadOnly()) 153 | { 154 | return 0; 155 | } 156 | 157 | m_Stream.write (reinterpret_cast(buffer), (std::streamsize)size); 158 | if (m_Stream) 159 | { 160 | return size; 161 | } 162 | 163 | return static_cast(m_Stream.gcount()); 164 | } 165 | 166 | // ***************************************************************************** 167 | // Protected Methods 168 | // ***************************************************************************** 169 | 170 | // ***************************************************************************** 171 | // Private Methods 172 | // ***************************************************************************** 173 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/src/CStringUtilsVFS.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CStringUtils.cpp 3 | // OpenJam 4 | // 5 | // Created by Yevgeniy Logachev on 11/19/14. 6 | // Copyright (c) 2014 yev. All rights reserved. 7 | // 8 | 9 | #include "CStringUtilsVFS.h" 10 | 11 | using namespace vfspp; 12 | 13 | void CStringUtils::Split(std::vector& tokens, const std::string& text, char delimeter) 14 | { 15 | size_t start = 0; 16 | size_t end = 0; 17 | while ((end = text.find(delimeter, start)) != std::string::npos) 18 | { 19 | tokens.push_back(text.substr(start, end - start)); 20 | start = end + 1; 21 | } 22 | tokens.push_back(text.substr(start)); 23 | } 24 | 25 | std::string CStringUtils::Replace(std::string string, const std::string& from, const std::string& to) 26 | { 27 | size_t pos = 0; 28 | while ((pos = string.find(from, pos)) != std::string::npos) 29 | { 30 | string.replace(pos, from.length(), to); 31 | pos += to.length(); 32 | } 33 | return string; 34 | } 35 | 36 | bool CStringUtils::EndsWith(std::string const& fullString, std::string const& ending) 37 | { 38 | if (fullString.length() >= ending.length()) 39 | { 40 | return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); 41 | } 42 | 43 | return false; 44 | } 45 | 46 | bool CStringUtils::StartsWith(std::string const& fullString, std::string const& starting) 47 | { 48 | if (fullString.length() >= starting.length()) 49 | { 50 | return (0 == fullString.compare(0, starting.length(), starting)); 51 | } 52 | 53 | return false; 54 | } 55 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/src/CStringUtilsVFS.h: -------------------------------------------------------------------------------- 1 | // 2 | // CStringUtils.h 3 | // OpenJam 4 | // 5 | // Created by Yevgeniy Logachev on 11/19/14. 6 | // Copyright (c) 2014 yev. All rights reserved. 7 | // 8 | 9 | #ifndef CSTRINGUTILS_H 10 | #define CSTRINGUTILS_H 11 | 12 | #include "VFS.h" 13 | 14 | namespace vfspp 15 | { 16 | 17 | class CStringUtils 18 | { 19 | public: 20 | static void Split(std::vector& tokens, const std::string& text, char delimeter); 21 | static std::string Replace(std::string string, const std::string& search, const std::string& replace); 22 | 23 | static bool EndsWith(const std::string& fullString, const std::string& ending); 24 | static bool StartsWith(const std::string& fullString, const std::string& starting); 25 | }; 26 | 27 | }; // namespace vfspp 28 | 29 | #endif /* defined(CSTRINGUTILS_H) */ 30 | -------------------------------------------------------------------------------- /samples/MeshViewer/src/vfspp/src/CVirtualFileSystem.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CVirtualFileSystem.cpp 3 | // vfspp 4 | // 5 | // Created by Yevgeniy Logachev on 6/23/16. 6 | // 7 | // 8 | 9 | #include "CVirtualFileSystem.h" 10 | #include "CStringUtilsVFS.h" 11 | 12 | using namespace vfspp; 13 | 14 | // ***************************************************************************** 15 | // Constants 16 | // ***************************************************************************** 17 | 18 | static CVirtualFileSystemPtr g_FS; 19 | 20 | // ***************************************************************************** 21 | // Public Methods 22 | // ***************************************************************************** 23 | 24 | struct SAliasComparator 25 | { 26 | bool operator()(const CVirtualFileSystem::SSortedAlias& a1, const CVirtualFileSystem::SSortedAlias& a2) const 27 | { 28 | return a1.alias.length() > a2.alias.length(); 29 | } 30 | }; 31 | 32 | void vfspp::vfs_initialize() 33 | { 34 | if (!g_FS) 35 | { 36 | g_FS.reset(new CVirtualFileSystem()); 37 | } 38 | } 39 | 40 | void vfspp::vfs_shutdown() 41 | { 42 | g_FS = nullptr; 43 | } 44 | 45 | CVirtualFileSystemPtr vfspp::vfs_get_global() 46 | { 47 | return g_FS; 48 | } 49 | 50 | CVirtualFileSystem::CVirtualFileSystem() 51 | { 52 | } 53 | 54 | CVirtualFileSystem::~CVirtualFileSystem() 55 | { 56 | std::for_each(m_FileSystem.begin(), m_FileSystem.end(), [](const TFileSystemMap::value_type& fs) 57 | { 58 | fs.second->Shutdown(); 59 | }); 60 | } 61 | 62 | void CVirtualFileSystem::AddFileSystem(const std::string& alias, IFileSystemPtr filesystem) 63 | { 64 | if (!filesystem) 65 | { 66 | return; 67 | } 68 | 69 | std::string a = alias; 70 | if (!CStringUtils::EndsWith(a, "/")) 71 | { 72 | a += "/"; 73 | } 74 | 75 | TFileSystemMap::const_iterator it = m_FileSystem.find(a); 76 | if (it == m_FileSystem.end()) 77 | { 78 | m_FileSystem[a] = filesystem; 79 | m_SortedAlias.push_back(SSortedAlias(a, filesystem)); 80 | m_SortedAlias.sort(SAliasComparator()); 81 | } 82 | } 83 | 84 | void CVirtualFileSystem::removeFileSystem(const std::string& alias) 85 | { 86 | std::string a = alias; 87 | if (!CStringUtils::EndsWith(a, "/")) 88 | { 89 | a += "/"; 90 | } 91 | 92 | TFileSystemMap::const_iterator it = m_FileSystem.find(a); 93 | if (it == m_FileSystem.end()) 94 | { 95 | m_FileSystem.erase(it); 96 | // TODO: remove from alias list 97 | } 98 | } 99 | 100 | bool CVirtualFileSystem::IsFileSystemExists(const std::string& alias) const 101 | { 102 | return (m_FileSystem.find(alias) != m_FileSystem.end()); 103 | } 104 | 105 | IFilePtr CVirtualFileSystem::openFile(const CFileInfo& filePath, IFile::FileMode mode) 106 | { 107 | IFilePtr file = nullptr; 108 | std::all_of(m_SortedAlias.begin(), m_SortedAlias.end(), [&](const TSortedAliasList::value_type& fs) 109 | { 110 | const std::string& alias = fs.alias; 111 | IFileSystemPtr filesystem = fs.filesystem; 112 | if (CStringUtils::StartsWith(filePath.basePath(), alias) && filePath.absolutePath().length() != alias.length()) 113 | { 114 | file = filesystem->openFile(filePath, mode); 115 | } 116 | 117 | if (file) 118 | { 119 | uintptr_t addr = reinterpret_cast(static_cast(file.get())); 120 | m_OpenedFiles[addr] = filesystem; 121 | 122 | return false; 123 | } 124 | 125 | return true; 126 | }); 127 | 128 | return file; 129 | } 130 | 131 | void CVirtualFileSystem::closeFile(IFilePtr file) 132 | { 133 | uintptr_t addr = reinterpret_cast(static_cast(file.get())); 134 | 135 | std::unordered_map::const_iterator it = m_OpenedFiles.find(addr); 136 | if (it != m_OpenedFiles.end()) 137 | { 138 | it->second->closeFile(file); 139 | m_OpenedFiles.erase(it); 140 | } 141 | } 142 | 143 | // ***************************************************************************** 144 | // Protected Methods 145 | // ***************************************************************************** 146 | 147 | // ***************************************************************************** 148 | // Private Methods 149 | // ***************************************************************************** 150 | -------------------------------------------------------------------------------- /samples/MeshViewer/vc2015/MeloViewer.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 16 3 | VisualStudioVersion = 16.0.29025.244 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MeshViewer", "MeshViewer.vcxproj", "{03E76676-40EA-476D-91CB-64372ED0A4FB}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|x64 = Debug|x64 10 | Release|x64 = Release|x64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {03E76676-40EA-476D-91CB-64372ED0A4FB}.Debug|x64.ActiveCfg = Debug|x64 14 | {03E76676-40EA-476D-91CB-64372ED0A4FB}.Debug|x64.Build.0 = Debug|x64 15 | {03E76676-40EA-476D-91CB-64372ED0A4FB}.Release|x64.ActiveCfg = Release|x64 16 | {03E76676-40EA-476D-91CB-64372ED0A4FB}.Release|x64.Build.0 = Release|x64 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | GlobalSection(ExtensibilityGlobals) = postSolution 22 | SolutionGuid = {6C65C4D1-F60C-4B38-BA23-866F34558FF3} 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /samples/MeshViewer/vc2015/Resources.rc: -------------------------------------------------------------------------------- 1 | #include "../include/Resources.h" 2 | 3 | 1 ICON "..\\resources\\cinder_app_icon.ico" 4 | -------------------------------------------------------------------------------- /samples/MeshViewer/xcode/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | CinderApp.icns 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Copyright © 2015 __MyCompanyName__. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /samples/MeshViewer/xcode/MeloViewer.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /samples/MeshViewer/xcode/MeloViewer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples/MeshViewer/xcode/MeloViewer.xcodeproj/project.xcworkspace/xcuserdata/vinjn.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildLocationStyle 6 | UseTargetSettings 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples/MeshViewer/xcode/MeloViewer.xcodeproj/xcuserdata/vinjn.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 22 | 23 | 24 | 26 | 39 | 40 | 41 | 43 | 56 | 57 | 58 | 60 | 73 | 74 | 75 | 77 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /samples/MeshViewer/xcode/MeloViewer.xcodeproj/xcuserdata/vinjn.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MeloViewer.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | MeshViewer.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/MeshViewer/xcode/MeloViewer_Prefix.pch: -------------------------------------------------------------------------------- 1 | #if defined( __cplusplus ) 2 | #include "cinder/Cinder.h" 3 | 4 | #include "cinder/app/App.h" 5 | 6 | #include "cinder/gl/gl.h" 7 | 8 | #include "cinder/CinderMath.h" 9 | #include "cinder/Matrix.h" 10 | #include "cinder/Vector.h" 11 | #include "cinder/Quaternion.h" 12 | #endif 13 | -------------------------------------------------------------------------------- /samples/MeshViewer/xcode_ios/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "8.0", 8 | "subtype" : "736h", 9 | "filename" : "Default-736h@3x~iphone.png", 10 | "scale" : "3x" 11 | }, 12 | { 13 | "orientation" : "landscape", 14 | "idiom" : "iphone", 15 | "extent" : "full-screen", 16 | "minimum-system-version" : "8.0", 17 | "subtype" : "736h", 18 | "scale" : "3x" 19 | }, 20 | { 21 | "extent" : "full-screen", 22 | "idiom" : "iphone", 23 | "subtype" : "667h", 24 | "filename" : "Default-667@2x.png", 25 | "minimum-system-version" : "8.0", 26 | "orientation" : "portrait", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "orientation" : "portrait", 31 | "idiom" : "iphone", 32 | "extent" : "full-screen", 33 | "minimum-system-version" : "7.0", 34 | "scale" : "2x" 35 | }, 36 | { 37 | "extent" : "full-screen", 38 | "idiom" : "iphone", 39 | "subtype" : "retina4", 40 | "filename" : "Default-568h@2x.png", 41 | "minimum-system-version" : "7.0", 42 | "orientation" : "portrait", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "orientation" : "portrait", 47 | "idiom" : "ipad", 48 | "extent" : "full-screen", 49 | "minimum-system-version" : "7.0", 50 | "scale" : "1x" 51 | }, 52 | { 53 | "orientation" : "landscape", 54 | "idiom" : "ipad", 55 | "extent" : "full-screen", 56 | "minimum-system-version" : "7.0", 57 | "scale" : "1x" 58 | }, 59 | { 60 | "orientation" : "portrait", 61 | "idiom" : "ipad", 62 | "extent" : "full-screen", 63 | "minimum-system-version" : "7.0", 64 | "scale" : "2x" 65 | }, 66 | { 67 | "orientation" : "landscape", 68 | "idiom" : "ipad", 69 | "extent" : "full-screen", 70 | "minimum-system-version" : "7.0", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "orientation" : "portrait", 75 | "idiom" : "iphone", 76 | "extent" : "full-screen", 77 | "scale" : "1x" 78 | }, 79 | { 80 | "orientation" : "portrait", 81 | "idiom" : "iphone", 82 | "extent" : "full-screen", 83 | "scale" : "2x" 84 | }, 85 | { 86 | "orientation" : "portrait", 87 | "idiom" : "iphone", 88 | "extent" : "full-screen", 89 | "filename" : "Default-568h@2x.png", 90 | "subtype" : "retina4", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "orientation" : "portrait", 95 | "idiom" : "ipad", 96 | "extent" : "to-status-bar", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "orientation" : "portrait", 101 | "idiom" : "ipad", 102 | "extent" : "to-status-bar", 103 | "scale" : "2x" 104 | } 105 | ], 106 | "info" : { 107 | "version" : 1, 108 | "author" : "xcode" 109 | } 110 | } -------------------------------------------------------------------------------- /samples/MeshViewer/xcode_ios/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/xcode_ios/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png -------------------------------------------------------------------------------- /samples/MeshViewer/xcode_ios/Images.xcassets/LaunchImage.launchimage/Default-667@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/xcode_ios/Images.xcassets/LaunchImage.launchimage/Default-667@2x.png -------------------------------------------------------------------------------- /samples/MeshViewer/xcode_ios/Images.xcassets/LaunchImage.launchimage/Default-736h@3x~iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/MeshViewer/xcode_ios/Images.xcassets/LaunchImage.launchimage/Default-736h@3x~iphone.png -------------------------------------------------------------------------------- /samples/MeshViewer/xcode_ios/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIcons 14 | 15 | CFBundlePrimaryIcon 16 | 17 | CFBundleIconFiles 18 | 19 | 20 | CinderApp_ios.png 21 | 22 | UIPrerenderedIcon 23 | 24 | 25 | 26 | CFBundleIdentifier 27 | $(PRODUCT_BUNDLE_IDENTIFIER) 28 | CFBundleInfoDictionaryVersion 29 | 6.0 30 | CFBundleName 31 | ${PRODUCT_NAME} 32 | CFBundlePackageType 33 | APPL 34 | CFBundleShortVersionString 35 | 1.0 36 | CFBundleSignature 37 | ???? 38 | CFBundleVersion 39 | 1 40 | LSRequiresIPhoneOS 41 | 42 | NSMainNibFile 43 | 44 | NSMainNibFile~ipad 45 | 46 | UILaunchStoryboardName 47 | LaunchScreen.xib 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | 52 | UISupportedInterfaceOrientations~ipad 53 | 54 | UIInterfaceOrientationPortrait 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /samples/MeshViewer/xcode_ios/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/MeshViewer/xcode_ios/MeshViewer_Prefix.pch: -------------------------------------------------------------------------------- 1 | #if defined( __cplusplus ) 2 | #include "cinder/Cinder.h" 3 | 4 | #include "cinder/app/App.h" 5 | 6 | #include "cinder/gl/gl.h" 7 | 8 | #include "cinder/CinderMath.h" 9 | #include "cinder/Matrix.h" 10 | #include "cinder/Vector.h" 11 | #include "cinder/Quaternion.h" 12 | #endif -------------------------------------------------------------------------------- /samples/SimpleSceneGraphApp/include/Resources.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cinder/CinderResources.h" 3 | 4 | //#define RES_MY_RES CINDER_RESOURCE( ../resources/, image_name.png, 128, IMAGE ) 5 | -------------------------------------------------------------------------------- /samples/SimpleSceneGraphApp/include/license.txt: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2010-2012, Paul Houx - All rights reserved. 3 | This code is intended for use with the Cinder C++ library: http://libcinder.org 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that 6 | the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and 9 | the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 11 | the following disclaimer in the documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 14 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 15 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 17 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 18 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 19 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20 | POSSIBILITY OF SUCH DAMAGE. 21 | -------------------------------------------------------------------------------- /samples/SimpleSceneGraphApp/vc2015/Resources.rc: -------------------------------------------------------------------------------- 1 | #include "Resources.h" 2 | 3 | ID ICON "cinder_app_icon.ico" 4 | 5 | //RES_MY_RES 6 | -------------------------------------------------------------------------------- /samples/SimpleSceneGraphApp/vc2015/SimpleSceneGraph.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 14 3 | VisualStudioVersion = 14.0.25420.1 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleSceneGraph", "SimpleSceneGraph.vcxproj", "{F26CECC0-AD66-407A-B679-246E95C84632}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Win32 = Debug|Win32 10 | Debug|x64 = Debug|x64 11 | Release|Win32 = Release|Win32 12 | Release|x64 = Release|x64 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {F26CECC0-AD66-407A-B679-246E95C84632}.Debug|Win32.ActiveCfg = Debug|Win32 16 | {F26CECC0-AD66-407A-B679-246E95C84632}.Debug|Win32.Build.0 = Debug|Win32 17 | {F26CECC0-AD66-407A-B679-246E95C84632}.Debug|x64.ActiveCfg = Debug|Win32 18 | {F26CECC0-AD66-407A-B679-246E95C84632}.Release|Win32.ActiveCfg = Release|Win32 19 | {F26CECC0-AD66-407A-B679-246E95C84632}.Release|Win32.Build.0 = Release|Win32 20 | {F26CECC0-AD66-407A-B679-246E95C84632}.Release|x64.ActiveCfg = Release|Win32 21 | EndGlobalSection 22 | GlobalSection(SolutionProperties) = preSolution 23 | HideSolutionNode = FALSE 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /samples/SimpleSceneGraphApp/vc2015/SimpleSceneGraph.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | {ff4a8577-86b3-4e52-8cb6-0401be32518d} 18 | 19 | 20 | {a9545b5e-e1ae-4077-a981-52ad92b38b0b} 21 | 22 | 23 | 24 | 25 | Blocks\nodes 26 | 27 | 28 | Blocks\nodes 29 | 30 | 31 | Blocks\nodes 32 | 33 | 34 | Blocks\nodes 35 | 36 | 37 | Source Files 38 | 39 | 40 | 41 | 42 | Header Files 43 | 44 | 45 | Blocks\nodes 46 | 47 | 48 | Blocks\nodes 49 | 50 | 51 | Blocks\nodes 52 | 53 | 54 | Blocks\nodes 55 | 56 | 57 | Blocks\nodes 58 | 59 | 60 | 61 | 62 | Resource Files 63 | 64 | 65 | -------------------------------------------------------------------------------- /samples/SimpleSceneGraphApp/vc2015/cinder_app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/SimpleSceneGraphApp/vc2015/cinder_app_icon.ico -------------------------------------------------------------------------------- /samples/XRoom/.gitignore: -------------------------------------------------------------------------------- 1 | assets 2 | -------------------------------------------------------------------------------- /samples/XRoom/build-vs2019.bat: -------------------------------------------------------------------------------- 1 | cd %~dp0\vs2019 2 | set proj=MeloViewer.sln 3 | set msbuild="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\amd64\MSBuild.exe" 4 | REM msbuild %proj% /p:Configuration=Debug /p:Platform=x64 /v:minimal /m 5 | %msbuild% %proj% /p:Configuration=Release /p:Platform=x64 /v:minimal /m 6 | REM msbuild %proj% /p:Configuration=Debug_Shared /p:Platform=x64 /v:minimal /m 7 | REM msbuild %proj% /p:Configuration=Release_Shared /p:Platform=x64 /v:minimal /m 8 | cd .. -------------------------------------------------------------------------------- /samples/XRoom/include/Resources.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cinder/CinderResources.h" 3 | 4 | //#define RES_MY_RES CINDER_RESOURCE( ../resources/, image_name.png, 128, IMAGE ) 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /samples/XRoom/include/item.def: -------------------------------------------------------------------------------- 1 | GROUP_DEF(App) 2 | ITEM_DEF(int, APP_WIDTH, 1024) 3 | ITEM_DEF(int, APP_HEIGHT, 768) 4 | ITEM_DEF(bool, GUI_VISIBLE, true) 5 | ITEM_DEF(bool, ENV_VISIBLE, true) 6 | ITEM_DEF(bool, XYZ_VISIBLE, false) 7 | ITEM_DEF(bool, WIRE_FRAME, false) 8 | ITEM_DEF(bool, FLIP_V, true) 9 | ITEM_DEF(bool, CONSOLE_ENABLED, false) 10 | 11 | GROUP_DEF(Environment) 12 | ITEM_DEF(string, IRRADIANCE_TEX, "CathedralIrradiance.dds") 13 | ITEM_DEF(string, RADIANCE_TEX, "CathedralRadiance.dds") 14 | ITEM_DEF(string, BRDF_LUT_TEX, "brdfLUT.png") 15 | ITEM_DEF(bool, IS_FXAA, false) 16 | 17 | GROUP_DEF(Camera) 18 | ITEM_DEF(float, CAM_POS_X, 10) 19 | ITEM_DEF(float, CAM_POS_Y, 10) 20 | ITEM_DEF(float, CAM_POS_Z, 10) 21 | ITEM_DEF(float, CAM_DIR_X, 0) 22 | ITEM_DEF(float, CAM_DIR_Y, 0) 23 | ITEM_DEF(float, CAM_DIR_Z, 0) 24 | ITEM_DEF(float, CAM_Z_NEAR, 0.1) 25 | ITEM_DEF(float, CAM_Z_FAR, 1000) 26 | 27 | GROUP_DEF(Model) 28 | //ITEM_DEF(string, MESH_NAME, "Cube/Cube.gltf") 29 | ITEM_DEF(string, TEX0_NAME, "checkerboard") 30 | ITEM_DEF(string, GC_RAW_FOLDER, "e:/BaiduNetdiskDownload/SP21_GC_RAW FILES/SP21_GC_RAW FILES") 31 | ITEM_DEF(string, OBJ_3D_JSON, "obj/obj_3d.json") 32 | ITEM_DEF(string, OBJ_BODY_JSON, "obj/obj_body.json") 33 | //ITEM_DEF(string, TEX1_NAME, "checkerboard") 34 | //ITEM_DEF(string, TEX2_NAME, "checkerboard") 35 | //ITEM_DEF(string, TEX3_NAME, "checkerboard") 36 | //ITEM_DEF(string, VS_NAME, "texture") 37 | //ITEM_DEF(string, FS_NAME, "texture") 38 | //ITEM_DEF_MINMAX(float, MESH_SCALE, 1, 0, 10) 39 | //ITEM_DEF(int, MESH_FILE_ID, 0) 40 | ITEM_DEF_MINMAX(float, POINT_SIZE, 1, 0, 10) 41 | 42 | -------------------------------------------------------------------------------- /samples/XRoom/resources/cinder_app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jing-interactive/melo/67fa14d19fea157124edddead2ca3fc54d370691/samples/XRoom/resources/cinder_app_icon.ico -------------------------------------------------------------------------------- /samples/XRoom/vs2019/Resources.rc: -------------------------------------------------------------------------------- 1 | #include "../include/Resources.h" 2 | 3 | 1 ICON "..\\resources\\cinder_app_icon.ico" 4 | -------------------------------------------------------------------------------- /samples/XRoom/vs2019/XRoom.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 16 3 | VisualStudioVersion = 16.0.29025.244 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XRoom", "XRoom.vcxproj", "{03E76676-40EA-476D-91CB-64372ED0A4FB}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|x64 = Debug|x64 10 | Release|x64 = Release|x64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {03E76676-40EA-476D-91CB-64372ED0A4FB}.Debug|x64.ActiveCfg = Debug|x64 14 | {03E76676-40EA-476D-91CB-64372ED0A4FB}.Debug|x64.Build.0 = Debug|x64 15 | {03E76676-40EA-476D-91CB-64372ED0A4FB}.Release|x64.ActiveCfg = Release|x64 16 | {03E76676-40EA-476D-91CB-64372ED0A4FB}.Release|x64.Build.0 = Release|x64 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | GlobalSection(ExtensibilityGlobals) = postSolution 22 | SolutionGuid = {6C65C4D1-F60C-4B38-BA23-866F34558FF3} 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /src/NodeExt.cpp: -------------------------------------------------------------------------------- 1 | #include "NodeExt.h" 2 | #include "cinder/GeomIo.h" 3 | #include "cinder/gl/gl.h" 4 | #include "cinder/TriMesh.h" 5 | 6 | using namespace std; 7 | using namespace melo; 8 | 9 | DirectionalLightNode::Ref DirectionalLightNode::create(float radius, Color color) 10 | { 11 | auto ref = std::make_shared(); 12 | ref->setName("DirectionalLightNode"); 13 | ref->radius = radius; 14 | ref->color = color; 15 | 16 | return ref; 17 | } 18 | 19 | void DirectionalLightNode::draw(DrawOrder order) 20 | { 21 | static auto shader = gl::getStockShader(gl::ShaderDef().lambert()); 22 | gl::ScopedGlslProg glsl(shader); 23 | gl::ScopedColor clr(color); 24 | gl::drawSphere({}, radius); 25 | } 26 | 27 | GridNode::Ref GridNode::create(float meters) 28 | { 29 | return std::make_shared(meters); 30 | } 31 | 32 | GridNode::GridNode(float meters) : mMeters(meters) 33 | { 34 | shader = gl::getStockShader(gl::ShaderDef().color()); 35 | 36 | #if 0 37 | vertBatch = gl::Batch::create(geom::WirePlane().size(vec2(meters)).subdivisions(ivec2(meters/3)), shader); 38 | #else 39 | vertBatch = gl::VertBatch::create(GL_LINES); 40 | vertBatch->begin(GL_LINES); 41 | for (int i = -meters; i <= meters; ++i) 42 | { 43 | vertBatch->color(Color(0.25f, 0.25f, 0.25f)); 44 | vertBatch->color(Color(0.25f, 0.25f, 0.25f)); 45 | vertBatch->color(Color(0.25f, 0.25f, 0.25f)); 46 | vertBatch->color(Color(0.25f, 0.25f, 0.25f)); 47 | 48 | vertBatch->vertex(float(i), 0.0f, -meters); 49 | vertBatch->vertex(float(i), 0.0f, +meters); 50 | vertBatch->vertex(-meters, 0.0f, float(i)); 51 | vertBatch->vertex(+meters, 0.0f, float(i)); 52 | } 53 | vertBatch->end(); 54 | #endif 55 | 56 | setName("GridNode"); 57 | } 58 | 59 | void GridNode::draw(DrawOrder order) 60 | { 61 | gl::ScopedDepthTest depthTest(false); 62 | gl::ScopedGlslProg glsl(shader); 63 | vertBatch->draw(); 64 | gl::drawCoordinateFrame(mMeters * 0.5f, mMeters * 0.05f, mMeters * 0.005f); 65 | } 66 | 67 | MeshNode::Ref MeshNode::create(TriMeshRef triMesh) 68 | { 69 | return std::make_shared(triMesh); 70 | } 71 | 72 | MeshNode::MeshNode(TriMeshRef triMesh) 73 | { 74 | rayCategory = 0xFF; 75 | auto aabb = triMesh->calcBoundingBox(); 76 | mBoundBoxMin = aabb.getMin(); 77 | mBoundBoxMax = aabb.getMax(); 78 | 79 | vboMesh = gl::VboMesh::create(*triMesh); 80 | shader = gl::getStockShader(gl::ShaderDef().lambert()); 81 | setName("MeshNode"); 82 | } 83 | 84 | MeshNode::Ref MeshNode::create(const geom::Source& source) 85 | { 86 | auto triMesh = TriMesh::create(source); 87 | auto ref = make_shared(triMesh); 88 | 89 | return ref; 90 | } 91 | 92 | void MeshNode::draw(DrawOrder order) 93 | { 94 | if (vboMesh) 95 | { 96 | gl::ScopedGlslProg glsl(shader); 97 | gl::draw(vboMesh); 98 | } 99 | } -------------------------------------------------------------------------------- /src/SceneIO.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/cigltf.h" 2 | #include "../include/melo.h" 3 | 4 | using namespace std; 5 | 6 | namespace melo 7 | { 8 | #if 1 9 | NodeRef loadScene(const std::string& filename) { return {}; } 10 | bool writeScene(NodeRef scene, const std::string& filename) { return true; } 11 | #else 12 | NodeRef loadScene(const std::string& filename) 13 | { 14 | NodeRef root; 15 | auto tree = ModelGLTF::create(filename); 16 | if (tree) 17 | { 18 | root = tree->currentScene->getChildren()[0]; 19 | root->rayCategory = 0; 20 | auto& children = root->getChildren(); 21 | for (int i = 0; i < children.size(); i++) 22 | { 23 | auto transform = children[i]->getTransform(); 24 | if (auto ptr = melo::create(children[i]->getName())) 25 | { 26 | children[i] = ptr; 27 | children[i]->setConstantTransform(transform); 28 | } 29 | } 30 | } 31 | 32 | return root; 33 | } 34 | 35 | static void addNode(NodeRef node, int& nodeidx, tinygltf::Model& gltfmodel, tinygltf::Scene& gltfscene) { 36 | tinygltf::Node gltfnode; 37 | gltfnode.name = node->getName(); 38 | auto ptr = glm::value_ptr(node->getTransform()); 39 | gltfnode.matrix = { ptr, ptr + 16 }; 40 | 41 | tinygltf::Value::Object attributes; 42 | attributes["visible"] = tinygltf::Value(node->isVisible()); 43 | gltfnode.extras = tinygltf::Value(attributes); 44 | gltfmodel.nodes.emplace_back(gltfnode); 45 | int idx = nodeidx; 46 | 47 | auto key = node->getName().find(".gltf"); 48 | if (key == string::npos) 49 | { 50 | for (auto& child : node->getChildren()) 51 | { 52 | addNode(child, nodeidx, gltfmodel, gltfscene); 53 | gltfmodel.nodes[idx].children.push_back(nodeidx); 54 | } 55 | } 56 | nodeidx++; 57 | }; 58 | 59 | bool writeScene(NodeRef scene, const std::string& filename) 60 | { 61 | tinygltf::Model gltfmodel; 62 | gltfmodel.asset.generator = "melo runtime"; 63 | gltfmodel.asset.version = "1.0"; 64 | gltfmodel.defaultScene = 0; 65 | tinygltf::Scene gltfscene; 66 | gltfscene.name = "A melo scene"; 67 | 68 | int nodeidx = 0; 69 | gltfscene.nodes.push_back(nodeidx); // "scene" only contains root node (aka #0) 70 | 71 | addNode(scene, nodeidx, gltfmodel, gltfscene); 72 | 73 | gltfmodel.scenes.emplace_back(gltfscene); 74 | 75 | //std::string name; 76 | //std::vector nodes; 77 | 78 | //ExtensionMap extensions; 79 | //Value extras; 80 | tinygltf::TinyGLTF factory; 81 | auto result = factory.WriteGltfSceneToFile(&gltfmodel, filename, 82 | false, false, true, false); 83 | 84 | return result; 85 | } 86 | #endif 87 | } -------------------------------------------------------------------------------- /src/SkyNode.cpp: -------------------------------------------------------------------------------- 1 | #include "SkyNode.h" 2 | #include "AssetManager.h" 3 | 4 | using namespace ci; 5 | 6 | namespace melo 7 | { 8 | SkyNode::Ref SkyNode::create(const std::string& skyTexturePath) 9 | { 10 | auto ref = std::make_shared(); 11 | ref->setName("SkyNode"); 12 | ref->mSkyTex = am::textureCubeMap(skyTexturePath); 13 | auto skyBoxShader = am::glslProg("SkyBox.vert", "SkyBox.frag"); 14 | if (!skyBoxShader) 15 | { 16 | return {}; 17 | } 18 | 19 | ref->skyBoxShader = skyBoxShader; 20 | 21 | ref->mSkyBoxBatch = gl::Batch::create(geom::Cube().size(vec3(1000)), ref->skyBoxShader); 22 | 23 | return ref; 24 | 25 | } 26 | 27 | void SkyNode::predraw(DrawOrder order) 28 | { 29 | skyBoxShader->uniform("uCubeMapTex", 0); 30 | skyBoxShader->uniform("uExposure", 2.0f); 31 | skyBoxShader->uniform("uGamma", 2.0f); 32 | } 33 | 34 | void SkyNode::draw(DrawOrder order) 35 | { 36 | if (!mSkyBoxBatch && !mSkyTex) return; 37 | 38 | //gl::ScopedDepthWrite depthWrite(false); 39 | gl::ScopedTextureBind scpTex(mSkyTex, 0); 40 | mSkyBoxBatch->draw(); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/postprocess/FXAA.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014, Paul Houx - All rights reserved. 3 | This code is intended for use with the Cinder C++ library: http://libcinder.org 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that 6 | the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this list of conditions and 9 | the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 11 | the following disclaimer in the documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 14 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 15 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 17 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 18 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 19 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 20 | POSSIBILITY OF SUCH DAMAGE. 21 | */ 22 | 23 | #include "cinder/app/App.h" 24 | #include "cinder/Log.h" 25 | 26 | #include "postprocess/FXAA.h" 27 | #include "AssetManager.h" 28 | 29 | using namespace ci; 30 | using namespace std; 31 | 32 | FXAA::FXAA() 33 | { 34 | auto glsl = am::glslProg( "postprocess/fxaa.vert", "postprocess/fxaa.frag" ); 35 | glsl->uniform( "uTexture", 0 ); 36 | 37 | mBatch = gl::Batch::create( geom::Rect( Rectf( 0, 0, 1, 1 ) ), glsl ); 38 | } 39 | 40 | void FXAA::apply( const gl::FboRef &destination, const gl::FboRef &source ) 41 | { 42 | gl::ScopedFramebuffer fbo( destination ); 43 | gl::ScopedViewport viewport( 0, 0, destination->getWidth(), destination->getHeight() ); 44 | gl::ScopedMatrices matrices; 45 | gl::setMatricesWindow( destination->getSize(), false ); 46 | 47 | // Make sure our source is linearly interpolated. 48 | GLenum minFilter = source->getFormat().getColorTextureFormat().getMinFilter(); 49 | GLenum magFilter = source->getFormat().getColorTextureFormat().getMagFilter(); 50 | source->getColorTexture()->setMinFilter( GL_LINEAR ); 51 | source->getColorTexture()->setMagFilter( GL_LINEAR ); 52 | 53 | // Perform FXAA anti-aliasing. 54 | gl::clear( ColorA( 0, 0, 0, 0 ) ); 55 | draw( source->getColorTexture(), destination->getBounds() ); 56 | 57 | // Restore texture parameters. 58 | source->getColorTexture()->setMinFilter( minFilter ); 59 | source->getColorTexture()->setMagFilter( magFilter ); 60 | } 61 | 62 | void FXAA::draw( const gl::TextureRef &source, const Area &bounds ) 63 | { 64 | if( ! mBatch ) 65 | return; 66 | 67 | const float w = (float)bounds.getWidth(); 68 | const float h = (float)bounds.getHeight(); 69 | 70 | mBatch->getGlslProg()->uniform( "uExtents", vec4( 1.0f / w, 1.0f / h, w, h ) ); 71 | 72 | gl::ScopedTextureBind tex0( source ); 73 | gl::ScopedModelMatrix modelScope; 74 | gl::scale( w, h, 1.0f ); 75 | 76 | mBatch->draw(); 77 | } --------------------------------------------------------------------------------