From 27a5cf0a4f603c228b74e44d2e15941cb12bb861 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 3 Nov 2023 03:01:06 +0000 Subject: [PATCH] Lightmap atlas shit --- .gitmodules | 6 + include/Orange/Graphics/LightmapAtlas.h | 14 + include/Orange/Graphics/Vertex.h | 14 +- meson.build | 405 +++++++++ src/Apps/Tools/{CubeTest.cpp => FrogTest.cpp} | 107 +-- src/Apps/Tools/Lightmapper.cpp | 855 ++++++++++++++++++ src/Apps/Tools/meson.build | 13 +- src/Orange/Graphics/LightmapAtlas.cpp | 197 ++++ src/Orange/Graphics/Mesh.cpp | 4 +- src/Orange/Render/Shaders/fs_HDRTest.frag | 6 + src/Orange/Render/Shaders/fs_Mesh.frag | 8 +- src/Orange/Render/Shaders/vs_Mesh.vert | 11 +- src/Orange/Render/Window.cpp | 2 +- src/Orange/meson.build | 1 + thirdparty/JoltPhysics | 1 + thirdparty/xatlas | 1 + 16 files changed, 1565 insertions(+), 80 deletions(-) create mode 100644 include/Orange/Graphics/LightmapAtlas.h rename src/Apps/Tools/{CubeTest.cpp => FrogTest.cpp} (93%) create mode 100644 src/Apps/Tools/Lightmapper.cpp create mode 100644 src/Orange/Graphics/LightmapAtlas.cpp create mode 160000 thirdparty/JoltPhysics create mode 160000 thirdparty/xatlas diff --git a/.gitmodules b/.gitmodules index e222a0b..59c70a2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,9 @@ [submodule "subprojects/libspng"] path = subprojects/libspng url = https://github.com/randy408/libspng +[submodule "thirdparty/JoltPhysics"] + path = thirdparty/JoltPhysics + url = https://github.com/jrouwe/JoltPhysics +[submodule "thirdparty/xatlas"] + path = thirdparty/xatlas + url = https://github.com/jpcy/xatlas diff --git a/include/Orange/Graphics/LightmapAtlas.h b/include/Orange/Graphics/LightmapAtlas.h new file mode 100644 index 0000000..0f519b2 --- /dev/null +++ b/include/Orange/Graphics/LightmapAtlas.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include + +namespace orange +{ + using LightmapAtlas = std::unique_ptr; + + Result CreateLightmapAtlasForMesh(MeshData& mesh); + + Vector GenerateDebugAtlasTexture(const LightmapAtlas& atlas); +} diff --git a/include/Orange/Graphics/Vertex.h b/include/Orange/Graphics/Vertex.h index a84e2ef..7df595a 100644 --- a/include/Orange/Graphics/Vertex.h +++ b/include/Orange/Graphics/Vertex.h @@ -20,22 +20,25 @@ namespace orange struct alignas(8) StaticVertex { vec3 pos; - vec2 uv; + vec2 texUV; + vec2 lightUV; vec3 normal; //vec3 tangent; static constexpr VkVertexInputAttributeDescription Attributes[] = { { .location = 0, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, pos)) }, - { .location = 1, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, uv)) }, - { .location = 2, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, normal)) }, + { .location = 1, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, texUV)) }, + { .location = 2, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, lightUV)) }, + { .location = 3, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, normal)) }, }; bool operator == (const StaticVertex& other) const { return pos == other.pos && - uv == other.uv && + texUV == other.texUV && + lightUV == other.lightUV && normal == other.normal;// && //tangent == other.tangent; } @@ -49,7 +52,8 @@ namespace orange { return pos == other.pos && - uv == other.uv && + texUV == other.texUV && + lightUV == other.lightUV && normal == other.normal && //tangent == other.tangent && boneIndices == other.boneIndices && diff --git a/meson.build b/meson.build index 2c9acc2..222d570 100644 --- a/meson.build +++ b/meson.build @@ -32,4 +32,409 @@ spng_proj = subproject('libspng', default_options: [ ]) spng_dep = spng_proj.get_variable('spng_dep') +xatlas_include = include_directories([ + 'thirdparty/xatlas/source/xatlas', +]) + +xatlas_src = files([ + 'thirdparty/xatlas/source/xatlas/xatlas.cpp', +]) + +joltphysics_include = include_directories([ + 'thirdparty/JoltPhysics', +]) + +joltphysics_src = files([ + 'thirdparty/JoltPhysics/Jolt/AABBTree/AABBTreeBuilder.cpp', + 'thirdparty/JoltPhysics/Jolt/AABBTree/AABBTreeBuilder.h', + 'thirdparty/JoltPhysics/Jolt/AABBTree/AABBTreeToBuffer.h', + 'thirdparty/JoltPhysics/Jolt/AABBTree/NodeCodec/NodeCodecQuadTreeHalfFloat.h', + 'thirdparty/JoltPhysics/Jolt/AABBTree/TriangleCodec/TriangleCodecIndexed8BitPackSOA4Flags.h', + 'thirdparty/JoltPhysics/Jolt/Core/ARMNeon.h', + 'thirdparty/JoltPhysics/Jolt/Core/Atomics.h', + 'thirdparty/JoltPhysics/Jolt/Core/ByteBuffer.h', + 'thirdparty/JoltPhysics/Jolt/Core/Color.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/Color.h', + 'thirdparty/JoltPhysics/Jolt/Core/Core.h', + 'thirdparty/JoltPhysics/Jolt/Core/Factory.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/Factory.h', + 'thirdparty/JoltPhysics/Jolt/Core/FixedSizeFreeList.h', + 'thirdparty/JoltPhysics/Jolt/Core/FPControlWord.h', + 'thirdparty/JoltPhysics/Jolt/Core/FPException.h', + 'thirdparty/JoltPhysics/Jolt/Core/FPFlushDenormals.h', + 'thirdparty/JoltPhysics/Jolt/Core/HashCombine.h', + 'thirdparty/JoltPhysics/Jolt/Core/InsertionSort.h', + 'thirdparty/JoltPhysics/Jolt/Core/IssueReporting.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/IssueReporting.h', + 'thirdparty/JoltPhysics/Jolt/Core/JobSystem.h', + 'thirdparty/JoltPhysics/Jolt/Core/JobSystemThreadPool.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/JobSystemThreadPool.h', + 'thirdparty/JoltPhysics/Jolt/Core/JobSystemWithBarrier.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/JobSystemWithBarrier.h', + 'thirdparty/JoltPhysics/Jolt/Core/LinearCurve.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/LinearCurve.h', + 'thirdparty/JoltPhysics/Jolt/Core/LockFreeHashMap.h', + 'thirdparty/JoltPhysics/Jolt/Core/Memory.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/Memory.h', + 'thirdparty/JoltPhysics/Jolt/Core/Mutex.h', + 'thirdparty/JoltPhysics/Jolt/Core/MutexArray.h', + 'thirdparty/JoltPhysics/Jolt/Core/NonCopyable.h', + 'thirdparty/JoltPhysics/Jolt/Core/Profiler.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/Profiler.h', + 'thirdparty/JoltPhysics/Jolt/Core/QuickSort.h', + 'thirdparty/JoltPhysics/Jolt/Core/Reference.h', + 'thirdparty/JoltPhysics/Jolt/Core/Result.h', + 'thirdparty/JoltPhysics/Jolt/Core/RTTI.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/RTTI.h', + 'thirdparty/JoltPhysics/Jolt/Core/Semaphore.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/Semaphore.h', + 'thirdparty/JoltPhysics/Jolt/Core/StaticArray.h', + 'thirdparty/JoltPhysics/Jolt/Core/StreamIn.h', + 'thirdparty/JoltPhysics/Jolt/Core/StreamOut.h', + 'thirdparty/JoltPhysics/Jolt/Core/StreamWrapper.h', + 'thirdparty/JoltPhysics/Jolt/Core/StringTools.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/StringTools.h', + 'thirdparty/JoltPhysics/Jolt/Core/STLAlignedAllocator.h', + 'thirdparty/JoltPhysics/Jolt/Core/STLAllocator.h', + 'thirdparty/JoltPhysics/Jolt/Core/STLTempAllocator.h', + 'thirdparty/JoltPhysics/Jolt/Core/TempAllocator.h', + 'thirdparty/JoltPhysics/Jolt/Core/TickCounter.cpp', + 'thirdparty/JoltPhysics/Jolt/Core/TickCounter.h', + 'thirdparty/JoltPhysics/Jolt/Core/UnorderedMap.h', + 'thirdparty/JoltPhysics/Jolt/Core/UnorderedSet.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/AABox.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/AABox4.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/ClipPoly.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/ClosestPoint.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/ConvexHullBuilder.cpp', + 'thirdparty/JoltPhysics/Jolt/Geometry/ConvexHullBuilder.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/ConvexHullBuilder2D.cpp', + 'thirdparty/JoltPhysics/Jolt/Geometry/ConvexHullBuilder2D.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/ConvexSupport.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/Ellipse.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/EPAConvexHullBuilder.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/EPAPenetrationDepth.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/GJKClosestPoint.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/IndexedTriangle.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/Indexify.cpp', + 'thirdparty/JoltPhysics/Jolt/Geometry/Indexify.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/MortonCode.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/OrientedBox.cpp', + 'thirdparty/JoltPhysics/Jolt/Geometry/OrientedBox.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/Plane.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/RayAABox.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/RayAABox8.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/RayCapsule.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/RayCylinder.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/RaySphere.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/RayTriangle.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/RayTriangle8.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/Sphere.h', + 'thirdparty/JoltPhysics/Jolt/Geometry/Triangle.h', + 'thirdparty/JoltPhysics/Jolt/Jolt.h', + 'thirdparty/JoltPhysics/Jolt/Math/DMat44.h', + 'thirdparty/JoltPhysics/Jolt/Math/Double3.h', + 'thirdparty/JoltPhysics/Jolt/Math/DVec3.h', + 'thirdparty/JoltPhysics/Jolt/Math/DynMatrix.h', + 'thirdparty/JoltPhysics/Jolt/Math/EigenValueSymmetric.h', + 'thirdparty/JoltPhysics/Jolt/Math/FindRoot.h', + 'thirdparty/JoltPhysics/Jolt/Math/Float2.h', + 'thirdparty/JoltPhysics/Jolt/Math/Float3.h', + 'thirdparty/JoltPhysics/Jolt/Math/Float4.h', + 'thirdparty/JoltPhysics/Jolt/Math/GaussianElimination.h', + 'thirdparty/JoltPhysics/Jolt/Math/HalfFloat.h', + 'thirdparty/JoltPhysics/Jolt/Math/Mat44.h', + 'thirdparty/JoltPhysics/Jolt/Math/Math.h', + 'thirdparty/JoltPhysics/Jolt/Math/MathTypes.h', + 'thirdparty/JoltPhysics/Jolt/Math/Matrix.h', + 'thirdparty/JoltPhysics/Jolt/Math/Quat.h', + 'thirdparty/JoltPhysics/Jolt/Math/Real.h', + 'thirdparty/JoltPhysics/Jolt/Math/Swizzle.h', + 'thirdparty/JoltPhysics/Jolt/Math/Trigonometry.h', + 'thirdparty/JoltPhysics/Jolt/Math/UVec4.h', + 'thirdparty/JoltPhysics/Jolt/Math/UVec8.h', + 'thirdparty/JoltPhysics/Jolt/Math/Vec3.cpp', + 'thirdparty/JoltPhysics/Jolt/Math/Vec3.h', + 'thirdparty/JoltPhysics/Jolt/Math/Vec4.h', + 'thirdparty/JoltPhysics/Jolt/Math/Vec8.h', + 'thirdparty/JoltPhysics/Jolt/Math/Vector.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/GetPrimitiveTypeOfType.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStream.cpp', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStream.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamBinaryIn.cpp', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamBinaryIn.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamBinaryOut.cpp', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamBinaryOut.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamIn.cpp', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamIn.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamOut.cpp', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamOut.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamTextIn.cpp', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamTextIn.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamTextOut.cpp', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamTextOut.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/ObjectStreamTypes.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/SerializableAttribute.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/SerializableAttributeEnum.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/SerializableAttributeTyped.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/SerializableObject.cpp', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/SerializableObject.h', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/TypeDeclarations.cpp', + 'thirdparty/JoltPhysics/Jolt/ObjectStream/TypeDeclarations.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/Body.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/Body.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyAccess.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyAccess.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyActivationListener.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyCreationSettings.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyCreationSettings.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyFilter.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyID.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyInterface.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyInterface.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyLock.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyLockInterface.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyLockMulti.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyManager.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyManager.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/BodyPair.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/MassProperties.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/MassProperties.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/MotionProperties.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/MotionProperties.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/MotionQuality.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Body/MotionType.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Character/Character.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Character/Character.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Character/CharacterBase.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Character/CharacterBase.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Character/CharacterVirtual.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Character/CharacterVirtual.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/AABoxCast.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/ActiveEdgeMode.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/ActiveEdges.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/BackFaceMode.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhase.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhase.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseBruteForce.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseBruteForce.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseLayer.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseQuadTree.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseQuadTree.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/BroadPhase/BroadPhaseQuery.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/BroadPhase/QuadTree.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/BroadPhase/QuadTree.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CastConvexVsTriangles.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CastConvexVsTriangles.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CastSphereVsTriangles.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CastSphereVsTriangles.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CastResult.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollectFacesMode.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollideConvexVsTriangles.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollideConvexVsTriangles.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollidePointResult.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollideShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollideSphereVsTriangles.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollideSphereVsTriangles.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollisionCollector.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollisionCollectorImpl.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollisionDispatch.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollisionDispatch.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollisionGroup.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/CollisionGroup.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/ContactListener.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/EstimateCollisionResponse.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/EstimateCollisionResponse.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/GroupFilter.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/GroupFilter.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/GroupFilterTable.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/GroupFilterTable.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/ManifoldBetweenTwoFaces.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/ManifoldBetweenTwoFaces.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/NarrowPhaseQuery.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/NarrowPhaseQuery.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/NarrowPhaseStats.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/NarrowPhaseStats.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/ObjectLayer.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/PhysicsMaterial.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/PhysicsMaterial.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/PhysicsMaterialSimple.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/PhysicsMaterialSimple.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/RayCast.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/BoxShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/BoxShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/CapsuleShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/CapsuleShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/CompoundShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/CompoundShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/CompoundShapeVisitors.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/ConvexHullShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/ConvexHullShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/ConvexShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/ConvexShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/CylinderShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/CylinderShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/DecoratedShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/DecoratedShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/GetTrianglesContext.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/HeightFieldShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/MeshShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/MeshShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/MutableCompoundShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/MutableCompoundShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/OffsetCenterOfMassShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/OffsetCenterOfMassShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/PolyhedronSubmergedVolumeCalculator.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/RotatedTranslatedShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/RotatedTranslatedShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/ScaledShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/ScaledShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/ScaleHelpers.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/Shape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/Shape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/SphereShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/SphereShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/StaticCompoundShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/StaticCompoundShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/SubShapeID.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/SubShapeIDPair.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/TaperedCapsuleShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/TaperedCapsuleShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/TriangleShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/Shape/TriangleShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/ShapeCast.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/ShapeFilter.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/SortReverseAndStore.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/TransformedShape.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Collision/TransformedShape.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConeConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConeConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/Constraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/Constraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintManager.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintManager.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/AngleConstraintPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/AxisConstraintPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/DualAxisConstraintPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/GearConstraintPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/HingeRotationConstraintPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/IndependentAxisConstraintPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/PointConstraintPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/RackAndPinionConstraintPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/RotationEulerConstraintPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/RotationQuatConstraintPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/SpringPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ConstraintPart/SwingTwistConstraintPart.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/ContactConstraintManager.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/DistanceConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/DistanceConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/FixedConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/FixedConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/GearConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/GearConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/HingeConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/HingeConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/MotorSettings.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/MotorSettings.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/PathConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/PathConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/PathConstraintPath.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/PathConstraintPath.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/PathConstraintPathHermite.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/PathConstraintPathHermite.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/PointConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/PointConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/PulleyConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/PulleyConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/RackAndPinionConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/RackAndPinionConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/SixDOFConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/SliderConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/SliderConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/SwingTwistConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/TwoBodyConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Constraints/TwoBodyConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/DeterminismLog.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/DeterminismLog.h', + 'thirdparty/JoltPhysics/Jolt/Physics/EActivation.h', + 'thirdparty/JoltPhysics/Jolt/Physics/IslandBuilder.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/IslandBuilder.h', + 'thirdparty/JoltPhysics/Jolt/Physics/LargeIslandSplitter.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/LargeIslandSplitter.h', + 'thirdparty/JoltPhysics/Jolt/Physics/PhysicsLock.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/PhysicsLock.h', + 'thirdparty/JoltPhysics/Jolt/Physics/PhysicsScene.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/PhysicsScene.h', + 'thirdparty/JoltPhysics/Jolt/Physics/PhysicsSettings.h', + 'thirdparty/JoltPhysics/Jolt/Physics/PhysicsStepListener.h', + 'thirdparty/JoltPhysics/Jolt/Physics/PhysicsSystem.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/PhysicsSystem.h', + 'thirdparty/JoltPhysics/Jolt/Physics/PhysicsUpdateContext.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/PhysicsUpdateContext.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Ragdoll/Ragdoll.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Ragdoll/Ragdoll.h', + 'thirdparty/JoltPhysics/Jolt/Physics/StateRecorder.h', + 'thirdparty/JoltPhysics/Jolt/Physics/StateRecorderImpl.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/StateRecorderImpl.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/TrackedVehicleController.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/TrackedVehicleController.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleAntiRollBar.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleAntiRollBar.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleCollisionTester.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleCollisionTester.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleConstraint.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleConstraint.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleController.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleController.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleDifferential.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleDifferential.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleEngine.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleEngine.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleTrack.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleTrack.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleTransmission.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/VehicleTransmission.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/Wheel.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/Wheel.h', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/WheeledVehicleController.cpp', + 'thirdparty/JoltPhysics/Jolt/Physics/Vehicle/WheeledVehicleController.h', + 'thirdparty/JoltPhysics/Jolt/RegisterTypes.cpp', + 'thirdparty/JoltPhysics/Jolt/RegisterTypes.h', + 'thirdparty/JoltPhysics/Jolt/Renderer/DebugRenderer.cpp', + 'thirdparty/JoltPhysics/Jolt/Renderer/DebugRenderer.h', + 'thirdparty/JoltPhysics/Jolt/Renderer/DebugRendererPlayback.cpp', + 'thirdparty/JoltPhysics/Jolt/Renderer/DebugRendererPlayback.h', + 'thirdparty/JoltPhysics/Jolt/Renderer/DebugRendererRecorder.cpp', + 'thirdparty/JoltPhysics/Jolt/Renderer/DebugRendererRecorder.h', + 'thirdparty/JoltPhysics/Jolt/Skeleton/SkeletalAnimation.cpp', + 'thirdparty/JoltPhysics/Jolt/Skeleton/SkeletalAnimation.h', + 'thirdparty/JoltPhysics/Jolt/Skeleton/Skeleton.cpp', + 'thirdparty/JoltPhysics/Jolt/Skeleton/Skeleton.h', + 'thirdparty/JoltPhysics/Jolt/Skeleton/SkeletonMapper.cpp', + 'thirdparty/JoltPhysics/Jolt/Skeleton/SkeletonMapper.h', + 'thirdparty/JoltPhysics/Jolt/Skeleton/SkeletonPose.cpp', + 'thirdparty/JoltPhysics/Jolt/Skeleton/SkeletonPose.h', + 'thirdparty/JoltPhysics/Jolt/TriangleGrouper/TriangleGrouper.h', + 'thirdparty/JoltPhysics/Jolt/TriangleGrouper/TriangleGrouperClosestCentroid.cpp', + 'thirdparty/JoltPhysics/Jolt/TriangleGrouper/TriangleGrouperClosestCentroid.h', + 'thirdparty/JoltPhysics/Jolt/TriangleGrouper/TriangleGrouperMorton.cpp', + 'thirdparty/JoltPhysics/Jolt/TriangleGrouper/TriangleGrouperMorton.h', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitter.cpp', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitter.h', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterBinning.cpp', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterBinning.h', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.cpp', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.h', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterLongestAxis.cpp', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterLongestAxis.h', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterMean.cpp', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterMean.h', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterMorton.cpp', + 'thirdparty/JoltPhysics/Jolt/TriangleSplitter/TriangleSplitterMorton.h', +]) + subdir('src') diff --git a/src/Apps/Tools/CubeTest.cpp b/src/Apps/Tools/FrogTest.cpp similarity index 93% rename from src/Apps/Tools/CubeTest.cpp rename to src/Apps/Tools/FrogTest.cpp index be147b2..81930a7 100644 --- a/src/Apps/Tools/CubeTest.cpp +++ b/src/Apps/Tools/FrogTest.cpp @@ -27,6 +27,48 @@ #include #include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + using namespace orange; struct MiniPipelineInfo @@ -217,11 +259,7 @@ int main(int argc, char** argv) if (!r_swapchain) return 1; - //auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/gman.obj"); - //auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/chair.obj"); auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/frog.obj"); - //auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/deck.obj"); - //auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/cube.obj"); if (!r_objData) return 1; @@ -243,61 +281,6 @@ int main(int argc, char** argv) auto r_mesh = ParseOBJ(*r_objData); -#if 0 - std::cout << std::endl; - std::cout << std::endl; - std::cout << std::endl; - std::cout << std::endl; - for (auto& vertex : r_mesh->vertexData.GetStaticVertices()) { - std::cout << std::hexfloat; - std::cout << "{ "; - - std::cout << "{ " << std::setw(16) << vertex.pos[0] << ", " << std::setw(16) << vertex.pos[1] << ", " << std::setw(16) << vertex.pos[2] << " }, "; - std::cout << "{ " << std::setw(16) << vertex.uv[0] << ", " << std::setw(16) << vertex.uv[1] << " }, "; - std::cout << "{ " << std::setw(16) << vertex.normal[0] << ", " << std::setw(16) << vertex.normal[1] << ", " << std::setw(16) << vertex.normal[2] << " } "; - - std::cout << "},"; - std::cout << std::endl; - } - std::cout << std::endl; - std::cout << std::endl; - std::cout << std::endl; -#endif - -#if 0 - std::cout << std::endl; - std::cout << std::endl; - std::cout << std::endl; - std::cout << std::endl; - int count = 0; - for (auto& index : r_mesh->indices) { - std::cout << std::setw(4) << index << "u, "; - count++; - if (count >= 16) { - std::cout << std::endl; - count = 0; - } - } - std::cout << std::endl; - std::cout << std::endl; - std::cout << std::endl; -#endif - - auto r_vmf = fs::OpenFileIntoTextBuffer("/home/joshua/Code/Desolation/game/sdk_content/maps/hl2_sdk/sdk_phys_constraint.vmf"); - - auto r_vmfkv = kv::KeyValues::ParseFromUTF8(*r_vmf); - if (!r_vmfkv) - { - fprintf(stderr, "Parsing VMF failed!\n"); - return 1; - } - - - kv::KeyValues &vmfkv = *r_vmfkv; - - std::cout << "editorversion: " << vmfkv["versioninfo"]["editorversion"].Get() << std::endl; - - auto newVertexSlice = *pooler.AllocSlice(sizeof(StaticVertex) * r_mesh->vertexData.VertexCount(), sizeof(StaticVertex)); auto newIndexSlice = *pooler.AllocSlice(sizeof(IndexType) * r_mesh->indices.size(), sizeof(IndexType)); r_mesh->vertexData.GetStaticVertices().copy((uint8_t*)(r_buffer->ptr) + newVertexSlice.offset); @@ -666,11 +649,11 @@ int main(int argc, char** argv) // log::info("mouse: %d %d", mouseDelta.x, mouseDelta.y); //} - const float sensitivity = 6.0f; + const float sensitivity = 0.002f; camera.offsetOrientation( - -sensitivity * dt * Radian( mouseDelta.x ), - sensitivity * dt * Radian( mouseDelta.y )); + -sensitivity * Radian( mouseDelta.x ), + sensitivity * Radian( mouseDelta.y )); frameData[r_swapchain->CurrentFrame()] = FrameData { diff --git a/src/Apps/Tools/Lightmapper.cpp b/src/Apps/Tools/Lightmapper.cpp new file mode 100644 index 0000000..5b71057 --- /dev/null +++ b/src/Apps/Tools/Lightmapper.cpp @@ -0,0 +1,855 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace orange; + +struct MiniPipelineInfo +{ + VkShaderModule vs; + VkShaderModule fs; + + VkPipelineLayout pipelineLayout; + + VkFormat colorFormat; + VkFormat depthFormat; + + bool enableDepthTest; + bool enableDepthWrites; + + Span vertexAttributes; +}; + +static VulkanResult CreateGraphicsPipeline(VkDevice device, const MiniPipelineInfo& info) +{ + VkPipelineShaderStageCreateInfo stages[] = + { + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = info.vs, + .pName = "main", + }, + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = info.fs, + .pName = "main", + }, + }; + + Array dynamicStates = + { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + }; + + VkPipelineDynamicStateCreateInfo dynamicStateInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + .dynamicStateCount = uint32_t(dynamicStates.size()), + .pDynamicStates = dynamicStates.data(), + }; + + VkVertexInputBindingDescription inputBindingDescription = + { + .binding = 0, + .stride = sizeof(StaticVertex), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, + }; + + VkPipelineVertexInputStateCreateInfo vertexInputInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = info.vertexAttributes.size ? 1u : 0u, + .pVertexBindingDescriptions = &inputBindingDescription, + .vertexAttributeDescriptionCount = uint32_t(info.vertexAttributes.size), + .pVertexAttributeDescriptions = info.vertexAttributes.data, + }; + + VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + .primitiveRestartEnable = VK_FALSE, + }; + + VkPipelineViewportStateCreateInfo viewportStateInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .viewportCount = 1, + .scissorCount = 1, + }; + + VkPipelineRasterizationStateCreateInfo rasterizationInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .cullMode = VK_CULL_MODE_BACK_BIT, + .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, + .lineWidth = 1.0f, + }; + + VkPipelineMultisampleStateCreateInfo multisampleInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, + }; + + VkPipelineDepthStencilStateCreateInfo depthStencilInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + .depthTestEnable = info.enableDepthTest, + .depthWriteEnable = info.enableDepthWrites, + .depthCompareOp = VK_COMPARE_OP_LESS, + .minDepthBounds = 0.0f, + .maxDepthBounds = 1.0f, + }; + + VkPipelineColorBlendAttachmentState attachmentBlendState = + { + .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, + }; + + VkPipelineColorBlendStateCreateInfo colorBlendStateInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .attachmentCount = 1, + .pAttachments = &attachmentBlendState, + }; + + VkPipelineRenderingCreateInfo renderingInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, + .viewMask = 0u, + .colorAttachmentCount = 1u, + .pColorAttachmentFormats = &info.colorFormat, + .depthAttachmentFormat = info.depthFormat, + }; + + VkGraphicsPipelineCreateInfo pipelineInfo = + { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .pNext = &renderingInfo, + .stageCount = Size(stages), + .pStages = stages, + .pVertexInputState = &vertexInputInfo, + .pInputAssemblyState = &inputAssemblyInfo, + .pViewportState = &viewportStateInfo, + .pRasterizationState = &rasterizationInfo, + .pMultisampleState = &multisampleInfo, + .pDepthStencilState = &depthStencilInfo, + .pColorBlendState = &colorBlendStateInfo, + .pDynamicState = &dynamicStateInfo, + .layout = info.pipelineLayout, + }; + + VkPipeline pipeline = VK_NULL_HANDLE; + VkResult res = VK_SUCCESS; + if ((res = vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline)) != VK_SUCCESS) + return VulkanResult::Error(res); + + return VulkanResult::Success(pipeline); +} + +struct alignas(16) Mesh +{ + uint32_t textureIdx; + uint32_t vertexOffset; // in sizeof(Vertex) + uint32_t indexOffset; // in sizeof(IndexType) + uint32_t indexCount; + AABB bounds; +}; + +struct alignas(16) Renderable +{ + mat4 transform; + uint32_t meshIdx; + vec3 color; // should replace with something more interesting lmao +}; + +// look at moving me if binary is big +SmallVector g_meshes; +SmallVector g_renderables; + +int main(int argc, char** argv) +{ + (void)argc; (void)argv; + + auto r_window = Window::Create(); + if (!r_window) + return 1; + + auto r_renderContext = RenderContext::Create("Cube Test"); + if (!r_renderContext) + return 1; + + auto r_surface = r_window->CreateSurface(r_renderContext->Instance()); + if (!r_surface) + return 1; + + auto r_swapchain = Swapchain::Create(*r_renderContext, *r_surface); + if (!r_swapchain) + return 1; + + auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/frog.obj"); + if (!r_objData) + return 1; + + auto r_buffer = r_renderContext->CreateBuffer(1024 * 1024 * 1024); + if (!r_buffer) + return 1; + auto pooler = MemoryPool{ *r_buffer }; + + auto r_vsMesh = r_renderContext->CreateShader(vs_Mesh); + if (!r_vsMesh) return 1; + auto r_vsFullscreen = r_renderContext->CreateShader(vs_Fullscreen); + if (!r_vsFullscreen) return 1; + auto r_fsMesh = r_renderContext->CreateShader(fs_Mesh); + if (!r_fsMesh) return 1; + auto r_fsRed = r_renderContext->CreateShader(fs_Red); + if (!r_fsRed) return 1; + auto r_fsSky = r_renderContext->CreateShader(fs_SkyGradient); + if (!r_fsSky) return 1; + + auto r_mesh = ParseOBJ(*r_objData); + if (!r_mesh) return 1; + + auto r_atlas = CreateLightmapAtlasForMesh(*r_mesh); + if (!r_atlas) return 1; + auto atlas = std::move(*r_atlas); + auto lightmapDebugTex = GenerateDebugAtlasTexture(atlas); + + auto newVertexSlice = *pooler.AllocSlice(sizeof(StaticVertex) * r_mesh->vertexData.VertexCount(), sizeof(StaticVertex)); + auto newIndexSlice = *pooler.AllocSlice(sizeof(IndexType) * r_mesh->indices.size(), sizeof(IndexType)); + r_mesh->vertexData.GetStaticVertices().copy((uint8_t*)(r_buffer->ptr) + newVertexSlice.offset); + r_mesh->indices.copy ((uint8_t*)(r_buffer->ptr) + newIndexSlice.offset); + + uint32_t meshIdx = uint32_t(g_meshes.emplace_back(Mesh + { + .textureIdx = 0, + .vertexOffset = uint32_t(newVertexSlice.offset / sizeof(StaticVertex)), + .indexOffset = uint32_t(newIndexSlice.offset / sizeof(IndexType)), + .indexCount = uint32_t(r_mesh->indices.size()), + .bounds = r_mesh->bounds, + })); + + g_renderables.emplace_back(Renderable + { + .transform = mat4{}, + .meshIdx = meshIdx, + .color = 1_vec3, + }); + + // + +#pragma region "make descriptor n shit" + VkSamplerCreateInfo samplerInfo = + { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .magFilter = VK_FILTER_LINEAR, + .minFilter = VK_FILTER_LINEAR, + .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR, + .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .mipLodBias = 0.0f, + .anisotropyEnable = VK_TRUE, + .maxAnisotropy = 16.0f, + .minLod = -FLT_MAX, + .maxLod = FLT_MAX, + }; + VkSampler sampler = VK_NULL_HANDLE; + vkCreateSampler(r_renderContext->Device(), &samplerInfo, nullptr, &sampler); + + constexpr uint32_t MaxBindlessResources = 32768; + VkDescriptorPoolSize bindlessPoolSizes[] = + { + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2u}, + { VK_DESCRIPTOR_TYPE_SAMPLER, 1u}, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MaxBindlessResources }, + }; + + VkDescriptorPoolCreateInfo poolInfo = + { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, + .maxSets = 1u, + .poolSizeCount = uint32_t(Size(bindlessPoolSizes)), + .pPoolSizes = bindlessPoolSizes, + }; + + VkDescriptorPool descriptorPool = VK_NULL_HANDLE; + vkCreateDescriptorPool(r_renderContext->Device(), &poolInfo, nullptr, &descriptorPool); + + VkDescriptorSetLayoutBinding layoutBindings[] = + { + { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_ALL, + }, + { + .binding = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = &sampler, + }, + { + .binding = 2, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_ALL, + }, + { + .binding = 3, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorCount = MaxBindlessResources, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + }, + }; + + constexpr VkDescriptorBindingFlags bindingFlags[] = + { + 0, + 0, + 0, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT, + }; + + Assert(Size(bindingFlags) == Size(layoutBindings)); + + VkDescriptorSetLayoutBindingFlagsCreateInfo layoutBindingFlagsInfo = + { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT, + .bindingCount = Size(bindingFlags), + .pBindingFlags = bindingFlags, + }; + + VkDescriptorSetLayoutCreateInfo layoutInfo = + { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .pNext = &layoutBindingFlagsInfo, + .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT, + .bindingCount = Size(layoutBindings), + .pBindings = layoutBindings, + }; + + VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE; + vkCreateDescriptorSetLayout(r_renderContext->Device(), &layoutInfo, nullptr, &descriptorSetLayout); + + VkDescriptorSetVariableDescriptorCountAllocateInfoEXT descriptorCountAllocInfo = + { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT, + .descriptorSetCount = 1, + .pDescriptorCounts = &MaxBindlessResources, + }; + + VkDescriptorSetAllocateInfo descriptorSetAllocInfo = + { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pNext = &descriptorCountAllocInfo, + .descriptorPool = descriptorPool, + .descriptorSetCount = 1, + .pSetLayouts = &descriptorSetLayout, + }; + + VkDescriptorSet descriptorSet = VK_NULL_HANDLE; + vkAllocateDescriptorSets(r_renderContext->Device(), &descriptorSetAllocInfo, &descriptorSet); + + struct PushConstants + { + uint32_t frameIdx; + }; + + VkPushConstantRange pushConstantRange = + { + .stageFlags = VK_SHADER_STAGE_VERTEX_BIT, + .offset = 0, + .size = sizeof(PushConstants), + }; + + VkPipelineLayoutCreateInfo pipelineLayoutInfo = + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .setLayoutCount = 1, + .pSetLayouts = &descriptorSetLayout, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &pushConstantRange, + }; + VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; + vkCreatePipelineLayout(r_renderContext->Device(), &pipelineLayoutInfo, nullptr, &pipelineLayout); + + // + VkFormat depthFormat = *FindDepthFormat(r_renderContext->PhysicalDevice()); + auto pipeline = *CreateGraphicsPipeline(r_renderContext->Device(), MiniPipelineInfo + { + .vs = *r_vsMesh, + .fs = *r_fsMesh, + .pipelineLayout = pipelineLayout, + .colorFormat = FormatToSrgbFormat(r_swapchain->Format()), + .depthFormat = depthFormat, + .enableDepthTest = true, + .enableDepthWrites = true, + .vertexAttributes = Span(StaticVertex::Attributes), + }); + + auto skyPipeline = *CreateGraphicsPipeline(r_renderContext->Device(), MiniPipelineInfo + { + .vs = *r_vsFullscreen, + .fs = *r_fsSky, + .pipelineLayout = pipelineLayout, + .colorFormat = FormatToSrgbFormat(r_swapchain->Format()), + .depthFormat = depthFormat, + .enableDepthTest = false, + .enableDepthWrites = false, + .vertexAttributes = Span(nullptr), + }); +#pragma endregion + + struct ImageUpload + { + BufferSlice from; + VkImage to; + VkExtent3D extent; + }; + Vector imageUploads; + + //auto r_pngData = fs::OpenFileIntoBuffer("/home/joshua/chair_color.png"); + auto r_pngData = fs::OpenFileIntoBuffer("/home/joshua/frog001.png"); + //auto r_pngData = fs::OpenFileIntoBuffer("/home/joshua/deck.png"); + if (!r_pngData) + return 1; + + spng_ctx *ctx = spng_ctx_new(0); + spng_set_png_buffer(ctx, r_pngData->data, r_pngData->size); + size_t pngOutSize = 0zu; + spng_decoded_image_size(ctx, SPNG_FMT_RGBA8, &pngOutSize); + auto pngLinearSlice = *pooler.AllocSlice(pngOutSize, 16); + spng_decode_image(ctx, pngLinearSlice.ptr, pngOutSize, SPNG_FMT_RGBA8, 0); + struct spng_ihdr ihdr; + spng_get_ihdr(ctx, &ihdr); + spng_ctx_free(ctx); + + // BLAH DEDUPE + auto r_texture = r_renderContext->CreateImage(pooler, ihdr.width, ihdr.height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + auto r_textureView = r_renderContext->CreateImageView(*r_texture, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT); + + { + VkDescriptorImageInfo descriptorImageInfo = + { + .imageView = *r_textureView, + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; + + VkWriteDescriptorSet writeImageDescriptorSet[] = + { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = descriptorSet, + .dstBinding = 3, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .pImageInfo = &descriptorImageInfo, + }, + }; + vkUpdateDescriptorSets(r_renderContext->Device(), Size(writeImageDescriptorSet), writeImageDescriptorSet, 0, nullptr); + + imageUploads.push_back(ImageUpload + { + .from = pngLinearSlice, + .to = *r_texture, + .extent = VkExtent3D{ ihdr.width, ihdr.height, 1u }, + }); + } + // + auto r_lightTexture = r_renderContext->CreateImage(pooler, atlas->width, atlas->height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); + auto r_lightTextureView = r_renderContext->CreateImageView(*r_lightTexture, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT); + + { + auto lightmapTextureData = *pooler.AllocSlice(pngOutSize, 16); + memcpy(lightmapTextureData.ptr, lightmapDebugTex.data(), lightmapDebugTex.size()); + + VkDescriptorImageInfo descriptorImageInfo = + { + .imageView = *r_lightTextureView, + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; + + VkWriteDescriptorSet writeImageDescriptorSet[] = + { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = descriptorSet, + .dstBinding = 3, + .dstArrayElement = 1, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .pImageInfo = &descriptorImageInfo, + }, + }; + vkUpdateDescriptorSets(r_renderContext->Device(), Size(writeImageDescriptorSet), writeImageDescriptorSet, 0, nullptr); + + imageUploads.push_back(ImageUpload + { + .from = lightmapTextureData, + .to = *r_lightTexture, + .extent = VkExtent3D{ atlas->width, atlas->height, 1u }, + }); + } + // + + Camera camera; + camera.transform.position = vec3{0.0f, 0.0f, 80.0f}; + camera.viewportAspectRatio = 16.0f / 9.0f; + //camera.offsetOrientation(1_deg * Seconds(t2 - t1).count(), 0_deg); + //camera.lookAt(vec3{40.0f, 40.0f, 0.0f}); + camera.transform.orientation = eulerAnglesToQuaternion(EulerAngles{ 0_deg, 0_deg, 0_deg }); + + auto meshData = r_mesh->vertexData.View(); + auto r_depthImage = r_renderContext->CreateImage(pooler, 1280, 720, depthFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); + auto depthImageView = *r_renderContext->CreateImageView(*r_depthImage, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT); + + struct FrameData + { + mat4 view_projection; + }; + + auto frameDataSlice = *pooler.AllocSlice(MaxFramesInFlight * sizeof(FrameData), 16); + FrameData* frameData = reinterpret_cast(frameDataSlice.ptr); + + VkDescriptorBufferInfo bufferInfo = + { + .buffer = r_buffer->buffer, + .offset = frameDataSlice.offset, + .range = frameDataSlice.size, + }; + + VkWriteDescriptorSet writeDescriptorSet[] = + { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = descriptorSet, + .dstBinding = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pBufferInfo = &bufferInfo, + }, + }; + vkUpdateDescriptorSets(r_renderContext->Device(), Size(writeDescriptorSet), writeDescriptorSet, 0, nullptr); + + struct Renderables + { + Renderable renderables[1024]; + }; + + auto renderablesSlice = *pooler.AllocSlice(MaxFramesInFlight * sizeof(Renderables), 16); + Renderables* gpuRenderables = reinterpret_cast(renderablesSlice.ptr); + + VkDescriptorBufferInfo renderblesBufferInfo = + { + .buffer = r_buffer->buffer, + .offset = renderablesSlice.offset, + .range = renderablesSlice.size, + }; + + VkWriteDescriptorSet renderablesWriteDescriptorSet[] = + { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = descriptorSet, + .dstBinding = 2, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pBufferInfo = &renderblesBufferInfo, + }, + }; + vkUpdateDescriptorSets(r_renderContext->Device(), Size(renderablesWriteDescriptorSet), renderablesWriteDescriptorSet, 0, nullptr); + + Input::InputHandler handler; + + r_window->EnableRelativeMouse(true); + + auto indirectBuffer = *pooler.AllocSlice(1024 * sizeof(VkDrawIndexedIndirectCommand), 256); + auto indirectPtr = reinterpret_cast(indirectBuffer.ptr); + for (size_t i = 0; i < g_renderables.size(); i++) { + const auto& renderable = g_renderables[i]; + const uint32_t meshIdx = renderable.meshIdx; + + indirectPtr[i] = VkDrawIndexedIndirectCommand + { + .indexCount = g_meshes[meshIdx].indexCount, + .instanceCount = 1u, + .firstIndex = g_meshes[meshIdx].indexOffset, + .vertexOffset = int32_t(g_meshes[meshIdx].vertexOffset), + .firstInstance = 0u, + }; + } + + auto countBuffer = *pooler.AllocSlice(sizeof(uint32_t), 16); + auto countPtr = reinterpret_cast(countBuffer.ptr); + *countPtr = uint32_t(g_renderables.size()); + + auto t1 = Time::now(); + while (r_window->Update(handler)) + { + const auto t2 = Time::now(); + auto delta = t2 - t1; + const float dt = Seconds(delta).count(); + t1 = t2; + + //char title[64]; + //stbsp_snprintf(title, sizeof(title), "CubeTest - %gfps", 1.0f / dt); + //r_window->SetTitle(title); + + { + auto mouseDelta = handler.getMouseMotionDelta(); + auto scrollDelta = handler.getMouseScrollDelta(); + //if (mouseDelta.x || mouseDelta.y) + //{ + // log::info("mouse: %d %d", mouseDelta.x, mouseDelta.y); + //} + + const float sensitivity = 0.002f; + + camera.offsetOrientation( + -sensitivity * Radian( mouseDelta.x ), + sensitivity * Radian( mouseDelta.y )); + + frameData[r_swapchain->CurrentFrame()] = FrameData + { + .view_projection = camera.projection() * camera.view(), + }; + + g_renderables.copy(gpuRenderables[r_swapchain->CurrentFrame()].renderables); + + const float movementSpeed = handler.get(Input::ButtonCodes::Key_LShift) ? 64.0f : 16.0f; + + if (scrollDelta.y) + { + camera.fieldOfView += Radian(5_deg) * -scrollDelta.y; + camera.fieldOfView = Clamp(camera.fieldOfView, Radian(5_deg), Radian(175_deg)); + } + + if (handler.get(Input::ButtonCodes::Key_W)) + camera.transform.position += camera.forward() * movementSpeed * dt; + else if (handler.get(Input::ButtonCodes::Key_S)) + camera.transform.position += camera.backward() * movementSpeed * dt; + + if (handler.get(Input::ButtonCodes::Key_A)) + camera.transform.position += camera.left() * movementSpeed * dt; + else if (handler.get(Input::ButtonCodes::Key_D)) + camera.transform.position += camera.right() * movementSpeed * dt; + } + + VkCommandBuffer cmdBuf = r_swapchain->CommandBuffer(); + r_renderContext->BeginCommandBuffer(cmdBuf); + { + for (auto& upload : imageUploads) + { + VkImageMemoryBarrier transferBarrier = + { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = 0, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + .image = upload.to, + .subresourceRange = FirstColorMipSubresourceRange, + }; + vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &transferBarrier); + + VkBufferImageCopy region = + { + .bufferOffset = upload.from.offset, + .imageSubresource = + { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0u, + .baseArrayLayer = 0u, + .layerCount = 1u, + }, + .imageExtent = upload.extent, + }; + vkCmdCopyBufferToImage(cmdBuf, upload.from.buffer, upload.to, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + + VkImageMemoryBarrier optimalBarrier = + { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, + .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + .image = upload.to, + .subresourceRange = FirstColorMipSubresourceRange, + }; + vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &optimalBarrier); + } + imageUploads.clear(); + + VkViewport viewport = + { + .x = 0.0f, + .y = 0.0f, + .width = float(r_swapchain->Extent().width), + .height = float(r_swapchain->Extent().height), + .minDepth = 0.0f, + .maxDepth = 1.0f, + }; + + VkRect2D scissor = + { + .offset = {0u, 0u}, + .extent = r_swapchain->Extent(), + }; + + vkCmdSetViewport(cmdBuf, 0, 1, &viewport); + vkCmdSetScissor(cmdBuf, 0, 1, &scissor); + + PushConstants pushConstants = + { + .frameIdx = r_swapchain->CurrentFrame(), + }; + vkCmdPushConstants(cmdBuf, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstants), &pushConstants); + + vkCmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); + VkDeviceSize zero = 0; + VkDeviceSize wholeSize = VK_WHOLE_SIZE; + VkDeviceSize validationBruhMoment = r_buffer->size; + //vkCmdBindVertexBuffers2(cmdBuf, 0, 1, &r_buffer->buffer, &zero, &wholeSize, nullptr); + vkCmdBindVertexBuffers2(cmdBuf, 0, 1, &r_buffer->buffer, &zero, &validationBruhMoment, nullptr); + vkCmdBindIndexBuffer(cmdBuf, r_buffer->buffer, zero, VulkanIndexType); + + const VkImageMemoryBarrier undefinedToColorBarrier = + { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .image = r_swapchain->Image(), + .subresourceRange = FirstColorMipSubresourceRange, + }; + + vkCmdPipelineBarrier( + cmdBuf, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + 0, + 0, nullptr, + 0, nullptr, + 1, &undefinedToColorBarrier); + + const VkImageMemoryBarrier undefinedToDepthBarrier = + { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + .image = *r_depthImage, + .subresourceRange = FirstDepthMipSubresourceRange, + }; + + vkCmdPipelineBarrier( + cmdBuf, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + 0, + 0, nullptr, + 0, nullptr, + 1, &undefinedToDepthBarrier); + + const VkRenderingAttachmentInfoKHR colorAttachmentInfos[] = + { + { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, + .imageView = r_swapchain->ImageView(), + .imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .clearValue = { .color = { .float32 = { 1.0f, 1.0f, 1.0f, 1.0f } } }, + }, + }; + + const VkRenderingAttachmentInfoKHR depthAttachmentInfo = + { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, + .imageView = depthImageView, + .imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .clearValue = { .color = { .float32 = { 1.0f, 1.0f, 1.0f, 1.0f } } }, + }; + + const VkRenderingInfo renderInfo = + { + .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, + .renderArea = { {}, r_swapchain->Extent() }, + .layerCount = 1, + .colorAttachmentCount = Size(colorAttachmentInfos), + .pColorAttachments = colorAttachmentInfos, + .pDepthAttachment = &depthAttachmentInfo, + }; + vkCmdBeginRendering(cmdBuf, &renderInfo); + { + vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, skyPipeline); + vkCmdDraw(cmdBuf, 3, 1, 0, 0); + + vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + vkCmdDrawIndexedIndirectCount(cmdBuf, indirectBuffer.buffer, indirectBuffer.offset, countBuffer.buffer, countBuffer.offset, 1024u, sizeof(VkDrawIndexedIndirectCommand)); + } + vkCmdEndRendering(cmdBuf); + + const VkImageMemoryBarrier colorToPresentBarrier = + { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + .image = r_swapchain->Image(), + .subresourceRange = FirstColorMipSubresourceRange, + }; + + vkCmdPipelineBarrier( + cmdBuf, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0, + 0, nullptr, + 0, nullptr, + 1, &colorToPresentBarrier); + } + r_renderContext->EndCommandBuffer(cmdBuf); + r_swapchain->Present(); + } + + return 0; +} diff --git a/src/Apps/Tools/meson.build b/src/Apps/Tools/meson.build index f3fde8e..40a9cad 100644 --- a/src/Apps/Tools/meson.build +++ b/src/Apps/Tools/meson.build @@ -1,9 +1,14 @@ -executable('CubeTest', 'CubeTest.cpp', orange_src, orange_shaders, +executable('FrogTest', 'FrogTest.cpp', orange_src, orange_shaders, joltphysics_src, xatlas_src, dependencies : [ sdl2_dep, vulkan_dep, spng_dep, miniz_dep ], - include_directories : [ orange_include ] + include_directories : [ orange_include, xatlas_include, joltphysics_include ] ) -executable('HDRTest', 'HDRTest.cpp', orange_src, orange_shaders, +executable('Lightmapper', 'Lightmapper.cpp', orange_src, orange_shaders, xatlas_src, dependencies : [ sdl2_dep, vulkan_dep, spng_dep, miniz_dep ], - include_directories : [ orange_include ] + include_directories : [ orange_include, xatlas_include, joltphysics_include ] +) + +executable('HDRTest', 'HDRTest.cpp', orange_src, orange_shaders, xatlas_src, + dependencies : [ sdl2_dep, vulkan_dep, spng_dep, miniz_dep ], + include_directories : [ orange_include, xatlas_include, joltphysics_include ] ) diff --git a/src/Orange/Graphics/LightmapAtlas.cpp b/src/Orange/Graphics/LightmapAtlas.cpp new file mode 100644 index 0000000..abe1217 --- /dev/null +++ b/src/Orange/Graphics/LightmapAtlas.cpp @@ -0,0 +1,197 @@ +#include + +namespace orange +{ + Result CreateLightmapAtlasForMesh(MeshData& mesh) + { + LightmapAtlas atlas{ xatlas::Create(), [](xatlas::Atlas *obj) { xatlas::Destroy(obj); } }; + + auto& verts = mesh.vertexData.GetStaticVertices(); + + xatlas::MeshDecl meshDecl; + meshDecl.vertexCount = verts.size(); + meshDecl.vertexPositionData = &verts[0].pos; + meshDecl.vertexPositionStride = sizeof(StaticVertex); + meshDecl.indexCount = (uint32_t)mesh.indices.size(); + meshDecl.indexData = &mesh.indices[0]; + meshDecl.indexFormat = sizeof(IndexType) == sizeof(uint32_t) ? xatlas::IndexFormat::UInt32 : xatlas::IndexFormat::UInt16; + + xatlas::AddMeshError error = xatlas::AddMesh(atlas.get(), meshDecl, 0); + if (error != xatlas::AddMeshError::Success) { + log::info("Error adding mesh: %s", xatlas::StringForEnum(error)); + return Result::Error(BasicErrorCode::Failed); + } + xatlas::AddMeshJoin(atlas.get()); + + log::info("Generating atlas..."); + xatlas::ChartOptions chartOptions; + xatlas::PackOptions packOptions; + //packOptions.resolution = 8192; + xatlas::Generate(atlas.get(), chartOptions, packOptions); + + log::info(" %d charts", atlas->chartCount); + log::info(" %d atlases", atlas->atlasCount); + for (uint32_t i = 0; i < atlas->atlasCount; i++) + log::info(" %d: %0.2f%% utilization", i, atlas->utilization[i] * 100.0f); + log::info(" %ux%u resolution", atlas->width, atlas->height); + + if (atlas->width > 0 && atlas->height > 0) + { + log::info("Updating mesh with new light UVs."); + + for (uint32_t i = 0; i < atlas->meshCount; i++) + { + // TODO: Multi meshes + const xatlas::Mesh &xatlas_mesh = atlas->meshes[i]; + + Vector atlasedVerts; + atlasedVerts.resize(xatlas_mesh.vertexCount); + + // Update vertices with new set. + for (uint32_t j = 0; j < xatlas_mesh.vertexCount; j++) + { + const xatlas::Vertex &v = xatlas_mesh.vertexArray[j]; + + atlasedVerts[j].pos = verts[v.xref].pos; + atlasedVerts[j].texUV = verts[v.xref].texUV; + atlasedVerts[j].lightUV = vec2(v.uv[0] / (float)atlas->width, v.uv[1] / (float)atlas->height); + atlasedVerts[j].normal = verts[v.xref].normal; + } + + verts.resize(atlasedVerts.size()); + atlasedVerts.copy(verts.data()); + + // Update indices + for (uint32_t j = 0; j < xatlas_mesh.indexCount; j++) + { + mesh.indices[j] = xatlas_mesh.indexArray[j]; + } + } + } + + return Result::Success(std::move(atlas)); + } + + // This code is just stolen from the XAtlas sample. + static void RandomColor(uint8_t *color) + { + for (int i = 0; i < 3; i++) + color[i] = uint8_t((rand() % 255 + 192) * 0.5f); + color[3] = 255; + } + + static void SetPixel(uint8_t *dest, int destWidth, int x, int y, const uint8_t *color) + { + uint8_t *pixel = &dest[x * 4 + y * (destWidth * 4)]; + pixel[0] = color[0]; + pixel[1] = color[1]; + pixel[2] = color[2]; + pixel[3] = 255; + } + + // https://github.com/miloyip/line/blob/master/line_bresenham.c + // License: public domain. + static void RasterizeLine(uint8_t *dest, int destWidth, const int *p1, const int *p2, const uint8_t *color) + { + const int dx = abs(p2[0] - p1[0]), sx = p1[0] < p2[0] ? 1 : -1; + const int dy = abs(p2[1] - p1[1]), sy = p1[1] < p2[1] ? 1 : -1; + int err = (dx > dy ? dx : -dy) / 2; + int current[2]; + current[0] = p1[0]; + current[1] = p1[1]; + while (SetPixel(dest, destWidth, current[0], current[1], color), current[0] != p2[0] || current[1] != p2[1]) + { + const int e2 = err; + if (e2 > -dx) { err -= dy; current[0] += sx; } + if (e2 < dy) { err += dx; current[1] += sy; } + } + } + + /* + https://github.com/ssloy/tinyrenderer/wiki/Lesson-2:-Triangle-rasterization-and-back-face-culling + Copyright Dmitry V. Sokolov + + This software is provided 'as-is', without any express or implied warranty. + In no event will the authors be held liable for any damages arising from the use of this software. + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it freely, + subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + */ + static void RasterizeTriangle(uint8_t *dest, int destWidth, const int *t0, const int *t1, const int *t2, const uint8_t *color) + { + if (t0[1] > t1[1]) std::swap(t0, t1); + if (t0[1] > t2[1]) std::swap(t0, t2); + if (t1[1] > t2[1]) std::swap(t1, t2); + int total_height = t2[1] - t0[1]; + for (int i = 0; i < total_height; i++) { + bool second_half = i > t1[1] - t0[1] || t1[1] == t0[1]; + int segment_height = second_half ? t2[1] - t1[1] : t1[1] - t0[1]; + float alpha = (float)i / total_height; + float beta = (float)(i - (second_half ? t1[1] - t0[1] : 0)) / segment_height; + int A[2], B[2]; + for (int j = 0; j < 2; j++) { + A[j] = int(t0[j] + (t2[j] - t0[j]) * alpha); + B[j] = int(second_half ? t1[j] + (t2[j] - t1[j]) * beta : t0[j] + (t1[j] - t0[j]) * beta); + } + if (A[0] > B[0]) std::swap(A, B); + for (int j = A[0]; j <= B[0]; j++) + SetPixel(dest, destWidth, j, t0[1] + i, color); + } + } + + Vector GenerateDebugAtlasTexture(const LightmapAtlas& lightmapAtlas) + { + const xatlas::Atlas *atlas = lightmapAtlas.get(); + Vector outputChartsImage; + + if (atlas->width > 0 && atlas->height > 0) + { + printf("Rasterizing result...\n"); + + // Dump images. + const uint32_t imageDataSize = atlas->width * atlas->height * 4; + outputChartsImage.resize(atlas->atlasCount * imageDataSize); + for (uint32_t i = 0; i < atlas->meshCount; i++) + { + const xatlas::Mesh &mesh = atlas->meshes[i]; + + const uint8_t white[] = { 255, 255, 255, 255 }; + + // Rasterize mesh charts. + for (uint32_t j = 0; j < mesh.chartCount; j++) + { + const xatlas::Chart *chart = &mesh.chartArray[j]; + uint8_t color[4]; + RandomColor(color); + for (uint32_t k = 0; k < chart->faceCount; k++) + { + const uint32_t face = chart->faceArray[k]; + + const uint32_t faceVertexCount = 3; + const uint32_t faceFirstIndex = face * 3; + + int verts[255][2]; + for (uint32_t l = 0; l < faceVertexCount; l++) + { + const xatlas::Vertex &v = mesh.vertexArray[mesh.indexArray[faceFirstIndex + l]]; + verts[l][0] = int(v.uv[0]); + verts[l][1] = int(v.uv[1]); + } + uint8_t *imageData = &outputChartsImage[chart->atlasIndex * imageDataSize]; + + RasterizeTriangle(imageData, atlas->width, verts[0], verts[1], verts[2], color); + + for (uint32_t l = 0; l < faceVertexCount; l++) + RasterizeLine(imageData, atlas->width, verts[l], verts[(l + 1) % faceVertexCount], white); + } + } + } + } + + return outputChartsImage; + } +} \ No newline at end of file diff --git a/src/Orange/Graphics/Mesh.cpp b/src/Orange/Graphics/Mesh.cpp index dc9b7c3..d36918c 100644 --- a/src/Orange/Graphics/Mesh.cpp +++ b/src/Orange/Graphics/Mesh.cpp @@ -14,7 +14,7 @@ namespace orange size_t operator() (const StaticVertex& key) const { size_t hash = 0; - return hash_combine(hash, key.pos.x, key.pos.y, key.pos.z, key.uv.x, key.uv.y, key.normal.x, key.normal.y, key.normal.z); + return hash_combine(hash, key.pos.x, key.pos.y, key.pos.z, key.texUV.x, key.texUV.y, key.lightUV.x, key.lightUV.y, key.normal.x, key.normal.y, key.normal.z); } }; @@ -91,7 +91,7 @@ namespace orange StaticVertex vertex = { .pos = indices[i][0] != -1 ? positions[indices[i][0]] : vec3{}, - .uv = indices[i][1] != -1 ? uvs [indices[i][1]] : vec2{}, + .texUV = indices[i][1] != -1 ? uvs [indices[i][1]] : vec2{}, .normal = indices[i][2] != -1 ? normals [indices[i][2]] : vec3{}, }; diff --git a/src/Orange/Render/Shaders/fs_HDRTest.frag b/src/Orange/Render/Shaders/fs_HDRTest.frag index 896c7a3..52959c5 100644 --- a/src/Orange/Render/Shaders/fs_HDRTest.frag +++ b/src/Orange/Render/Shaders/fs_HDRTest.frag @@ -178,6 +178,12 @@ void main() outColor = vec4(nitsToPq(sdfOutColor.rgb), 1.0); } else if (test == nextTest++) + { + vec3 color = coords.x >= 0.5 ? vec3(0.0, targetNits, 0.0) : vec3(targetNits, 0.0, 0.0); + + outColor = vec4(nitsToPq(color), 1.0); + } + else if (test == nextTest++) { const vec3 start = vec3(0.0); const vec3 end = vec3(targetNits); diff --git a/src/Orange/Render/Shaders/fs_Mesh.frag b/src/Orange/Render/Shaders/fs_Mesh.frag index efa3461..3b97247 100644 --- a/src/Orange/Render/Shaders/fs_Mesh.frag +++ b/src/Orange/Render/Shaders/fs_Mesh.frag @@ -5,11 +5,15 @@ layout(set = 0, binding = 1) uniform sampler s_sampler; layout(set = 0, binding = 3) uniform texture2D s_images[]; layout(location = 0) in flat uint meshIdx; -layout(location = 1) in vec2 uv; +layout(location = 1) in vec2 uv_albedo; +layout(location = 2) in vec2 uv_light; layout(location = 0) out vec4 outColor; void main() { - outColor = texture(sampler2D(s_images[nonuniformEXT(meshIdx)], s_sampler), uv); + //outColor = texture(sampler2D(s_images[nonuniformEXT(meshIdx)], s_sampler), uv); + //outColor = texture(sampler2D(s_images[0], s_sampler), uv_albedo); + outColor = texture(sampler2D(s_images[1], s_sampler), uv_light); + //outColor = texture(sampler2D(s_images[0], s_sampler), uv_albedo) * texture(sampler2D(s_images[1], s_sampler), uv_light); } \ No newline at end of file diff --git a/src/Orange/Render/Shaders/vs_Mesh.vert b/src/Orange/Render/Shaders/vs_Mesh.vert index f33e54e..3fe0e35 100644 --- a/src/Orange/Render/Shaders/vs_Mesh.vert +++ b/src/Orange/Render/Shaders/vs_Mesh.vert @@ -6,11 +6,13 @@ #include "common_vs.h" layout(location = 0) in vec3 i_pos; -layout(location = 1) in vec2 i_uv; -layout(location = 2) in vec3 i_normal; +layout(location = 1) in vec2 i_uv_albedo; +layout(location = 2) in vec2 i_uv_lightmap; +layout(location = 3) in vec3 i_normal; layout(location = 0) out flat uint o_meshIdx; -layout(location = 1) out vec2 o_uv; +layout(location = 1) out vec2 o_uv_albedo; +layout(location = 2) out vec2 o_uv_lightmap; void main() { @@ -19,5 +21,6 @@ void main() u_renderable.frame[p_constants.frame].renderables[gl_DrawIDARB].world * vec4(i_pos, 1.0); o_meshIdx = u_renderable.frame[p_constants.frame].renderables[gl_DrawIDARB].meshIdx; - o_uv = i_uv; + o_uv_albedo = i_uv_albedo; + o_uv_lightmap = i_uv_lightmap; } \ No newline at end of file diff --git a/src/Orange/Render/Window.cpp b/src/Orange/Render/Window.cpp index 55c0fa7..ecd9985 100644 --- a/src/Orange/Render/Window.cpp +++ b/src/Orange/Render/Window.cpp @@ -19,7 +19,7 @@ namespace orange } SDL_Window* window = nullptr; - if (!(window = SDL_CreateWindow("Orange", 0, 0, 1280, 800, SDL_WINDOW_VULKAN))) + if (!(window = SDL_CreateWindow("Orange", 0, 0, 4, 4, SDL_WINDOW_VULKAN))) { log::err("Failed to create SDL window: %s", Window::GetError()); return Result::Error(BasicErrorCode::Failed); diff --git a/src/Orange/meson.build b/src/Orange/meson.build index a331cad..0d17a66 100644 --- a/src/Orange/meson.build +++ b/src/Orange/meson.build @@ -14,6 +14,7 @@ orange_src = files([ 'Formats/KeyValues.cpp', + 'Graphics/LightmapAtlas.cpp', 'Graphics/Mesh.cpp', 'Render/Input.cpp', diff --git a/thirdparty/JoltPhysics b/thirdparty/JoltPhysics new file mode 160000 index 0000000..5d960e7 --- /dev/null +++ b/thirdparty/JoltPhysics @@ -0,0 +1 @@ +Subproject commit 5d960e76b3ed29abf2f3c55decb1f58d29bd42bb diff --git a/thirdparty/xatlas b/thirdparty/xatlas new file mode 160000 index 0000000..f700c77 --- /dev/null +++ b/thirdparty/xatlas @@ -0,0 +1 @@ +Subproject commit f700c7790aaa030e794b52ba7791a05c085faf0c