Compare commits

..

12 Commits

Author SHA1 Message Date
Thraix 72c2bb5336 Add StateMachine class 2026-06-28 20:44:16 +02:00
Thraix f27911fe28 Fix enums printing " for first and last enum 2026-06-26 07:26:46 +02:00
Thraix 9a3b3aa13c Rework tracing system and enum creators
- Rework tracing system, now using "{}" for formatting instead of the
  standard %s,%d,%f formatting that C++ uses.
- Rework enums creators to not take in namespace
- Fix single use CommandBuffers sometimes failing due to indexing them
  with the current frame in flight
- Add DropEvent to Window
2026-05-03 12:40:47 +02:00
Thraix 9d5a5314a7 Rework ECS framework
- Add queue systems when adding/removing components and systems
- Add GlobalData to ECSManager, used to store data that is not specific
  to entities
- Add View class, used to for loop all entities that contains the given
  Components
- Rework how signaling works
2026-02-07 18:25:13 +01:00
Thraix e5866b2dcb Format all files based on clang-format file 2026-01-28 23:04:31 +01:00
Thraix 6c1c558998 Add EcsManager::Find() 2025-08-24 22:05:09 +02:00
Thraix 71e02f3015 Fix multiple creation of runtime framebuffers
- Framebuffer names are now generated based on Uuids, as such we can
  create multiple runtime Framebuffers
- Framebuffers now uses ints instead of uint32_t, to avoid issues where
  we do "-framebuffer.GetWidth()", which will return an odd uint32_t
  value
- Add some additional AssetRef constructors
2025-08-19 20:14:04 +02:00
Thraix 3c4365083f Add GetWidth and GetHeight to Texture2D 2025-08-13 21:25:56 +02:00
Thraix 717f452908 Set all descriptor sets when calling Pipeline::SetDescriptorSets
- When calling Pipeline::SetDescriptorSets, it now sets all
  descriptor sets for all frames that can be in flight. Meaning
  SetDescriptorSets doesn't need to be called each render pass.
2025-08-12 22:18:23 +02:00
Thraix aca495960f Fix varius minor issues
- Asset will now generate a uuid if it is not inside the meta file
- Device cleanup/idling improved
- FileSystem now prints which file failed to open
- Renderer header file now has the same parameter names as the source file
2025-08-10 20:18:41 +02:00
Tim Håkansson 4d2dfce31c Add Linux support
- Add linux build system using MakeGen
- Fix a swapchain validation error, likelydue to my linux system using a
  different vulkan version
- Make DescriptorPool take in amount of descriptors it needs, instead of
  allocating a mass amount for every pool, causing loads of RAM/VRAM usage
2025-08-09 21:42:15 +02:00
Thraix ecc11f07db Improve vulkan resource freeing
and some minor improvements to the Renderer, now taking in an
AssetRef<Pipeline> as parameter.
2024-10-11 20:06:22 +02:00
157 changed files with 3591 additions and 1493 deletions
+334
View File
@@ -0,0 +1,334 @@
---
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: true
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseArrows: false
AlignCaseColons: false
AlignConsecutiveTableGenBreakingDAGArgColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenCondOperatorColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenDefinitionColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowShortBlocksOnASingleLine: Never
AllowShortCaseExpressionOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AllowShortNamespacesOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AttributeMacros:
- __capability
- absl_nonnull
- absl_nullable
- absl_nullability_unknown
BinPackArguments: false
BinPackLongBracedList: true
BinPackParameters: false
BitFieldColonSpacing: Both
BracedInitializerIndentWidth: -1
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakAfterReturnType: None
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Allman
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTemplateCloser: false
BreakBeforeTernaryOperators: true
BreakBinaryOperations: Never
BreakConstructorInitializers: BeforeColon
BreakFunctionDefinitionParameters: false
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
BreakTemplateDeclarations: Yes
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
EnumTrailingComma: Leave
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: true
IndentExportBlock: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLines:
AtEndOfFile: false
AtStartOfBlock: false
AtStartOfFile: true
KeepFormFeed: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MainIncludeChar: Quote
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
OneLineFormatOffRegex: ''
PackConstructorInitializers: Never
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakBeforeMemberAccess: 150
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakScopeResolution: 500
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
PPIndentWidth: -1
QualifierAlignment: Leave
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: pb
BasedOnStyle: google
ReferenceAlignment: Pointer
ReflowComments: Always
RemoveBracesLLVM: false
RemoveEmptyLinesInUnwrappedLines: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Always
ShortNamespaceLines: 1
SkipMacroDefinitionBody: false
SortIncludes:
Enabled: true
IgnoreCase: false
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterOperatorKeyword: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterNot: false
AfterOverloadedOperator: false
AfterPlacementOperator: true
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
ExceptDoubleParentheses: false
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: Auto
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TableGenBreakInsideDAGArg: DontBreak
TabWidth: 2
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
WrapNamespaceBodyWithEmptyLines: Leave
...
+2
View File
@@ -9,3 +9,5 @@ bin/
.cache .cache
libs libs
imgui.ini imgui.ini
Makefile
compile_flags.txt
+1 -1
View File
@@ -202,7 +202,6 @@
<ClCompile Include="src\copium\event\WindowResizeEvent.cpp" /> <ClCompile Include="src\copium\event\WindowResizeEvent.cpp" />
<ClCompile Include="src\copium\mesh\Mesh.cpp" /> <ClCompile Include="src\copium\mesh\Mesh.cpp" />
<ClCompile Include="src\copium\renderer\LineVertex.cpp" /> <ClCompile Include="src\copium\renderer\LineVertex.cpp" />
<ClCompile Include="src\copium\renderer\LineVertex.h" />
<ClCompile Include="src\copium\pipeline\ShaderBinding.cpp" /> <ClCompile Include="src\copium\pipeline\ShaderBinding.cpp" />
<ClCompile Include="src\copium\renderer\Batch.cpp" /> <ClCompile Include="src\copium\renderer\Batch.cpp" />
<ClCompile Include="src\copium\renderer\LineRenderer.cpp" /> <ClCompile Include="src\copium\renderer\LineRenderer.cpp" />
@@ -287,6 +286,7 @@
<ClInclude Include="src\copium\pipeline\ShaderBinding.h" /> <ClInclude Include="src\copium\pipeline\ShaderBinding.h" />
<ClInclude Include="src\copium\renderer\Batch.h" /> <ClInclude Include="src\copium\renderer\Batch.h" />
<ClInclude Include="src\copium\renderer\LineRenderer.h" /> <ClInclude Include="src\copium\renderer\LineRenderer.h" />
<ClInclude Include="src\copium\renderer\LineVertex.h" />
<ClInclude Include="src\copium\renderer\Renderer.h" /> <ClInclude Include="src\copium\renderer\Renderer.h" />
<ClInclude Include="src\copium\renderer\RendererVertex.h" /> <ClInclude Include="src\copium\renderer\RendererVertex.h" />
<ClInclude Include="src\copium\sampler\DepthAttachment.h" /> <ClInclude Include="src\copium\sampler\DepthAttachment.h" />
+3 -3
View File
@@ -216,9 +216,6 @@
<ClCompile Include="src\copium\event\ViewportResize.cpp"> <ClCompile Include="src\copium\event\ViewportResize.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\copium\renderer\LineVertex.h">
<Filter>Header Files</Filter>
</ClCompile>
<ClCompile Include="src\copium\renderer\LineRenderer.cpp"> <ClCompile Include="src\copium\renderer\LineRenderer.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@@ -479,5 +476,8 @@
<ClInclude Include="src\copium\renderer\LineRenderer.h"> <ClInclude Include="src\copium\renderer\LineRenderer.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\copium\renderer\LineVertex.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>
+53
View File
@@ -0,0 +1,53 @@
<makegen>
<configuration name="Release">
<define>MSDF_ATLAS_PUBLIC=</define>
<define>GLM_FORCE_LEFT_HANDED</define>
<define>GLM_FORCE_RADIANS</define>
<define>GLM_FORCE_DEPTH_ZERO_TO_ONE</define>
<dependency>../ext/projects/imgui/</dependency>
<dependency>../ext/projects/msdf-atlas-gen/</dependency>
<dependency>../ext/projects/msdfgen-core/</dependency>
<dependency>../ext/projects/msdfgen-ext/</dependency>
<generatehfile>false</generatehfile>
<outputdir>bin/Release/</outputdir>
<outputname>libcopium.so</outputname>
<outputtype>sharedlibrary</outputtype>
<projectname>Copium Engine</projectname>
<srcdir>src/</srcdir>
<includedir>src/</includedir>
<includedir>../ext/repos/imgui/</includedir>
<includedir>../ext/repos/imgui/backends/</includedir>
<includedir>../ext/repos/freetype/</includedir>
<includedir>../ext/repos/msdf-atlas-gen/msdfgen/</includedir>
<includedir>../ext/repos/msdf-atlas-gen/</includedir>
<includedir>../ext/repos/stb/</includedir>
</configuration>
<configuration name="Debug">
<cflag>-g3</cflag>
<cflag>-w</cflag>
<define>_DEBUG</define>
<define>MSDF_ATLAS_PUBLIC=</define>
<define>GLM_FORCE_LEFT_HANDED</define>
<define>GLM_FORCE_RADIANS</define>
<define>GLM_FORCE_DEPTH_ZERO_TO_ONE</define>
<dependency>../ext/projects/imgui/</dependency>
<dependency>../ext/projects/msdf-atlas-gen/</dependency>
<dependency>../ext/projects/msdfgen-core/</dependency>
<dependency>../ext/projects/msdfgen-ext/</dependency>
<generatehfile>false</generatehfile>
<outputdir>bin/Debug/</outputdir>
<outputname>libcopium.so</outputname>
<outputtype>sharedlibrary</outputtype>
<projectname>Copium Engine</projectname>
<srcdir>src/</srcdir>
<includedir>src/</includedir>
<includedir>../ext/repos/imgui/</includedir>
<includedir>../ext/repos/imgui/backends/</includedir>
<includedir>../ext/repos/freetype/</includedir>
<includedir>../ext/repos/msdf-atlas-gen/msdfgen/</includedir>
<includedir>../ext/repos/msdf-atlas-gen/</includedir>
<includedir>../ext/repos/stb/</includedir>
</configuration>
<target>Debug</target>
<version>v1.3.4</version>
</makegen>
+4 -4
View File
@@ -1,17 +1,17 @@
#pragma once #pragma once
#include "copium/asset/AssetMeta.h"
#include "copium/util/MetaFile.h"
#include "copium/util/Uuid.h"
#include <stdint.h> #include <stdint.h>
#include "copium/asset/AssetMeta.h"
#include "copium/util/Uuid.h"
namespace Copium namespace Copium
{ {
class Asset class Asset
{ {
friend class AssetManager; friend class AssetManager;
public: public:
Asset(); Asset();
virtual ~Asset(); virtual ~Asset();
+13 -3
View File
@@ -1,6 +1,9 @@
#include "copium/asset/AssetFile.h" #include "copium/asset/AssetFile.h"
#include <fstream>
#include "copium/util/FileSystem.h" #include "copium/util/FileSystem.h"
#include "copium/util/Trace.h"
namespace Copium namespace Copium
{ {
@@ -28,7 +31,7 @@ namespace Copium
Load(metaFile, assetType); Load(metaFile, assetType);
return; return;
} }
CP_WARN("Unknown Asset type in file: %s", metaFile.GetFilePath().c_str()); CP_WARN("Unknown Asset type in file: {}", metaFile.GetFilePath());
} }
const std::string& AssetFile::GetPath() const const std::string& AssetFile::GetPath() const
@@ -41,9 +44,16 @@ namespace Copium
return uuid; return uuid;
} }
void AssetFile::Load(const MetaFile& metaFile, const std::string& className) void AssetFile::Load(MetaFile& metaFile, const std::string& className)
{ {
const MetaFileClass& metaClass = metaFile.GetMetaClass(className); MetaFileClass& metaClass = metaFile.GetMetaClass(className);
if (!metaClass.HasValue("uuid"))
{
CP_WARN("Asset ({}) has no UUID assigned, generating new one", path);
metaClass.AddValue("uuid", Uuid{}.ToString());
std::fstream file{path};
file << metaFile;
}
uuid = Uuid{metaClass.GetValue("uuid")}; uuid = Uuid{metaClass.GetValue("uuid")};
dateModified = FileSystem::DateModified(path); dateModified = FileSystem::DateModified(path);
} }
+3 -2
View File
@@ -1,6 +1,5 @@
#pragma once #pragma once
#include "copium/asset/AssetMeta.h"
#include "copium/util/MetaFile.h" #include "copium/util/MetaFile.h"
#include "copium/util/Uuid.h" #include "copium/util/Uuid.h"
@@ -9,6 +8,7 @@ namespace Copium
class AssetFile class AssetFile
{ {
friend class AssetManager; friend class AssetManager;
private: private:
static std::vector<std::string> assetTypes; static std::vector<std::string> assetTypes;
std::string path; std::string path;
@@ -23,8 +23,9 @@ namespace Copium
const std::string& GetPath() const; const std::string& GetPath() const;
Uuid GetUuid() const; Uuid GetUuid() const;
private: private:
void Load(const MetaFile& metaFile, const std::string& className); void Load(MetaFile& metaFile, const std::string& className);
static void RegisterAssetType(const std::string& assetType); static void RegisterAssetType(const std::string& assetType);
}; };
} }
+14 -7
View File
@@ -1,7 +1,7 @@
#pragma once #pragma once
#include "copium/asset/AssetMeta.h"
#include "copium/asset/AssetManager.h" #include "copium/asset/AssetManager.h"
#include "copium/asset/AssetMeta.h"
namespace Copium namespace Copium
{ {
@@ -11,27 +11,33 @@ namespace Copium
public: public:
AssetHandle() AssetHandle()
: id{NULL_ASSET_ID} : id{NULL_ASSET_ID}
{} {
}
AssetHandle(const std::string& assetName) AssetHandle(const std::string& assetName)
: id{AssetManager::LoadAsset(assetName).GetId()} : id{AssetManager::LoadAsset(assetName).GetId()}
{} {
}
AssetHandle(const Uuid& uuid) AssetHandle(const Uuid& uuid)
: id{AssetManager::LoadAsset(uuid).GetId()} : id{AssetManager::LoadAsset(uuid).GetId()}
{} {
}
AssetHandle(AssetType& asset) AssetHandle(AssetType& asset)
: id{AssetManager::DuplicateAsset(asset.GetId())} : id{AssetManager::DuplicateAsset(asset.GetId())}
{} {
}
AssetHandle(const std::string& name, std::unique_ptr<AssetType>&& runtimeAsset) AssetHandle(const std::string& name, std::unique_ptr<AssetType>&& runtimeAsset)
: id{AssetManager::RegisterRuntimeAsset(name, std::move(runtimeAsset)).GetId()} : id{AssetManager::RegisterRuntimeAsset(name, std::move(runtimeAsset)).GetId()}
{} {
}
AssetHandle(AssetId id) AssetHandle(AssetId id)
: id{AssetManager::DuplicateAsset(id)} : id{AssetManager::DuplicateAsset(id)}
{} {
}
AssetId GetId() const AssetId GetId() const
{ {
@@ -53,6 +59,7 @@ namespace Copium
{ {
return id != NULL_ASSET_ID; return id != NULL_ASSET_ID;
} }
private: private:
AssetId id; AssetId id;
}; };
+26 -26
View File
@@ -1,13 +1,10 @@
#include "copium/asset/AssetManager.h" #include "copium/asset/AssetManager.h"
#include "copium/buffer/Framebuffer.h"
#include "copium/sampler/ColorAttachment.h"
#include "copium/sampler/Texture2D.h"
#include "copium/util/Common.h"
#include "copium/util/MetaFile.h"
#include <fstream>
#include <filesystem> #include <filesystem>
#include <fstream>
#include "copium/util/MetaFile.h"
#include "copium/util/Trace.h"
namespace Copium namespace Copium
{ {
@@ -30,15 +27,19 @@ namespace Copium
if (std::filesystem::is_directory(it->path())) if (std::filesystem::is_directory(it->path()))
continue; continue;
std::filesystem::path assetDirPath{assetDir}; std::filesystem::path assetDirPath{assetDir};
std::string assetPath = assetDir + "/" + std::filesystem::absolute(it->path()).string().substr(std::filesystem::absolute(assetDirPath).string().size() + 1).c_str(); std::string assetPath = assetDir + "/" +
std::filesystem::absolute(it->path())
.string()
.substr(std::filesystem::absolute(assetDirPath).string().size() + 1)
.c_str();
try try
{ {
CP_DEBUG("Registering Asset: %s", assetPath.c_str()); CP_DEBUG("Registering Asset: {}", assetPath);
cachedAssetFiles.emplace_back(assetPath); cachedAssetFiles.emplace_back(assetPath);
} }
catch (RuntimeException& exception) catch (RuntimeException& exception)
{ {
CP_ERR("Failed to register Asset: %s", assetPath.c_str()); CP_ERR("Failed to register Asset: {}", assetPath);
} }
} }
} }
@@ -67,7 +68,7 @@ namespace Copium
Asset& AssetManager::LoadAsset(const std::string& assetPath) Asset& AssetManager::LoadAsset(const std::string& assetPath)
{ {
CP_DEBUG("Loading Asset: %s", assetPath.c_str()); CP_DEBUG("Loading Asset: {}", assetPath);
for (auto& dir : assetDirs) for (auto& dir : assetDirs)
{ {
@@ -79,13 +80,12 @@ namespace Copium
return LoadAssetFromPath(path); return LoadAssetFromPath(path);
} }
CP_ABORT("Unknown Asset: %s", assetPath.c_str()); CP_ABORT("Unknown Asset: {}", assetPath);
} }
Asset& AssetManager::LoadAsset(const Uuid& uuid) Asset& AssetManager::LoadAsset(const Uuid& uuid)
{ {
CP_DEBUG("Loading uuid Asset: %s", uuid.ToString().c_str()); CP_DEBUG("Loading uuid Asset: {}", uuid);
for (auto&& assetFile : cachedAssetFiles) for (auto&& assetFile : cachedAssetFiles)
{ {
if (assetFile.NeedReload()) if (assetFile.NeedReload())
@@ -96,16 +96,16 @@ namespace Copium
return LoadAssetFromPath(assetFile.GetPath()); return LoadAssetFromPath(assetFile.GetPath());
} }
CP_ABORT("Asset not found with uuid=%s", uuid.ToString().c_str()); CP_ABORT("Asset not found with uuid={}", uuid);
// TODO: Reload the assetCache to see if a new file has appeared with that uuid // TODO: Reload the assetCache to see if a new file has appeared with that uuid
} }
AssetId AssetManager::DuplicateAsset(AssetId id) AssetId AssetManager::DuplicateAsset(AssetId id)
{ {
auto it = assets.find(id); auto it = assets.find(id);
CP_ASSERT(it != assets.end(), "Failed to find asset with id=%d", id); CP_ASSERT(it != assets.end(), "Failed to find asset with id={}", id);
CP_DEBUG("Duplicating asset: %s", it->second->GetName().c_str()); CP_DEBUG("Duplicating asset: {}", it->second->GetName());
it->second->metaData.loadCount++; it->second->metaData.loadCount++;
return id; return id;
} }
@@ -118,7 +118,7 @@ namespace Copium
CP_WARN("Asset not loaded"); CP_WARN("Asset not loaded");
return; return;
} }
CP_DEBUG("Unloading Asset: %s (%d instances left)", it->second->GetName().c_str(), it->second->metaData.loadCount - 1); CP_DEBUG("Unloading Asset: {} ({} instances left)", it->second->GetName(), it->second->metaData.loadCount - 1);
it->second->metaData.loadCount--; it->second->metaData.loadCount--;
if (it->second->metaData.loadCount > 0) if (it->second->metaData.loadCount > 0)
@@ -140,7 +140,7 @@ namespace Copium
{ {
if (assets.empty()) if (assets.empty())
return; return;
CP_WARN("Performing auto clean up of %d non unloaded assets", assets.size()); CP_WARN("Performing auto clean up of {} non unloaded assets", assets.size());
while (!assets.empty()) while (!assets.empty())
{ {
UnloadAsset(assets.begin()->second->GetId()); UnloadAsset(assets.begin()->second->GetId());
@@ -149,18 +149,18 @@ namespace Copium
CP_ASSERT(pathToAssetCache.empty(), "Path To Asset Cache not empty after full unload"); CP_ASSERT(pathToAssetCache.empty(), "Path To Asset Cache not empty after full unload");
} }
Asset& AssetManager::RegisterRuntimeAsset(const std::string& name, std::unique_ptr<Asset>&& asset) Asset& AssetManager::RegisterRuntimeAsset(const std::string& name, const Uuid& uuid, std::unique_ptr<Asset>&& asset)
{ {
CP_DEBUG("Registering Runtime Asset: %s", name.c_str()); CP_DEBUG("Registering Runtime Asset: {}", name);
auto it = nameToAssetCache.find(name); auto it = nameToAssetCache.find(name);
CP_ASSERT(it == nameToAssetCache.end(), "Asset already exists: %s", name); CP_ASSERT(it == nameToAssetCache.end(), "Asset already exists: {}", name);
AssetId id = runtimeAssetId++; AssetId id = runtimeAssetId++;
Asset* asset2 = assets.emplace(id, std::move(asset)).first->second.get(); Asset* asset2 = assets.emplace(id, std::move(asset)).first->second.get();
asset2->metaData.id = id; asset2->metaData.id = id;
asset2->metaData.name = name; asset2->metaData.name = name;
asset2->metaData.uuid = Uuid(); asset2->metaData.uuid = uuid;
asset2->metaData.isRuntime = true; asset2->metaData.isRuntime = true;
nameToAssetCache.emplace(name, id); nameToAssetCache.emplace(name, id);
return *asset2; return *asset2;
@@ -168,7 +168,7 @@ namespace Copium
Asset& AssetManager::LoadAssetFromPath(const std::string& filepath) Asset& AssetManager::LoadAssetFromPath(const std::string& filepath)
{ {
CP_DEBUG("Loading Asset: %s", filepath.c_str()); CP_DEBUG("Loading Asset: {}", filepath);
auto it = pathToAssetCache.find(filepath); auto it = pathToAssetCache.find(filepath);
if (it != pathToAssetCache.end()) if (it != pathToAssetCache.end())
{ {
@@ -180,9 +180,9 @@ namespace Copium
MetaFile metaFile{filepath}; MetaFile metaFile{filepath};
for (auto& assetType : assetTypes) for (auto& assetType : assetTypes)
{ {
if(metaFile.HasMetaClass(assetType.first)) if (metaFile.HasMetaClass(assetType.first))
return assetType.second(metaFile, assetType.first); return assetType.second(metaFile, assetType.first);
} }
CP_ABORT("Unknown Asset type: %s", filepath.c_str()); CP_ABORT("Unknown Asset type: {}", filepath);
} }
} }
+24 -8
View File
@@ -1,18 +1,20 @@
#pragma once #pragma once
#include "copium/asset/Asset.h"
#include "copium/asset/AssetFile.h"
#include "copium/util/Common.h"
#include <functional> #include <functional>
#include <map> #include <map>
#include <memory>
#include <vector> #include <vector>
#include "copium/asset/Asset.h"
#include "copium/asset/AssetFile.h"
#include "copium/util/Trace.h"
namespace Copium namespace Copium
{ {
class AssetManager class AssetManager
{ {
CP_STATIC_CLASS(AssetManager); CP_STATIC_CLASS(AssetManager);
private: private:
using CreateAssetFunc = std::function<Asset&(const MetaFile& metaFile, const std::string& str)>; using CreateAssetFunc = std::function<Asset&(const MetaFile& metaFile, const std::string& str)>;
static std::map<std::string, CreateAssetFunc> assetTypes; static std::map<std::string, CreateAssetFunc> assetTypes;
@@ -33,14 +35,16 @@ namespace Copium
static Asset& LoadAsset(const Uuid& uuid); static Asset& LoadAsset(const Uuid& uuid);
static AssetId DuplicateAsset(AssetId id); static AssetId DuplicateAsset(AssetId id);
static void UnloadAsset(AssetId id); static void UnloadAsset(AssetId id);
static Asset& RegisterRuntimeAsset(const std::string& name, std::unique_ptr<Asset>&& asset); static Asset& RegisterRuntimeAsset(const std::string& name, const Uuid& uuid, std::unique_ptr<Asset>&& asset);
static const std::vector<AssetFile>& GetAssetFiles(); static const std::vector<AssetFile>& GetAssetFiles();
static void Cleanup(); static void Cleanup();
template <typename AssetType> template <typename AssetType>
static void RegisterAssetType(const std::string& assetType) static void RegisterAssetType(const std::string& assetType)
{ {
CP_ASSERT(assetTypes.emplace(assetType, &AssetManager::CreateAsset<AssetType>).second, "Asset type already exists: %s", assetType.c_str()); CP_ASSERT(assetTypes.emplace(assetType, &AssetManager::CreateAsset<AssetType>).second,
"Asset type already exists: {}",
assetType.c_str());
AssetFile::RegisterAssetType(assetType); AssetFile::RegisterAssetType(assetType);
} }
@@ -70,13 +74,25 @@ namespace Copium
} }
template <typename AssetT> template <typename AssetT>
static AssetT& RegisterRuntimeAsset(const std::string& name, std::unique_ptr<AssetT>&& assetT) static AssetT& RegisterRuntimeAsset(const std::string& name, const Uuid& uuid, std::unique_ptr<AssetT>&& assetT)
{ {
AssetT* ptr = assetT.release(); AssetT* ptr = assetT.release();
Asset& asset = RegisterRuntimeAsset(name, std::unique_ptr<Asset>((Asset*)ptr)); Asset& asset = RegisterRuntimeAsset(name, uuid, std::unique_ptr<Asset>((Asset*)ptr));
return *(AssetT*)&asset; return *(AssetT*)&asset;
} }
template <typename AssetT>
static AssetT& RegisterRuntimeAsset(const std::string& name, std::unique_ptr<AssetT>&& assetT)
{
return RegisterRuntimeAsset(name, Uuid{}, std::move(assetT));
}
template <typename AssetT>
static AssetT& RegisterRuntimeAsset(const Uuid& uuid, std::unique_ptr<AssetT>&& assetT)
{
return RegisterRuntimeAsset(uuid.ToString(), uuid, std::move(assetT));
}
private: private:
static Asset& LoadAssetFromPath(const std::string& filepath); static Asset& LoadAssetFromPath(const std::string& filepath);
+3 -2
View File
@@ -1,10 +1,11 @@
#pragma once #pragma once
#include "copium/util/Uuid.h"
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include "copium/util/Uuid.h"
namespace Copium namespace Copium
{ {
static constexpr int NULL_ASSET_ID = 0; static constexpr int NULL_ASSET_ID = 0;
+39 -11
View File
@@ -10,27 +10,53 @@ namespace Copium
public: public:
AssetRef() AssetRef()
: id{std::shared_ptr<AssetId>(new AssetId(NULL_ASSET_ID), AssetIdUnloader{})} : id{std::shared_ptr<AssetId>(new AssetId(NULL_ASSET_ID), AssetIdUnloader{})}
{} {
}
AssetRef(const std::string& assetName) explicit AssetRef(const std::string& assetName)
: id{std::shared_ptr<AssetId>(new AssetId(AssetManager::LoadAsset(assetName).GetId()), AssetIdUnloader{})} : id{std::shared_ptr<AssetId>(new AssetId(AssetManager::LoadAsset(assetName).GetId()), AssetIdUnloader{})}
{} {
}
AssetRef(const Uuid& uuid) explicit AssetRef(const Uuid& uuid)
: id{std::shared_ptr<AssetId>(new AssetId(AssetManager::LoadAsset(uuid).GetId()), AssetIdUnloader{})} : id{std::shared_ptr<AssetId>(new AssetId(AssetManager::LoadAsset(uuid).GetId()), AssetIdUnloader{})}
{} {
}
AssetRef(AssetType& asset) explicit AssetRef(AssetType& asset)
: id{std::shared_ptr<AssetId>(new AssetId(AssetManager::DuplicateAsset(asset.GetId())), AssetIdUnloader{})} : id{std::shared_ptr<AssetId>(new AssetId(AssetManager::DuplicateAsset(asset.GetId())), AssetIdUnloader{})}
{} {
}
explicit AssetRef(std::unique_ptr<AssetType>&& runtimeAsset)
: id{std::shared_ptr<AssetId>(
new AssetId(AssetManager::RegisterRuntimeAsset(Uuid{}, std::move(runtimeAsset)).GetId()), AssetIdUnloader{})}
{
}
AssetRef(const Uuid& uuid, std::unique_ptr<AssetType>&& runtimeAsset)
: id{std::shared_ptr<AssetId>(
new AssetId(AssetManager::RegisterRuntimeAsset(uuid, std::move(runtimeAsset)).GetId()), AssetIdUnloader{})}
{
}
AssetRef(const std::string& name, std::unique_ptr<AssetType>&& runtimeAsset) AssetRef(const std::string& name, std::unique_ptr<AssetType>&& runtimeAsset)
: id{std::shared_ptr<AssetId>(new AssetId(AssetManager::RegisterRuntimeAsset(name, std::move(runtimeAsset)).GetId()), AssetIdUnloader{})} : id{std::shared_ptr<AssetId>(
{} new AssetId(AssetManager::RegisterRuntimeAsset(name, std::move(runtimeAsset)).GetId()), AssetIdUnloader{})}
{
}
AssetRef(const std::string& name, const Uuid& uuid, std::unique_ptr<AssetType>&& runtimeAsset)
: id{std::shared_ptr<AssetId>(
new AssetId(AssetManager::RegisterRuntimeAsset(name, uuid, std::move(runtimeAsset)).GetId()),
AssetIdUnloader{})}
{
}
AssetRef(AssetId id) AssetRef(AssetId id)
: id{std::shared_ptr<AssetId>(new AssetId(AssetManager::DuplicateAsset(id)), AssetIdUnloader{})} : id{std::shared_ptr<AssetId>(new AssetId(AssetManager::DuplicateAsset(id)), AssetIdUnloader{})}
{} {
}
AssetId GetId() const AssetId GetId() const
{ {
@@ -48,7 +74,8 @@ namespace Copium
} }
private: private:
struct AssetIdUnloader { struct AssetIdUnloader
{
void operator()(AssetId* id) void operator()(AssetId* id)
{ {
if (*id != NULL_ASSET_ID) if (*id != NULL_ASSET_ID)
@@ -57,6 +84,7 @@ namespace Copium
} }
} }
}; };
private: private:
std::shared_ptr<AssetId> id; std::shared_ptr<AssetId> id;
}; };
+22 -7
View File
@@ -5,7 +5,8 @@
namespace Copium namespace Copium
{ {
Buffer::Buffer(VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count) Buffer::Buffer(VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count)
: size{size}, count{count} : size{size},
count{count}
{ {
VkBufferCreateInfo createInfo{}; VkBufferCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@@ -23,15 +24,22 @@ namespace Copium
allocateInfo.allocationSize = memoryRequirements.size; allocateInfo.allocationSize = memoryRequirements.size;
allocateInfo.memoryTypeIndex = Vulkan::GetDevice().FindMemoryType(memoryRequirements.memoryTypeBits, properties); allocateInfo.memoryTypeIndex = Vulkan::GetDevice().FindMemoryType(memoryRequirements.memoryTypeBits, properties);
CP_VK_ASSERT(vkAllocateMemory(Vulkan::GetDevice(), &allocateInfo, nullptr, &memory), "Failed to allocate buffer memory"); CP_VK_ASSERT(vkAllocateMemory(Vulkan::GetDevice(), &allocateInfo, nullptr, &memory),
"Failed to allocate buffer memory");
vkBindBufferMemory(Vulkan::GetDevice(), handle, memory, 0); vkBindBufferMemory(Vulkan::GetDevice(), handle, memory, 0);
} }
Buffer::~Buffer() Buffer::~Buffer()
{ {
vkFreeMemory(Vulkan::GetDevice(), memory, nullptr); VkDeviceMemory memoryCpy = memory;
vkDestroyBuffer(Vulkan::GetDevice(), handle, nullptr); VkBuffer handleCpy = handle;
Vulkan::GetDevice().QueueIdleCommand(
[memoryCpy, handleCpy]()
{
vkFreeMemory(Vulkan::GetDevice(), memoryCpy, nullptr);
vkDestroyBuffer(Vulkan::GetDevice(), handleCpy, nullptr);
});
} }
void Buffer::Update(void* indexData, int index) void Buffer::Update(void* indexData, int index)
@@ -54,7 +62,10 @@ namespace Copium
void Buffer::UpdateStaging(void* data) void Buffer::UpdateStaging(void* data)
{ {
VkDeviceSize bufferSize = size * count; VkDeviceSize bufferSize = size * count;
Buffer stagingBuffer{VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1}; Buffer stagingBuffer{VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
bufferSize,
1};
stagingBuffer.Update(data, 0); stagingBuffer.Update(data, 0);
@@ -63,7 +74,10 @@ namespace Copium
void Buffer::UpdateStaging(void* data, VkDeviceSize offset, VkDeviceSize size) void Buffer::UpdateStaging(void* data, VkDeviceSize offset, VkDeviceSize size)
{ {
Buffer stagingBuffer{VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size, 1}; Buffer stagingBuffer{VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
size,
1};
stagingBuffer.Update(data, 0); stagingBuffer.Update(data, 0);
@@ -111,7 +125,8 @@ namespace Copium
allocateInfo.commandBufferCount = 1; allocateInfo.commandBufferCount = 1;
VkCommandBuffer commandBuffer; VkCommandBuffer commandBuffer;
CP_VK_ASSERT(vkAllocateCommandBuffers(Vulkan::GetDevice(), &allocateInfo, &commandBuffer), "Failed to initialize command buffer"); CP_VK_ASSERT(vkAllocateCommandBuffers(Vulkan::GetDevice(), &allocateInfo, &commandBuffer),
"Failed to initialize command buffer");
VkCommandBufferBeginInfo beginInfo{}; VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+3 -2
View File
@@ -1,14 +1,15 @@
#pragma once #pragma once
#include "copium/util/Common.h"
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
#include "copium/util/Common.h"
namespace Copium namespace Copium
{ {
class Buffer class Buffer
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(Buffer); CP_DELETE_COPY_AND_MOVE_CTOR(Buffer);
protected: protected:
VkDeviceMemory memory; VkDeviceMemory memory;
VkBuffer handle; VkBuffer handle;
@@ -1,6 +1,7 @@
#include "copium/buffer/CommandBuffer.h" #include "copium/buffer/CommandBuffer.h"
#include "copium/core/Vulkan.h" #include "copium/core/Vulkan.h"
#include "copium/util/Trace.h"
namespace Copium namespace Copium
{ {
@@ -16,7 +17,7 @@ namespace Copium
commandBuffers.resize(SwapChain::MAX_FRAMES_IN_FLIGHT); commandBuffers.resize(SwapChain::MAX_FRAMES_IN_FLIGHT);
break; break;
default: default:
CP_ABORT("Unreachable switch case: %s", ToString(type).c_str()); CP_ABORT("Unreachable switch case: {}", type);
} }
VkCommandBufferAllocateInfo allocateInfo{}; VkCommandBufferAllocateInfo allocateInfo{};
@@ -24,12 +25,21 @@ namespace Copium
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocateInfo.commandPool = Vulkan::GetDevice().GetCommandPool(); allocateInfo.commandPool = Vulkan::GetDevice().GetCommandPool();
allocateInfo.commandBufferCount = commandBuffers.size(); allocateInfo.commandBufferCount = commandBuffers.size();
CP_VK_ASSERT(vkAllocateCommandBuffers(Vulkan::GetDevice(), &allocateInfo, commandBuffers.data()), "Failed to allocate CommandBuffer"); CP_VK_ASSERT(vkAllocateCommandBuffers(Vulkan::GetDevice(), &allocateInfo, commandBuffers.data()),
"Failed to allocate CommandBuffer");
} }
CommandBuffer::~CommandBuffer() CommandBuffer::~CommandBuffer()
{ {
vkFreeCommandBuffers(Vulkan::GetDevice(), Vulkan::GetDevice().GetCommandPool(), commandBuffers.size(), commandBuffers.data()); std::vector<VkCommandBuffer> commandBuffersCpy = commandBuffers;
Vulkan::GetDevice().QueueIdleCommand(
[commandBuffersCpy]()
{
vkFreeCommandBuffers(Vulkan::GetDevice(),
Vulkan::GetDevice().GetCommandPool(),
commandBuffersCpy.size(),
commandBuffersCpy.data());
});
} }
// TODO: Test as constexpr function to see if it avoids the switch case // TODO: Test as constexpr function to see if it avoids the switch case
@@ -40,32 +50,46 @@ namespace Copium
beginInfo.flags = 0; beginInfo.flags = 0;
beginInfo.pInheritanceInfo = nullptr; beginInfo.pInheritanceInfo = nullptr;
int index = Vulkan::GetSwapChain().GetFlightIndex();
switch (type) switch (type)
{ {
case CommandBufferType::SingleUse: case CommandBufferType::SingleUse:
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
index = 0;
break; break;
case CommandBufferType::Dynamic: case CommandBufferType::Dynamic:
break; break;
default: default:
CP_ABORT("Unreachable switch case: %s", ToString(type).c_str()); CP_ABORT("Unreachable switch case: {}", type);
} }
vkResetCommandBuffer(commandBuffers[Vulkan::GetSwapChain().GetFlightIndex()], 0); vkResetCommandBuffer(commandBuffers[index], 0);
CP_VK_ASSERT(vkBeginCommandBuffer(commandBuffers[Vulkan::GetSwapChain().GetFlightIndex()], &beginInfo), "Failed to begin command buffer"); CP_VK_ASSERT(vkBeginCommandBuffer(commandBuffers[index], &beginInfo), "Failed to begin command buffer");
} }
void CommandBuffer::End() void CommandBuffer::End()
{ {
vkEndCommandBuffer(commandBuffers[Vulkan::GetSwapChain().GetFlightIndex()]); int index = Vulkan::GetSwapChain().GetFlightIndex();
if (type == CommandBufferType::SingleUse)
{
index = 0;
}
vkEndCommandBuffer(commandBuffers[index]);
} }
void CommandBuffer::Submit() void CommandBuffer::Submit()
{ {
int index = Vulkan::GetSwapChain().GetFlightIndex();
if (type == CommandBufferType::SingleUse)
{
index = 0;
}
VkSubmitInfo submitInfo{}; VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffers[Vulkan::GetSwapChain().GetFlightIndex()]; submitInfo.pCommandBuffers = &commandBuffers[index];
vkQueueSubmit(Vulkan::GetDevice().GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE); vkQueueSubmit(Vulkan::GetDevice().GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
// TODO: if singleUse? // TODO: if singleUse?
@@ -74,6 +98,11 @@ namespace Copium
CommandBuffer::operator VkCommandBuffer() const CommandBuffer::operator VkCommandBuffer() const
{ {
return commandBuffers[Vulkan::GetSwapChain().GetFlightIndex()]; int index = Vulkan::GetSwapChain().GetFlightIndex();
if (type == CommandBufferType::SingleUse)
{
index = 0;
}
return commandBuffers[index];
} }
} }
@@ -1,18 +1,18 @@
#pragma once #pragma once
#include <vulkan/vulkan.hpp>
#include "copium/util/Common.h" #include "copium/util/Common.h"
#include "copium/util/Enum.h" #include "copium/util/Enum.h"
#include <vulkan/vulkan.hpp>
#define CP_COMMAND_BUFFER_TYPE_ENUMS SingleUse, Dynamic
CP_ENUM_CREATOR(Copium, CommandBufferType, CP_COMMAND_BUFFER_TYPE_ENUMS);
namespace Copium namespace Copium
{ {
CP_ENUM_CREATOR(CommandBufferType, SingleUse, Dynamic);
class CommandBuffer class CommandBuffer
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(CommandBuffer); CP_DELETE_COPY_AND_MOVE_CTOR(CommandBuffer);
private: private:
std::vector<VkCommandBuffer> commandBuffers; std::vector<VkCommandBuffer> commandBuffers;
const CommandBufferType type; const CommandBufferType type;
@@ -8,6 +8,7 @@ namespace Copium
class CommandBufferScoped final : public CommandBuffer class CommandBufferScoped final : public CommandBuffer
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(CommandBufferScoped); CP_DELETE_COPY_AND_MOVE_CTOR(CommandBufferScoped);
public: public:
CommandBufferScoped(); CommandBufferScoped();
+35 -17
View File
@@ -1,6 +1,5 @@
#include "copium/buffer/Framebuffer.h" #include "copium/buffer/Framebuffer.h"
#include "copium/asset/AssetManager.h"
#include "copium/buffer/CommandBuffer.h" #include "copium/buffer/CommandBuffer.h"
#include "copium/core/Vulkan.h" #include "copium/core/Vulkan.h"
#include "copium/sampler/Image.h" #include "copium/sampler/Image.h"
@@ -12,17 +11,25 @@ namespace Copium
const MetaFileClass& metaClass = metaFile.GetMetaClass("Framebuffer"); const MetaFileClass& metaClass = metaFile.GetMetaClass("Framebuffer");
colorAttachment = AssetRef<ColorAttachment>(Uuid{metaClass.GetValue("rendertexture-uuid")}); colorAttachment = AssetRef<ColorAttachment>(Uuid{metaClass.GetValue("rendertexture-uuid")});
ColorAttachment& attachment = colorAttachment.GetAsset(); ColorAttachment& attachment = colorAttachment.GetAsset();
width = attachment.GetWidth(); width = attachment.GetWidth();
height = attachment.GetHeight(); height = attachment.GetHeight();
CP_ASSERT(width > 0, "Width of framebuffer is less than 1: {}", width);
CP_ASSERT(height > 0, "Height of framebuffer is less than 1: {}", height);
InitializeDepthBuffer(); InitializeDepthBuffer();
InitializeRenderPass(); InitializeRenderPass();
InitializeFramebuffers(); InitializeFramebuffers();
} }
Framebuffer::Framebuffer(uint32_t width, uint32_t height) Framebuffer::Framebuffer(int width, int height, const SamplerCreator& samplerCreator)
: width{width}, height{height} : width{width},
height{height}
{ {
InitializeImage(); CP_ASSERT(width > 0, "Width of framebuffer is less than 1: {}", width);
CP_ASSERT(height > 0, "Height of framebuffer is less than 1: {}", height);
InitializeImage(samplerCreator);
InitializeDepthBuffer(); InitializeDepthBuffer();
InitializeRenderPass(); InitializeRenderPass();
InitializeFramebuffers(); InitializeFramebuffers();
@@ -30,14 +37,23 @@ namespace Copium
Framebuffer::~Framebuffer() Framebuffer::~Framebuffer()
{ {
for (auto& framebuffer : framebuffers) std::vector<VkFramebuffer> framebuffersCpy = framebuffers;
VkRenderPass renderPassCpy = renderPass;
Vulkan::GetDevice().QueueIdleCommand(
[framebuffersCpy, renderPassCpy]()
{
for (auto& framebuffer : framebuffersCpy)
vkDestroyFramebuffer(Vulkan::GetDevice(), framebuffer, nullptr); vkDestroyFramebuffer(Vulkan::GetDevice(), framebuffer, nullptr);
vkDestroyRenderPass(Vulkan::GetDevice(), renderPass, nullptr); vkDestroyRenderPass(Vulkan::GetDevice(), renderPassCpy, nullptr);
});
} }
void Framebuffer::Resize(uint32_t width, uint32_t height) void Framebuffer::Resize(int width, int height)
{ {
vkDeviceWaitIdle(Vulkan::GetDevice()); CP_ASSERT(width > 0, "Width of framebuffer is less than 1: {}", width);
CP_ASSERT(height > 0, "Height of framebuffer is less than 1: {}", height);
Vulkan::GetDevice().WaitIdle();
this->width = width; this->width = width;
this->height = height; this->height = height;
for (auto&& framebuffer : framebuffers) for (auto&& framebuffer : framebuffers)
@@ -57,9 +73,9 @@ namespace Copium
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.renderPass = renderPass; renderPassBeginInfo.renderPass = renderPass;
renderPassBeginInfo.framebuffer = framebuffers[Vulkan::GetSwapChain().GetFlightIndex()]; renderPassBeginInfo.framebuffer = framebuffers[Vulkan::GetSwapChain().GetFlightIndex()];
;
renderPassBeginInfo.renderArea.offset = {0, 0}; renderPassBeginInfo.renderArea.offset = {0, 0};
renderPassBeginInfo.renderArea.extent = {width, height}; renderPassBeginInfo.renderArea.extent = {static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
renderPassBeginInfo.clearValueCount = clearValues.size(); renderPassBeginInfo.clearValueCount = clearValues.size();
renderPassBeginInfo.pClearValues = clearValues.data(); renderPassBeginInfo.pClearValues = clearValues.data();
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
@@ -74,7 +90,7 @@ namespace Copium
vkCmdSetViewport(commandBuffer, 0, 1, &viewport); vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
VkRect2D scissor{}; VkRect2D scissor{};
scissor.offset = {0, 0}; scissor.offset = {0, 0};
scissor.extent = {width, height}; scissor.extent = {static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
vkCmdSetScissor(commandBuffer, 0, 1, &scissor); vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
} }
@@ -98,19 +114,19 @@ namespace Copium
return colorAttachment.GetAsset(); return colorAttachment.GetAsset();
} }
uint32_t Framebuffer::GetWidth() const int Framebuffer::GetWidth() const
{ {
return width; return width;
} }
uint32_t Framebuffer::GetHeight() const int Framebuffer::GetHeight() const
{ {
return height; return height;
} }
void Framebuffer::InitializeImage() void Framebuffer::InitializeImage(const SamplerCreator& samplerCreator)
{ {
colorAttachment = AssetManager::RegisterRuntimeAsset("Framebuffer::ColorAttachment", std::make_unique<ColorAttachment>(width, height, SamplerCreator{})); colorAttachment = AssetRef(std::make_unique<ColorAttachment>(width, height, samplerCreator));
} }
void Framebuffer::InitializeDepthBuffer() void Framebuffer::InitializeDepthBuffer()
@@ -179,7 +195,8 @@ namespace Copium
renderPassCreateInfo.dependencyCount = dependencies.size(); renderPassCreateInfo.dependencyCount = dependencies.size();
renderPassCreateInfo.pDependencies = dependencies.data(); renderPassCreateInfo.pDependencies = dependencies.data();
CP_VK_ASSERT(vkCreateRenderPass(Vulkan::GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "Failed to initialze render pass"); CP_VK_ASSERT(vkCreateRenderPass(Vulkan::GetDevice(), &renderPassCreateInfo, nullptr, &renderPass),
"Failed to initialze render pass");
} }
void Framebuffer::InitializeFramebuffers() void Framebuffer::InitializeFramebuffers()
@@ -199,7 +216,8 @@ namespace Copium
createInfo.height = height; createInfo.height = height;
createInfo.layers = 1; createInfo.layers = 1;
CP_VK_ASSERT(vkCreateFramebuffer(Vulkan::GetDevice(), &createInfo, nullptr, &framebuffers[i]), "Failed to initialize framebuffer"); CP_VK_ASSERT(vkCreateFramebuffer(Vulkan::GetDevice(), &createInfo, nullptr, &framebuffers[i]),
"Failed to initialize framebuffer");
} }
} }
} }
+11 -10
View File
@@ -1,45 +1,46 @@
#pragma once #pragma once
#include <vulkan/vulkan.hpp>
#include "copium/asset/Asset.h" #include "copium/asset/Asset.h"
#include "copium/asset/AssetMeta.h"
#include "copium/asset/AssetRef.h" #include "copium/asset/AssetRef.h"
#include "copium/buffer/CommandBuffer.h" #include "copium/buffer/CommandBuffer.h"
#include "copium/sampler/ColorAttachment.h" #include "copium/sampler/ColorAttachment.h"
#include "copium/sampler/DepthAttachment.h" #include "copium/sampler/DepthAttachment.h"
#include "copium/util/Common.h" #include "copium/util/Common.h"
#include <vulkan/vulkan.hpp>
namespace Copium namespace Copium
{ {
class Framebuffer final : public Asset class Framebuffer final : public Asset
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(Framebuffer); CP_DELETE_COPY_AND_MOVE_CTOR(Framebuffer);
private: private:
AssetRef<ColorAttachment> colorAttachment; AssetRef<ColorAttachment> colorAttachment;
std::unique_ptr<DepthAttachment> depthAttachment; std::unique_ptr<DepthAttachment> depthAttachment;
std::vector<VkFramebuffer> framebuffers; std::vector<VkFramebuffer> framebuffers;
VkRenderPass renderPass; VkRenderPass renderPass;
uint32_t width; int width;
uint32_t height; int height;
public: public:
Framebuffer(const MetaFile& metaFile); Framebuffer(const MetaFile& metaFile);
Framebuffer(uint32_t width, uint32_t height); Framebuffer(int width, int height, const SamplerCreator& samplerCreator);
~Framebuffer(); ~Framebuffer();
void Resize(uint32_t width, uint32_t height); void Resize(int width, int height);
void Bind(const CommandBuffer& commandBuffer); void Bind(const CommandBuffer& commandBuffer);
void Unbind(const CommandBuffer& commandBuffer); void Unbind(const CommandBuffer& commandBuffer);
VkRenderPass GetRenderPass() const; VkRenderPass GetRenderPass() const;
VkFramebuffer GetFramebuffer() const; VkFramebuffer GetFramebuffer() const;
const ColorAttachment& GetColorAttachment() const; const ColorAttachment& GetColorAttachment() const;
uint32_t GetWidth() const; int GetWidth() const;
uint32_t GetHeight() const; int GetHeight() const;
private: private:
void InitializeImage(); void InitializeImage(const SamplerCreator& samplerCreator);
void InitializeDepthBuffer(); void InitializeDepthBuffer();
void InitializeRenderPass(); void InitializeRenderPass();
void InitializeFramebuffers(); void InitializeFramebuffers();
@@ -2,12 +2,18 @@
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
#include "copium/util/Trace.h"
namespace Copium namespace Copium
{ {
IndexBuffer::IndexBuffer(int indexCount) IndexBuffer::IndexBuffer(int indexCount)
: Buffer{VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexCount * sizeof(uint16_t), 1}, : Buffer{VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
indexCount * sizeof(uint16_t),
1},
indexCount{indexCount} indexCount{indexCount}
{} {
}
void IndexBuffer::Bind(const CommandBuffer& commandBuffer) void IndexBuffer::Bind(const CommandBuffer& commandBuffer)
{ {
@@ -9,8 +9,10 @@ namespace Copium
class IndexBuffer final : public Buffer class IndexBuffer final : public Buffer
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(IndexBuffer); CP_DELETE_COPY_AND_MOVE_CTOR(IndexBuffer);
private: private:
int indexCount; int indexCount;
public: public:
IndexBuffer(int indexCount); IndexBuffer(int indexCount);
@@ -6,8 +6,12 @@ namespace Copium
{ {
RendererVertexBuffer::RendererVertexBuffer(const VertexDescriptor& descriptor, int vertexCount) RendererVertexBuffer::RendererVertexBuffer(const VertexDescriptor& descriptor, int vertexCount)
: Buffer{VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, descriptor.GetVertexSize() * vertexCount, SwapChain::MAX_FRAMES_IN_FLIGHT} : Buffer{VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
{} VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
descriptor.GetVertexSize() * vertexCount,
SwapChain::MAX_FRAMES_IN_FLIGHT}
{
}
void RendererVertexBuffer::Bind(const CommandBuffer& commandBuffer) void RendererVertexBuffer::Bind(const CommandBuffer& commandBuffer)
{ {
@@ -9,6 +9,7 @@ namespace Copium
class RendererVertexBuffer : public Buffer class RendererVertexBuffer : public Buffer
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(RendererVertexBuffer); CP_DELETE_COPY_AND_MOVE_CTOR(RendererVertexBuffer);
public: public:
RendererVertexBuffer(const VertexDescriptor& descriptor, int vertexCount); RendererVertexBuffer(const VertexDescriptor& descriptor, int vertexCount);
@@ -5,7 +5,11 @@
namespace Copium namespace Copium
{ {
UniformBuffer::UniformBuffer(ShaderBinding binding) UniformBuffer::UniformBuffer(ShaderBinding binding)
: Buffer{VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, binding.GetUniformBufferSize(), SwapChain::MAX_FRAMES_IN_FLIGHT}, binding{binding} : Buffer{VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
binding.GetUniformBufferSize(),
SwapChain::MAX_FRAMES_IN_FLIGHT},
binding{binding}
{ {
buffer.resize(Buffer::GetSize()); buffer.resize(Buffer::GetSize());
} }
@@ -21,49 +25,53 @@ namespace Copium
void UniformBuffer::Set(const std::string& str, const glm::mat3& data) void UniformBuffer::Set(const std::string& str, const glm::mat3& data)
{ {
CP_ASSERT(binding.GetUniformType(str) == UniformType::Mat3, "Uniform type missmatch = %s", str.c_str()); CP_ASSERT(binding.GetUniformType(str) == UniformType::Mat3, "Uniform type missmatch = {}", str);
uint32_t offset = binding.GetUniformOffset(str); uint32_t offset = binding.GetUniformOffset(str);
memcpy(buffer.data() + offset, &data, sizeof(glm::mat3)); // memcpy(buffer.data() + offset, &data[0], sizeof(glm::vec3));
// memcpy(buffer.data() + offset + 16, &data[1], sizeof(glm::vec3));
// memcpy(buffer.data() + offset + 32, &data[2], sizeof(glm::vec3));
glm::mat4x3 mat43{data};
memcpy(buffer.data() + offset, &mat43, sizeof(glm::mat4x3));
} }
void UniformBuffer::Set(const std::string& str, const glm::mat4& data) void UniformBuffer::Set(const std::string& str, const glm::mat4& data)
{ {
CP_ASSERT(binding.GetUniformType(str) == UniformType::Mat4, "Uniform type missmatch = %s", str.c_str()); CP_ASSERT(binding.GetUniformType(str) == UniformType::Mat4, "Uniform type missmatch = {}", str);
uint32_t offset = binding.GetUniformOffset(str); uint32_t offset = binding.GetUniformOffset(str);
memcpy(buffer.data() + offset, &data, sizeof(glm::mat4)); memcpy(buffer.data() + offset, &data, sizeof(glm::mat4));
} }
void UniformBuffer::Set(const std::string& str, const glm::vec2& data) void UniformBuffer::Set(const std::string& str, const glm::vec2& data)
{ {
CP_ASSERT(binding.GetUniformType(str) == UniformType::Vec2, "Uniform type missmatch = %s", str.c_str()); CP_ASSERT(binding.GetUniformType(str) == UniformType::Vec2, "Uniform type missmatch = {}", str);
uint32_t offset = binding.GetUniformOffset(str); uint32_t offset = binding.GetUniformOffset(str);
memcpy(buffer.data() + offset, &data, sizeof(glm::vec2)); memcpy(buffer.data() + offset, &data, sizeof(glm::vec2));
} }
void UniformBuffer::Set(const std::string& str, const glm::vec3& data) void UniformBuffer::Set(const std::string& str, const glm::vec3& data)
{ {
CP_ASSERT(binding.GetUniformType(str) == UniformType::Vec3, "Uniform type missmatch = %s", str.c_str()); CP_ASSERT(binding.GetUniformType(str) == UniformType::Vec3, "Uniform type missmatch = {}", str);
uint32_t offset = binding.GetUniformOffset(str); uint32_t offset = binding.GetUniformOffset(str);
memcpy(buffer.data() + offset, &data, sizeof(glm::vec3)); memcpy(buffer.data() + offset, &data, sizeof(glm::vec3));
} }
void UniformBuffer::Set(const std::string& str, const glm::vec4& data) void UniformBuffer::Set(const std::string& str, const glm::vec4& data)
{ {
CP_ASSERT(binding.GetUniformType(str) == UniformType::Vec4, "Uniform type missmatch = %s", str.c_str()); CP_ASSERT(binding.GetUniformType(str) == UniformType::Vec4, "Uniform type missmatch = {}", str);
uint32_t offset = binding.GetUniformOffset(str); uint32_t offset = binding.GetUniformOffset(str);
memcpy(buffer.data() + offset, &data, sizeof(glm::vec4)); memcpy(buffer.data() + offset, &data, sizeof(glm::vec4));
} }
void UniformBuffer::Set(const std::string& str, float data) void UniformBuffer::Set(const std::string& str, float data)
{ {
CP_ASSERT(binding.GetUniformType(str) == UniformType::Float, "Uniform type missmatch = %s", str.c_str()); CP_ASSERT(binding.GetUniformType(str) == UniformType::Float, "Uniform type missmatch = {}", str);
uint32_t offset = binding.GetUniformOffset(str); uint32_t offset = binding.GetUniformOffset(str);
memcpy(buffer.data() + offset, &data, sizeof(float)); memcpy(buffer.data() + offset, &data, sizeof(float));
} }
void UniformBuffer::Set(const std::string& str, int data) void UniformBuffer::Set(const std::string& str, int data)
{ {
CP_ASSERT(binding.GetUniformType(str) == UniformType::Int, "Uniform type missmatch = %s", str.c_str()); CP_ASSERT(binding.GetUniformType(str) == UniformType::Int, "Uniform type missmatch = {}", str);
uint32_t offset = binding.GetUniformOffset(str); uint32_t offset = binding.GetUniformOffset(str);
memcpy(buffer.data() + offset, &data, sizeof(int)); memcpy(buffer.data() + offset, &data, sizeof(int));
} }
@@ -1,17 +1,18 @@
#pragma once #pragma once
#include <glm/glm.hpp>
#include <vulkan/vulkan.hpp>
#include "copium/buffer/Buffer.h" #include "copium/buffer/Buffer.h"
#include "copium/pipeline/ShaderBinding.h" #include "copium/pipeline/ShaderBinding.h"
#include "copium/util/Common.h" #include "copium/util/Common.h"
#include <glm/glm.hpp>
#include <vulkan/vulkan.hpp>
namespace Copium namespace Copium
{ {
class UniformBuffer final : public Buffer class UniformBuffer final : public Buffer
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(UniformBuffer); CP_DELETE_COPY_AND_MOVE_CTOR(UniformBuffer);
private: private:
ShaderBinding binding; ShaderBinding binding;
std::vector<uint8_t> buffer; std::vector<uint8_t> buffer;
@@ -3,7 +3,10 @@
namespace Copium namespace Copium
{ {
VertexBuffer::VertexBuffer(const VertexDescriptor& descriptor, int vertexCount) VertexBuffer::VertexBuffer(const VertexDescriptor& descriptor, int vertexCount)
: Buffer{VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, descriptor.GetVertexSize() * vertexCount, 1} : Buffer{VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
descriptor.GetVertexSize() * vertexCount,
1}
{ {
VkDeviceSize offset = 0; VkDeviceSize offset = 0;
for (auto&& binding : descriptor.GetBindings()) for (auto&& binding : descriptor.GetBindings())
@@ -1,21 +1,23 @@
#pragma once #pragma once
#include <vector>
#include <vulkan/vulkan.hpp>
#include "copium/buffer/Buffer.h" #include "copium/buffer/Buffer.h"
#include "copium/buffer/CommandBuffer.h" #include "copium/buffer/CommandBuffer.h"
#include "copium/pipeline/VertexDescriptor.h" #include "copium/pipeline/VertexDescriptor.h"
#include "copium/util/Common.h" #include "copium/util/Common.h"
#include <vector>
#include <vulkan/vulkan.hpp>
namespace Copium namespace Copium
{ {
class VertexBuffer final : public Buffer class VertexBuffer final : public Buffer
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(VertexBuffer); CP_DELETE_COPY_AND_MOVE_CTOR(VertexBuffer);
private: private:
std::vector<VkDeviceSize> bindingOffsets; std::vector<VkDeviceSize> bindingOffsets;
std::vector<VkDeviceSize> bindingSizes; std::vector<VkDeviceSize> bindingSizes;
public: public:
VertexBuffer(const VertexDescriptor& descriptor, int vertexCount); VertexBuffer(const VertexDescriptor& descriptor, int vertexCount);
+20 -11
View File
@@ -1,6 +1,7 @@
#include "copium/core/DebugMessenger.h" #include "copium/core/DebugMessenger.h"
#include "copium/core/Instance.h" #include "copium/core/Instance.h"
#include "copium/util/Trace.h"
namespace Copium namespace Copium
{ {
@@ -18,7 +19,8 @@ namespace Copium
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
createInfo.pfnUserCallback = DebugCallback; createInfo.pfnUserCallback = DebugCallback;
createInfo.pUserData = nullptr; createInfo.pUserData = nullptr;
CP_VK_ASSERT(vkCreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger), "Failed to initialze debug messenger"); CP_VK_ASSERT(vkCreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger),
"Failed to initialze debug messenger");
} }
DebugMessenger::~DebugMessenger() DebugMessenger::~DebugMessenger()
@@ -38,19 +40,24 @@ namespace Copium
#else #else
DebugMessenger::DebugMessenger(Instance& instance) DebugMessenger::DebugMessenger(Instance& instance)
: instance{instance} : instance{instance}
{} {
}
DebugMessenger::~DebugMessenger() DebugMessenger::~DebugMessenger()
{} {
}
void DebugMessenger::AddRequiredExtensions(std::vector<const char*>* extensions) void DebugMessenger::AddRequiredExtensions(std::vector<const char*>* extensions)
{} {
}
void DebugMessenger::AddRequiredLayers(std::vector<const char*>* layers) void DebugMessenger::AddRequiredLayers(std::vector<const char*>* layers)
{} {
}
#endif #endif
VKAPI_ATTR VkBool32 VKAPI_CALL DebugMessenger::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VKAPI_ATTR VkBool32 VKAPI_CALL
DebugMessenger::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType, VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData) void* pUserData)
@@ -58,9 +65,9 @@ namespace Copium
if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
{ {
if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
CP_ABORT("%s", pCallbackData->pMessage); CP_ABORT("{}", pCallbackData->pMessage);
else else
CP_WARN("%s", pCallbackData->pMessage); CP_WARN("{}", pCallbackData->pMessage);
} }
return VK_FALSE; return VK_FALSE;
} }
@@ -78,9 +85,11 @@ namespace Copium
void DebugMessenger::vkDestroyDebugUtilsMessengerEXT(VkInstance instance, void DebugMessenger::vkDestroyDebugUtilsMessengerEXT(VkInstance instance,
VkDebugUtilsMessengerEXT debugMessenger, VkDebugUtilsMessengerEXT debugMessenger,
const VkAllocationCallbacks* pAllocator) { const VkAllocationCallbacks* pAllocator)
auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"); {
if (func != nullptr) { auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
if (func != nullptr)
{
func(instance, debugMessenger, pAllocator); func(instance, debugMessenger, pAllocator);
} }
} }
@@ -1,9 +1,9 @@
#pragma once #pragma once
#include "copium/util/Common.h"
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
#include "copium/util/Common.h"
namespace Copium namespace Copium
{ {
class Instance; class Instance;
@@ -11,10 +11,12 @@ namespace Copium
class DebugMessenger final class DebugMessenger final
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(DebugMessenger); CP_DELETE_COPY_AND_MOVE_CTOR(DebugMessenger);
private: private:
Instance& instance; Instance& instance;
VkDebugUtilsMessengerEXT debugMessenger; VkDebugUtilsMessengerEXT debugMessenger;
public: public:
DebugMessenger(Instance& instance); DebugMessenger(Instance& instance);
~DebugMessenger(); ~DebugMessenger();
+36 -3
View File
@@ -1,5 +1,6 @@
#include "Device.h" #include "Device.h"
#include "copium/core/QueueFamilies.h"
#include "copium/core/Vulkan.h" #include "copium/core/Vulkan.h"
#include "copium/core/Window.h" #include "copium/core/Window.h"
@@ -11,6 +12,7 @@ namespace Copium
InitializeLogicalDevice(); InitializeLogicalDevice();
InitializeCommandPool(); InitializeCommandPool();
} }
Device::~Device() Device::~Device()
{ {
vkDestroyCommandPool(device, commandPool, nullptr); vkDestroyCommandPool(device, commandPool, nullptr);
@@ -65,6 +67,34 @@ namespace Copium
CP_ABORT("Failed to find suitable memory type"); CP_ABORT("Failed to find suitable memory type");
} }
void Device::WaitIdle()
{
vkDeviceWaitIdle(device);
CleanupIdleQueue();
}
void Device::WaitIdleIfCommandQueued()
{
if (!idleCommands.empty())
{
WaitIdle();
}
}
void Device::CleanupIdleQueue()
{
while (!idleCommands.empty())
{
idleCommands.front()();
idleCommands.pop();
}
}
void Device::QueueIdleCommand(std::function<void()> idleCommand)
{
idleCommands.emplace(idleCommand);
}
void Device::SelectPhysicalDevice() void Device::SelectPhysicalDevice()
{ {
uint32_t deviceCount; uint32_t deviceCount;
@@ -81,18 +111,21 @@ namespace Copium
{ {
VkPhysicalDeviceProperties deviceProperties; VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(device, &deviceProperties); vkGetPhysicalDeviceProperties(device, &deviceProperties);
CP_INFO_CONT("\t%s", deviceProperties.deviceName); CP_INFO_CONT("\t{}", deviceProperties.deviceName);
devicePriorities.emplace_back(device, GetPhysicalDevicePriority(device)); devicePriorities.emplace_back(device, GetPhysicalDevicePriority(device));
} }
std::sort(devicePriorities.begin(), devicePriorities.end(), [](const std::pair<VkPhysicalDevice, uint32_t>& lhs, const std::pair<VkPhysicalDevice, uint32_t>& rhs) { return lhs.second > rhs.second; }); std::sort(devicePriorities.begin(),
devicePriorities.end(),
[](const std::pair<VkPhysicalDevice, uint32_t>& lhs, const std::pair<VkPhysicalDevice, uint32_t>& rhs)
{ return lhs.second > rhs.second; });
auto&& it = devicePriorities.begin(); auto&& it = devicePriorities.begin();
CP_ASSERT(it->second != 0, "Failed to find suitable gpu"); CP_ASSERT(it->second != 0, "Failed to find suitable gpu");
VkPhysicalDeviceProperties deviceProperties; VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(it->first, &deviceProperties); vkGetPhysicalDeviceProperties(it->first, &deviceProperties);
physicalDevice = it->first; physicalDevice = it->first;
CP_INFO("Selecting device: %s", deviceProperties.deviceName); CP_INFO("Selecting device: {}", deviceProperties.deviceName);
} }
void Device::InitializeLogicalDevice() void Device::InitializeLogicalDevice()
+22 -14
View File
@@ -1,27 +1,18 @@
#pragma once #pragma once
#include "copium/core/QueueFamilies.h" #include <functional>
#include "copium/util/Common.h" #include <queue>
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
#include "copium/util/Common.h"
namespace Copium namespace Copium
{ {
class Vulkan; class Vulkan;
class Device class Device
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(Device); CP_DELETE_COPY_AND_MOVE_CTOR(Device);
private:
VkPhysicalDevice physicalDevice;
VkDevice device;
VkCommandPool commandPool;
// TODO: Move to SwapChain?
uint32_t graphicsQueueIndex;
uint32_t presentQueueIndex;
VkQueue graphicsQueue;
VkQueue presentQueue;
// TODO end
public: public:
Device(); Device();
@@ -35,6 +26,23 @@ namespace Copium
VkPhysicalDevice GetPhysicalDevice() const; VkPhysicalDevice GetPhysicalDevice() const;
operator VkDevice() const; operator VkDevice() const;
uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
void WaitIdle();
void WaitIdleIfCommandQueued();
void CleanupIdleQueue();
void QueueIdleCommand(std::function<void()> idleCommand);
private:
VkPhysicalDevice physicalDevice;
VkDevice device;
VkCommandPool commandPool;
// TODO: Move to SwapChain?
uint32_t graphicsQueueIndex;
uint32_t presentQueueIndex;
VkQueue graphicsQueue;
VkQueue presentQueue;
std::queue<std::function<void()>> idleCommands;
// TODO end
private: private:
void SelectPhysicalDevice(); void SelectPhysicalDevice();
@@ -1,16 +1,16 @@
#include "ImGuiInstance.h" #include "ImGuiInstance.h"
#include "copium/core/Vulkan.h"
#include "copium/buffer/CommandBufferScoped.h"
#include <imgui.h>
#include <backends/imgui_impl_glfw.h> #include <backends/imgui_impl_glfw.h>
#include <backends/imgui_impl_vulkan.h> #include <backends/imgui_impl_vulkan.h>
#include <imgui.h>
#include "copium/buffer/CommandBufferScoped.h"
#include "copium/core/Vulkan.h"
namespace Copium namespace Copium
{ {
ImGuiInstance::ImGuiInstance() ImGuiInstance::ImGuiInstance()
: descriptorPool{std::make_unique<DescriptorPool>()} : descriptorPool{std::make_unique<DescriptorPool>(SwapChain::MAX_FRAMES_IN_FLIGHT, 1)}
{ {
InitializeImGui(); InitializeImGui();
InitializeDescriptorSetLayout(); InitializeDescriptorSetLayout();
@@ -92,7 +92,8 @@ namespace Copium
createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
createInfo.bindingCount = 1; createInfo.bindingCount = 1;
createInfo.pBindings = layoutBindings.data(); createInfo.pBindings = layoutBindings.data();
CP_VK_ASSERT(vkCreateDescriptorSetLayout(Vulkan::GetDevice(), &createInfo, nullptr, &descriptorSetLayout), "Failed to create ImGui DescriptorSetLayout"); CP_VK_ASSERT(vkCreateDescriptorSetLayout(Vulkan::GetDevice(), &createInfo, nullptr, &descriptorSetLayout),
"Failed to create ImGui DescriptorSetLayout");
ShaderBinding binding; ShaderBinding binding;
binding.name = "texture"; binding.name = "texture";
+6 -5
View File
@@ -1,7 +1,8 @@
#include "Instance.h" #include "copium/core/Instance.h"
#include "copium/core/QueueFamilies.h" #include <GLFW/glfw3.h>
#include "copium/util/Common.h"
#include "copium/util/Trace.h"
namespace Copium namespace Copium
{ {
@@ -42,7 +43,7 @@ namespace Copium
CP_INFO("Supported Extensions:"); CP_INFO("Supported Extensions:");
for (auto&& extension : extensions) for (auto&& extension : extensions)
{ {
CP_INFO_CONT("\t%s", extension.extensionName); CP_INFO_CONT("\t{}", extension.extensionName);
} }
std::vector<const char*> layers{}; std::vector<const char*> layers{};
@@ -88,7 +89,7 @@ namespace Copium
CP_INFO("Supported Layers:"); CP_INFO("Supported Layers:");
for (auto&& availableLayer : availableLayers) for (auto&& availableLayer : availableLayers)
{ {
CP_INFO_CONT("\t%s", availableLayer.layerName); CP_INFO_CONT("\t{}", availableLayer.layerName);
} }
for (auto&& layer : layers) for (auto&& layer : layers)
+3 -3
View File
@@ -1,15 +1,15 @@
#pragma once #pragma once
#include "copium/core/DebugMessenger.h" #include <memory>
#include <GLFW/glfw3.h> #include "copium/core/DebugMessenger.h"
#include <set>
namespace Copium namespace Copium
{ {
class Instance final class Instance final
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(Instance); CP_DELETE_COPY_AND_MOVE_CTOR(Instance);
private: private:
VkInstance instance; VkInstance instance;
std::unique_ptr<DebugMessenger> debugMessenger; std::unique_ptr<DebugMessenger> debugMessenger;
+2 -1
View File
@@ -1,8 +1,9 @@
#pragma once #pragma once
#include <optional>
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <optional>
namespace Copium namespace Copium
{ {
struct QueueFamiliesQuery struct QueueFamiliesQuery
+39 -19
View File
@@ -4,10 +4,10 @@
#include "copium/core/Vulkan.h" #include "copium/core/Vulkan.h"
#include "copium/sampler/Image.h" #include "copium/sampler/Image.h"
#include <GLFW/glfw3.h>
namespace Copium namespace Copium
{ {
const int SwapChain::MAX_FRAMES_IN_FLIGHT = 2;
SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice) SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice)
{ {
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities); vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities);
@@ -35,6 +35,8 @@ namespace Copium
} }
SwapChain::SwapChain() SwapChain::SwapChain()
: flightIndex{0},
resizeFramebuffer{false}
{ {
Initialize(); Initialize();
InitializeImageViews(); InitializeImageViews();
@@ -49,9 +51,13 @@ namespace Copium
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i)
{ {
vkDestroyFence(Vulkan::GetDevice(), inFlightFences[i], nullptr); vkDestroyFence(Vulkan::GetDevice(), inFlightFences[i], nullptr);
vkDestroySemaphore(Vulkan::GetDevice(), renderFinishedSemaphores[i], nullptr);
vkDestroySemaphore(Vulkan::GetDevice(), imageAvailableSemaphores[i], nullptr); vkDestroySemaphore(Vulkan::GetDevice(), imageAvailableSemaphores[i], nullptr);
} }
for (size_t i = 0; i < images.size(); ++i)
{
vkDestroySemaphore(Vulkan::GetDevice(), renderFinishedSemaphores[i], nullptr);
}
Destroy(); Destroy();
vkDestroyRenderPass(Vulkan::GetDevice(), renderPass, nullptr); vkDestroyRenderPass(Vulkan::GetDevice(), renderPass, nullptr);
} }
@@ -115,7 +121,8 @@ namespace Copium
{ {
vkWaitForFences(Vulkan::GetDevice(), 1, &inFlightFences[flightIndex], VK_TRUE, UINT64_MAX); vkWaitForFences(Vulkan::GetDevice(), 1, &inFlightFences[flightIndex], VK_TRUE, UINT64_MAX);
VkResult result = vkAcquireNextImageKHR(Vulkan::GetDevice(), handle, UINT64_MAX, imageAvailableSemaphores[flightIndex], VK_NULL_HANDLE, &imageIndex); VkResult result = vkAcquireNextImageKHR(
Vulkan::GetDevice(), handle, UINT64_MAX, imageAvailableSemaphores[flightIndex], VK_NULL_HANDLE, &imageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR) if (result == VK_ERROR_OUT_OF_DATE_KHR)
{ {
Recreate(); Recreate();
@@ -137,9 +144,10 @@ namespace Copium
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cmd; submitInfo.pCommandBuffers = &cmd;
submitInfo.signalSemaphoreCount = 1; submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &renderFinishedSemaphores[flightIndex]; submitInfo.pSignalSemaphores = &renderFinishedSemaphores[imageIndex];
CP_VK_ASSERT(vkQueueSubmit(Vulkan::GetDevice().GetGraphicsQueue(), 1, &submitInfo, inFlightFences[flightIndex]), "Failed to submit command buffer"); CP_VK_ASSERT(vkQueueSubmit(Vulkan::GetDevice().GetGraphicsQueue(), 1, &submitInfo, inFlightFences[flightIndex]),
"Failed to submit command buffer");
} }
void SwapChain::EndPresent() void SwapChain::EndPresent()
@@ -147,7 +155,7 @@ namespace Copium
VkPresentInfoKHR presentInfo{}; VkPresentInfoKHR presentInfo{};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1; presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = &renderFinishedSemaphores[flightIndex]; presentInfo.pWaitSemaphores = &renderFinishedSemaphores[imageIndex];
presentInfo.swapchainCount = 1; presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &handle; presentInfo.pSwapchains = &handle;
presentInfo.pImageIndices = &imageIndex; presentInfo.pImageIndices = &imageIndex;
@@ -179,7 +187,7 @@ namespace Copium
glfwWaitEvents(); glfwWaitEvents();
} }
vkDeviceWaitIdle(Vulkan::GetDevice()); Vulkan::GetDevice().WaitIdle();
Destroy(); Destroy();
@@ -243,7 +251,8 @@ namespace Copium
createInfo.pQueueFamilyIndices = nullptr; createInfo.pQueueFamilyIndices = nullptr;
} }
CP_VK_ASSERT(vkCreateSwapchainKHR(Vulkan::GetDevice(), &createInfo, nullptr, &handle), "Failed to initialize the swapchain"); CP_VK_ASSERT(vkCreateSwapchainKHR(Vulkan::GetDevice(), &createInfo, nullptr, &handle),
"Failed to initialize the swapchain");
vkGetSwapchainImagesKHR(Vulkan::GetDevice(), handle, &imageCount, nullptr); vkGetSwapchainImagesKHR(Vulkan::GetDevice(), handle, &imageCount, nullptr);
images.resize(imageCount); images.resize(imageCount);
@@ -303,8 +312,10 @@ namespace Copium
VkSubpassDependency dependency{}; VkSubpassDependency dependency{};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0; dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; dependency.srcStageMask =
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.dstStageMask =
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.srcAccessMask = 0; dependency.srcAccessMask = 0;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
@@ -318,7 +329,8 @@ namespace Copium
renderPassCreateInfo.dependencyCount = 1; renderPassCreateInfo.dependencyCount = 1;
renderPassCreateInfo.pDependencies = &dependency; renderPassCreateInfo.pDependencies = &dependency;
CP_VK_ASSERT(vkCreateRenderPass(Vulkan::GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "Failed to initialze render pass"); CP_VK_ASSERT(vkCreateRenderPass(Vulkan::GetDevice(), &renderPassCreateInfo, nullptr, &renderPass),
"Failed to initialze render pass");
} }
void SwapChain::InitializeFramebuffers() void SwapChain::InitializeFramebuffers()
@@ -338,27 +350,34 @@ namespace Copium
createInfo.height = extent.height; createInfo.height = extent.height;
createInfo.layers = 1; createInfo.layers = 1;
CP_VK_ASSERT(vkCreateFramebuffer(Vulkan::GetDevice(), &createInfo, nullptr, &framebuffers[i]), "Failed to initialize swap chain framebuffer"); CP_VK_ASSERT(vkCreateFramebuffer(Vulkan::GetDevice(), &createInfo, nullptr, &framebuffers[i]),
"Failed to initialize swap chain framebuffer");
} }
} }
void SwapChain::InitializeSyncObjects() void SwapChain::InitializeSyncObjects()
{ {
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT); imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
inFlightFences.resize(MAX_FRAMES_IN_FLIGHT); inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
VkSemaphoreCreateInfo semaphoreCreateInfo{}; VkSemaphoreCreateInfo semaphoreCreateInfo{};
semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i)
{ {
CP_VK_ASSERT(vkCreateSemaphore(Vulkan::GetDevice(), &semaphoreCreateInfo, nullptr, &imageAvailableSemaphores[i]), "Failed to initialize available image semaphore"); CP_VK_ASSERT(vkCreateSemaphore(Vulkan::GetDevice(), &semaphoreCreateInfo, nullptr, &imageAvailableSemaphores[i]),
CP_VK_ASSERT(vkCreateSemaphore(Vulkan::GetDevice(), &semaphoreCreateInfo, nullptr, &renderFinishedSemaphores[i]), "Failed to initialize render finished semaphore"); "Failed to initialize available image semaphore");
VkFenceCreateInfo fenceCreateInfo{}; VkFenceCreateInfo fenceCreateInfo{};
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
CP_VK_ASSERT(vkCreateFence(Vulkan::GetDevice(), &fenceCreateInfo, nullptr, &inFlightFences[i]), "Failed to initialize in flight fence"); CP_VK_ASSERT(vkCreateFence(Vulkan::GetDevice(), &fenceCreateInfo, nullptr, &inFlightFences[i]),
"Failed to initialize in flight fence");
}
renderFinishedSemaphores.resize(images.size());
for (size_t i = 0; i < renderFinishedSemaphores.size(); i++)
{
CP_VK_ASSERT(vkCreateSemaphore(Vulkan::GetDevice(), &semaphoreCreateInfo, nullptr, &renderFinishedSemaphores[i]),
"Failed to initialize render finished semaphore");
} }
} }
@@ -379,7 +398,8 @@ namespace Copium
{ {
for (auto&& availableFormat : availableFormats) for (auto&& availableFormat : availableFormats)
{ {
if (availableFormat.format == VK_FORMAT_R8G8B8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) if (availableFormat.format == VK_FORMAT_R8G8B8A8_UNORM &&
availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
{ {
return availableFormat; return availableFormat;
} }
@@ -410,7 +430,7 @@ namespace Copium
int width, height; int width, height;
glfwGetFramebufferSize(window, &width, &height); glfwGetFramebufferSize(window, &width, &height);
VkExtent2D extent{width, height}; VkExtent2D extent{static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
extent.width = std::clamp(extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); extent.width = std::clamp(extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
extent.height = std::clamp(extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height); extent.height = std::clamp(extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
return extent; return extent;
+9 -5
View File
@@ -1,13 +1,15 @@
#pragma once #pragma once
#include <GLFW/glfw3.h>
#include <vulkan/vulkan.h>
#include <memory>
#include <vector>
#include "copium/buffer/CommandBuffer.h" #include "copium/buffer/CommandBuffer.h"
#include "copium/sampler/DepthAttachment.h" #include "copium/sampler/DepthAttachment.h"
#include "copium/util/Common.h" #include "copium/util/Common.h"
#include <GLFW/glfw3.h>
#include <vector>
#include <vulkan/vulkan.h>
namespace Copium namespace Copium
{ {
struct SwapChainSupportDetails struct SwapChainSupportDetails
@@ -23,8 +25,10 @@ namespace Copium
class SwapChain final class SwapChain final
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(SwapChain); CP_DELETE_COPY_AND_MOVE_CTOR(SwapChain);
public: public:
static const int MAX_FRAMES_IN_FLIGHT = 2; static const int MAX_FRAMES_IN_FLIGHT;
private: private:
VkSwapchainKHR handle; VkSwapchainKHR handle;
VkRenderPass renderPass; VkRenderPass renderPass;
+26 -4
View File
@@ -16,17 +16,22 @@ namespace Copium
std::unique_ptr<SwapChain> Vulkan::swapChain; std::unique_ptr<SwapChain> Vulkan::swapChain;
std::unique_ptr<ImGuiInstance> Vulkan::imGuiInstance; std::unique_ptr<ImGuiInstance> Vulkan::imGuiInstance;
AssetHandle<Texture2D> Vulkan::emptyTexture2D; AssetHandle<Texture2D> Vulkan::emptyTexture2D;
AssetHandle<Texture2D> Vulkan::whiteTexture2D;
void Vulkan::Initialize() void Vulkan::Initialize()
{ {
Timer timer; Timer timer;
timer.Start(); timer.Start();
glfwSetErrorCallback(glfw_error_callback);
CP_ASSERT(glfwInit() == GLFW_TRUE, "Failed to initialize the glfw context");
instance = std::make_unique<Instance>("Copium Engine"); instance = std::make_unique<Instance>("Copium Engine");
window = std::make_unique<Window>("Copium Engine", 1440, 810, WindowMode::Windowed); window = std::make_unique<Window>("Copium Engine", 1440, 810, WindowMode::Windowed);
device = std::make_unique<Device>(); device = std::make_unique<Device>();
swapChain = std::make_unique<SwapChain>(); swapChain = std::make_unique<SwapChain>();
imGuiInstance = std::make_unique<ImGuiInstance>(); imGuiInstance = std::make_unique<ImGuiInstance>();
CP_INFO("Initialized Vulkan in %f seconds", timer.Elapsed()); CP_INFO("Initialized Vulkan in {} seconds", timer.Elapsed());
timer.Start(); timer.Start();
AssetManager::RegisterAssetType<Texture2D>("Texture2D"); AssetManager::RegisterAssetType<Texture2D>("Texture2D");
@@ -36,19 +41,26 @@ namespace Copium
AssetManager::RegisterAssetType<Font>("Font"); AssetManager::RegisterAssetType<Font>("Font");
// TODO: Make the working directory always be relative to the assets folder // TODO: Make the working directory always be relative to the assets folder
// By looking at where the executable is, since that should always be in the bin folder (it currently isn't though) // By looking at where the executable is, since that should always be in the bin folder (it currently isn't
// though)
AssetManager::RegisterAssetDir("assets/"); AssetManager::RegisterAssetDir("assets/");
emptyTexture2D = AssetHandle<Texture2D>{"empty_texture2d", std::make_unique<Texture2D>(std::vector<uint8_t>{255, 0, 255, 255}, 1, 1, SamplerCreator{})}; emptyTexture2D = AssetHandle<Texture2D>{
CP_INFO("Initialized AssetManager in %f seconds", timer.Elapsed()); "empty_texture2d", std::make_unique<Texture2D>(std::vector<uint8_t>{255, 0, 255, 255}, 1, 1, SamplerCreator{})};
whiteTexture2D = AssetHandle<Texture2D>{
"white_texture2d", std::make_unique<Texture2D>(std::vector<uint8_t>{255, 255, 255, 255}, 1, 1, SamplerCreator{})};
CP_INFO("Initialized AssetManager in {} seconds", timer.Elapsed());
} }
void Vulkan::Destroy() void Vulkan::Destroy()
{ {
emptyTexture2D.UnloadAsset(); emptyTexture2D.UnloadAsset();
whiteTexture2D.UnloadAsset();
AssetManager::UnregisterAssetDir("assets/"); AssetManager::UnregisterAssetDir("assets/");
AssetManager::Cleanup(); AssetManager::Cleanup();
imGuiInstance.reset(); imGuiInstance.reset();
device->WaitIdle();
swapChain.reset(); swapChain.reset();
device->CleanupIdleQueue();
device.reset(); device.reset();
window.reset(); window.reset();
instance.reset(); instance.reset();
@@ -79,6 +91,11 @@ namespace Copium
return *imGuiInstance; return *imGuiInstance;
} }
AssetHandle<Texture2D> Vulkan::GetWhiteTexture2D()
{
return whiteTexture2D;
}
AssetHandle<Texture2D> Vulkan::GetEmptyTexture2D() AssetHandle<Texture2D> Vulkan::GetEmptyTexture2D()
{ {
return emptyTexture2D; return emptyTexture2D;
@@ -88,4 +105,9 @@ namespace Copium
{ {
return instance && window && device && swapChain; return instance && window && device && swapChain;
} }
void Vulkan::glfw_error_callback(int error, const char* description)
{
CP_ABORT("GLFW Error {}: {}\n", error, description);
}
} }
+11 -4
View File
@@ -1,21 +1,22 @@
#pragma once #pragma once
#include <memory>
#include "copium/asset/AssetHandle.h" #include "copium/asset/AssetHandle.h"
#include "copium/core/Device.h" #include "copium/core/Device.h"
#include "copium/core/ImGuiInstance.h"
#include "copium/core/Instance.h" #include "copium/core/Instance.h"
#include "copium/core/SwapChain.h" #include "copium/core/SwapChain.h"
#include "copium/core/Window.h" #include "copium/core/Window.h"
#include "copium/core/ImGuiInstance.h"
#include "copium/util/Common.h"
#include "copium/sampler/Texture2D.h" #include "copium/sampler/Texture2D.h"
#include "copium/util/Common.h"
#include <memory>
namespace Copium namespace Copium
{ {
class Vulkan class Vulkan
{ {
CP_STATIC_CLASS(Vulkan); CP_STATIC_CLASS(Vulkan);
private: private:
static std::unique_ptr<Instance> instance; static std::unique_ptr<Instance> instance;
static std::unique_ptr<Window> window; static std::unique_ptr<Window> window;
@@ -24,6 +25,8 @@ namespace Copium
static std::unique_ptr<ImGuiInstance> imGuiInstance; static std::unique_ptr<ImGuiInstance> imGuiInstance;
static AssetHandle<Texture2D> emptyTexture2D; static AssetHandle<Texture2D> emptyTexture2D;
static AssetHandle<Texture2D> whiteTexture2D;
public: public:
static void Initialize(); static void Initialize();
static void Destroy(); static void Destroy();
@@ -33,6 +36,10 @@ namespace Copium
static SwapChain& GetSwapChain(); static SwapChain& GetSwapChain();
static ImGuiInstance& GetImGuiInstance(); static ImGuiInstance& GetImGuiInstance();
static bool Valid(); static bool Valid();
static AssetHandle<Texture2D> GetWhiteTexture2D();
static AssetHandle<Texture2D> GetEmptyTexture2D(); static AssetHandle<Texture2D> GetEmptyTexture2D();
private:
static void glfw_error_callback(int error, const char* description);
}; };
} }
+26 -9
View File
@@ -1,6 +1,9 @@
#include "copium/core/Window.h" #include "copium/core/Window.h"
#include <GLFW/glfw3.h>
#include "copium/core/Vulkan.h" #include "copium/core/Vulkan.h"
#include "copium/event/DropEvent.h"
#include "copium/event/EventDispatcher.h" #include "copium/event/EventDispatcher.h"
#include "copium/event/Input.h" #include "copium/event/Input.h"
#include "copium/event/KeyPressEvent.h" #include "copium/event/KeyPressEvent.h"
@@ -9,15 +12,14 @@
#include "copium/event/MousePressEvent.h" #include "copium/event/MousePressEvent.h"
#include "copium/event/MouseReleaseEvent.h" #include "copium/event/MouseReleaseEvent.h"
#include "copium/event/MouseScrollEvent.h" #include "copium/event/MouseScrollEvent.h"
#include "copium/event/WindowResizeEvent.h"
#include "copium/event/WindowFocusEvent.h" #include "copium/event/WindowFocusEvent.h"
#include "copium/event/WindowResizeEvent.h"
#include <GLFW/glfw3.h>
namespace Copium namespace Copium
{ {
Window::Window(const std::string& windowName, int width, int height, WindowMode mode) Window::Window(const std::string& windowName, int width, int height, WindowMode mode)
: width{width}, height{height} : width{width},
height{height}
{ {
InitializeWindow(windowName, width, height, mode); InitializeWindow(windowName, width, height, mode);
InitializeSurface(); InitializeSurface();
@@ -32,7 +34,6 @@ namespace Copium
bool Window::ShouldClose() const bool Window::ShouldClose() const
{ {
return glfwWindowShouldClose(window); return glfwWindowShouldClose(window);
} }
int Window::GetWidth() const int Window::GetWidth() const
@@ -72,6 +73,8 @@ namespace Copium
{ {
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
CP_ASSERT(glfwVulkanSupported(), "Vulkan is not supported");
switch (mode) switch (mode)
{ {
case WindowMode::Fullscreen: case WindowMode::Fullscreen:
@@ -99,7 +102,7 @@ namespace Copium
break; break;
} }
default: default:
CP_ABORT("Unreachable switch case: %s", ToString(mode).c_str()); CP_ABORT("Unreachable switch case: {}", mode);
} }
CP_ASSERT(window, "Failed to initialize glfw window"); CP_ASSERT(window, "Failed to initialize glfw window");
@@ -111,11 +114,13 @@ namespace Copium
glfwSetCursorPosCallback(window, MouseMoveCallback); glfwSetCursorPosCallback(window, MouseMoveCallback);
glfwSetWindowFocusCallback(window, WindowFocusCallback); glfwSetWindowFocusCallback(window, WindowFocusCallback);
glfwSetScrollCallback(window, MouseScrollCallback); glfwSetScrollCallback(window, MouseScrollCallback);
glfwSetDropCallback(window, DropCallback);
} }
void Window::InitializeSurface() void Window::InitializeSurface()
{ {
CP_VK_ASSERT(glfwCreateWindowSurface(Vulkan::GetInstance(), window, nullptr, &surface), "Failed to create Vulkan surface"); CP_VK_ASSERT(glfwCreateWindowSurface(Vulkan::GetInstance(), window, nullptr, &surface),
"Failed to create Vulkan surface");
} }
void Window::FramebufferResizeCallback(GLFWwindow* glfwWindow, int width, int height) void Window::FramebufferResizeCallback(GLFWwindow* glfwWindow, int width, int height)
@@ -147,7 +152,8 @@ namespace Copium
} }
} }
catch (RuntimeException& exception) catch (RuntimeException& exception)
{} {
}
} }
void Window::MouseButtonCallback(GLFWwindow* glfwWindow, int button, int action, int mods) void Window::MouseButtonCallback(GLFWwindow* glfwWindow, int button, int action, int mods)
@@ -166,7 +172,8 @@ namespace Copium
} }
} }
catch (RuntimeException& exception) catch (RuntimeException& exception)
{} {
}
} }
void Window::MouseMoveCallback(GLFWwindow* glfwWindow, double xpos, double ypos) void Window::MouseMoveCallback(GLFWwindow* glfwWindow, double xpos, double ypos)
@@ -187,4 +194,14 @@ namespace Copium
{ {
EventDispatcher::QueueEvent(MouseScrollEvent{(int)xoffset, (int)yoffset}); EventDispatcher::QueueEvent(MouseScrollEvent{(int)xoffset, (int)yoffset});
} }
void Window::DropCallback(GLFWwindow* window, int pathCount, const char* paths[])
{
std::vector<std::string> filePaths;
for (int i = 0; i < pathCount; i++)
{
filePaths.emplace_back(paths[i]);
}
EventDispatcher::QueueEvent(DropEvent{filePaths});
}
} }
+7 -8
View File
@@ -1,24 +1,22 @@
#pragma once #pragma once
#include <vulkan/vulkan.hpp>
#include "copium/util/Common.h" #include "copium/util/Common.h"
#include "copium/util/Enum.h" #include "copium/util/Enum.h"
#include <vulkan/vulkan.hpp> #define CP_WINDOW_MODE_ENUMS
#define CP_WINDOW_MODE_ENUMS \
Fullscreen, \
BorderlessWindowed, \
Windowed
CP_ENUM_CREATOR(Copium, WindowMode, CP_WINDOW_MODE_ENUMS);
struct GLFWwindow; struct GLFWwindow;
namespace Copium namespace Copium
{ {
CP_ENUM_CREATOR(WindowMode, Fullscreen, BorderlessWindowed, Windowed);
class Window final class Window final
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(Window); CP_DELETE_COPY_AND_MOVE_CTOR(Window);
private: private:
GLFWwindow* window; GLFWwindow* window;
VkSurfaceKHR surface; VkSurfaceKHR surface;
@@ -50,5 +48,6 @@ namespace Copium
static void MouseMoveCallback(GLFWwindow* window, double xpos, double ypos); static void MouseMoveCallback(GLFWwindow* window, double xpos, double ypos);
static void WindowFocusCallback(GLFWwindow* window, int focused); static void WindowFocusCallback(GLFWwindow* window, int focused);
static void MouseScrollCallback(GLFWwindow* window, double xoffset, double yoffset); static void MouseScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
static void DropCallback(GLFWwindow* window, int path_count, const char* paths[]);
}; };
} }
@@ -1,19 +1,28 @@
#pragma once #pragma once
#include "copium/ecs/ECSManager.h" #include "copium/ecs/Config.h"
namespace Copium namespace Copium
{ {
class ECSManager;
template <typename Component> template <typename Component>
class ComponentListener class ComponentListener
{ {
public: public:
using component_type = Component; using component_type = Component;
friend class ECSManager; friend class ECSManager;
protected: protected:
ECSManager* manager; ECSManager* manager;
public: public:
virtual void Added(EntityId entityId, Component& component) {} virtual void Added(EntityId entityId, Component& component)
virtual void Removed(EntityId entityId, Component& component) {} {
}
virtual void Removed(EntityId entityId, Component& component)
{
}
}; };
} }
+116 -26
View File
@@ -1,12 +1,12 @@
#pragma once #pragma once
#include <vector>
#include "copium/ecs/ComponentListener.h"
#include "copium/ecs/ComponentPoolBase.h"
#include "copium/ecs/Config.h" #include "copium/ecs/Config.h"
#include "copium/ecs/EntitySet.h" #include "copium/ecs/EntitySet.h"
#include "copium/ecs/ComponentPoolBase.h" #include "copium/util/Trace.h"
#include "copium/ecs/ComponentListener.h"
#include "copium/util/Common.h"
#include <vector>
namespace Copium namespace Copium
{ {
@@ -14,17 +14,29 @@ namespace Copium
class ComponentPool : public ComponentPoolBase class ComponentPool : public ComponentPoolBase
{ {
using Iterator = typename std::vector<Component>::iterator; using Iterator = typename std::vector<Component>::iterator;
private: private:
std::vector<Component> components; std::vector<Component> components;
ComponentListener<Component>* listener = nullptr; ComponentListener<Component>* listener = nullptr;
enum class QueueOperation
{
Add,
Remove
};
std::vector<QueueOperation> queueOperationOrder;
std::vector<std::pair<EntityId, Component>> addQueue;
std::vector<EntityId> removeQueue;
public: public:
ComponentPool() ComponentPool()
{} {
}
~ComponentPool() override ~ComponentPool() override
{ {
if(listener) if (listener)
delete listener; delete listener;
} }
@@ -33,34 +45,61 @@ namespace Copium
Emplace(entity, component); Emplace(entity, component);
} }
Component& Emplace(EntityId entity, const Component& component) void Emplace(EntityId entity, const Component& component)
{ {
components.push_back(component); addQueue.emplace_back(entity, component);
entities.Emplace(entity); queueOperationOrder.emplace_back(QueueOperation::Add);
if(listener)
listener->Added(entity, components.back());
return components.back();
} }
bool Erase(EntityId entity) override bool Erase(EntityId entity) override
{ {
size_t index = entities.Find(entity); if (entities.Find(entity) == entities.Size())
if (!entities.Erase(entity))
return false; return false;
if (listener)
{ removeQueue.emplace_back(entity);
auto it = components.begin() + index; queueOperationOrder.emplace_back(QueueOperation::Remove);
Component component = *it;
components.erase(it);
listener->Removed(entity, component);
}
else
{
components.erase(components.begin() + index);
}
return true; return true;
} }
void CommitUpdates() override
{
if (queueOperationOrder.empty())
return;
CP_ASSERT(queueOperationOrder.size() == addQueue.size() + removeQueue.size(),
"queueOperationOrder size={} doesn't match the sum of the addQueue size={} and removeQueue size={}, "
"which is {}",
queueOperationOrder.size(),
addQueue.size(),
removeQueue.size(),
addQueue.size() + removeQueue.size());
int addQueueIndex = 0;
int removeQueueIndex = 0;
for (QueueOperation queueOperation : queueOperationOrder)
{
switch (queueOperation)
{
case QueueOperation::Add:
{
CommitAddComponent(addQueueIndex);
addQueueIndex++;
break;
}
case QueueOperation::Remove:
{
CommitRemoveComponent(removeQueueIndex);
removeQueueIndex++;
break;
}
}
}
removeQueue.clear();
addQueue.clear();
queueOperationOrder.clear();
}
Component& At(size_t index) Component& At(size_t index)
{ {
return operator[](index); return operator[](index);
@@ -109,5 +148,56 @@ namespace Copium
{ {
return components.end(); return components.end();
} }
void CommitAddComponent(int queueIndex)
{
CP_ASSERT(
queueIndex < addQueue.size(), "queueIndex={} is greater than the addQueueSize={}", queueIndex, addQueue.size());
const auto& [entity, component] = addQueue[queueIndex];
// TODO: Debugging errors caused by this assert might be a bit difficult, since there wont be any stacktrace for
// where the component was added. Might want to validate this in AddComponent somehow (like looping through
// the queued changes and work out if the component already exists)
CP_ASSERT(Find(entity) == Size(),
"Component already exists in entity (entity={}, Component={})",
entity,
typeid(Component).name());
components.push_back(component);
entities.Emplace(entity);
if (listener)
listener->Added(entity, components.back());
}
void CommitRemoveComponent(int queueIndex)
{
CP_ASSERT(queueIndex < removeQueue.size(),
"queueIndex={} is greater than the removeQueueSize={}",
queueIndex,
removeQueue.size());
const auto& entity = removeQueue[queueIndex];
size_t index = entities.Find(entity);
if (!entities.Erase(entity))
{
// TODO: Debugging warnings caused by this might be a bit difficult, since there wont be any stacktrace for
// where the component was added. Might want to validate this in AddComponent somehow (like looping
// through the queued changes and work out if the component already exists)
CP_WARN("Entity did not contain component (entity={}, Component={})", entity, typeid(Component).name());
return;
}
if (listener)
{
auto it = components.begin() + index;
Component component = *it;
components.erase(it);
listener->Removed(entity, component);
}
else
{
components.erase(components.begin() + index);
}
}
}; };
} }
@@ -1,21 +1,23 @@
#pragma once #pragma once
#include <vector>
#include "copium/ecs/Config.h" #include "copium/ecs/Config.h"
#include "copium/ecs/EntitySet.h" #include "copium/ecs/EntitySet.h"
#include <vector>
namespace Copium namespace Copium
{ {
class ComponentPoolBase class ComponentPoolBase
{ {
protected: protected:
EntitySet entities; EntitySet entities;
public: public:
virtual ~ComponentPoolBase() = default; virtual ~ComponentPoolBase() = default;
virtual size_t Size() = 0; virtual size_t Size() = 0;
virtual bool Erase(EntityId entity) = 0; virtual bool Erase(EntityId entity) = 0;
virtual void CommitUpdates() = 0;
std::vector<EntityId>& GetEntities(); std::vector<EntityId>& GetEntities();
const std::vector<EntityId>& GetEntities() const; const std::vector<EntityId>& GetEntities() const;
}; };
+1
View File
@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <limits> #include <limits>
namespace Copium namespace Copium
+41 -13
View File
@@ -1,32 +1,40 @@
#include "copium/ecs/ECSManager.h" #include "copium/ecs/ECSManager.h"
#include "copium/util/Common.h" #include "copium/util/Trace.h"
namespace Copium namespace Copium
{ {
std::vector<EntityId> ECSManager::emptyEntities = {};
ECSManager::ECSManager() ECSManager::ECSManager()
: systemPool{std::make_unique<SystemPool>(this)} {
{} }
ECSManager::~ECSManager() ECSManager::~ECSManager()
{ {
for (auto&& components : componentPool) for (auto&& components : componentPools)
{ {
delete components.second; delete components.second;
} }
componentPool.clear(); componentPools.clear();
} }
void ECSManager::UpdateSystems() void ECSManager::CommitEntityUpdates()
{ {
systemPool->Update(); for (auto& componentPool : componentPools)
{
componentPool.second->CommitUpdates();
}
} }
void ECSManager::UpdateSystems(const Signal& signal) void ECSManager::UpdateSystems(const Uuid& systemPoolId)
{ {
// TODO: Maybe we want a different pool for Signal based Systems for performance reasons? auto it = systemPools.find(systemPoolId);
// Maybe even a pool for each type of Signal? CP_ASSERT(it != systemPools.end(), "SystemPool doesn't exist with Uuid={}", systemPoolId);
systemPool->Update(signal); it->second->CommitSignals();
CommitEntityUpdates();
it->second->CommitUpdates();
it->second->Update();
} }
size_t ECSManager::GetEntityCount() const size_t ECSManager::GetEntityCount() const
@@ -36,6 +44,13 @@ namespace Copium
EntityId ECSManager::CreateEntity() EntityId ECSManager::CreateEntity()
{ {
if (!destroyedEntityIds.empty())
{
EntityId newId = *destroyedEntityIds.begin();
destroyedEntityIds.erase(destroyedEntityIds.begin());
return newId;
}
CP_ASSERT(currentEntityId != MAX_NUM_ENTITIES, "No more entities available"); CP_ASSERT(currentEntityId != MAX_NUM_ENTITIES, "No more entities available");
entities.emplace(currentEntityId); entities.emplace(currentEntityId);
currentEntityId++; currentEntityId++;
@@ -45,9 +60,22 @@ namespace Copium
void ECSManager::DestroyEntity(EntityId entity) void ECSManager::DestroyEntity(EntityId entity)
{ {
auto it = entities.find(entity); auto it = entities.find(entity);
CP_ASSERT(it != entities.end(), "Entity does not exist in ECSManager (entity=%u)", entity); CP_ASSERT(it != entities.end(), "Entity does not exist in ECSManager (entity={})", entity);
if (entity == currentEntityId - 1)
{
currentEntityId--;
while (!destroyedEntityIds.empty() && *destroyedEntityIds.rbegin() == currentEntityId - 1)
{
destroyedEntityIds.erase(std::prev(destroyedEntityIds.end()));
}
}
else
{
destroyedEntityIds.emplace(entity);
}
entities.erase(it); entities.erase(it);
for (auto&& pool : componentPool) for (auto&& pool : componentPools)
{ {
pool.second->Erase(entity); pool.second->Erase(entity);
} }
+110 -36
View File
@@ -1,46 +1,80 @@
#pragma once #pragma once
#include <functional>
#include <map>
#include <memory>
#include <set>
#include <typeindex>
#include <unordered_set>
#include "copium/ecs/ComponentPool.h" #include "copium/ecs/ComponentPool.h"
#include "copium/ecs/Config.h" #include "copium/ecs/Config.h"
#include "copium/ecs/Signal.h" #include "copium/ecs/Signal.h"
#include "copium/ecs/SystemPool.h" #include "copium/ecs/SystemPool.h"
#include "copium/util/Common.h" #include "copium/util/Common.h"
#include "copium/util/GenericType.h"
#include <functional> #include "copium/util/Trace.h"
#include <map> #include "copium/util/Uuid.h"
#include <typeindex>
#include <unordered_set>
#include <vector>
namespace Copium namespace Copium
{ {
class ECSManager final class ECSManager final
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(ECSManager);
private: private:
std::unordered_set<EntityId> entities; std::unordered_set<EntityId> entities;
std::map<std::type_index, ComponentPoolBase*> componentPool; std::map<std::type_index, ComponentPoolBase*> componentPools;
std::map<Uuid, std::unique_ptr<SystemPool>> systemPools;
EntityId currentEntityId = 1;
std::set<EntityId> destroyedEntityIds;
std::map<std::type_index, GenericType> globalDatas;
std::unique_ptr<SystemPool> systemPool;
int currentEntityId = 1;
public: public:
static std::vector<EntityId> emptyEntities;
ECSManager(); ECSManager();
~ECSManager(); ~ECSManager();
template <typename SystemClass, typename... Args> template <typename SystemClass, typename... Args>
SystemOrderer AddSystem(const Args&... args) SystemOrderer& AddSystem(const Uuid& systemPoolId)
{ {
return systemPool->AddSystem(typeid(SystemClass), new SystemClass{args...}); auto it = systemPools.find(systemPoolId);
if (it == systemPools.end())
it = systemPools.emplace(systemPoolId, std::make_unique<SystemPool>(this)).first;
return it->second->AddSystem(typeid(SystemClass), new SystemClass{});
} }
template <typename SystemClass> template <typename SystemClass>
void RemoveSystem() void RemoveSystem(const Uuid& systemPoolId)
{ {
systemPool->MoveSystemBefore(typeid(SystemClass)); auto it = systemPools.find(systemPoolId);
CP_ASSERT(it != systemPools.end(), "SystemPool doesn't exist with Uuid={}", systemPoolId);
it->second->RemoveSystem(typeid(SystemClass));
if (it->second->IsEmpty())
systemPools.erase(it);
} }
void UpdateSystems(); void CommitEntityUpdates();
void UpdateSystems(const Signal& signal);
void UpdateSystems(const Uuid& systemPoolId);
template <typename S, typename... Args>
void SendSignal(const Args&... args)
{
Signal::ValidateSignal<S>();
for (auto& systemPool : systemPools)
{
S* newSignal = new S{args...};
newSignal->uuid = S::UUID;
systemPool.second->SendSignal(newSignal);
}
}
EntityId CreateEntity(); EntityId CreateEntity();
void DestroyEntity(EntityId entity); void DestroyEntity(EntityId entity);
@@ -62,38 +96,36 @@ namespace Copium
else else
{ {
ComponentPool<Component>* pool{new ComponentPool<Component>{}}; ComponentPool<Component>* pool{new ComponentPool<Component>{}};
componentPool.emplace(GetComponentId<Component>(), pool); componentPools.emplace(GetComponentId<Component>(), pool);
pool->SetComponentListener(listener); pool->SetComponentListener(listener);
} }
} }
template <typename... Components> template <typename... Components>
std::tuple<Components&...> AddComponents(EntityId entity, Components&&... components) void AddComponents(EntityId entity, Components&&... components)
{ {
return std::forward_as_tuple(AddComponent(entity, Components(components))...); (AddComponent(entity, components), ...);
} }
template <typename Component, typename... Args> template <typename Component, typename... Args>
Component& AddComponent(EntityId entity, Args&&... args) void AddComponent(EntityId entity, Args&&... args)
{ {
return AddComponent(entity, Component{args...}); AddComponent(entity, Component{args...});
} }
template <typename Component> template <typename Component>
Component& AddComponent(EntityId entity, const Component& component) void AddComponent(EntityId entity, const Component& component)
{ {
auto pool = GetComponentPool<Component>(); auto pool = GetComponentPool<Component>();
if (pool) if (pool)
{ {
CP_ASSERT(!HasComponent<Component>(entity), "Component already exists in entity (entity=%u, Component=%s)", entity, typeid(Component).name()); pool->Emplace(entity, component);
return pool->Emplace(entity, component);
} }
else else
{ {
ComponentPool<Component>* pool{new ComponentPool{entity, component}}; ComponentPool<Component>* pool{new ComponentPool{entity, component}};
auto ret = componentPool.emplace(GetComponentId<Component>(), pool); auto ret = componentPools.emplace(GetComponentId<Component>(), pool);
return pool->At(0);
} }
} }
@@ -101,7 +133,7 @@ namespace Copium
void RemoveComponent(EntityId entity) void RemoveComponent(EntityId entity)
{ {
auto pool = GetComponentPoolAssure<Component>(); auto pool = GetComponentPoolAssure<Component>();
CP_ASSERT(pool->Erase(entity), "Entity did not contain component (entity=%u, Component=%s)", entity, typeid(Component).name()); pool->Erase(entity);
} }
template <typename... Components> template <typename... Components>
@@ -115,7 +147,8 @@ namespace Copium
{ {
auto pool = GetComponentPoolAssure<Component>(); auto pool = GetComponentPoolAssure<Component>();
Component* component = pool->FindComponent(entity); Component* component = pool->FindComponent(entity);
CP_ASSERT(component, "Entity did not contain component (entity=%u, Component=%s)", entity, typeid(Component).name()); CP_ASSERT(
component, "Entity did not contain component (entity={}, Component={})", entity, typeid(Component).name());
return *component; return *component;
} }
@@ -210,26 +243,67 @@ namespace Copium
return 0; return 0;
} }
template <typename Component, typename... Components>
EntityId Find()
{
return Find<Component, Components...>([](EntityId, const Component& component, const Components&... components)
{ return true; });
}
template <typename T> template <typename T>
std::type_index GetComponentId() std::type_index GetComponentId()
{ {
return std::type_index(typeid(T)); return std::type_index(typeid(T));
} }
private: template <typename T, typename... Args>
template <typename Component> void AddGlobalData(const Args&... args)
ComponentPool<Component>* GetComponentPool()
{ {
auto it = componentPool.find(GetComponentId<Component>()); auto it = globalDatas.find(typeid(T));
return it == componentPool.end() ? nullptr : static_cast<ComponentPool<Component>*>(it->second); CP_ASSERT(!HasGlobalData<T>(), "Global with typeid={} already exists. Do nothing", typeid(T).name());
globalDatas.emplace(typeid(T), GenericType::Create<T>(args...));
}
template <typename T>
T& GetGlobalData()
{
auto it = globalDatas.find(typeid(T));
CP_ASSERT(it != globalDatas.end(), "Global with typeid={} doesn't exist");
return it->second.Get<T>();
}
template <typename T>
bool HasGlobalData()
{
return globalDatas.find(typeid(T)) != globalDatas.end();
}
template <typename T>
void RemoveGlobalData()
{
auto it = globalDatas.find(typeid(T));
CP_ASSERT("Global with typeid={} doesn't exist. Do nothing", typeid(T).name());
globalDatas.erase(it);
} }
template <typename Component> template <typename Component>
ComponentPool<Component>* GetComponentPoolAssure() ComponentPool<std::remove_const_t<Component>>* GetComponentPool()
{ {
auto it = componentPool.find(GetComponentId<Component>()); auto it = componentPools.find(GetComponentId<Component>());
CP_ASSERT(it != componentPool.end(), "Component has not been added to an entity (Component=%s)", typeid(Component).name()); return it == componentPools.end() ? nullptr
return static_cast<ComponentPool<Component>*>(it->second); : static_cast<ComponentPool<std::remove_const_t<Component>>*>(it->second);
}
template <typename Component>
ComponentPool<std::remove_const_t<Component>>* GetComponentPoolAssure()
{
auto it = componentPools.find(GetComponentId<Component>());
CP_ASSERT(it != componentPools.end(),
"Component has not been added to an entity (Component={})",
typeid(Component).name());
return static_cast<ComponentPool<std::remove_const_t<Component>>*>(it->second);
} }
}; };
} }
+18 -7
View File
@@ -3,16 +3,22 @@
namespace Copium namespace Copium
{ {
Entity::Entity() Entity::Entity()
: manager{nullptr}, id{INVALID_ENTITY} : manager{nullptr},
{} id{INVALID_ENTITY}
{
}
Entity::Entity(ECSManager* manager) Entity::Entity(ECSManager* manager)
: manager{manager}, id{INVALID_ENTITY} : manager{manager},
{} id{INVALID_ENTITY}
{
}
Entity::Entity(ECSManager* manager, EntityId id) Entity::Entity(ECSManager* manager, EntityId id)
: manager{manager}, id{id} : manager{manager},
{} id{id}
{
}
Entity::operator EntityId() const Entity::operator EntityId() const
{ {
@@ -34,7 +40,7 @@ namespace Copium
return id != entity.id; return id != entity.id;
} }
Entity::operator bool() const bool Entity::IsValid() const
{ {
if (id == INVALID_ENTITY) if (id == INVALID_ENTITY)
return false; return false;
@@ -43,6 +49,11 @@ namespace Copium
return false; return false;
} }
Entity::operator bool() const
{
return IsValid();
}
void Entity::Invalidate() void Entity::Invalidate()
{ {
id = INVALID_ENTITY; id = INVALID_ENTITY;
+5 -4
View File
@@ -24,6 +24,7 @@ namespace Copium
bool operator!=(const Entity& entity); bool operator!=(const Entity& entity);
operator bool() const; operator bool() const;
bool IsValid() const;
void Invalidate(); void Invalidate();
void Destroy(); void Destroy();
void SetId(EntityId entityId); void SetId(EntityId entityId);
@@ -33,15 +34,15 @@ namespace Copium
static Entity Create(ECSManager* manager); static Entity Create(ECSManager* manager);
template <typename Component, typename... Args> template <typename Component, typename... Args>
inline Component& AddComponent(Args... args) inline void AddComponent(Args... args)
{ {
return manager->AddComponent<Component>(id, args...); manager->AddComponent<Component>(id, args...);
} }
template <typename... Components> template <typename... Components>
std::tuple<Components&...> AddComponents(Components&&... components) void AddComponents(Components&&... components)
{ {
return manager->AddComponents(id, components...); manager->AddComponents(id, components...);
} }
template <typename Component> template <typename Component>
+18 -4
View File
@@ -55,9 +55,23 @@ namespace Copium
return entitiesList.size(); return entitiesList.size();
} }
std::vector<EntityId>& EntitySet::GetList() { return entitiesList; } std::vector<EntityId>& EntitySet::GetList()
const std::vector<EntityId>& EntitySet::GetList() const { return entitiesList; } {
return entitiesList;
}
std::vector<EntityId>::iterator EntitySet::begin() { return entitiesList.begin(); } const std::vector<EntityId>& EntitySet::GetList() const
std::vector<EntityId>::iterator EntitySet::end() { return entitiesList.end(); } {
return entitiesList;
}
std::vector<EntityId>::iterator EntitySet::begin()
{
return entitiesList.begin();
}
std::vector<EntityId>::iterator EntitySet::end()
{
return entitiesList.end();
}
} }
+2 -2
View File
@@ -1,10 +1,10 @@
#pragma once #pragma once
#include "copium/ecs/Config.h"
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "copium/ecs/Config.h"
namespace Copium namespace Copium
{ {
class EntitySet class EntitySet
-10
View File
@@ -1,10 +0,0 @@
#include "copium/ecs/Signal.h"
namespace Copium
{
int Signal::GetAllocatedId()
{
allocatedIds++;
return allocatedIds;
}
}
+27 -33
View File
@@ -1,48 +1,42 @@
#pragma once #pragma once
#define CP_SIGNAL_DECLERATION_DEFINITION() \ #include "copium/util/Uuid.h"
static int GetIdStatic() \
{ \
static int id = GetAllocatedId(); \
return id; \
} \
\
int GetId() const \
{ \
return GetIdStatic(); \
}
#define CP_SIGNAL_DECLERATION(SignalClass) \ #define CP_REGISTER_SIGNAL static inline Copium::Uuid UUID = Copium::Uuid()
static int GetIdStatic(); \
int GetId() const override
#define CP_SIGNAL_DEFINITION(SignalClass) \
int SignalClass::GetIdStatic() \
{ \
static int id = GetAllocatedId(); \
return id; \
} \
\
int SignalClass::GetId() const \
{ \
return GetIdStatic(); \
}
namespace Copium namespace Copium
{ {
class Signal class Signal
{ {
private:
static inline int allocatedIds = 0;
public: public:
Signal() = default; Signal() = default;
virtual ~Signal() = default;
virtual int GetId() const = 0; const Uuid& GetUuid() const
{
return uuid;
}
protected: template <typename T>
static int GetAllocatedId(); static void ValidateSignal()
{
static_assert(std::is_base_of_v<Signal, T>, "ValidateSignal : Given T is does not have Signal as base class");
static_assert(
has_static_uuid<T>(),
"ValidateSignal : Given T has not defined a UUID. Did you add CP_REGISTER_SIGNAL to your Signal class?");
}
private:
friend class ECSManager;
Uuid uuid;
template <typename, typename = void>
struct has_static_uuid : std::false_type
{
}; };
template <typename T>
struct has_static_uuid<T, std::void_t<decltype(T::UUID)>> : std::true_type
{
};
};
} }
+36 -23
View File
@@ -1,43 +1,56 @@
#pragma once #pragma once
#include <set>
#include "copium/ecs/ECSManager.h" #include "copium/ecs/ECSManager.h"
#include "copium/ecs/SystemBase.h" #include "copium/ecs/Signal.h"
#include "copium/ecs/Entity.h"
namespace Copium namespace Copium
{ {
template <typename... Components> class System
class System : public SystemBase
{ {
public: public:
void Run() override virtual ~System() = default;
virtual void Run() = 0;
virtual void HandleSignal(const Signal& signal)
{ {
manager->Each<Components...>([&](EntityId entityId, Components&... components) { RunEntity(Entity{manager, entityId}, components...); });
} }
void Run(const Signal& signal) override const bool IsSignalSubscribed(const Uuid& uuid) const
{ {
manager->Each<Components...>([&](EntityId entityId, Components&... components) { RunEntity(signal, Entity{manager, entityId}, components...); }); return subscribedSignals.count(uuid) != 0;
} }
virtual void RunEntity(Entity entity, Components&... components) {}; template <typename S>
virtual void RunEntity(const Signal& signal, Entity entity, Components&... components) {}; void SubscribeToSignal()
// TODO: Not sure if this is the way entities should be validated
std::set<EntityId> loggedEntities;
template <typename... Components>
bool ValidateEntity(Entity entity)
{ {
if (entity && entity.HasComponents<Components...>()) Signal::ValidateSignal<S>();
subscribedSignals.emplace(S::UUID);
}
template <typename S>
void UnsubscribeToSignal()
{ {
loggedEntities.erase(entity); Signal::ValidateSignal<S>();
return true; subscribedSignals.erase(S::UUID);
} }
if (loggedEntities.find(entity) == loggedEntities.end())
CP_WARN("Invalid Entity"); void SetECSManager(ECSManager* manager)
loggedEntities.emplace(entity); {
return false; this->manager = manager;
} }
template <typename S, typename... Args>
void SendSignal(const Args&... args)
{
manager->SendSignal<S>(args...);
}
protected:
ECSManager* manager;
private:
std::set<Uuid> subscribedSignals{};
}; };
} }
-19
View File
@@ -1,19 +0,0 @@
#pragma once
#include "copium/ecs/Signal.h"
namespace Copium
{
class ECSManager;
class SystemBase
{
friend class SystemPool;
protected:
ECSManager* manager;
public:
virtual void Run() = 0;
virtual void Run(const Signal& signal) = 0;
};
}
+25 -3
View File
@@ -7,14 +7,36 @@ namespace Copium
SystemOrderer::SystemOrderer(std::type_index systemId, SystemPool* systemPool) SystemOrderer::SystemOrderer(std::type_index systemId, SystemPool* systemPool)
: systemId{systemId}, : systemId{systemId},
systemPool{systemPool} systemPool{systemPool}
{} {
}
void SystemOrderer::Before(const std::type_index& otherSystemId) void SystemOrderer::CommitOrdering()
{
for (const auto& [orderOperation, systemId] : orderQueue)
{
switch (orderOperation)
{
case OrderOperation::Before:
{
CommitBefore(systemId);
break;
}
case OrderOperation::After:
{
CommitAfter(systemId);
break;
}
}
}
orderQueue.clear();
}
void SystemOrderer::CommitBefore(const std::type_index& otherSystemId)
{ {
systemPool->MoveSystemBefore(systemId, otherSystemId); systemPool->MoveSystemBefore(systemId, otherSystemId);
} }
void SystemOrderer::After(const std::type_index& otherSystemId) void SystemOrderer::CommitAfter(const std::type_index& otherSystemId)
{ {
systemPool->MoveSystemAfter(systemId, otherSystemId); systemPool->MoveSystemAfter(systemId, otherSystemId);
} }
+21 -11
View File
@@ -1,8 +1,7 @@
#pragma once #pragma once
#include <vector>
#include <map>
#include <typeindex> #include <typeindex>
#include <vector>
namespace Copium namespace Copium
{ {
@@ -10,26 +9,37 @@ namespace Copium
class SystemOrderer class SystemOrderer
{ {
private:
std::type_index systemId;
SystemPool* systemPool = nullptr;
public: public:
SystemOrderer(std::type_index systemId, SystemPool* systemPool); SystemOrderer(std::type_index systemId, SystemPool* systemPool);
template <typename Other> template <typename System>
void Before() void Before()
{ {
Before(typeid(Other)); orderQueue.emplace_back(OrderOperation::Before, typeid(System));
} }
template <typename Other> template <typename System>
void After() void After()
{ {
After(typeid(Other)); orderQueue.emplace_back(OrderOperation::After, typeid(System));
} }
private: private:
void Before(const std::type_index& otherSystemId); enum class OrderOperation
void After(const std::type_index& otherSystemId); {
Before,
After
};
std::type_index systemId;
SystemPool* systemPool = nullptr;
std::vector<std::pair<OrderOperation, std::type_index>> orderQueue;
private:
friend class SystemPool;
void CommitOrdering();
void CommitBefore(const std::type_index& otherSystemId);
void CommitAfter(const std::type_index& otherSystemId);
}; };
} }
+111 -22
View File
@@ -1,10 +1,15 @@
#include "copium/ecs/SystemPool.h" #include "copium/ecs/SystemPool.h"
#include <algorithm>
#include "copium/ecs/System.h"
namespace Copium namespace Copium
{ {
SystemPool::SystemPool(ECSManager* manager) SystemPool::SystemPool(ECSManager* manager)
: manager{manager} : manager{manager}
{} {
}
SystemPool::~SystemPool() SystemPool::~SystemPool()
{ {
@@ -16,28 +21,56 @@ namespace Copium
systems.clear(); systems.clear();
} }
SystemOrderer SystemPool::AddSystem(const std::type_index& systemId, SystemBase* system) SystemOrderer& SystemPool::AddSystem(const std::type_index& systemId, System* system)
{ {
system->manager = manager; system->SetECSManager(manager);
CP_ASSERT(systems.find(systemId) == systems.end(), "System already exist in Ecs"); addQueue.emplace_back(systemId, system, SystemOrderer{systemId, this});
systems.emplace(systemId, system); queueOperationOrder.emplace_back(QueueOperation::Add);
systemOrder.emplace_back(system); return std::get<2>(addQueue.back());
return SystemOrderer{systemId, this};
} }
void SystemPool::RemoveSystem(const std::type_index& systemId) void SystemPool::RemoveSystem(const std::type_index& systemId)
{ {
auto it = systems.find(systemId); removeQueue.emplace_back(systemId);
if (it == systems.end()) queueOperationOrder.emplace_back(QueueOperation::Remove);
{
CP_WARN("System does not exist in Ecs");
return;
} }
auto itOrder = std::find(systemOrder.begin(), systemOrder.end(), it->second); void SystemPool::CommitUpdates()
delete it->second; {
systems.erase(it); if (queueOperationOrder.empty())
systemOrder.erase(itOrder); return;
CP_ASSERT(queueOperationOrder.size() == addQueue.size() + removeQueue.size(),
"queueOperationOrder size={} doesn't match the sum of the addQueue size={} and removeQueue size={}, "
"which is {}",
queueOperationOrder.size(),
addQueue.size(),
removeQueue.size(),
addQueue.size() + removeQueue.size());
int addQueueIndex = 0;
int removeQueueIndex = 0;
for (QueueOperation queueOperation : queueOperationOrder)
{
switch (queueOperation)
{
case QueueOperation::Add:
{
CommitAddSystem(addQueueIndex);
addQueueIndex++;
break;
}
case QueueOperation::Remove:
{
CommitRemoveSystem(removeQueueIndex);
removeQueueIndex++;
break;
}
}
}
removeQueue.clear();
addQueue.clear();
queueOperationOrder.clear();
} }
void SystemPool::Update() void SystemPool::Update()
@@ -48,20 +81,44 @@ namespace Copium
} }
} }
void SystemPool::Update(const Signal& signal) void SystemPool::SendSignal(Signal* signal)
{ {
signalQueue.emplace(signal);
}
void SystemPool::CommitSignals()
{
while (!signalQueue.empty())
{
auto& signal = signalQueue.front();
for (auto& system : systemOrder) for (auto& system : systemOrder)
{ {
system->Run(signal); if (system->IsSignalSubscribed(signal->GetUuid()))
{
system->HandleSignal(*signal);
} }
} }
delete signal;
signalQueue.pop();
}
}
size_t SystemPool::Size() const
{
return systemOrder.size();
}
bool SystemPool::IsEmpty() const
{
return systemOrder.empty();
}
void SystemPool::MoveSystemAfter(const std::type_index& systemId, const std::type_index& afterSystemId) void SystemPool::MoveSystemAfter(const std::type_index& systemId, const std::type_index& afterSystemId)
{ {
auto it1 = systems.find(systemId); auto it1 = systems.find(systemId);
CP_ASSERT(it1 != systems.end(), "System does not exist in SystemPool"); CP_ASSERT(it1 != systems.end(), "System with typeid={} does not exist in SystemPool", systemId.name());
auto it2 = systems.find(afterSystemId); auto it2 = systems.find(afterSystemId);
CP_ASSERT(it2 != systems.end(), "System does not exist in SystemPool"); CP_ASSERT(it2 != systems.end(), "System with typeid={} does not exist in SystemPool", afterSystemId.name());
auto itSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it1->second); auto itSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it1->second);
auto itAfterSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it2->second); auto itAfterSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it2->second);
@@ -71,13 +128,45 @@ namespace Copium
void SystemPool::MoveSystemBefore(const std::type_index& systemId, const std::type_index& beforeSystemId) void SystemPool::MoveSystemBefore(const std::type_index& systemId, const std::type_index& beforeSystemId)
{ {
auto it1 = systems.find(systemId); auto it1 = systems.find(systemId);
CP_ASSERT(it1 != systems.end(), "System does not exist in SystemPool"); CP_ASSERT(it1 != systems.end(), "System with typeid={} does not exist in SystemPool", systemId.name());
auto it2 = systems.find(beforeSystemId); auto it2 = systems.find(beforeSystemId);
CP_ASSERT(it2 != systems.end(), "System does not exist in SystemPool"); CP_ASSERT(it2 != systems.end(), "System with typeid={} does not exist in SystemPool", beforeSystemId.name());
auto itSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it1->second); auto itSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it1->second);
auto itBeforeSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it2->second); auto itBeforeSystemId = std::find(systemOrder.rbegin(), systemOrder.rend(), it2->second);
std::rotate(itSystemId, itSystemId + 1, itBeforeSystemId + 1); std::rotate(itSystemId, itSystemId + 1, itBeforeSystemId + 1);
} }
void SystemPool::CommitAddSystem(int queueIndex)
{
CP_ASSERT(
queueIndex < addQueue.size(), "queueIndex={} is greater than the addQueueSize={}", queueIndex, addQueue.size());
auto& [systemId, system, ordering] = addQueue[queueIndex];
CP_ASSERT(systems.find(systemId) == systems.end(), "System with typeid={} already exists in SystemPool");
systems.emplace(systemId, system);
systemOrder.emplace_back(system);
ordering.CommitOrdering();
}
void SystemPool::CommitRemoveSystem(int queueIndex)
{
CP_ASSERT(queueIndex < removeQueue.size(),
"queueIndex={} is greater than the removeQueueSize={}",
queueIndex,
removeQueue.size());
const auto& systemId = removeQueue[queueIndex];
auto it = systems.find(systemId);
CP_ASSERT(it != systems.end(), "System with typeid={} does not exist in SystemPool", systemId.name());
auto itOrder = std::find(systemOrder.begin(), systemOrder.end(), it->second);
CP_ASSERT(itOrder != systemOrder.end(), "System with typeid={} does not exist in systemOrder", systemId.name());
delete it->second;
systems.erase(it);
systemOrder.erase(itOrder);
}
} }
+33 -12
View File
@@ -1,36 +1,57 @@
#pragma once #pragma once
#include "copium/ecs/SystemBase.h"
#include "copium/ecs/SystemOrderer.h"
#include "copium/ecs/Signal.h"
#include "copium/util/Common.h"
#include <vector>
#include <map> #include <map>
#include <queue>
#include <typeindex> #include <typeindex>
#include <vector>
#include "copium/ecs/Signal.h"
#include "copium/ecs/SystemOrderer.h"
#include "copium/util/Common.h"
namespace Copium namespace Copium
{ {
class ECSManager; class ECSManager;
class System;
class SystemPool final class SystemPool final
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(SystemPool); CP_DELETE_COPY_AND_MOVE_CTOR(SystemPool);
private:
ECSManager* manager;
std::map<std::type_index, SystemBase*> systems;
std::vector<SystemBase*> systemOrder;
public: public:
SystemPool(ECSManager* manager); SystemPool(ECSManager* manager);
~SystemPool(); ~SystemPool();
SystemOrderer AddSystem(const std::type_index& systemId, SystemBase* system); SystemOrderer& AddSystem(const std::type_index& systemId, System* system);
void RemoveSystem(const std::type_index& systemId); void RemoveSystem(const std::type_index& systemId);
void Update(); void Update();
void Update(const Signal& signal); void SendSignal(Signal* signal);
void CommitSignals();
void CommitUpdates();
size_t Size() const;
bool IsEmpty() const;
void MoveSystemAfter(const std::type_index& systemId, const std::type_index& afterSystemId); void MoveSystemAfter(const std::type_index& systemId, const std::type_index& afterSystemId);
void MoveSystemBefore(const std::type_index& systemId, const std::type_index& beforeSystemId); void MoveSystemBefore(const std::type_index& systemId, const std::type_index& beforeSystemId);
private:
ECSManager* manager;
std::map<std::type_index, System*> systems;
std::vector<System*> systemOrder;
enum class QueueOperation
{
Add,
Remove
};
std::vector<QueueOperation> queueOperationOrder;
std::vector<std::tuple<std::type_index, System*, SystemOrderer>> addQueue;
std::vector<std::type_index> removeQueue;
std::queue<Signal*> signalQueue;
void CommitAddSystem(int queueIndex);
void CommitRemoveSystem(int queueIndex);
}; };
} }
+113
View File
@@ -0,0 +1,113 @@
#pragma once
#include "copium/ecs/ECSManager.h"
#include "copium/ecs/Entity.h"
namespace Copium
{
template <typename Component, typename... Components>
struct View
{
class Iterator
{
public:
std::tuple<Entity, Component&, Components&...> operator*()
{
EntityId entityId{entities[index]};
CP_ASSERT((manager->HasComponents<Component, Components...>(entityId)),
"entity doesn't contains all components");
return std::forward_as_tuple<Entity, Component&, Components&...>(
Entity{manager, entityId}, firstPool->At(index), manager->GetComponent<Components>(entityId)...);
}
Iterator& operator++()
{
++index;
FindNextEntity();
return *this;
}
Iterator operator++(int)
{
Iterator it = *this;
++*this;
return it;
}
Iterator operator+(size_t advance)
{
Iterator it = *this;
for (int i = 0; i < advance; i++)
++it;
return it;
}
bool operator==(const Iterator& other) const
{
return index == other.index;
}
bool operator!=(const Iterator& other) const
{
return !(*this == other);
}
private:
friend class View;
ECSManager* manager;
ComponentPool<std::remove_const_t<Component>>* firstPool;
const std::vector<EntityId>& entities;
int index;
Iterator(ECSManager* manager, ComponentPool<std::remove_const_t<Component>>* firstPool)
: manager{manager},
firstPool{firstPool},
entities{firstPool ? firstPool->GetEntities() : ECSManager::emptyEntities},
index{0}
{
}
static Iterator Begin(ECSManager* manager)
{
Iterator iterator{manager, manager->GetComponentPool<Component>()};
iterator.FindNextEntity();
return iterator;
}
static Iterator End(ECSManager* manager)
{
Iterator iterator{manager, manager->GetComponentPool<Component>()};
if (iterator.firstPool)
iterator.index = iterator.firstPool->GetEntities().size();
return iterator;
}
void FindNextEntity()
{
while (index < entities.size() && !manager->HasComponents<Components...>(entities[index]))
{
++index;
}
}
};
View(ECSManager* manager)
: manager{manager}
{
}
Iterator begin()
{
return Iterator::Begin(manager);
}
Iterator end()
{
return Iterator::End(manager);
}
private:
ECSManager* manager;
};
}
@@ -0,0 +1,15 @@
#include "copium/event/DropEvent.h"
namespace Copium
{
DropEvent::DropEvent(const std::vector<std::string>& filePaths)
: Event{EventType::Drop},
filePaths{filePaths}
{
}
const std::vector<std::string>& DropEvent::GetFilePaths() const
{
return filePaths;
}
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#include "copium/event/Event.h"
namespace Copium
{
class DropEvent : public Event
{
private:
std::vector<std::string> filePaths;
public:
DropEvent(const std::vector<std::string>& filePaths);
const std::vector<std::string>& GetFilePaths() const;
};
}
+2 -1
View File
@@ -5,7 +5,8 @@ namespace Copium
Event::Event(EventType type) Event::Event(EventType type)
: type{type} : type{type}
{} {
}
EventType Event::GetType() const EventType Event::GetType() const
{ {
+3
View File
@@ -8,9 +8,12 @@ namespace Copium
{ {
private: private:
EventType type; EventType type;
public: public:
Event(EventType type); Event(EventType type);
virtual ~Event() = default;
EventType GetType() const; EventType GetType() const;
}; };
} }
@@ -1,6 +1,6 @@
#include "copium/event/EventDispatcher.h" #include "copium/event/EventDispatcher.h"
#include "copium/util/Common.h" #include "copium/util/Trace.h"
namespace Copium namespace Copium
{ {
@@ -35,7 +35,7 @@ namespace Copium
focusedEventHandler = eventHandler; focusedEventHandler = eventHandler;
return; return;
default: default:
CP_ABORT("Unreachable switch case: %s", ToString(result).c_str()); CP_ABORT("Unreachable switch case: {}", result);
} }
} }
} }
@@ -1,12 +1,12 @@
#pragma once #pragma once
#include <memory>
#include <queue>
#include <vector>
#include "copium/event/Event.h" #include "copium/event/Event.h"
#include "copium/event/EventHandler.h" #include "copium/event/EventHandler.h"
#include <memory>
#include <vector>
#include <queue>
namespace Copium namespace Copium
{ {
class EventDispatcher class EventDispatcher
@@ -15,12 +15,14 @@ namespace Copium
static EventHandler* focusedEventHandler; static EventHandler* focusedEventHandler;
static std::vector<EventHandler*> eventHandlers; static std::vector<EventHandler*> eventHandlers;
static std::queue<std::unique_ptr<Event>> events; static std::queue<std::unique_ptr<Event>> events;
public: public:
template <typename EventType> template <typename EventType>
static void QueueEvent(const EventType& event) static void QueueEvent(const EventType& event)
{ {
events.push(std::make_unique<EventType>(event)); events.push(std::make_unique<EventType>(event));
} }
static void Dispatch(); static void Dispatch();
static void AddEventHandler(EventHandler* eventHandler); static void AddEventHandler(EventHandler* eventHandler);
static void RemoveEventHandler(EventHandler* eventHandler); static void RemoveEventHandler(EventHandler* eventHandler);
+4 -6
View File
@@ -2,9 +2,7 @@
#include "copium/util/Enum.h" #include "copium/util/Enum.h"
#define CP_EVENT_RESULT_ENUMS \ namespace Copium
Continue, \ {
Handled, \ CP_ENUM_CREATOR(EventResult, Continue, Handled, Focus);
Focus }
CP_ENUM_CREATOR(Copium, EventResult, CP_EVENT_RESULT_ENUMS);
@@ -1,15 +0,0 @@
#include "copium/event/EventSignal.h"
namespace Copium
{
EventSignal::EventSignal(const Event& event)
: event{event}
{}
const Event& EventSignal::GetEvent() const
{
return event;
}
CP_SIGNAL_DEFINITION(EventSignal);
}
@@ -1,22 +0,0 @@
#pragma once
#include "copium/event/Event.h"
#include "copium/ecs/Signal.h"
namespace Copium
{
class EventSignal : public Signal
{
private:
const Event& event;
public:
EventSignal(const Event& event);
const Event& GetEvent() const;
CP_SIGNAL_DECLERATION(EventSignal);
};
}
+14 -7
View File
@@ -2,10 +2,17 @@
#include "copium/util/Enum.h" #include "copium/util/Enum.h"
#define CP_EVENT_TYPE_ENUMS \ namespace Copium
MouseMove, MousePress, MouseRelease, MouseScroll, \ {
KeyPress, KeyRelease, \ CP_ENUM_CREATOR(EventType,
WindowResize, WindowFocus, \ MouseMove,
ViewportResize MousePress,
MouseRelease,
CP_ENUM_CREATOR(Copium, EventType, CP_EVENT_TYPE_ENUMS); MouseScroll,
KeyPress,
KeyRelease,
WindowResize,
WindowFocus,
ViewportResize,
Drop);
}
+260 -136
View File
@@ -1,10 +1,11 @@
#include "copium/event/Input.h" #include "copium/event/Input.h"
#include "copium/util/Common.h"
#include "copium/core/Vulkan.h"
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include "copium/core/Vulkan.h"
#include "copium/event/InputCode.h"
#include "copium/util/Trace.h"
namespace Copium namespace Copium
{ {
bool Input::keyDownList[MAX_NUM_KEYS]; bool Input::keyDownList[MAX_NUM_KEYS];
@@ -16,49 +17,49 @@ namespace Copium
bool Input::IsKeyPressed(int keyCode) bool Input::IsKeyPressed(int keyCode)
{ {
CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range %d", keyCode); CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range {}", keyCode);
return keyEventList[keyCode] && keyDownList[keyCode]; return keyEventList[keyCode] && keyDownList[keyCode];
} }
bool Input::IsKeyReleased(int keyCode) bool Input::IsKeyReleased(int keyCode)
{ {
CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range %d", keyCode); CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range {}", keyCode);
return keyEventList[keyCode] && !keyDownList[keyCode]; return keyEventList[keyCode] && !keyDownList[keyCode];
} }
bool Input::IsKeyDown(int keyCode) bool Input::IsKeyDown(int keyCode)
{ {
CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range %d", keyCode); CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range {}", keyCode);
return keyDownList[keyCode]; return keyDownList[keyCode];
} }
bool Input::IsKeyUp(int keyCode) bool Input::IsKeyUp(int keyCode)
{ {
CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range %d", keyCode); CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range {}", keyCode);
return !keyDownList[keyCode]; return !keyDownList[keyCode];
} }
bool Input::IsMousePressed(int button) bool Input::IsMousePressed(int button)
{ {
CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range %d", button); CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range {}", button);
return mouseEventList[button] && mouseDownList[button]; return mouseEventList[button] && mouseDownList[button];
} }
bool Input::IsMouseReleased(int button) bool Input::IsMouseReleased(int button)
{ {
CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range %d", button); CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range {}", button);
return mouseEventList[button] && !mouseDownList[button]; return mouseEventList[button] && !mouseDownList[button];
} }
bool Input::IsMouseDown(int button) bool Input::IsMouseDown(int button)
{ {
CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range %d", button); CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range {}", button);
return mouseDownList[button]; return mouseDownList[button];
} }
bool Input::IsMouseUp(int button) bool Input::IsMouseUp(int button)
{ {
CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range %d", button); CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range {}", button);
return !mouseDownList[button]; return !mouseDownList[button];
} }
@@ -74,19 +75,20 @@ namespace Copium
glm::vec2 Input::GetMouseWindowPos() glm::vec2 Input::GetMouseWindowPos()
{ {
return glm::vec2{(mousePos.x + 1.0f) * 0.5f * Vulkan::GetWindow().GetWidth(), (1.0f - mousePos.y) * 0.5f * Vulkan::GetWindow().GetHeight()}; return glm::vec2{(mousePos.x + 1.0f) * 0.5f * Vulkan::GetWindow().GetWidth(),
(1.0f - mousePos.y) * 0.5f * Vulkan::GetWindow().GetHeight()};
} }
void Input::OnKey(int keyCode, bool pressed) void Input::OnKey(int keyCode, bool pressed)
{ {
CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range %d", keyCode); CP_ASSERT(keyCode >= 0 && keyCode < MAX_NUM_KEYS, "KeyCode is out of range {}", keyCode);
keyDownList[keyCode] = pressed; keyDownList[keyCode] = pressed;
keyEventList[keyCode] = true; keyEventList[keyCode] = true;
} }
void Input::OnMouse(int button, bool pressed) void Input::OnMouse(int button, bool pressed)
{ {
CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range %d", button); CP_ASSERT(button >= 0 && button < MAX_NUM_MOUSE_BUTTONS, "button is out of range {}", button);
mouseDownList[button] = pressed; mouseDownList[button] = pressed;
mouseEventList[button] = true; mouseEventList[button] = true;
} }
@@ -119,128 +121,250 @@ namespace Copium
{ {
switch (key) switch (key)
{ {
case CP_KEY_SPACE: return "Space"; case CP_KEY_SPACE:
case CP_KEY_APOSTROPHE: return "\'"; return "Space";
case CP_KEY_COMMA: return ","; case CP_KEY_APOSTROPHE:
case CP_KEY_MINUS: return "-"; return "\'";
case CP_KEY_PERIOD: return "."; case CP_KEY_COMMA:
case CP_KEY_SLASH: return "/"; return ",";
case CP_KEY_0: return "0"; case CP_KEY_MINUS:
case CP_KEY_1: return "1"; return "-";
case CP_KEY_2: return "2"; case CP_KEY_PERIOD:
case CP_KEY_3: return "3"; return ".";
case CP_KEY_4: return "4"; case CP_KEY_SLASH:
case CP_KEY_5: return "5"; return "/";
case CP_KEY_6: return "6"; case CP_KEY_0:
case CP_KEY_7: return "7"; return "0";
case CP_KEY_8: return "8"; case CP_KEY_1:
case CP_KEY_9: return "9"; return "1";
case CP_KEY_SEMICOLON: return ";"; case CP_KEY_2:
case CP_KEY_EQUAL: return "="; return "2";
case CP_KEY_A: return "A"; case CP_KEY_3:
case CP_KEY_B: return "B"; return "3";
case CP_KEY_C: return "C"; case CP_KEY_4:
case CP_KEY_D: return "D"; return "4";
case CP_KEY_E: return "E"; case CP_KEY_5:
case CP_KEY_F: return "F"; return "5";
case CP_KEY_G: return "G"; case CP_KEY_6:
case CP_KEY_H: return "H"; return "6";
case CP_KEY_I: return "I"; case CP_KEY_7:
case CP_KEY_J: return "J"; return "7";
case CP_KEY_K: return "K"; case CP_KEY_8:
case CP_KEY_L: return "L"; return "8";
case CP_KEY_M: return "M"; case CP_KEY_9:
case CP_KEY_N: return "N"; return "9";
case CP_KEY_O: return "O"; case CP_KEY_SEMICOLON:
case CP_KEY_P: return "P"; return ";";
case CP_KEY_Q: return "Q"; case CP_KEY_EQUAL:
case CP_KEY_R: return "R"; return "=";
case CP_KEY_S: return "S"; case CP_KEY_A:
case CP_KEY_T: return "T"; return "A";
case CP_KEY_U: return "U"; case CP_KEY_B:
case CP_KEY_V: return "V"; return "B";
case CP_KEY_W: return "W"; case CP_KEY_C:
case CP_KEY_X: return "X"; return "C";
case CP_KEY_Y: return "Y"; case CP_KEY_D:
case CP_KEY_Z: return "Z"; return "D";
case CP_KEY_LEFT_BRACKET: return "["; case CP_KEY_E:
case CP_KEY_BACKSLASH: return "\\"; return "E";
case CP_KEY_RIGHT_BRACKET: return "]"; case CP_KEY_F:
case CP_KEY_GRAVE_ACCENT: return "Grave Accent ?"; return "F";
case CP_KEY_WORLD_1: return "World 1 ?"; case CP_KEY_G:
case CP_KEY_WORLD_2: return "World 2 ?"; return "G";
case CP_KEY_ESCAPE: return "Escape"; case CP_KEY_H:
case CP_KEY_ENTER: return "Enter"; return "H";
case CP_KEY_TAB: return "Tab"; case CP_KEY_I:
case CP_KEY_BACKSPACE: return "Return"; return "I";
case CP_KEY_INSERT: return "Insert"; case CP_KEY_J:
case CP_KEY_DELETE: return "Delete"; return "J";
case CP_KEY_RIGHT: return "Right Arrow"; case CP_KEY_K:
case CP_KEY_LEFT: return "Left Arrow"; return "K";
case CP_KEY_DOWN: return "Down Arrow"; case CP_KEY_L:
case CP_KEY_UP: return "Up Arrow"; return "L";
case CP_KEY_PAGE_UP: return "Page Up"; case CP_KEY_M:
case CP_KEY_PAGE_DOWN: return "Page Down"; return "M";
case CP_KEY_HOME: return "Home"; case CP_KEY_N:
case CP_KEY_END: return "End"; return "N";
case CP_KEY_CAPS_LOCK: return "Caps Lock"; case CP_KEY_O:
case CP_KEY_SCROLL_LOCK: return "Scroll Lock"; return "O";
case CP_KEY_NUM_LOCK: return "Num Lock"; case CP_KEY_P:
case CP_KEY_PRINT_SCREEN: return "Print Screen"; return "P";
case CP_KEY_PAUSE: return "Pause"; case CP_KEY_Q:
case CP_KEY_F1: return "F1"; return "Q";
case CP_KEY_F2: return "F2"; case CP_KEY_R:
case CP_KEY_F3: return "F3"; return "R";
case CP_KEY_F4: return "F4"; case CP_KEY_S:
case CP_KEY_F5: return "F5"; return "S";
case CP_KEY_F6: return "F6"; case CP_KEY_T:
case CP_KEY_F7: return "F7"; return "T";
case CP_KEY_F8: return "F8"; case CP_KEY_U:
case CP_KEY_F9: return "F9"; return "U";
case CP_KEY_F10: return "F10"; case CP_KEY_V:
case CP_KEY_F11: return "F11"; return "V";
case CP_KEY_F12: return "F12"; case CP_KEY_W:
case CP_KEY_F13: return "F13"; return "W";
case CP_KEY_F14: return "F14"; case CP_KEY_X:
case CP_KEY_F15: return "F15"; return "X";
case CP_KEY_F16: return "F16"; case CP_KEY_Y:
case CP_KEY_F17: return "F17"; return "Y";
case CP_KEY_F18: return "F18"; case CP_KEY_Z:
case CP_KEY_F19: return "F19"; return "Z";
case CP_KEY_F20: return "F20"; case CP_KEY_LEFT_BRACKET:
case CP_KEY_F21: return "F21"; return "[";
case CP_KEY_F22: return "F22"; case CP_KEY_BACKSLASH:
case CP_KEY_F23: return "F23"; return "\\";
case CP_KEY_F24: return "F24"; case CP_KEY_RIGHT_BRACKET:
case CP_KEY_F25: return "F25"; return "]";
case CP_KEY_KP_0: return "Keypad 0"; case CP_KEY_GRAVE_ACCENT:
case CP_KEY_KP_1: return "Keypad 1"; return "Grave Accent ?";
case CP_KEY_KP_2: return "Keypad 2"; case CP_KEY_WORLD_1:
case CP_KEY_KP_3: return "Keypad 3"; return "World 1 ?";
case CP_KEY_KP_4: return "Keypad 4"; case CP_KEY_WORLD_2:
case CP_KEY_KP_5: return "Keypad 5"; return "World 2 ?";
case CP_KEY_KP_6: return "Keypad 6"; case CP_KEY_ESCAPE:
case CP_KEY_KP_7: return "Keypad 7"; return "Escape";
case CP_KEY_KP_8: return "Keypad 8"; case CP_KEY_ENTER:
case CP_KEY_KP_9: return "Keypad 9"; return "Enter";
case CP_KEY_KP_DECIMAL: return "Keypad ,"; case CP_KEY_TAB:
case CP_KEY_KP_DIVIDE: return "Keypad /"; return "Tab";
case CP_KEY_KP_MULTIPLY: return "Keypad *"; case CP_KEY_BACKSPACE:
case CP_KEY_KP_SUBTRACT: return "Keypad -"; return "Return";
case CP_KEY_KP_ADD: return "Keypad +"; case CP_KEY_INSERT:
case CP_KEY_KP_ENTER: return "Keypad Enter"; return "Insert";
case CP_KEY_KP_EQUAL: return "Keypad ="; case CP_KEY_DELETE:
case CP_KEY_LEFT_SHIFT: return "Left Shift"; return "Delete";
case CP_KEY_LEFT_CONTROL: return "Left Control"; case CP_KEY_RIGHT:
case CP_KEY_LEFT_ALT: return "Left Alt"; return "Right Arrow";
case CP_KEY_LEFT_SUPER: return "Left Super"; case CP_KEY_LEFT:
case CP_KEY_RIGHT_SHIFT: return "Right Shift"; return "Left Arrow";
case CP_KEY_RIGHT_CONTROL: return "Right Control"; case CP_KEY_DOWN:
case CP_KEY_RIGHT_ALT: return "Right Alt"; return "Down Arrow";
case CP_KEY_RIGHT_SUPER: return "Right Super"; case CP_KEY_UP:
case CP_KEY_MENU: return "Menu"; return "Up Arrow";
case CP_KEY_UNBOUND: return "Unbound"; case CP_KEY_PAGE_UP:
default: return "Unknown " + std::to_string(key); return "Page Up";
case CP_KEY_PAGE_DOWN:
return "Page Down";
case CP_KEY_HOME:
return "Home";
case CP_KEY_END:
return "End";
case CP_KEY_CAPS_LOCK:
return "Caps Lock";
case CP_KEY_SCROLL_LOCK:
return "Scroll Lock";
case CP_KEY_NUM_LOCK:
return "Num Lock";
case CP_KEY_PRINT_SCREEN:
return "Print Screen";
case CP_KEY_PAUSE:
return "Pause";
case CP_KEY_F1:
return "F1";
case CP_KEY_F2:
return "F2";
case CP_KEY_F3:
return "F3";
case CP_KEY_F4:
return "F4";
case CP_KEY_F5:
return "F5";
case CP_KEY_F6:
return "F6";
case CP_KEY_F7:
return "F7";
case CP_KEY_F8:
return "F8";
case CP_KEY_F9:
return "F9";
case CP_KEY_F10:
return "F10";
case CP_KEY_F11:
return "F11";
case CP_KEY_F12:
return "F12";
case CP_KEY_F13:
return "F13";
case CP_KEY_F14:
return "F14";
case CP_KEY_F15:
return "F15";
case CP_KEY_F16:
return "F16";
case CP_KEY_F17:
return "F17";
case CP_KEY_F18:
return "F18";
case CP_KEY_F19:
return "F19";
case CP_KEY_F20:
return "F20";
case CP_KEY_F21:
return "F21";
case CP_KEY_F22:
return "F22";
case CP_KEY_F23:
return "F23";
case CP_KEY_F24:
return "F24";
case CP_KEY_F25:
return "F25";
case CP_KEY_KP_0:
return "Keypad 0";
case CP_KEY_KP_1:
return "Keypad 1";
case CP_KEY_KP_2:
return "Keypad 2";
case CP_KEY_KP_3:
return "Keypad 3";
case CP_KEY_KP_4:
return "Keypad 4";
case CP_KEY_KP_5:
return "Keypad 5";
case CP_KEY_KP_6:
return "Keypad 6";
case CP_KEY_KP_7:
return "Keypad 7";
case CP_KEY_KP_8:
return "Keypad 8";
case CP_KEY_KP_9:
return "Keypad 9";
case CP_KEY_KP_DECIMAL:
return "Keypad ,";
case CP_KEY_KP_DIVIDE:
return "Keypad /";
case CP_KEY_KP_MULTIPLY:
return "Keypad *";
case CP_KEY_KP_SUBTRACT:
return "Keypad -";
case CP_KEY_KP_ADD:
return "Keypad +";
case CP_KEY_KP_ENTER:
return "Keypad Enter";
case CP_KEY_KP_EQUAL:
return "Keypad =";
case CP_KEY_LEFT_SHIFT:
return "Left Shift";
case CP_KEY_LEFT_CONTROL:
return "Left Control";
case CP_KEY_LEFT_ALT:
return "Left Alt";
case CP_KEY_LEFT_SUPER:
return "Left Super";
case CP_KEY_RIGHT_SHIFT:
return "Right Shift";
case CP_KEY_RIGHT_CONTROL:
return "Right Control";
case CP_KEY_RIGHT_ALT:
return "Right Alt";
case CP_KEY_RIGHT_SUPER:
return "Right Super";
case CP_KEY_MENU:
return "Menu";
case CP_KEY_UNBOUND:
return "Unbound";
default:
return "Unknown " + std::to_string(key);
} }
} }
} }
+3 -5
View File
@@ -1,11 +1,9 @@
#pragma once #pragma once
#include <vector>
#include "copium/event/InputCode.h"
#include "copium/util/BoundingBox.h"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <string>
#include "copium/util/BoundingBox.h"
namespace Copium namespace Copium
{ {
+1 -3
View File
@@ -1,7 +1,5 @@
#pragma once #pragma once
#include "copium/util/Enum.h"
#define CP_MOUSE_LEFT 0 #define CP_MOUSE_LEFT 0
#define CP_MOUSE_RIGHT 1 #define CP_MOUSE_RIGHT 1
#define CP_MOUSE_MIDDLE 2 #define CP_MOUSE_MIDDLE 2
@@ -128,4 +126,4 @@
#define CP_KEY_RIGHT_ALT 346 #define CP_KEY_RIGHT_ALT 346
#define CP_KEY_RIGHT_SUPER 347 #define CP_KEY_RIGHT_SUPER 347
#define CP_KEY_MENU 348 #define CP_KEY_MENU 348
#define CP_KEY_UNBOUND 0xffffffff #define CP_KEY_UNBOUND 0x0fffffff
@@ -3,8 +3,10 @@
namespace Copium namespace Copium
{ {
KeyPressEvent::KeyPressEvent(int button) KeyPressEvent::KeyPressEvent(int button)
: Event{EventType::KeyPress}, button{button} : Event{EventType::KeyPress},
{} button{button}
{
}
int KeyPressEvent::GetButton() const int KeyPressEvent::GetButton() const
{ {
@@ -8,6 +8,7 @@ namespace Copium
{ {
private: private:
int button; int button;
public: public:
KeyPressEvent(int button); KeyPressEvent(int button);
@@ -3,8 +3,10 @@
namespace Copium namespace Copium
{ {
KeyReleaseEvent::KeyReleaseEvent(int button) KeyReleaseEvent::KeyReleaseEvent(int button)
: Event{EventType::KeyRelease}, button{button} : Event{EventType::KeyRelease},
{} button{button}
{
}
int KeyReleaseEvent::GetButton() const int KeyReleaseEvent::GetButton() const
{ {
@@ -8,6 +8,7 @@ namespace Copium
{ {
private: private:
int button; int button;
public: public:
KeyReleaseEvent(int button); KeyReleaseEvent(int button);
@@ -3,8 +3,11 @@
namespace Copium namespace Copium
{ {
MouseMoveEvent::MouseMoveEvent(glm::vec2 pos, glm::vec2 delta) MouseMoveEvent::MouseMoveEvent(glm::vec2 pos, glm::vec2 delta)
: Event{EventType::MouseMove}, pos{pos}, delta{delta} : Event{EventType::MouseMove},
{} pos{pos},
delta{delta}
{
}
glm::vec2 MouseMoveEvent::GetPos() const glm::vec2 MouseMoveEvent::GetPos() const
{ {
@@ -1,9 +1,9 @@
#pragma once #pragma once
#include "copium/event/Event.h"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "copium/event/Event.h"
namespace Copium namespace Copium
{ {
class MouseMoveEvent : public Event class MouseMoveEvent : public Event
@@ -11,6 +11,7 @@ namespace Copium
private: private:
glm::vec2 pos; glm::vec2 pos;
glm::vec2 delta; glm::vec2 delta;
public: public:
MouseMoveEvent(glm::vec2 pos, glm::vec2 delta); MouseMoveEvent(glm::vec2 pos, glm::vec2 delta);
@@ -3,8 +3,10 @@
namespace Copium namespace Copium
{ {
MousePressEvent::MousePressEvent(int button) MousePressEvent::MousePressEvent(int button)
: Event{EventType::MousePress}, button{button} : Event{EventType::MousePress},
{} button{button}
{
}
int MousePressEvent::GetButton() const int MousePressEvent::GetButton() const
{ {
@@ -1,15 +1,16 @@
#pragma once #pragma once
#include "copium/event/Event.h"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "copium/event/Event.h"
namespace Copium namespace Copium
{ {
class MousePressEvent : public Event class MousePressEvent : public Event
{ {
private: private:
int button; int button;
public: public:
MousePressEvent(int button); MousePressEvent(int button);
@@ -3,8 +3,10 @@
namespace Copium namespace Copium
{ {
MouseReleaseEvent::MouseReleaseEvent(int button) MouseReleaseEvent::MouseReleaseEvent(int button)
: Event{EventType::MouseRelease}, button{button} : Event{EventType::MouseRelease},
{} button{button}
{
}
int MouseReleaseEvent::GetButton() const int MouseReleaseEvent::GetButton() const
{ {
@@ -1,15 +1,16 @@
#pragma once #pragma once
#include "copium/event/Event.h"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "copium/event/Event.h"
namespace Copium namespace Copium
{ {
class MouseReleaseEvent : public Event class MouseReleaseEvent : public Event
{ {
private: private:
int button; int button;
public: public:
MouseReleaseEvent(int button); MouseReleaseEvent(int button);
@@ -3,8 +3,11 @@
namespace Copium namespace Copium
{ {
MouseScrollEvent::MouseScrollEvent(int scrollX, int scrollY) MouseScrollEvent::MouseScrollEvent(int scrollX, int scrollY)
: Event{EventType::MouseScroll}, scrollX{scrollX}, scrollY{scrollY} : Event{EventType::MouseScroll},
{} scrollX{scrollX},
scrollY{scrollY}
{
}
int MouseScrollEvent::GetScrollX() const int MouseScrollEvent::GetScrollX() const
{ {
@@ -9,6 +9,7 @@ namespace Copium
private: private:
int scrollX; int scrollX;
int scrollY; int scrollY;
public: public:
MouseScrollEvent(int scrollX, int scrollY); MouseScrollEvent(int scrollX, int scrollY);
@@ -3,8 +3,10 @@
namespace Copium namespace Copium
{ {
ViewportResize::ViewportResize(const BoundingBox& viewport) ViewportResize::ViewportResize(const BoundingBox& viewport)
: Event(EventType::ViewportResize), viewport{viewport} : Event(EventType::ViewportResize),
{} viewport{viewport}
{
}
const BoundingBox& ViewportResize::GetViewport() const const BoundingBox& ViewportResize::GetViewport() const
{ {
@@ -1,7 +1,6 @@
#pragma once #pragma once
#include "copium/event/Event.h" #include "copium/event/Event.h"
#include "copium/event/EventType.h"
#include "copium/util/BoundingBox.h" #include "copium/util/BoundingBox.h"
namespace Copium namespace Copium
@@ -9,6 +8,7 @@ namespace Copium
class ViewportResize : public Event class ViewportResize : public Event
{ {
BoundingBox viewport; BoundingBox viewport;
public: public:
ViewportResize(const BoundingBox& viewport); ViewportResize(const BoundingBox& viewport);
@@ -3,8 +3,10 @@
namespace Copium namespace Copium
{ {
WindowFocusEvent::WindowFocusEvent(bool focused) WindowFocusEvent::WindowFocusEvent(bool focused)
: Event{EventType::WindowFocus}, focused{focused} : Event{EventType::WindowFocus},
{} focused{focused}
{
}
bool WindowFocusEvent::IsFocused() const bool WindowFocusEvent::IsFocused() const
{ {
@@ -8,6 +8,7 @@ namespace Copium
{ {
private: private:
bool focused; bool focused;
public: public:
WindowFocusEvent(bool focused); WindowFocusEvent(bool focused);
@@ -3,8 +3,11 @@
namespace Copium namespace Copium
{ {
WindowResizeEvent::WindowResizeEvent(int width, int height) WindowResizeEvent::WindowResizeEvent(int width, int height)
: Event{EventType::WindowResize}, width{width}, height{height} : Event{EventType::WindowResize},
{} width{width},
height{height}
{
}
int WindowResizeEvent::GetWidth() const int WindowResizeEvent::GetWidth() const
{ {
@@ -9,6 +9,7 @@ namespace Copium
private: private:
int width; int width;
int height; int height;
public: public:
WindowResizeEvent(int width, int height); WindowResizeEvent(int width, int height);
+7 -5
View File
@@ -1,21 +1,23 @@
#pragma once #pragma once
#include <memory>
#include <vector>
#include "copium/buffer/CommandBuffer.h"
#include "copium/buffer/IndexBuffer.h" #include "copium/buffer/IndexBuffer.h"
#include "copium/buffer/VertexBuffer.h" #include "copium/buffer/VertexBuffer.h"
#include "copium/buffer/CommandBuffer.h"
#include "copium/util/Common.h" #include "copium/util/Common.h"
#include <vector>
#include <memory>
namespace Copium namespace Copium
{ {
class Mesh class Mesh
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(Mesh); CP_DELETE_COPY_AND_MOVE_CTOR(Mesh);
private: private:
std::unique_ptr<IndexBuffer> indexBuffer; std::unique_ptr<IndexBuffer> indexBuffer;
std::unique_ptr<VertexBuffer> vertexBuffer; std::unique_ptr<VertexBuffer> vertexBuffer;
public: public:
template <typename T> template <typename T>
Mesh(const std::vector<T>& vertices, const std::vector<uint16_t>& indices); Mesh(const std::vector<T>& vertices, const std::vector<uint16_t>& indices);
@@ -30,6 +32,6 @@ namespace Copium
indexBuffer = std::make_unique<IndexBuffer>(indices.size()); indexBuffer = std::make_unique<IndexBuffer>(indices.size());
indexBuffer->UpdateStaging((void*)indices.data()); indexBuffer->UpdateStaging((void*)indices.data());
vertexBuffer = std::make_unique<VertexBuffer>(T::GetDescriptor(), vertices.size()); vertexBuffer = std::make_unique<VertexBuffer>(T::GetDescriptor(), vertices.size());
vertexBuffer ->UpdateStaging(0, (void*)vertices.data()); vertexBuffer->UpdateStaging(0, (void*)vertices.data());
} }
} }
+2 -3
View File
@@ -1,9 +1,9 @@
#pragma once #pragma once
#include "copium/pipeline/VertexDescriptor.h"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "copium/pipeline/VertexDescriptor.h"
namespace Copium namespace Copium
{ {
struct Vertex struct Vertex
@@ -15,4 +15,3 @@ namespace Copium
static VertexDescriptor GetDescriptor(); static VertexDescriptor GetDescriptor();
}; };
} }
@@ -5,7 +5,8 @@ namespace Copium
VertexDescriptor VertexPassthrough::GetDescriptor() VertexDescriptor VertexPassthrough::GetDescriptor()
{ {
VertexDescriptor descriptor{}; VertexDescriptor descriptor{};
descriptor.AddAttribute(0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(VertexPassthrough, texCoord), sizeof(VertexPassthrough)); descriptor.AddAttribute(
0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(VertexPassthrough, texCoord), sizeof(VertexPassthrough));
return descriptor; return descriptor;
} }
} }
@@ -1,9 +1,9 @@
#pragma once #pragma once
#include "copium/pipeline/VertexDescriptor.h"
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "copium/pipeline/VertexDescriptor.h"
namespace Copium namespace Copium
{ {
struct VertexPassthrough struct VertexPassthrough
@@ -1,51 +1,73 @@
#include "copium/pipeline/DescriptorPool.h" #include "copium/pipeline/DescriptorPool.h"
#include "copium/core/SwapChain.h"
#include "copium/core/Vulkan.h" #include "copium/core/Vulkan.h"
namespace Copium namespace Copium
{ {
DescriptorPool::DescriptorPool() DescriptorPool::DescriptorPool(int uniformDescriptorSets, int imageDescriptorSets)
{ {
std::vector<VkDescriptorPoolSize> poolSizes{2}; std::vector<VkDescriptorPoolSize> poolSizes;
poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; if (uniformDescriptorSets != 0)
poolSizes[0].descriptorCount = DESCRIPTOR_SET_COUNT * SwapChain::MAX_FRAMES_IN_FLIGHT; // TODO: how should this actually be determined? {
VkDescriptorPoolSize descriptorSetPoolSize;
descriptorSetPoolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorSetPoolSize.descriptorCount = uniformDescriptorSets;
poolSizes.emplace_back(descriptorSetPoolSize);
}
poolSizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLER; if (imageDescriptorSets != 0)
poolSizes[1].descriptorCount = DESCRIPTOR_SET_COUNT * SwapChain::MAX_FRAMES_IN_FLIGHT; // TODO: how should this actually be determined? {
VkDescriptorPoolSize descriptorSetPoolSize;
descriptorSetPoolSize.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptorSetPoolSize.descriptorCount = imageDescriptorSets;
poolSizes.emplace_back(descriptorSetPoolSize);
}
VkDescriptorPoolCreateInfo createInfo{}; VkDescriptorPoolCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
createInfo.poolSizeCount = poolSizes.size(); createInfo.poolSizeCount = poolSizes.size();
createInfo.pPoolSizes = poolSizes.data(); createInfo.pPoolSizes = poolSizes.data();
createInfo.maxSets = DESCRIPTOR_SET_COUNT * SwapChain::MAX_FRAMES_IN_FLIGHT; createInfo.maxSets = uniformDescriptorSets + imageDescriptorSets; // I have no actual idea if this is fine
createInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; createInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
CP_VK_ASSERT(vkCreateDescriptorPool(Vulkan::GetDevice(), &createInfo, nullptr, &descriptorPool), "Failed to initialize descriptor pool"); CP_VK_ASSERT(vkCreateDescriptorPool(Vulkan::GetDevice(), &createInfo, nullptr, &descriptorPool),
"Failed to initialize descriptor pool");
} }
DescriptorPool::~DescriptorPool() DescriptorPool::~DescriptorPool()
{ {
vkDestroyDescriptorPool(Vulkan::GetDevice(), descriptorPool, nullptr); VkDescriptorPool descriptorPoolCpy = descriptorPool;
Vulkan::GetDevice().QueueIdleCommand([descriptorPoolCpy]()
{ vkDestroyDescriptorPool(Vulkan::GetDevice(), descriptorPoolCpy, nullptr); });
} }
std::vector<VkDescriptorSet> DescriptorPool::AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout) std::vector<VkDescriptorSet> DescriptorPool::AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout)
{ {
std::vector<VkDescriptorSet> descriptorSets{SwapChain::MAX_FRAMES_IN_FLIGHT}; std::vector<VkDescriptorSet> descriptorSets{(size_t)SwapChain::MAX_FRAMES_IN_FLIGHT};
std::vector<VkDescriptorSetLayout> layouts{SwapChain::MAX_FRAMES_IN_FLIGHT, descriptorSetLayout}; std::vector<VkDescriptorSetLayout> layouts{(size_t)SwapChain::MAX_FRAMES_IN_FLIGHT, descriptorSetLayout};
VkDescriptorSetAllocateInfo allocateInfo{}; VkDescriptorSetAllocateInfo allocateInfo{};
allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocateInfo.descriptorPool = descriptorPool; allocateInfo.descriptorPool = descriptorPool;
allocateInfo.descriptorSetCount = descriptorSets.size(); allocateInfo.descriptorSetCount = descriptorSets.size();
allocateInfo.pSetLayouts = layouts.data(); allocateInfo.pSetLayouts = layouts.data();
CP_VK_ASSERT(vkAllocateDescriptorSets(Vulkan::GetDevice(), &allocateInfo, descriptorSets.data()), "Failed to allocate descriptor sets"); CP_VK_ASSERT(vkAllocateDescriptorSets(Vulkan::GetDevice(), &allocateInfo, descriptorSets.data()),
"Failed to allocate descriptor sets");
return descriptorSets; return descriptorSets;
} }
void DescriptorPool::FreeDescriptorSets(const std::vector<VkDescriptorSet>& descriptorSets) void DescriptorPool::FreeDescriptorSets(const std::vector<VkDescriptorSet>& descriptorSets)
{ {
vkFreeDescriptorSets(Vulkan::GetDevice(), descriptorPool, descriptorSets.size(), descriptorSets.data()); VkDescriptorPool descriptorPoolCpy = descriptorPool;
std::vector<VkDescriptorSet> descriptorSetsCpy = descriptorSets;
Vulkan::GetDevice().QueueIdleCommand(
[descriptorPoolCpy, descriptorSetsCpy]()
{
vkFreeDescriptorSets(
Vulkan::GetDevice(), descriptorPoolCpy, descriptorSetsCpy.size(), descriptorSetsCpy.data());
});
} }
DescriptorPool::operator VkDescriptorPool() const DescriptorPool::operator VkDescriptorPool() const
@@ -1,19 +1,20 @@
#pragma once #pragma once
#include "copium/util/Common.h"
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
#include "copium/util/Common.h"
namespace Copium namespace Copium
{ {
class DescriptorPool final class DescriptorPool final
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorPool); CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorPool);
private: private:
VkDescriptorPool descriptorPool; VkDescriptorPool descriptorPool;
static const int DESCRIPTOR_SET_COUNT = 1000000;
public: public:
DescriptorPool(); DescriptorPool(int uniformDescriptorSets, int imageDescriptorSets);
~DescriptorPool(); ~DescriptorPool();
std::vector<VkDescriptorSet> AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout); std::vector<VkDescriptorSet> AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout);
@@ -4,8 +4,12 @@
namespace Copium namespace Copium
{ {
DescriptorSet::DescriptorSet(DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout, const std::set<ShaderBinding>& bindings) DescriptorSet::DescriptorSet(DescriptorPool& descriptorPool,
: descriptorPool{descriptorPool}, descriptorSetLayout{descriptorSetLayout}, bindings{bindings} VkDescriptorSetLayout descriptorSetLayout,
const std::set<ShaderBinding>& bindings)
: descriptorPool{descriptorPool},
descriptorSetLayout{descriptorSetLayout},
bindings{bindings}
{ {
CP_ASSERT(!bindings.empty(), "Cannot initialize DescriptorSet with empty ShaderBindings"); CP_ASSERT(!bindings.empty(), "Cannot initialize DescriptorSet with empty ShaderBindings");
@@ -64,7 +68,8 @@ namespace Copium
void DescriptorSet::SetSamplers(const std::vector<const Sampler*>& samplers, uint32_t binding) void DescriptorSet::SetSamplers(const std::vector<const Sampler*>& samplers, uint32_t binding)
{ {
for (size_t i = 0; i < descriptorSets.size(); ++i) { for (size_t i = 0; i < descriptorSets.size(); ++i)
{
std::vector<VkWriteDescriptorSet> descriptorWrites{samplers.size()}; std::vector<VkWriteDescriptorSet> descriptorWrites{samplers.size()};
for (size_t j = 0; j < samplers.size(); j++) for (size_t j = 0; j < samplers.size(); j++)
{ {
@@ -105,7 +110,7 @@ namespace Copium
UniformBuffer& DescriptorSet::GetUniformBuffer(const std::string& uniformBuffer) UniformBuffer& DescriptorSet::GetUniformBuffer(const std::string& uniformBuffer)
{ {
auto it = uniformBuffers.find(uniformBuffer); auto it = uniformBuffers.find(uniformBuffer);
CP_ASSERT(it != uniformBuffers.end(), "UniformBuffer not found = %s", uniformBuffer.c_str()); CP_ASSERT(it != uniformBuffers.end(), "UniformBuffer not found = {}", uniformBuffer);
return *it->second; return *it->second;
} }
@@ -114,6 +119,11 @@ namespace Copium
return bindings.begin()->set; return bindings.begin()->set;
} }
VkDescriptorSet DescriptorSet::GetVkDescriptorSet(int flightIndex) const
{
return descriptorSets[flightIndex];
}
DescriptorSet::operator VkDescriptorSet() const DescriptorSet::operator VkDescriptorSet() const
{ {
return descriptorSets[Vulkan::GetSwapChain().GetFlightIndex()]; return descriptorSets[Vulkan::GetSwapChain().GetFlightIndex()];
@@ -121,7 +131,8 @@ namespace Copium
void DescriptorSet::SetUniformBuffer(const UniformBuffer& uniformBuffer, uint32_t binding) void DescriptorSet::SetUniformBuffer(const UniformBuffer& uniformBuffer, uint32_t binding)
{ {
for (size_t i = 0; i < descriptorSets.size(); ++i) { for (size_t i = 0; i < descriptorSets.size(); ++i)
{
VkDescriptorBufferInfo bufferInfo = uniformBuffer.GetDescriptorBufferInfo(i); VkDescriptorBufferInfo bufferInfo = uniformBuffer.GetDescriptorBufferInfo(i);
VkWriteDescriptorSet descriptorWrite{}; VkWriteDescriptorSet descriptorWrite{};
@@ -1,24 +1,24 @@
#pragma once #pragma once
#include <glm/glm.hpp>
#include <map>
#include <memory>
#include <set>
#include <vector>
#include <vulkan/vulkan.hpp>
#include "copium/buffer/UniformBuffer.h" #include "copium/buffer/UniformBuffer.h"
#include "copium/pipeline/DescriptorPool.h" #include "copium/pipeline/DescriptorPool.h"
#include "copium/pipeline/ShaderBinding.h" #include "copium/pipeline/ShaderBinding.h"
#include "copium/pipeline/ShaderReflector.h"
#include "copium/sampler/Sampler.h" #include "copium/sampler/Sampler.h"
#include "copium/util/Common.h" #include "copium/util/Common.h"
#include <glm/glm.hpp>
#include <vulkan/vulkan.hpp>
#include <map>
#include <set>
#include <vector>
namespace Copium namespace Copium
{ {
class DescriptorSet final class DescriptorSet final
{ {
CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorSet); CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorSet);
private: private:
DescriptorPool& descriptorPool; DescriptorPool& descriptorPool;
VkDescriptorSetLayout descriptorSetLayout; VkDescriptorSetLayout descriptorSetLayout;
@@ -28,7 +28,9 @@ namespace Copium
std::map<std::string, std::unique_ptr<UniformBuffer>> uniformBuffers; std::map<std::string, std::unique_ptr<UniformBuffer>> uniformBuffers;
public: public:
DescriptorSet(DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout, const std::set<ShaderBinding>& bindings); DescriptorSet(DescriptorPool& descriptorPool,
VkDescriptorSetLayout descriptorSetLayout,
const std::set<ShaderBinding>& bindings);
~DescriptorSet(); ~DescriptorSet();
void SetSampler(const Sampler& sampler, uint32_t binding, int arrayIndex = 0); void SetSampler(const Sampler& sampler, uint32_t binding, int arrayIndex = 0);
@@ -37,8 +39,10 @@ namespace Copium
void SetSamplersDynamic(const std::vector<const Sampler*>& samplers, uint32_t binding); void SetSamplersDynamic(const std::vector<const Sampler*>& samplers, uint32_t binding);
UniformBuffer& GetUniformBuffer(const std::string& uniformBuffer); UniformBuffer& GetUniformBuffer(const std::string& uniformBuffer);
uint32_t GetSetIndex() const; uint32_t GetSetIndex() const;
VkDescriptorSet GetVkDescriptorSet(int flightIndex) const;
operator VkDescriptorSet() const; operator VkDescriptorSet() const;
private: private:
void SetUniformBuffer(const UniformBuffer& uniformBuffer, uint32_t binding); void SetUniformBuffer(const UniformBuffer& uniformBuffer, uint32_t binding);
}; };

Some files were not shown because too many files have changed in this diff Show More