Adding nlohmanns json library
This commit is contained in:
@@ -10,3 +10,6 @@
|
||||
[submodule "external/slang"]
|
||||
path = external/slang
|
||||
url = https://github.com/shader-slang/slang.git
|
||||
[submodule "external/json"]
|
||||
path = external/json
|
||||
url = https://github.com/nlohmann/json.git
|
||||
|
||||
Vendored
+7
-1
@@ -14,6 +14,12 @@
|
||||
"type_traits": "cpp",
|
||||
"vector": "cpp",
|
||||
"*.rh": "cpp",
|
||||
"memory": "cpp"
|
||||
"memory": "cpp",
|
||||
"*.ipp": "cpp",
|
||||
"iostream": "cpp",
|
||||
"initializer_list": "cpp"
|
||||
},
|
||||
"C_Cpp.default.browse.limitSymbolsToIncludedHeaders": false,
|
||||
"C_Cpp.default.intelliSenseMode": "msvc-x64",
|
||||
"C_Cpp.errorSquiggles": "Disabled",
|
||||
}
|
||||
+8
-4
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED 20)
|
||||
|
||||
# Handle superbuild first
|
||||
option (USE_SUPERBUILD "Whether or not a superbuild should be invoked" ON)
|
||||
@@ -11,6 +11,7 @@ set(SLANG_ROOT ${EXTERNAL_ROOT}/slang)
|
||||
set(BOOST_ROOT ${EXTERNAL_ROOT}/boost)
|
||||
set(GLM_ROOT ${EXTERNAL_ROOT}/glm)
|
||||
set(GLFW_ROOT ${EXTERNAL_ROOT}/glfw)
|
||||
set(JSON_ROOT ${EXTERNAL_ROOT}/json)
|
||||
set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE})
|
||||
set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})
|
||||
@@ -34,9 +35,11 @@ else()
|
||||
project (Seele)
|
||||
endif()
|
||||
|
||||
add_subdirectory(${GLFW_ROOT})
|
||||
find_package(Vulkan REQUIRED)
|
||||
find_package(Boost REQUIRED COMPONENTS serialization)
|
||||
find_package(Threads)
|
||||
include(${JSON_IMPORT})
|
||||
include(${GLFW_IMPORT})
|
||||
|
||||
include_directories(${GLFW_ROOT}/include)
|
||||
include_directories(${GLM_INCLUDE_DIRS})
|
||||
@@ -52,11 +55,12 @@ if(WIN32)
|
||||
add_compile_definitions(USE_EXTENSIONS)
|
||||
endif()
|
||||
add_executable(SeeleEngine "")
|
||||
add_subdirectory(src/)
|
||||
target_link_libraries(SeeleEngine glfw)
|
||||
target_link_libraries(SeeleEngine nlohmann_json::nlohmann_json)
|
||||
target_link_libraries(SeeleEngine ${Boost_LIBRARIES})
|
||||
target_link_libraries(SeeleEngine ${Vulkan_LIBRARY})
|
||||
target_link_libraries(SeeleEngine glfw ${GLFW_LIBRARIES})
|
||||
target_link_libraries(SeeleEngine ${SLANG_LIBRARY})
|
||||
add_subdirectory(src/)
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(SeeleEngine PRIVATE /DEBUG:FASTLINK /Zi /W4)
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"buildRoot": "${projectDir}\\bin\\${name}",
|
||||
"installRoot": "${projectDir}\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"cmakeCommandArgs": "-DUSE_SUPERBUILD=TRUE",
|
||||
"buildCommandArgs": "-v",
|
||||
"ctestCommandArgs": "",
|
||||
"variables": []
|
||||
|
||||
+30
-17
@@ -18,7 +18,7 @@ ExternalProject_Add(boost
|
||||
SOURCE_DIR ${BOOST_ROOT}
|
||||
UPDATE_COMMAND ""
|
||||
CONFIGURE_COMMAND ./bootstrap.${BOOTSTRAP_EXTENSION} --with-libraries=serialization,test
|
||||
BUILD_COMMAND ./b2 link=static
|
||||
BUILD_COMMAND ./b2 link=static -d0
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
@@ -37,23 +37,36 @@ list(APPEND EXTRA_CMAKE_ARGS
|
||||
-DGLM_INCLUDE_DIRS=${GLM_ROOT}
|
||||
)
|
||||
|
||||
#--------------------JSON------------------
|
||||
#list(APPEND DEPENDENCIES nlohmann_json)
|
||||
set(JSON_MultipleHeaders ON CACHE INTERNAL "")
|
||||
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||
set(JSON_Install OFF CACHE INTERNAL "")
|
||||
|
||||
add_subdirectory(${JSON_ROOT})
|
||||
export(TARGETS nlohmann_json
|
||||
NAMESPACE nlohmann_json::
|
||||
FILE ${nlohmann_json_BINARY_DIR}/json_target.cmake)
|
||||
|
||||
list(APPEND EXTRA_CMAKE_ARGS
|
||||
-DJSON_IMPORT=${nlohmann_json_BINARY_DIR}/json_target.cmake
|
||||
)
|
||||
|
||||
|
||||
#--------------GLFW------------------------------
|
||||
#list(APPEND DEPENDENCIES glfw)
|
||||
#set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
|
||||
#set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||
#set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
#
|
||||
#ExternalProject_Add(glfw
|
||||
# SOURCE_DIR ${GLFW_ROOT}
|
||||
# BINARY_DIR ${CMAKE_BINARY_DIR}/lib
|
||||
# INSTALL_COMMAND "")
|
||||
#
|
||||
#list(APPEND EXTRA_CMAKE_ARGS
|
||||
# -DGLFW_INCLUDE_DIRS=${GLFW_ROOT}/include
|
||||
# -DGLFW_LIBRARY=${CMAKE_BINARY_DIR}/lib/src/glfw3.lib
|
||||
# )
|
||||
#
|
||||
list(APPEND DEPENDENCIES glfw)
|
||||
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
|
||||
add_subdirectory(${GLFW_ROOT})
|
||||
export(TARGETS glfw
|
||||
FILE ${GLFW_BINARY_DIR}/glfw.cmake)
|
||||
|
||||
list(APPEND EXTRA_CMAKE_ARGS
|
||||
-DGLFW_IMPORT=${GLFW_BINARY_DIR}/glfw.cmake
|
||||
)
|
||||
|
||||
#--------------SLang------------------------------
|
||||
list(APPEND DEPENDENCIES slang)
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE}_${CMAKE_PLATFORM} SLANG_CONFIG)
|
||||
@@ -83,7 +96,7 @@ endif()
|
||||
|
||||
|
||||
list(APPEND EXTRA_CMAKE_ARGS
|
||||
-DSLANG_INCLUDE_DIRS=${EXTERNAL_ROOT}
|
||||
-DSLANG_INCLUDE_DIRS=${EXTERNAL_ROOT}/slang
|
||||
-DSLANG_LIBRARY=${SLANG_LIB_PATH})
|
||||
|
||||
list(APPEND DEPENDENT_BINARIES ${SLANG_ROOT}/${SLANG_BINARY})
|
||||
|
||||
+1
Submodule external/json added at 634fa87e5a
@@ -0,0 +1,11 @@
|
||||
#include "Asset.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Asset::Asset()
|
||||
{
|
||||
}
|
||||
|
||||
Asset::~Asset()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class Asset
|
||||
{
|
||||
public:
|
||||
Asset();
|
||||
virtual ~Asset();
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(Asset);
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,6 @@
|
||||
target_sources(SeeleEngine
|
||||
PRIVATE
|
||||
Asset.h
|
||||
Asset.cpp
|
||||
FileAsset.h
|
||||
FileAsset.cpp)
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "FileAsset.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
FileAsset::FileAsset()
|
||||
: path("")
|
||||
, name("")
|
||||
{
|
||||
}
|
||||
|
||||
FileAsset::FileAsset(const std::string &fullPath)
|
||||
: path(fullPath)
|
||||
{
|
||||
name = fullPath.substr(fullPath.find_last_of('\\')+1);
|
||||
}
|
||||
|
||||
FileAsset::FileAsset(const std::string &directory, const std::string &name)
|
||||
: path(directory+name)
|
||||
, name(name)
|
||||
{
|
||||
}
|
||||
|
||||
FileAsset::~FileAsset()
|
||||
{
|
||||
}
|
||||
|
||||
std::ifstream &FileAsset::getReadStream()
|
||||
{
|
||||
if(inStream.is_open())
|
||||
{
|
||||
return inStream;
|
||||
}
|
||||
inStream.open(path);
|
||||
return inStream;
|
||||
}
|
||||
|
||||
std::ofstream &FileAsset::getWriteStream()
|
||||
{
|
||||
if(outStream.is_open())
|
||||
{
|
||||
return outStream;
|
||||
}
|
||||
outStream.open(path);
|
||||
return outStream;
|
||||
}
|
||||
|
||||
void FileAsset::rename(const std::string& newName)
|
||||
{
|
||||
if(inStream.is_open())
|
||||
{
|
||||
inStream.close();
|
||||
}
|
||||
if(outStream.is_open())
|
||||
{
|
||||
outStream.flush();
|
||||
outStream.close();
|
||||
}
|
||||
path.replace(path.find_last_of(name), name.size(), newName);
|
||||
name = newName;
|
||||
inStream.open(path);
|
||||
outStream.open(path);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "Asset.h"
|
||||
#include <fstream>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class FileAsset
|
||||
{
|
||||
public:
|
||||
FileAsset();
|
||||
FileAsset(const std::string& directory, const std::string& name);
|
||||
FileAsset(const std::string& fullPath);
|
||||
virtual ~FileAsset();
|
||||
std::ifstream& getReadStream();
|
||||
std::ofstream& getWriteStream();
|
||||
void rename(const std::string& newName);
|
||||
private:
|
||||
std::string name;
|
||||
std::string path;
|
||||
uint32 byteSize;
|
||||
std::ifstream inStream;
|
||||
std::ofstream outStream;
|
||||
};
|
||||
}
|
||||
@@ -4,6 +4,9 @@ target_sources(SeeleEngine
|
||||
MinimalEngine.cpp
|
||||
main.cpp)
|
||||
|
||||
add_subdirectory(Asset/)
|
||||
add_subdirectory(Containers/)
|
||||
add_subdirectory(Graphics/)
|
||||
add_subdirectory(Material/)
|
||||
add_subdirectory(Math/)
|
||||
add_subdirectory(Containers/)
|
||||
add_subdirectory(Scene/)
|
||||
@@ -372,7 +372,11 @@ public:
|
||||
{
|
||||
return N;
|
||||
}
|
||||
inline T *data() const
|
||||
inline T *data()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
inline const T* data() const
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
typedef uint64_t uint64;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint8_t uint8;
|
||||
typedef uint64_t uint64;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint8_t uint8;
|
||||
|
||||
typedef int64_t int64;
|
||||
typedef int32_t int32;
|
||||
typedef int16_t int16;
|
||||
typedef int8_t int8;
|
||||
}
|
||||
typedef int64_t int64;
|
||||
typedef int32_t int32;
|
||||
typedef int16_t int16;
|
||||
typedef int8_t int8;
|
||||
} // namespace Seele
|
||||
@@ -4,6 +4,7 @@ target_sources(SeeleEngine
|
||||
ForwardPlusRenderPath.cpp
|
||||
GraphicsResources.h
|
||||
GraphicsResources.cpp
|
||||
GraphicsInitializer.h
|
||||
GraphicsEnums.h
|
||||
Graphics.h
|
||||
Graphics.cpp
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
#include "ForwardPlusRenderPath.h"
|
||||
#include "Scene/Scene.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Material/Material.h"
|
||||
#include "GraphicsResources.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Seele::ForwardPlusRenderPath::ForwardPlusRenderPath(Gfx::PGraphics graphics, Gfx::PViewport viewport)
|
||||
: SceneRenderPath(graphics, viewport)
|
||||
{
|
||||
|
||||
PMaterial material = new Material("D:\\Private\\Programming\\C++\\Seele\\test.mat");
|
||||
material->compile();
|
||||
}
|
||||
|
||||
Seele::ForwardPlusRenderPath::~ForwardPlusRenderPath()
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
void Seele::ForwardPlusRenderPath::beginFrame()
|
||||
{
|
||||
@@ -17,6 +23,19 @@ void Seele::ForwardPlusRenderPath::beginFrame()
|
||||
|
||||
void Seele::ForwardPlusRenderPath::render()
|
||||
{
|
||||
for (auto entry : scene->getMeshBatches())
|
||||
{
|
||||
PMaterial material = entry.key;
|
||||
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
|
||||
renderCommand->bindPipeline(material->getPipeline());
|
||||
for (auto drawState : entry.value.instances)
|
||||
{
|
||||
renderCommand->bindVertexBuffer(drawState.vertexBuffer);
|
||||
renderCommand->bindIndexBuffer(drawState.indexBuffer);
|
||||
renderCommand->bindDescriptor(drawState.instance->getDescriptor());
|
||||
renderCommand->draw(drawState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Seele::ForwardPlusRenderPath::endFrame()
|
||||
|
||||
@@ -6,11 +6,12 @@ namespace Seele
|
||||
class ForwardPlusRenderPath : public SceneRenderPath
|
||||
{
|
||||
public:
|
||||
ForwardPlusRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target);
|
||||
virtual ~ForwardPlusRenderPath();
|
||||
ForwardPlusRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target);
|
||||
virtual ~ForwardPlusRenderPath();
|
||||
virtual void beginFrame() override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -20,12 +20,15 @@ public:
|
||||
virtual void beginRenderPass(PRenderPass renderPass) = 0;
|
||||
virtual void endRenderPass() = 0;
|
||||
|
||||
virtual void executeCommands(Array<PRenderCommand> commands) = 0;
|
||||
|
||||
virtual PTexture2D createTexture2D(const TextureCreateInfo &createInfo) = 0;
|
||||
virtual PUniformBuffer createUniformBuffer(const BulkResourceData &bulkData) = 0;
|
||||
virtual PStructuredBuffer createStructuredBuffer(const BulkResourceData &bulkData) = 0;
|
||||
virtual PVertexBuffer createVertexBuffer(const BulkResourceData &bulkData) = 0;
|
||||
virtual PIndexBuffer createIndexBuffer(const BulkResourceData &bulkData) = 0;
|
||||
|
||||
virtual PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0;
|
||||
virtual PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) = 0;
|
||||
virtual PRenderCommand createRenderCommand() = 0;
|
||||
virtual PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) = 0;
|
||||
protected:
|
||||
friend class Window;
|
||||
};
|
||||
|
||||
@@ -1846,5 +1846,12 @@ typedef enum SeStencilFaceFlagBits
|
||||
SE_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
||||
} SeStencilFaceFlagBits;
|
||||
typedef SeFlags SeStencilFaceFlags;
|
||||
enum class QueueType
|
||||
{
|
||||
GRAPHICS = 1,
|
||||
COMPUTE = 2,
|
||||
TRANSFER = 3,
|
||||
DEDICATED_TRANSFER = 4
|
||||
};
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,188 @@
|
||||
#include "GraphicsEnums.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
struct GraphicsInitializer
|
||||
{
|
||||
const char *windowLayoutFile;
|
||||
const char *applicationName;
|
||||
const char *engineName;
|
||||
void *windowHandle;
|
||||
/**
|
||||
* layers defines the enabled Vulkan layers used in the instance,
|
||||
* if ENABLE_VALIDATION is defined, standard validation is already enabled
|
||||
* not yet implemented
|
||||
*/
|
||||
Array<const char *> layers;
|
||||
Array<const char *> instanceExtensions;
|
||||
Array<const char *> deviceExtensions;
|
||||
GraphicsInitializer()
|
||||
: applicationName("SeeleEngine"), engineName("SeeleEngine"), layers{"VK_LAYER_LUNARG_standard_validation"}, instanceExtensions{}, deviceExtensions{"VK_KHR_swapchain"}, windowHandle(nullptr)
|
||||
{
|
||||
}
|
||||
GraphicsInitializer(const GraphicsInitializer &other)
|
||||
: applicationName(other.applicationName), engineName(other.engineName), layers(other.layers), instanceExtensions(other.instanceExtensions), deviceExtensions(other.deviceExtensions)
|
||||
{
|
||||
}
|
||||
};
|
||||
struct WindowCreateInfo
|
||||
{
|
||||
int32 width;
|
||||
int32 height;
|
||||
const char *title;
|
||||
bool bFullscreen;
|
||||
Gfx::SeFormat pixelFormat;
|
||||
void *windowHandle;
|
||||
};
|
||||
struct ViewportCreateInfo
|
||||
{
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
uint32 offsetX;
|
||||
uint32 offsetY;
|
||||
};
|
||||
struct TextureCreateInfo
|
||||
{
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
uint32 depth;
|
||||
bool bArray;
|
||||
uint32 arrayLayers;
|
||||
uint32 mipLevels;
|
||||
uint32 samples;
|
||||
Gfx::SeFormat format;
|
||||
Gfx::SeImageUsageFlagBits usage;
|
||||
Gfx::QueueType queueType;
|
||||
TextureCreateInfo()
|
||||
: width(1), height(1), depth(1), bArray(false), arrayLayers(1), mipLevels(1), samples(1), format(Gfx::SE_FORMAT_R32G32B32A32_SFLOAT), queueType(Gfx::QueueType::GRAPHICS), usage(Gfx::SE_IMAGE_USAGE_SAMPLED_BIT)
|
||||
{
|
||||
}
|
||||
};
|
||||
// doesnt own the data, only proxy it
|
||||
struct BulkResourceData
|
||||
{
|
||||
uint32 size;
|
||||
uint8 *data;
|
||||
Gfx::QueueType owner;
|
||||
BulkResourceData()
|
||||
: size(0), data(nullptr), owner(Gfx::QueueType::GRAPHICS)
|
||||
{
|
||||
}
|
||||
};
|
||||
struct VertexBufferCreateInfo
|
||||
{
|
||||
BulkResourceData resourceData;
|
||||
// bytes per vertex
|
||||
uint32 vertexSize;
|
||||
uint32 numVertices;
|
||||
VertexBufferCreateInfo()
|
||||
: resourceData(), vertexSize(0), numVertices(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
struct IndexBufferCreateInfo
|
||||
{
|
||||
BulkResourceData resourceData;
|
||||
Gfx::SeIndexType indexType;
|
||||
IndexBufferCreateInfo()
|
||||
: resourceData(), indexType(Gfx::SeIndexType::SE_INDEX_TYPE_UINT16)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
namespace Gfx
|
||||
{
|
||||
struct SePushConstantRange
|
||||
{
|
||||
SeShaderStageFlags stageFlags;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
};
|
||||
struct VertexElement
|
||||
{
|
||||
uint32 location;
|
||||
SeFormat vertexFormat;
|
||||
uint32 offset;
|
||||
};
|
||||
struct RasterizationState
|
||||
{
|
||||
uint8 depthClampEnable : 1;
|
||||
uint8 rasterizerDiscardEnable : 1;
|
||||
uint8 depthBiasEnable : 1;
|
||||
float depthBoasConstantFactor;
|
||||
float depthBiasClamp;
|
||||
float depthBiasSlopeFactor;
|
||||
float lineWidth;
|
||||
SePolygonMode polygonMode;
|
||||
SeCullModeFlags cullMode;
|
||||
SeFrontFace frontFace;
|
||||
};
|
||||
struct MultisampleState
|
||||
{
|
||||
uint32 samples;
|
||||
float minSampleShading;
|
||||
uint8 sampleShadingEnable : 1;
|
||||
uint8 alphaCoverageEnable;
|
||||
uint8 alphaToOneEnable;
|
||||
};
|
||||
struct DepthStencilState
|
||||
{
|
||||
uint8 depthTestEnable : 1;
|
||||
uint8 depthWriteEnable : 1;
|
||||
uint8 depthBoundsTestEnable : 1;
|
||||
uint8 stencilTestEnable : 1;
|
||||
SeCompareOp depthCompareOp;
|
||||
SeStencilOp front;
|
||||
SeStencilOp back;
|
||||
float minDepthBounds;
|
||||
float maxDepthBounds;
|
||||
};
|
||||
struct ColorBlendState
|
||||
{
|
||||
uint8 logicOpEnable : 1;
|
||||
SeLogicOp logicOp;
|
||||
uint32 attachmentCount;
|
||||
struct BlendAttachment
|
||||
{
|
||||
uint8 blendEnable;
|
||||
SeBlendFactor srcColorBlendFactor;
|
||||
SeBlendFactor dstColorBlendFactor;
|
||||
SeBlendOp colorBlendOp;
|
||||
SeBlendFactor srcAlphaBlendFactor;
|
||||
SeBlendFactor dstAlphaBlendFactor;
|
||||
SeBlendOp alphaBlendOp;
|
||||
SeColorComponentFlags colorWriteMask;
|
||||
} blendAttachments[16];
|
||||
float blendConstants[4];
|
||||
};
|
||||
} // namespace Gfx
|
||||
DECLARE_NAME_REF(Gfx, VertexDeclaration);
|
||||
DECLARE_NAME_REF(Gfx, VertexShader);
|
||||
DECLARE_NAME_REF(Gfx, ControlShader);
|
||||
DECLARE_NAME_REF(Gfx, EvaluationShader);
|
||||
DECLARE_NAME_REF(Gfx, GeometryShader);
|
||||
DECLARE_NAME_REF(Gfx, FragmentShader);
|
||||
DECLARE_NAME_REF(Gfx, PipelineLayout);
|
||||
DECLARE_NAME_REF(Gfx, RenderPass);
|
||||
struct GraphicsPipelineCreateInfo
|
||||
{
|
||||
Gfx::PVertexDeclaration vertexDeclaration;
|
||||
Gfx::PVertexShader vertexShader;
|
||||
Gfx::PControlShader controlShader;
|
||||
Gfx::PEvaluationShader evalShader;
|
||||
Gfx::PGeometryShader geometryShader;
|
||||
Gfx::PFragmentShader fragmentShader;
|
||||
Gfx::PPipelineLayout pipelineLayout;
|
||||
Gfx::PRenderPass renderPass;
|
||||
Gfx::SePrimitiveTopology topology;
|
||||
Gfx::RasterizationState rasterizationState;
|
||||
Gfx::DepthStencilState depthStencilState;
|
||||
Gfx::MultisampleState multisampleState;
|
||||
Gfx::ColorBlendState colorBlend;
|
||||
GraphicsPipelineCreateInfo()
|
||||
{
|
||||
std::memset(this, 0, sizeof(*this));
|
||||
}
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "GraphicsResources.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
@@ -46,6 +47,7 @@ void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layo
|
||||
else
|
||||
{
|
||||
descriptorSetLayouts[setIndex] = layout;
|
||||
layout->setIndex = setIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +63,67 @@ UniformBuffer::UniformBuffer()
|
||||
UniformBuffer::~UniformBuffer()
|
||||
{
|
||||
}
|
||||
VertexBuffer::VertexBuffer(uint32 numVertices, uint32 vertexSize)
|
||||
: numVertices(numVertices), vertexSize(vertexSize)
|
||||
{
|
||||
}
|
||||
VertexBuffer::~VertexBuffer()
|
||||
{
|
||||
}
|
||||
IndexBuffer::IndexBuffer(uint32 size, Gfx::SeIndexType indexType)
|
||||
: indexType(indexType)
|
||||
{
|
||||
switch (indexType)
|
||||
{
|
||||
case SE_INDEX_TYPE_UINT16:
|
||||
numIndices = size / 16;
|
||||
break;
|
||||
case SE_INDEX_TYPE_UINT32:
|
||||
numIndices = size / 32;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
IndexBuffer::~IndexBuffer()
|
||||
{
|
||||
}
|
||||
VertexStream::VertexStream(PVertexBuffer buffer, uint8 instanced)
|
||||
: buffer(buffer)
|
||||
, instanced(instanced)
|
||||
{
|
||||
}
|
||||
VertexStream::~VertexStream()
|
||||
{
|
||||
}
|
||||
void VertexStream::addVertexElement(VertexElement element)
|
||||
{
|
||||
vertexDescription.add(element);
|
||||
}
|
||||
const Array<VertexElement> VertexStream::getVertexDescriptions() const
|
||||
{
|
||||
return vertexDescription;
|
||||
}
|
||||
Gfx::PVertexBuffer VertexStream::getVertexBuffer()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
VertexDeclaration::VertexDeclaration()
|
||||
{
|
||||
}
|
||||
VertexDeclaration::~VertexDeclaration()
|
||||
{
|
||||
}
|
||||
uint32 VertexDeclaration::addVertexStream(const VertexStream &element)
|
||||
{
|
||||
uint32 currIndex = vertexStreams.size();
|
||||
vertexStreams.add(element);
|
||||
return currIndex;
|
||||
}
|
||||
const Array<VertexStream> &VertexDeclaration::getVertexStreams() const
|
||||
{
|
||||
return vertexStreams;
|
||||
}
|
||||
|
||||
RenderTargetLayout::RenderTargetLayout()
|
||||
: inputAttachments(), colorAttachments(), depthAttachment()
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#pragma once
|
||||
#include "GraphicsEnums.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Containers/List.h"
|
||||
#include "Math/MemCRC.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "GraphicsInitializer.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define ENABLE_VALIDATION
|
||||
@@ -9,97 +12,35 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
|
||||
DECLARE_NAME_REF(Gfx, VertexBuffer);
|
||||
DECLARE_NAME_REF(Gfx, IndexBuffer);
|
||||
struct DrawInstance
|
||||
{
|
||||
enum class QueueType
|
||||
{
|
||||
GRAPHICS = 1,
|
||||
COMPUTE = 2,
|
||||
TRANSFER = 3,
|
||||
DEDICATED_TRANSFER = 4
|
||||
};
|
||||
} // namespace Gfx
|
||||
struct GraphicsInitializer
|
||||
{
|
||||
const char *windowLayoutFile;
|
||||
const char *applicationName;
|
||||
const char *engineName;
|
||||
void *windowHandle;
|
||||
/**
|
||||
* layers defines the enabled Vulkan layers used in the instance,
|
||||
* if ENABLE_VALIDATION is defined, standard validation is already enabled
|
||||
* not yet implemented
|
||||
*/
|
||||
Array<const char *> layers;
|
||||
Array<const char *> instanceExtensions;
|
||||
Array<const char *> deviceExtensions;
|
||||
GraphicsInitializer()
|
||||
: applicationName("SeeleEngine"), engineName("SeeleEngine"), layers{"VK_LAYER_LUNARG_standard_validation"}, instanceExtensions{}, deviceExtensions{"VK_KHR_swapchain"}, windowHandle(nullptr)
|
||||
{
|
||||
}
|
||||
GraphicsInitializer(const GraphicsInitializer &other)
|
||||
: applicationName(other.applicationName), engineName(other.engineName), layers(other.layers), instanceExtensions(other.instanceExtensions), deviceExtensions(other.deviceExtensions)
|
||||
Matrix4 modelMatrix;
|
||||
PMaterialInstance instance;
|
||||
Gfx::PIndexBuffer indexBuffer;
|
||||
Gfx::PVertexBuffer vertexBuffer;
|
||||
|
||||
uint32 numInstances;
|
||||
uint32 baseVertexIndex;
|
||||
uint32 minVertexIndex;
|
||||
uint32 firstInstance;
|
||||
DrawInstance()
|
||||
: instance(nullptr), indexBuffer(nullptr), vertexBuffer(nullptr), modelMatrix(1), numInstances(1), baseVertexIndex(0), minVertexIndex(0), firstInstance(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
struct WindowCreateInfo
|
||||
struct DrawState
|
||||
{
|
||||
int32 width;
|
||||
int32 height;
|
||||
const char *title;
|
||||
bool bFullscreen;
|
||||
Gfx::SeFormat pixelFormat;
|
||||
void *windowHandle;
|
||||
};
|
||||
struct ViewportCreateInfo
|
||||
{
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
uint32 offsetX;
|
||||
uint32 offsetY;
|
||||
bool bFullscreen;
|
||||
bool bVsync;
|
||||
};
|
||||
struct TextureCreateInfo
|
||||
{
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
uint32 depth;
|
||||
bool bArray;
|
||||
uint32 arrayLayers;
|
||||
uint32 mipLevels;
|
||||
uint32 samples;
|
||||
Gfx::SeFormat format;
|
||||
Gfx::SeImageUsageFlagBits usage;
|
||||
Gfx::QueueType queueType;
|
||||
TextureCreateInfo()
|
||||
: width(1), height(1), depth(1), bArray(false), arrayLayers(1), mipLevels(1), samples(1), format(Gfx::SE_FORMAT_R32G32B32A32_SFLOAT), usage(Gfx::SE_IMAGE_USAGE_SAMPLED_BIT)
|
||||
Array<DrawInstance> instances;
|
||||
|
||||
DrawState()
|
||||
{
|
||||
}
|
||||
};
|
||||
//doesnt own the data, only proxy it
|
||||
struct BulkResourceData
|
||||
{
|
||||
uint32 size;
|
||||
uint8 *data;
|
||||
Gfx::QueueType owner;
|
||||
};
|
||||
namespace Gfx
|
||||
{
|
||||
struct SePushConstantRange
|
||||
{
|
||||
SeShaderStageFlags stageFlags;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
};
|
||||
class RenderCommandBase
|
||||
{
|
||||
public:
|
||||
virtual ~RenderCommandBase()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(RenderCommandBase);
|
||||
class SamplerState
|
||||
{
|
||||
public:
|
||||
@@ -108,6 +49,54 @@ public:
|
||||
}
|
||||
};
|
||||
DEFINE_REF(SamplerState);
|
||||
|
||||
class VertexShader
|
||||
{
|
||||
public:
|
||||
VertexShader() {}
|
||||
virtual ~VertexShader() {}
|
||||
};
|
||||
DEFINE_REF(VertexShader);
|
||||
class ControlShader
|
||||
{
|
||||
public:
|
||||
ControlShader() {}
|
||||
virtual ~ControlShader() {}
|
||||
uint32 getNumPatches() const { return numPatchPoints; }
|
||||
|
||||
protected:
|
||||
uint32 numPatchPoints;
|
||||
};
|
||||
DEFINE_REF(ControlShader);
|
||||
class EvaluationShader
|
||||
{
|
||||
public:
|
||||
EvaluationShader() {}
|
||||
virtual ~EvaluationShader() {}
|
||||
};
|
||||
DEFINE_REF(EvaluationShader);
|
||||
class GeometryShader
|
||||
{
|
||||
public:
|
||||
GeometryShader() {}
|
||||
virtual ~GeometryShader() {}
|
||||
};
|
||||
DEFINE_REF(GeometryShader);
|
||||
class FragmentShader
|
||||
{
|
||||
public:
|
||||
FragmentShader() {}
|
||||
virtual ~FragmentShader() {}
|
||||
};
|
||||
DEFINE_REF(FragmentShader);
|
||||
class ComputeShader
|
||||
{
|
||||
public:
|
||||
ComputeShader() {}
|
||||
virtual ~ComputeShader() {}
|
||||
};
|
||||
DEFINE_REF(ComputeShader);
|
||||
|
||||
class DescriptorBinding
|
||||
{
|
||||
public:
|
||||
@@ -155,13 +144,18 @@ public:
|
||||
virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0;
|
||||
virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0;
|
||||
virtual bool operator<(PDescriptorSet other) = 0;
|
||||
|
||||
virtual uint32 getSetIndex() const = 0;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet);
|
||||
|
||||
class DescriptorLayout
|
||||
{
|
||||
public:
|
||||
DescriptorLayout() {}
|
||||
DescriptorLayout()
|
||||
: setIndex(0)
|
||||
{
|
||||
}
|
||||
virtual ~DescriptorLayout() {}
|
||||
void operator=(const DescriptorLayout &other)
|
||||
{
|
||||
@@ -172,10 +166,12 @@ public:
|
||||
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1);
|
||||
virtual PDescriptorSet allocatedDescriptorSet();
|
||||
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
|
||||
inline uint32 getSetIndex() const { return setIndex; }
|
||||
|
||||
protected:
|
||||
Array<DescriptorBinding> descriptorBindings;
|
||||
PDescriptorAllocator allocator;
|
||||
uint32 setIndex;
|
||||
friend class PipelineLayout;
|
||||
friend class DescriptorAllocator;
|
||||
};
|
||||
@@ -195,22 +191,6 @@ protected:
|
||||
Array<SePushConstantRange> pushConstants;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout);
|
||||
class VertexDeclaration
|
||||
{
|
||||
public:
|
||||
virtual ~VertexDeclaration()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(VertexDeclaration);
|
||||
class GraphicsPipeline
|
||||
{
|
||||
public:
|
||||
virtual ~GraphicsPipeline()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(GraphicsPipeline);
|
||||
class UniformBuffer
|
||||
{
|
||||
public:
|
||||
@@ -221,17 +201,40 @@ DEFINE_REF(UniformBuffer);
|
||||
class VertexBuffer
|
||||
{
|
||||
public:
|
||||
virtual ~VertexBuffer()
|
||||
VertexBuffer(uint32 numVertices, uint32 vertexSize);
|
||||
virtual ~VertexBuffer();
|
||||
inline uint32 getNumVertices()
|
||||
{
|
||||
return numVertices;
|
||||
}
|
||||
// Size of one vertex in bytes
|
||||
inline uint32 getVertexSize()
|
||||
{
|
||||
return vertexSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32 numVertices;
|
||||
uint32 vertexSize;
|
||||
};
|
||||
DEFINE_REF(VertexBuffer);
|
||||
class IndexBuffer
|
||||
{
|
||||
public:
|
||||
virtual ~IndexBuffer()
|
||||
IndexBuffer(uint32 size, Gfx::SeIndexType index);
|
||||
virtual ~IndexBuffer();
|
||||
inline uint32 getNumIndices() const
|
||||
{
|
||||
return numIndices;
|
||||
}
|
||||
inline Gfx::SeIndexType getIndexType() const
|
||||
{
|
||||
return indexType;
|
||||
}
|
||||
|
||||
protected:
|
||||
Gfx::SeIndexType indexType;
|
||||
uint32 numIndices;
|
||||
};
|
||||
DEFINE_REF(IndexBuffer);
|
||||
class StructuredBuffer
|
||||
@@ -242,6 +245,44 @@ public:
|
||||
}
|
||||
};
|
||||
DEFINE_REF(StructuredBuffer);
|
||||
class VertexStream
|
||||
{
|
||||
public:
|
||||
VertexStream() {}
|
||||
VertexStream(PVertexBuffer buffer, uint8 instanced);
|
||||
~VertexStream();
|
||||
void addVertexElement(VertexElement element);
|
||||
const Array<VertexElement> getVertexDescriptions() const;
|
||||
PVertexBuffer getVertexBuffer();
|
||||
inline uint8 isInstanced() const { return instanced; }
|
||||
|
||||
private:
|
||||
PVertexBuffer buffer;
|
||||
Array<VertexElement> vertexDescription;
|
||||
uint8 instanced;
|
||||
};
|
||||
class VertexDeclaration
|
||||
{
|
||||
public:
|
||||
VertexDeclaration();
|
||||
~VertexDeclaration();
|
||||
uint32 addVertexStream(const VertexStream &vertexStream);
|
||||
const Array<VertexStream> &getVertexStreams() const;
|
||||
|
||||
private:
|
||||
Array<VertexStream> vertexStreams;
|
||||
};
|
||||
DEFINE_REF(VertexDeclaration);
|
||||
class GraphicsPipeline
|
||||
{
|
||||
public:
|
||||
GraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) : createInfo(createInfo) {}
|
||||
virtual ~GraphicsPipeline(){}
|
||||
const GraphicsPipelineCreateInfo& getCreateInfo() const {return createInfo;}
|
||||
protected:
|
||||
GraphicsPipelineCreateInfo createInfo;
|
||||
};
|
||||
DEFINE_REF(GraphicsPipeline);
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
@@ -259,6 +300,20 @@ public:
|
||||
};
|
||||
DEFINE_REF(Texture2D);
|
||||
|
||||
class RenderCommand
|
||||
{
|
||||
public:
|
||||
virtual ~RenderCommand()
|
||||
{
|
||||
}
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
|
||||
virtual void bindVertexBuffer(Gfx::PVertexBuffer vertexBuffer) = 0;
|
||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
|
||||
virtual void draw(DrawInstance data) = 0;
|
||||
};
|
||||
DEFINE_REF(RenderCommand);
|
||||
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
@@ -285,6 +340,7 @@ public:
|
||||
virtual ~Viewport();
|
||||
virtual void resize(uint32 newX, uint32 newY) = 0;
|
||||
virtual void move(uint32 newOffsetX, uint32 newOffsetY) = 0;
|
||||
|
||||
protected:
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
@@ -364,12 +420,13 @@ DEFINE_REF(RenderTargetLayout);
|
||||
class RenderPass
|
||||
{
|
||||
public:
|
||||
virtual ~RenderPass()
|
||||
{
|
||||
}
|
||||
};
|
||||
DEFINE_REF(RenderPass);
|
||||
RenderPass(PRenderTargetLayout layout) : layout(layout) {}
|
||||
virtual ~RenderPass() {}
|
||||
inline PRenderTargetLayout getLayout() const { return layout; }
|
||||
|
||||
protected:
|
||||
PRenderTargetLayout layout;
|
||||
};
|
||||
DEFINE_REF(RenderPass);
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -1 +1 @@
|
||||
#include "Mesh.h"
|
||||
#include "Mesh.h"
|
||||
|
||||
@@ -8,8 +8,9 @@ class Mesh
|
||||
public:
|
||||
Mesh(Gfx::PVertexBuffer vertexBuffer, Gfx::PIndexBuffer indexBuffer);
|
||||
~Mesh();
|
||||
|
||||
private:
|
||||
Gfx::VertexBuffer vertexBuffer;
|
||||
Gfx::IndexBuffer indexBuffer;
|
||||
};
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "RenderCore.h"
|
||||
#include "SceneView.h"
|
||||
|
||||
Seele::RenderCore::RenderCore()
|
||||
{
|
||||
@@ -16,7 +17,13 @@ void Seele::RenderCore::init()
|
||||
mainWindowInfo.width = 1280;
|
||||
mainWindowInfo.height = 720;
|
||||
mainWindowInfo.bFullscreen = false;
|
||||
windowManager->addWindow(mainWindowInfo);
|
||||
auto window = windowManager->addWindow(mainWindowInfo);
|
||||
ViewportCreateInfo sceneViewInfo;
|
||||
sceneViewInfo.sizeX = 1280;
|
||||
sceneViewInfo.sizeY = 720;
|
||||
sceneViewInfo.offsetX = 0;
|
||||
sceneViewInfo.offsetY = 0;
|
||||
PSceneView sceneView = new SceneView(windowManager->getGraphics(), window, sceneViewInfo);
|
||||
}
|
||||
|
||||
void Seele::RenderCore::renderLoop()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "WindowManager.h"
|
||||
#include "Scene/Scene.h"
|
||||
namespace Seele
|
||||
{
|
||||
class RenderCore
|
||||
@@ -12,6 +13,7 @@ public:
|
||||
void shutdown();
|
||||
|
||||
private:
|
||||
PScene scene;
|
||||
PWindowManager windowManager;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "RenderPath.h"
|
||||
#include "GraphicsResources.h"
|
||||
|
||||
Seele::RenderPath::RenderPath(Gfx::PGraphics graphics, Gfx::PViewport target)
|
||||
: graphics(graphics)
|
||||
, target(target)
|
||||
: graphics(graphics), target(target)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ Seele::RenderPath::~RenderPath()
|
||||
{
|
||||
}
|
||||
|
||||
void Seele::RenderPath::applyArea(Rect newArea)
|
||||
void Seele::RenderPath::applyArea(URect newArea)
|
||||
{
|
||||
target->resize(newArea.size.x, newArea.size.y);
|
||||
target->move(newArea.offset.x, newArea.offset.y);
|
||||
|
||||
@@ -8,10 +8,11 @@ class RenderPath
|
||||
public:
|
||||
RenderPath(Gfx::PGraphics graphics, Gfx::PViewport target);
|
||||
virtual ~RenderPath();
|
||||
virtual void applyArea(Rect area);
|
||||
virtual void applyArea(URect area);
|
||||
virtual void beginFrame() = 0;
|
||||
virtual void render() = 0;
|
||||
virtual void endFrame() = 0;
|
||||
|
||||
protected:
|
||||
Gfx::PGraphics graphics;
|
||||
Gfx::PViewport target;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "SceneRenderPath.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
Seele::SceneRenderPath::SceneRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target)
|
||||
: RenderPath(graphics, target)
|
||||
{
|
||||
scene = new Scene();
|
||||
}
|
||||
|
||||
Seele::SceneRenderPath::~SceneRenderPath()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Scene);
|
||||
class SceneRenderPath : public RenderPath
|
||||
{
|
||||
public:
|
||||
@@ -11,5 +12,8 @@ public:
|
||||
virtual void beginFrame() = 0;
|
||||
virtual void render() = 0;
|
||||
virtual void endFrame() = 0;
|
||||
|
||||
protected:
|
||||
PScene scene;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "SceneView.h"
|
||||
#include "ForwardPlusRenderPath.h"
|
||||
#include "Window.h"
|
||||
|
||||
Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo& createInfo)
|
||||
Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo)
|
||||
: View(graphics, owner, createInfo)
|
||||
{
|
||||
renderer = new ForwardPlusRenderPath(graphics, viewport);
|
||||
|
||||
@@ -5,7 +5,8 @@ namespace Seele
|
||||
class SceneView : public View
|
||||
{
|
||||
public:
|
||||
SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo& createInfo);
|
||||
SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo);
|
||||
~SceneView();
|
||||
};
|
||||
DEFINE_REF(SceneView);
|
||||
} // namespace Seele
|
||||
@@ -1,9 +1,8 @@
|
||||
#include "View.h"
|
||||
#include "Window.h"
|
||||
|
||||
Seele::View::View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& viewportInfo)
|
||||
: graphics(graphics)
|
||||
, owner(owner)
|
||||
Seele::View::View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &viewportInfo)
|
||||
: graphics(graphics), owner(window)
|
||||
{
|
||||
viewport = graphics->createViewport(owner->getGfxHandle(), viewportInfo);
|
||||
}
|
||||
@@ -27,7 +26,7 @@ void Seele::View::endFrame()
|
||||
renderer->endFrame();
|
||||
}
|
||||
|
||||
void Seele::View::applyArea(Rect area)
|
||||
void Seele::View::applyArea(URect area)
|
||||
{
|
||||
renderer->applyArea(area);
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@ DECLARE_REF(Window);
|
||||
class View
|
||||
{
|
||||
public:
|
||||
View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo);
|
||||
View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo);
|
||||
virtual ~View();
|
||||
void beginFrame();
|
||||
void render();
|
||||
void endFrame();
|
||||
void applyArea(Rect area);
|
||||
void applyArea(URect area);
|
||||
|
||||
protected:
|
||||
Gfx::PGraphics graphics;
|
||||
|
||||
@@ -18,6 +18,12 @@ target_sources(SeeleEngine
|
||||
VulkanInitializer.cpp
|
||||
VulkanRenderPass.h
|
||||
VulkanRenderPass.cpp
|
||||
VulkanPipeline.h
|
||||
VulkanPipeline.cpp
|
||||
VulkanPipelineCache.h
|
||||
VulkanPipelineCache.cpp
|
||||
VulkanShader.h
|
||||
VulkanShader.cpp
|
||||
VulkanTexture.cpp
|
||||
VulkanQueue.h
|
||||
VulkanQueue.cpp
|
||||
|
||||
@@ -5,12 +5,8 @@
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
SubAllocation::SubAllocation(Allocation* owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize)
|
||||
: owner(owner)
|
||||
, size(size)
|
||||
, allocatedOffset(allocatedOffset)
|
||||
, alignedOffset(alignedOffset)
|
||||
, allocatedSize(allocatedSize)
|
||||
SubAllocation::SubAllocation(Allocation *owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize)
|
||||
: owner(owner), size(size), allocatedOffset(allocatedOffset), alignedOffset(alignedOffset), allocatedSize(allocatedSize)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,9 +25,9 @@ bool SubAllocation::isReadable() const
|
||||
return owner->isReadable();
|
||||
}
|
||||
|
||||
void* SubAllocation::getMappedPointer()
|
||||
void *SubAllocation::getMappedPointer()
|
||||
{
|
||||
return (uint8*)owner->getMappedPointer() + alignedOffset;
|
||||
return (uint8 *)owner->getMappedPointer() + alignedOffset;
|
||||
}
|
||||
|
||||
void SubAllocation::flushMemory()
|
||||
@@ -44,15 +40,9 @@ void SubAllocation::invalidateMemory()
|
||||
owner->invalidateMemory();
|
||||
}
|
||||
|
||||
Allocation::Allocation(PGraphics graphics, Allocator* allocator, VkDeviceSize size, uint8 memoryTypeIndex,
|
||||
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo* dedicatedInfo)
|
||||
: device(graphics->getDevice())
|
||||
, allocator(allocator)
|
||||
, bytesAllocated(0)
|
||||
, bytesUsed(0)
|
||||
, readable(properties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
||||
, properties(properties)
|
||||
, memoryTypeIndex(memoryTypeIndex)
|
||||
Allocation::Allocation(PGraphics graphics, Allocator *allocator, VkDeviceSize size, uint8 memoryTypeIndex,
|
||||
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
|
||||
: device(graphics->getDevice()), allocator(allocator), bytesAllocated(0), bytesUsed(0), readable(properties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), properties(properties), memoryTypeIndex(memoryTypeIndex)
|
||||
{
|
||||
VkMemoryAllocateInfo allocInfo =
|
||||
init::MemoryAllocateInfo();
|
||||
@@ -110,8 +100,8 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
|
||||
{
|
||||
freeAllocation->size -= size;
|
||||
freeAllocation->allocatedSize -= size;
|
||||
freeAllocation->allocatedOffset += allocatedOffset;
|
||||
freeAllocation->alignedOffset += allocatedOffset;
|
||||
freeAllocation->allocatedOffset += size;
|
||||
freeAllocation->alignedOffset += size;
|
||||
PSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, size, alignedOffset, size);
|
||||
activeAllocations[allocatedOffset] = subAlloc.getHandle();
|
||||
freeRanges.erase(allocatedOffset);
|
||||
@@ -123,15 +113,15 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Allocation::markFree(SubAllocation* allocation)
|
||||
void Allocation::markFree(SubAllocation *allocation)
|
||||
{
|
||||
VkDeviceSize lowerBound = allocation->allocatedOffset;
|
||||
VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize;
|
||||
PSubAllocation allocHandle;
|
||||
for(auto freeRange : freeRanges)
|
||||
for (auto freeRange : freeRanges)
|
||||
{
|
||||
PSubAllocation freeAlloc = freeRange.value;
|
||||
if(freeAlloc->allocatedOffset + freeAlloc->allocatedSize + 1 == lowerBound)
|
||||
if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize + 1 == lowerBound)
|
||||
{
|
||||
freeAlloc->allocatedSize += allocation->allocatedSize;
|
||||
allocHandle = freeAlloc;
|
||||
@@ -139,9 +129,9 @@ void Allocation::markFree(SubAllocation* allocation)
|
||||
}
|
||||
}
|
||||
auto foundAlloc = freeRanges.find(upperBound + 1);
|
||||
if(foundAlloc != freeRanges.end())
|
||||
if (foundAlloc != freeRanges.end())
|
||||
{
|
||||
if(allocHandle == nullptr)
|
||||
if (allocHandle == nullptr)
|
||||
{
|
||||
allocHandle->allocatedSize += foundAlloc->value->allocatedSize;
|
||||
freeRanges.erase(foundAlloc->key);
|
||||
@@ -153,7 +143,7 @@ void Allocation::markFree(SubAllocation* allocation)
|
||||
allocHandle->alignedOffset -= allocation->allocatedSize;
|
||||
}
|
||||
}
|
||||
if(allocHandle == nullptr)
|
||||
if (allocHandle == nullptr)
|
||||
{
|
||||
allocHandle = new SubAllocation(this, allocation->alignedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize);
|
||||
freeRanges[allocation->allocatedOffset] = allocHandle;
|
||||
@@ -170,16 +160,16 @@ Allocator::Allocator(PGraphics graphics)
|
||||
for (size_t i = 0; i < memProperties.memoryHeapCount; ++i)
|
||||
{
|
||||
VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i];
|
||||
HeapInfo& heapInfo = heaps[i];
|
||||
HeapInfo &heapInfo = heaps[i];
|
||||
heapInfo.maxSize = memoryHeap.size;
|
||||
}
|
||||
}
|
||||
|
||||
Allocator::~Allocator()
|
||||
{
|
||||
for(auto heap : heaps)
|
||||
for (auto heap : heaps)
|
||||
{
|
||||
for(auto alloc : heap.allocations)
|
||||
for (auto alloc : heap.allocations)
|
||||
{
|
||||
assert(alloc->activeAllocations.empty());
|
||||
assert(alloc->freeRanges.size() == 1);
|
||||
@@ -189,45 +179,45 @@ Allocator::~Allocator()
|
||||
graphics = nullptr;
|
||||
}
|
||||
|
||||
PSubAllocation Allocator::allocate(const VkMemoryRequirements2& memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo* dedicatedInfo)
|
||||
PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
|
||||
{
|
||||
const VkMemoryRequirements& requirements = memRequirements2.memoryRequirements;
|
||||
const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements;
|
||||
uint8 memoryTypeIndex;
|
||||
VK_CHECK(findMemoryType(requirements.memoryTypeBits, properties, &memoryTypeIndex));
|
||||
uint32 heapIndex = memProperties.memoryTypes[memoryTypeIndex].heapIndex;
|
||||
|
||||
if(memRequirements2.pNext != nullptr)
|
||||
|
||||
if (memRequirements2.pNext != nullptr)
|
||||
{
|
||||
VkMemoryDedicatedRequirements* dedicatedReq = (VkMemoryDedicatedRequirements*)memRequirements2.pNext;
|
||||
if(dedicatedReq->prefersDedicatedAllocation)
|
||||
VkMemoryDedicatedRequirements *dedicatedReq = (VkMemoryDedicatedRequirements *)memRequirements2.pNext;
|
||||
if (dedicatedReq->prefersDedicatedAllocation)
|
||||
{
|
||||
PAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
|
||||
heaps[heapIndex].allocations.add(newAllocation);
|
||||
return newAllocation->getSuballocation(requirements.size, requirements.alignment);
|
||||
}
|
||||
}
|
||||
for(auto alloc : heaps[heapIndex].allocations)
|
||||
for (auto alloc : heaps[heapIndex].allocations)
|
||||
{
|
||||
PSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment);
|
||||
if(suballoc != nullptr)
|
||||
if (suballoc != nullptr)
|
||||
{
|
||||
return suballoc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// no suitable allocations found, allocate new block
|
||||
PAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : MemoryBlockSize, memoryTypeIndex, properties, nullptr);
|
||||
heaps[heapIndex].allocations.add(newAllocation);
|
||||
return newAllocation->getSuballocation(requirements.size, requirements.alignment);
|
||||
}
|
||||
|
||||
void Allocator::free(Allocation* allocation)
|
||||
void Allocator::free(Allocation *allocation)
|
||||
{
|
||||
for(auto heap : heaps)
|
||||
for (auto heap : heaps)
|
||||
{
|
||||
for(uint32 i = 0; i < heap.allocations.size(); ++i)
|
||||
for (uint32 i = 0; i < heap.allocations.size(); ++i)
|
||||
{
|
||||
if(heap.allocations[i] == allocation)
|
||||
if (heap.allocations[i] == allocation)
|
||||
{
|
||||
heap.allocations.remove(i, false);
|
||||
return;
|
||||
@@ -236,7 +226,7 @@ void Allocator::free(Allocation* allocation)
|
||||
}
|
||||
}
|
||||
|
||||
VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint8* typeIndex)
|
||||
VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint8 *typeIndex)
|
||||
{
|
||||
for (uint8 memoryIndex = 0; memoryIndex < memProperties.memoryTypeCount && typeBits; ++memoryIndex)
|
||||
{
|
||||
@@ -250,43 +240,37 @@ VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags proper
|
||||
}
|
||||
typeBits >>= 1;
|
||||
}
|
||||
|
||||
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
StagingBuffer::StagingBuffer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
StagingBuffer::~StagingBuffer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
StagingManager::StagingManager(PGraphics graphics, PAllocator allocator)
|
||||
: graphics(graphics)
|
||||
, allocator(allocator)
|
||||
: graphics(graphics), allocator(allocator)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
StagingManager::~StagingManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void StagingManager::clearPending()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead)
|
||||
{
|
||||
for(auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
|
||||
{
|
||||
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
|
||||
{
|
||||
auto freeBuffer = *it;
|
||||
if(freeBuffer->allocation->getSize() == size && freeBuffer->allocation->isReadable() == bCPURead)
|
||||
if (freeBuffer->allocation->getSize() == size && freeBuffer->allocation->isReadable() == bCPURead)
|
||||
{
|
||||
activeBuffers.add(freeBuffer.getHandle());
|
||||
freeBuffers.remove(it, false);
|
||||
@@ -311,14 +295,13 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageF
|
||||
bufferQuery.buffer = stagingBuffer->buffer;
|
||||
vkGetBufferMemoryRequirements2(vulkanDevice, &bufferQuery, &memReqs);
|
||||
|
||||
memReqs.memoryRequirements.alignment =
|
||||
(16 > memReqs.memoryRequirements.alignment) ?
|
||||
16 : memReqs.memoryRequirements.alignment;
|
||||
memReqs.memoryRequirements.alignment =
|
||||
(16 > memReqs.memoryRequirements.alignment) ? 16 : memReqs.memoryRequirements.alignment;
|
||||
|
||||
stagingBuffer->allocation = allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (bCPURead ? VK_MEMORY_PROPERTY_HOST_CACHED_BIT : VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), stagingBuffer->buffer);
|
||||
stagingBuffer->allocation = allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (bCPURead ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_HOST_CACHED_BIT), stagingBuffer->buffer);
|
||||
stagingBuffer->bReadable = bCPURead;
|
||||
vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset());
|
||||
|
||||
|
||||
activeBuffers.add(stagingBuffer.getHandle());
|
||||
return stagingBuffer;
|
||||
}
|
||||
|
||||
@@ -58,9 +58,14 @@ Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::Q
|
||||
|
||||
Buffer::~Buffer()
|
||||
{
|
||||
auto fence = getCommands()->getCommands()->getFence();
|
||||
auto &deletionQueue = graphics->getDeletionQueue();
|
||||
VkDevice device = graphics->getDevice();
|
||||
VkBuffer buf[Gfx::numFramesBuffered];
|
||||
for (uint32 i = 0; i < numBuffers; ++i)
|
||||
{
|
||||
vkDestroyBuffer(graphics->getDevice(), buffers[i].buffer, nullptr);
|
||||
buf[i] = buffers[i].buffer;
|
||||
deletionQueue.addPendingDelete(fence, [device, buf, i]() { vkDestroyBuffer(device, buf[i], nullptr); });
|
||||
buffers[i].allocation = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -221,10 +226,9 @@ void Buffer::unlock()
|
||||
std::memset(®ion, 0, sizeof(VkBufferCopy));
|
||||
region.size = size;
|
||||
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion);
|
||||
|
||||
graphics->getStagingManager()->releaseStagingBuffer(stagingBuffer);
|
||||
}
|
||||
transferOwnership(pending.prevQueue);
|
||||
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,13 +282,14 @@ VkAccessFlags StructuredBuffer::getDestAccessMask()
|
||||
return VK_ACCESS_MEMORY_READ_BIT;
|
||||
}
|
||||
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics, const BulkResourceData &resourceData)
|
||||
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, resourceData.owner)
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData)
|
||||
: Buffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, resourceData.resourceData.owner)
|
||||
, Gfx::VertexBuffer(resourceData.numVertices, resourceData.vertexSize)
|
||||
{
|
||||
if (resourceData.data != nullptr)
|
||||
if (resourceData.resourceData.data != nullptr)
|
||||
{
|
||||
void *data = lock();
|
||||
std::memcpy(data, resourceData.data, resourceData.size);
|
||||
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
@@ -303,13 +308,14 @@ VkAccessFlags VertexBuffer::getDestAccessMask()
|
||||
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
|
||||
}
|
||||
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics, const BulkResourceData &resourceData)
|
||||
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, resourceData.owner)
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData)
|
||||
: Buffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, resourceData.resourceData.owner)
|
||||
, Gfx::IndexBuffer(resourceData.resourceData.size, resourceData.indexType)
|
||||
{
|
||||
if (resourceData.data != nullptr)
|
||||
if (resourceData.resourceData.data != nullptr)
|
||||
{
|
||||
void *data = lock();
|
||||
std::memcpy(data, resourceData.data, resourceData.size);
|
||||
std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanPipeline.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanFramebuffer.h"
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanPipeline.h"
|
||||
#include "VulkanDescriptorSets.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -74,7 +77,6 @@ void CmdBuffer::endRenderPass()
|
||||
{
|
||||
vkCmdEndRenderPass(handle);
|
||||
state = State::InsideBegin;
|
||||
|
||||
}
|
||||
|
||||
void CmdBuffer::executeCommands(Array<PSecondaryCmdBuffer> commands)
|
||||
@@ -112,6 +114,11 @@ void CmdBuffer::refreshFence()
|
||||
}
|
||||
}
|
||||
|
||||
PFence CmdBuffer::getFence()
|
||||
{
|
||||
return fence;
|
||||
}
|
||||
|
||||
SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
|
||||
: CmdBufferBase(graphics, cmdPool)
|
||||
{
|
||||
@@ -145,6 +152,33 @@ void SecondaryCmdBuffer::end()
|
||||
VK_CHECK(vkEndCommandBuffer(handle));
|
||||
}
|
||||
|
||||
void SecondaryCmdBuffer::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline)
|
||||
{
|
||||
pipeline = gfxPipeline.cast<GraphicsPipeline>();
|
||||
pipeline->bind(handle);
|
||||
}
|
||||
void SecondaryCmdBuffer::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
|
||||
{
|
||||
VkDescriptorSet setHandle = descriptorSet.cast<DescriptorSet>()->getHandle();
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
|
||||
}
|
||||
void SecondaryCmdBuffer::bindVertexBuffer(Gfx::PVertexBuffer vertexBuffer)
|
||||
{
|
||||
PVertexBuffer buf = vertexBuffer.cast<VertexBuffer>();
|
||||
const VkBuffer bufHandle[1] = {buf->getHandle()};
|
||||
const VkDeviceSize offsets[1] = {0};
|
||||
vkCmdBindVertexBuffers(handle, 0, 1, bufHandle, offsets);
|
||||
}
|
||||
void SecondaryCmdBuffer::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
|
||||
{
|
||||
PIndexBuffer buf = indexBuffer.cast<IndexBuffer>();
|
||||
vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, VK_INDEX_TYPE_UINT16);
|
||||
}
|
||||
void SecondaryCmdBuffer::draw(DrawInstance data)
|
||||
{
|
||||
vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, data.firstInstance);
|
||||
}
|
||||
|
||||
CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
|
||||
: graphics(graphics), queue(queue)
|
||||
{
|
||||
@@ -220,4 +254,4 @@ void CommandBufferManager::waitForCommands(PCmdBuffer cmdBuffer, uint32 timeout)
|
||||
{
|
||||
cmdBuffer->fence->wait(timeout);
|
||||
cmdBuffer->refreshFence();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Vulkan
|
||||
{
|
||||
DECLARE_REF(RenderPass);
|
||||
DECLARE_REF(Framebuffer);
|
||||
class CmdBufferBase : public Gfx::RenderCommandBase
|
||||
class CmdBufferBase
|
||||
{
|
||||
public:
|
||||
CmdBufferBase(PGraphics graphics, VkCommandPool cmdPool);
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
void executeCommands(Array<PSecondaryCmdBuffer> secondaryCommands);
|
||||
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
|
||||
void refreshFence();
|
||||
PFence getFence();
|
||||
enum State
|
||||
{
|
||||
ReadyBegin,
|
||||
@@ -64,15 +65,22 @@ private:
|
||||
};
|
||||
DEFINE_REF(CmdBuffer);
|
||||
|
||||
class SecondaryCmdBuffer : public CmdBufferBase
|
||||
DECLARE_REF(GraphicsPipeline);
|
||||
class SecondaryCmdBuffer : public CmdBufferBase, public Gfx::RenderCommand
|
||||
{
|
||||
public:
|
||||
SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~SecondaryCmdBuffer();
|
||||
void begin(PCmdBuffer parent);
|
||||
void end();
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override;
|
||||
virtual void bindVertexBuffer(Gfx::PVertexBuffer vertexBuffer) override;
|
||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
|
||||
virtual void draw(DrawInstance data) override;
|
||||
|
||||
private:
|
||||
PGraphicsPipeline pipeline;
|
||||
};
|
||||
DEFINE_REF(SecondaryCmdBuffer);
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ private:
|
||||
PGraphics graphics;
|
||||
Array<VkDescriptorSetLayoutBinding> bindings;
|
||||
VkDescriptorSetLayout layoutHandle;
|
||||
friend class PipelineStateCacheManager;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout);
|
||||
class PipelineLayout : public Gfx::PipelineLayout
|
||||
@@ -49,10 +48,33 @@ private:
|
||||
uint32 layoutHash;
|
||||
VkPipelineLayout layoutHandle;
|
||||
PGraphics graphics;
|
||||
friend class PipelineStateCacheManager;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout);
|
||||
|
||||
class DescriptorAllocator : public Gfx::DescriptorAllocator
|
||||
{
|
||||
public:
|
||||
DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout);
|
||||
virtual ~DescriptorAllocator();
|
||||
virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet);
|
||||
|
||||
inline VkDescriptorPool getHandle() const
|
||||
{
|
||||
return poolHandle;
|
||||
}
|
||||
inline DescriptorLayout getLayout() const
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
int maxSets = 512;
|
||||
VkDescriptorPool poolHandle;
|
||||
DescriptorLayout &layout;
|
||||
};
|
||||
DEFINE_REF(DescriptorAllocator);
|
||||
|
||||
class DescriptorSet : public Gfx::DescriptorSet
|
||||
{
|
||||
public:
|
||||
@@ -70,6 +92,10 @@ public:
|
||||
{
|
||||
return setHandle;
|
||||
}
|
||||
virtual uint32 getSetIndex() const
|
||||
{
|
||||
return owner->getLayout().getSetIndex();
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void writeChanges();
|
||||
@@ -83,24 +109,5 @@ private:
|
||||
};
|
||||
DEFINE_REF(DescriptorSet);
|
||||
|
||||
class DescriptorAllocator : public Gfx::DescriptorAllocator
|
||||
{
|
||||
public:
|
||||
DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout);
|
||||
virtual ~DescriptorAllocator();
|
||||
virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet);
|
||||
|
||||
inline VkDescriptorPool getHandle()
|
||||
{
|
||||
return poolHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
int maxSets = 512;
|
||||
VkDescriptorPool poolHandle;
|
||||
DescriptorLayout &layout;
|
||||
};
|
||||
DEFINE_REF(DescriptorAllocator);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -8,9 +8,7 @@ using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRenderTargetLayout renderTargetLayout)
|
||||
: graphics(graphics)
|
||||
, layout(renderTargetLayout)
|
||||
, renderPass(renderPass)
|
||||
: graphics(graphics), layout(renderTargetLayout), renderPass(renderPass)
|
||||
{
|
||||
FramebufferDescription description;
|
||||
std::memset(&description, 0, sizeof(FramebufferDescription));
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
{
|
||||
return hash;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 hash;
|
||||
PGraphics graphics;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanFramebuffer.h"
|
||||
#include "VulkanPipelineCache.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include <glfw/glfw3.h>
|
||||
|
||||
@@ -42,6 +43,7 @@ void Graphics::init(GraphicsInitializer initInfo)
|
||||
computeCommands = new CommandBufferManager(this, computeQueue);
|
||||
transferCommands = new CommandBufferManager(this, transferQueue);
|
||||
dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue);
|
||||
pipelineCache = new PipelineCache(this, "pipeline.cache");
|
||||
}
|
||||
|
||||
Gfx::PWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
|
||||
@@ -67,7 +69,7 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
|
||||
uint32 framebufferHash = rp->getFramebufferHash();
|
||||
PFramebuffer framebuffer;
|
||||
auto found = allocatedFramebuffers.find(framebufferHash);
|
||||
if(found == allocatedFramebuffers.end())
|
||||
if (found == allocatedFramebuffers.end())
|
||||
{
|
||||
framebuffer = new Framebuffer(this, rp, rp->getLayout());
|
||||
}
|
||||
@@ -83,6 +85,18 @@ void Graphics::endRenderPass()
|
||||
graphicsCommands->getCommands()->endRenderPass();
|
||||
}
|
||||
|
||||
void Graphics::executeCommands(Array<Gfx::PRenderCommand> commands)
|
||||
{
|
||||
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||
for (uint32 i = 0; i < commands.size(); ++i)
|
||||
{
|
||||
PSecondaryCmdBuffer buf = commands[i].cast<SecondaryCmdBuffer>();
|
||||
buf->end();
|
||||
cmdBuffers[i] = buf->getHandle();
|
||||
}
|
||||
vkCmdExecuteCommands(graphicsCommands->getCommands()->getHandle(), cmdBuffers.size(), cmdBuffers.data());
|
||||
}
|
||||
|
||||
Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
PTexture2D result = new Texture2D(this, createInfo.width, createInfo.height, createInfo.bArray,
|
||||
@@ -91,28 +105,39 @@ Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::PUniformBuffer Graphics::createUniformBuffer(const BulkResourceData &bulkData)
|
||||
Gfx::PUniformBuffer Graphics::createUniformBuffer(const BulkResourceData &bulkData)
|
||||
{
|
||||
PUniformBuffer uniformBuffer = new UniformBuffer(this, bulkData);
|
||||
return uniformBuffer;
|
||||
}
|
||||
|
||||
Gfx::PStructuredBuffer Graphics::createStructuredBuffer(const BulkResourceData &bulkData)
|
||||
Gfx::PStructuredBuffer Graphics::createStructuredBuffer(const BulkResourceData &bulkData)
|
||||
{
|
||||
PStructuredBuffer structuredBuffer = new StructuredBuffer(this, bulkData);
|
||||
return structuredBuffer;
|
||||
}
|
||||
Gfx::PVertexBuffer Graphics::createVertexBuffer(const BulkResourceData &bulkData)
|
||||
Gfx::PVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData)
|
||||
{
|
||||
PVertexBuffer vertexBuffer = new VertexBuffer(this, bulkData);
|
||||
return vertexBuffer;
|
||||
}
|
||||
|
||||
Gfx::PIndexBuffer Graphics::createIndexBuffer(const BulkResourceData &bulkData)
|
||||
Gfx::PIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkData)
|
||||
{
|
||||
PIndexBuffer indexBuffer = new IndexBuffer(this, bulkData);
|
||||
return indexBuffer;
|
||||
}
|
||||
Gfx::PRenderCommand Graphics::createRenderCommand()
|
||||
{
|
||||
PSecondaryCmdBuffer cmdBuffer = graphicsCommands->createSecondaryCmdBuffer();
|
||||
cmdBuffer->begin(getGraphicsCommands()->getCommands());
|
||||
return cmdBuffer;
|
||||
}
|
||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo)
|
||||
{
|
||||
PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
VkInstance Graphics::getInstance() const
|
||||
{
|
||||
@@ -173,6 +198,7 @@ Array<const char *> Graphics::getRequiredExtensions()
|
||||
}
|
||||
void Graphics::initInstance(GraphicsInitializer initInfo)
|
||||
{
|
||||
glfwInit();
|
||||
VkApplicationInfo appInfo = {};
|
||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
appInfo.pApplicationName = initInfo.applicationName;
|
||||
|
||||
@@ -11,6 +11,8 @@ DECLARE_REF(StagingManager);
|
||||
DECLARE_REF(CommandBufferManager);
|
||||
DECLARE_REF(Queue);
|
||||
DECLARE_REF(Framebuffer);
|
||||
DECLARE_REF(RenderCommand);
|
||||
DECLARE_REF(PipelineCache);
|
||||
class Graphics : public Gfx::Graphics
|
||||
{
|
||||
public:
|
||||
@@ -29,6 +31,10 @@ public:
|
||||
{
|
||||
return queueMapping;
|
||||
}
|
||||
QueueOwnedResourceDeletion &getDeletionQueue()
|
||||
{
|
||||
return deletionQueue;
|
||||
}
|
||||
|
||||
PAllocator getAllocator();
|
||||
PStagingManager getStagingManager();
|
||||
@@ -42,11 +48,15 @@ public:
|
||||
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
|
||||
virtual void endRenderPass() override;
|
||||
|
||||
virtual void executeCommands(Array<Gfx::PRenderCommand> commands) override;
|
||||
|
||||
virtual Gfx::PTexture2D createTexture2D(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::PUniformBuffer createUniformBuffer(const BulkResourceData &bulkData) override;
|
||||
virtual Gfx::PStructuredBuffer createStructuredBuffer(const BulkResourceData &bulkData) override;
|
||||
virtual Gfx::PVertexBuffer createVertexBuffer(const BulkResourceData &bulkData) override;
|
||||
virtual Gfx::PIndexBuffer createIndexBuffer(const BulkResourceData &bulkData) override;
|
||||
virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::PRenderCommand createRenderCommand() override;
|
||||
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override;
|
||||
|
||||
protected:
|
||||
Array<const char *> getRequiredExtensions();
|
||||
@@ -64,6 +74,8 @@ protected:
|
||||
PQueue transferQueue;
|
||||
PQueue dedicatedTransferQueue;
|
||||
QueueFamilyMapping queueMapping;
|
||||
QueueOwnedResourceDeletion deletionQueue;
|
||||
PPipelineCache pipelineCache;
|
||||
PCommandBufferManager graphicsCommands;
|
||||
PCommandBufferManager computeCommands;
|
||||
PCommandBufferManager transferCommands;
|
||||
|
||||
@@ -1145,3 +1145,166 @@ Gfx::SeAttachmentLoadOp Seele::Vulkan::cast(const VkAttachmentLoadOp &loadOp)
|
||||
return SE_ATTACHMENT_LOAD_OP_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
|
||||
VkIndexType Seele::Vulkan::cast(const Gfx::SeIndexType &indexType)
|
||||
{
|
||||
switch (indexType)
|
||||
{
|
||||
case Gfx::SE_INDEX_TYPE_UINT16:
|
||||
return VK_INDEX_TYPE_UINT16;
|
||||
case Gfx::SE_INDEX_TYPE_UINT32:
|
||||
return VK_INDEX_TYPE_UINT32;
|
||||
default:
|
||||
return VK_INDEX_TYPE_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SeIndexType Seele::Vulkan::cast(const VkIndexType &indexType)
|
||||
{
|
||||
switch (indexType)
|
||||
{
|
||||
case VK_INDEX_TYPE_UINT16:
|
||||
return Gfx::SE_INDEX_TYPE_UINT16;
|
||||
case VK_INDEX_TYPE_UINT32:
|
||||
return Gfx::SE_INDEX_TYPE_UINT32;
|
||||
default:
|
||||
return Gfx::SE_INDEX_TYPE_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
|
||||
VkPrimitiveTopology Seele::Vulkan::cast(const Gfx::SePrimitiveTopology &topology)
|
||||
{
|
||||
switch (topology)
|
||||
{
|
||||
case SE_PRIMITIVE_TOPOLOGY_POINT_LIST:
|
||||
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
case SE_PRIMITIVE_TOPOLOGY_LINE_LIST:
|
||||
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
case SE_PRIMITIVE_TOPOLOGY_LINE_STRIP:
|
||||
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
|
||||
case SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
case SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
case SE_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
|
||||
case SE_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
|
||||
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
|
||||
case SE_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
|
||||
return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
|
||||
case SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
|
||||
case SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
|
||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
|
||||
case SE_PRIMITIVE_TOPOLOGY_PATCH_LIST:
|
||||
return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
|
||||
default:
|
||||
return VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SePrimitiveTopology Seele::Vulkan::cast(const VkPrimitiveTopology &topology)
|
||||
{
|
||||
switch (topology)
|
||||
{
|
||||
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
|
||||
return SE_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
|
||||
return SE_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
|
||||
return SE_PRIMITIVE_TOPOLOGY_LINE_STRIP;
|
||||
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
|
||||
return SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
|
||||
return SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
|
||||
return SE_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
|
||||
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
|
||||
return SE_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
|
||||
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
|
||||
return SE_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
|
||||
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
|
||||
return SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
|
||||
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
|
||||
return SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
|
||||
case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
|
||||
return SE_PRIMITIVE_TOPOLOGY_PATCH_LIST;
|
||||
default:
|
||||
return SE_PRIMITIVE_TOPOLOGY_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
|
||||
VkPolygonMode Seele::Vulkan::cast(const Gfx::SePolygonMode &mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case SE_POLYGON_MODE_FILL:
|
||||
return VK_POLYGON_MODE_FILL;
|
||||
case SE_POLYGON_MODE_LINE:
|
||||
return VK_POLYGON_MODE_LINE;
|
||||
case SE_POLYGON_MODE_POINT:
|
||||
return VK_POLYGON_MODE_POINT;
|
||||
default:
|
||||
return VK_POLYGON_MODE_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SePolygonMode Seele::Vulkan::cast(const VkPolygonMode &mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case VK_POLYGON_MODE_FILL:
|
||||
return SE_POLYGON_MODE_FILL;
|
||||
case VK_POLYGON_MODE_LINE:
|
||||
return SE_POLYGON_MODE_LINE;
|
||||
case VK_POLYGON_MODE_POINT:
|
||||
return SE_POLYGON_MODE_POINT;
|
||||
default:
|
||||
return SE_POLYGON_MODE_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
VkCompareOp Seele::Vulkan::cast(const Gfx::SeCompareOp &op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case SE_COMPARE_OP_NEVER:
|
||||
return VK_COMPARE_OP_NEVER;
|
||||
case SE_COMPARE_OP_LESS:
|
||||
return VK_COMPARE_OP_LESS;
|
||||
case SE_COMPARE_OP_EQUAL:
|
||||
return VK_COMPARE_OP_EQUAL;
|
||||
case SE_COMPARE_OP_LESS_OR_EQUAL:
|
||||
return VK_COMPARE_OP_LESS_OR_EQUAL;
|
||||
case SE_COMPARE_OP_GREATER:
|
||||
return VK_COMPARE_OP_GREATER;
|
||||
case SE_COMPARE_OP_NOT_EQUAL:
|
||||
return VK_COMPARE_OP_NOT_EQUAL;
|
||||
case SE_COMPARE_OP_GREATER_OR_EQUAL:
|
||||
return VK_COMPARE_OP_GREATER_OR_EQUAL;
|
||||
case SE_COMPARE_OP_ALWAYS:
|
||||
return VK_COMPARE_OP_ALWAYS;
|
||||
default:
|
||||
return VK_COMPARE_OP_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case VK_COMPARE_OP_NEVER:
|
||||
return SE_COMPARE_OP_NEVER;
|
||||
case VK_COMPARE_OP_LESS:
|
||||
return SE_COMPARE_OP_LESS;
|
||||
case VK_COMPARE_OP_EQUAL:
|
||||
return SE_COMPARE_OP_EQUAL;
|
||||
case VK_COMPARE_OP_LESS_OR_EQUAL:
|
||||
return SE_COMPARE_OP_LESS_OR_EQUAL;
|
||||
case VK_COMPARE_OP_GREATER:
|
||||
return SE_COMPARE_OP_GREATER;
|
||||
case VK_COMPARE_OP_NOT_EQUAL:
|
||||
return SE_COMPARE_OP_NOT_EQUAL;
|
||||
case VK_COMPARE_OP_GREATER_OR_EQUAL:
|
||||
return SE_COMPARE_OP_GREATER_OR_EQUAL;
|
||||
case VK_COMPARE_OP_ALWAYS:
|
||||
return SE_COMPARE_OP_ALWAYS;
|
||||
default:
|
||||
return SE_COMPARE_OP_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,17 @@ namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
|
||||
enum class ShaderType
|
||||
{
|
||||
VERTEX = 0,
|
||||
CONTROL = 1,
|
||||
EVALUATION = 2,
|
||||
GEOMETRY = 3,
|
||||
FRAGMENT = 4,
|
||||
COMPUTE = 5,
|
||||
};
|
||||
|
||||
VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType);
|
||||
Gfx::SeDescriptorType cast(const VkDescriptorType &descriptorType);
|
||||
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits &stage);
|
||||
@@ -26,5 +37,13 @@ VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp &storeOp);
|
||||
Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp &storeOp);
|
||||
VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp &loadOp);
|
||||
Gfx::SeAttachmentLoadOp cast(const VkAttachmentLoadOp &loadOp);
|
||||
VkIndexType cast(const Gfx::SeIndexType &indexType);
|
||||
Gfx::SeIndexType cast(const VkIndexType &indexType);
|
||||
VkPrimitiveTopology cast(const Gfx::SePrimitiveTopology &topology);
|
||||
Gfx::SePrimitiveTopology cast(const VkPrimitiveTopology &topology);
|
||||
VkPolygonMode cast(const Gfx::SePolygonMode &mode);
|
||||
Gfx::SePolygonMode cast(const VkPolygonMode &mode);
|
||||
VkCompareOp cast(const Gfx::SeCompareOp &op);
|
||||
Gfx::SeCompareOp cast(const VkCompareOp &op);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -7,6 +7,49 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
List<QueueOwnedResourceDeletion::PendingItem> QueueOwnedResourceDeletion::deletionQueue;
|
||||
volatile bool QueueOwnedResourceDeletion::running;
|
||||
std::mutex QueueOwnedResourceDeletion::mutex;
|
||||
std::condition_variable QueueOwnedResourceDeletion::cv;
|
||||
|
||||
QueueOwnedResourceDeletion::QueueOwnedResourceDeletion()
|
||||
{
|
||||
worker = std::thread(&run);
|
||||
running = true;
|
||||
}
|
||||
|
||||
QueueOwnedResourceDeletion::~QueueOwnedResourceDeletion()
|
||||
{
|
||||
worker.join();
|
||||
}
|
||||
|
||||
void QueueOwnedResourceDeletion::addPendingDelete(PFence fence, std::function<void()> func)
|
||||
{
|
||||
PendingItem item;
|
||||
item.fence = fence;
|
||||
item.func = func;
|
||||
deletionQueue.add(item);
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
cv.notify_all();
|
||||
}
|
||||
|
||||
void QueueOwnedResourceDeletion::run()
|
||||
{
|
||||
while (running || !deletionQueue.empty())
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
cv.wait(lock);
|
||||
auto entry = deletionQueue.begin();
|
||||
PFence fence = entry->fence;
|
||||
fence->wait(1000ull);
|
||||
if (fence->isSignaled())
|
||||
{
|
||||
entry->func();
|
||||
deletionQueue.remove(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QueueOwnedResource::QueueOwnedResource(PGraphics graphics, Gfx::QueueType startQueueType)
|
||||
: graphics(graphics), currentOwner(startQueueType)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
#include <condition_variable>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
namespace Seele
|
||||
@@ -39,6 +42,10 @@ public:
|
||||
return fence;
|
||||
}
|
||||
void wait(uint32 timeout);
|
||||
bool operator<(const Fence &other) const
|
||||
{
|
||||
return fence < other.fence;
|
||||
}
|
||||
|
||||
private:
|
||||
bool signaled;
|
||||
@@ -76,6 +83,26 @@ struct QueueFamilyMapping
|
||||
return srcIndex != dstIndex;
|
||||
}
|
||||
};
|
||||
class QueueOwnedResourceDeletion
|
||||
{
|
||||
public:
|
||||
QueueOwnedResourceDeletion();
|
||||
virtual ~QueueOwnedResourceDeletion();
|
||||
static void addPendingDelete(PFence fence, std::function<void()> function);
|
||||
|
||||
private:
|
||||
std::thread worker;
|
||||
static volatile bool running;
|
||||
static void run();
|
||||
struct PendingItem
|
||||
{
|
||||
PFence fence;
|
||||
std::function<void()> func;
|
||||
};
|
||||
static std::mutex mutex;
|
||||
static std::condition_variable cv;
|
||||
static List<PendingItem> deletionQueue;
|
||||
};
|
||||
class QueueOwnedResource
|
||||
{
|
||||
public:
|
||||
@@ -154,7 +181,7 @@ DEFINE_REF(StructuredBuffer);
|
||||
class VertexBuffer : public Buffer, public Gfx::VertexBuffer
|
||||
{
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, const BulkResourceData &resourceData);
|
||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData);
|
||||
virtual ~VertexBuffer();
|
||||
|
||||
protected:
|
||||
@@ -166,7 +193,7 @@ DEFINE_REF(VertexBuffer);
|
||||
class IndexBuffer : public Buffer, public Gfx::IndexBuffer
|
||||
{
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, const BulkResourceData &resourceData);
|
||||
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData);
|
||||
virtual ~IndexBuffer();
|
||||
|
||||
protected:
|
||||
@@ -251,7 +278,8 @@ class Texture2D : public TextureBase, public Gfx::Texture2D
|
||||
public:
|
||||
Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
|
||||
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
|
||||
uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner = Gfx::QueueType::GRAPHICS, VkImage existingImage = VK_NULL_HANDLE);
|
||||
uint32 samples, Gfx::SeImageUsageFlags usage,
|
||||
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~Texture2D();
|
||||
inline uint32 getSizeX() const
|
||||
{
|
||||
@@ -334,6 +362,7 @@ public:
|
||||
virtual ~Viewport();
|
||||
virtual void resize(uint32 newX, uint32 newY);
|
||||
virtual void move(uint32 newOffsetX, uint32 newOffsetY);
|
||||
|
||||
protected:
|
||||
private:
|
||||
PGraphics graphics;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "VulkanPipeline.h"
|
||||
#include "VulkanDescriptorSets.h"
|
||||
#include "VulkanGraphics.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const GraphicsPipelineCreateInfo& createInfo)
|
||||
: Gfx::GraphicsPipeline(createInfo)
|
||||
, graphics(graphics)
|
||||
, layout(pipelineLayout)
|
||||
, pipeline(handle)
|
||||
{
|
||||
}
|
||||
|
||||
GraphicsPipeline::~GraphicsPipeline()
|
||||
{
|
||||
}
|
||||
|
||||
void GraphicsPipeline::bind(VkCommandBuffer handle)
|
||||
{
|
||||
vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
}
|
||||
|
||||
VkPipelineLayout GraphicsPipeline::getLayout() const
|
||||
{
|
||||
return layout->getHandle();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
DECLARE_REF(PipelineLayout);
|
||||
DECLARE_REF(Graphics);
|
||||
class GraphicsPipeline : public Gfx::GraphicsPipeline
|
||||
{
|
||||
public:
|
||||
GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const GraphicsPipelineCreateInfo& createInfo);
|
||||
virtual ~GraphicsPipeline();
|
||||
void bind(VkCommandBuffer handle);
|
||||
VkPipelineLayout getLayout() const;
|
||||
private:
|
||||
VkPipeline pipeline;
|
||||
PPipelineLayout layout;
|
||||
PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(GraphicsPipeline);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,240 @@
|
||||
#include "VulkanPipelineCache.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanDescriptorSets.h"
|
||||
#include "VulkanShader.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath)
|
||||
: graphics(graphics)
|
||||
, cacheFile(cacheFilePath)
|
||||
{
|
||||
std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate);
|
||||
VkPipelineCacheCreateInfo cacheCreateInfo;
|
||||
cacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
|
||||
cacheCreateInfo.pNext = nullptr;
|
||||
cacheCreateInfo.flags = 0;
|
||||
cacheCreateInfo.initialDataSize = 0;
|
||||
if(stream.good())
|
||||
{
|
||||
Array<uint8> cacheData;
|
||||
uint32 fileSize = static_cast<uint32>(stream.tellg());
|
||||
cacheData.resize(fileSize);
|
||||
stream.seekg(0);
|
||||
stream.read((char*)cacheData.data(), fileSize);
|
||||
cacheCreateInfo.initialDataSize = fileSize;
|
||||
cacheCreateInfo.pInitialData = cacheData.data();
|
||||
}
|
||||
VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache));
|
||||
}
|
||||
|
||||
PipelineCache::~PipelineCache()
|
||||
{
|
||||
VkDeviceSize cacheSize;
|
||||
vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, nullptr);
|
||||
Array<uint8> cacheData;
|
||||
vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, cacheData.data());
|
||||
std::ofstream stream(cacheFile, std::ios::binary);
|
||||
stream.write((char*)cacheData.data(), cacheSize);
|
||||
stream.flush();
|
||||
stream.close();
|
||||
vkDestroyPipelineCache(graphics->getDevice(), cache, nullptr);
|
||||
}
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo& gfxInfo)
|
||||
{
|
||||
VkGraphicsPipelineCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
createInfo.pNext = 0;
|
||||
createInfo.flags = 0;
|
||||
createInfo.stageCount = 0;
|
||||
VkPipelineTessellationStateCreateInfo tessInfo;
|
||||
VkPipelineShaderStageCreateInfo stageInfos[5];
|
||||
std::memset(stageInfos, 0, sizeof(stageInfos));
|
||||
if(gfxInfo.vertexShader != nullptr)
|
||||
{
|
||||
PVertexShader shader = gfxInfo.vertexShader.cast<VertexShader>();
|
||||
VkPipelineShaderStageCreateInfo& vertInfo = stageInfos[createInfo.stageCount++];
|
||||
vertInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
vertInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
vertInfo.module = shader->getModuleHandle();
|
||||
vertInfo.pName = shader->getEntryPointName();
|
||||
}
|
||||
if(gfxInfo.controlShader != nullptr)
|
||||
{
|
||||
assert(gfxInfo.evalShader != nullptr);
|
||||
PControlShader control = gfxInfo.controlShader.cast<ControlShader>();
|
||||
PEvaluationShader eval = gfxInfo.evalShader.cast<EvaluationShader>();
|
||||
|
||||
VkPipelineShaderStageCreateInfo& controlInfo = stageInfos[createInfo.stageCount++];
|
||||
controlInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
controlInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
||||
controlInfo.module = control->getModuleHandle();
|
||||
controlInfo.pName = control->getEntryPointName();
|
||||
|
||||
VkPipelineShaderStageCreateInfo& evalInfo = stageInfos[createInfo.stageCount++];
|
||||
evalInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
evalInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
|
||||
evalInfo.module = eval->getModuleHandle();
|
||||
evalInfo.pName = eval->getEntryPointName();
|
||||
|
||||
tessInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
|
||||
tessInfo.pNext = 0;
|
||||
tessInfo.flags = 0;
|
||||
tessInfo.patchControlPoints = control->getNumPatches();
|
||||
}
|
||||
if(gfxInfo.geometryShader != nullptr)
|
||||
{
|
||||
PGeometryShader geometry = gfxInfo.geometryShader.cast<GeometryShader>();
|
||||
|
||||
VkPipelineShaderStageCreateInfo& geometryInfo = stageInfos[createInfo.stageCount++];
|
||||
geometryInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
geometryInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT;
|
||||
geometryInfo.module = geometry->getModuleHandle();
|
||||
geometryInfo.pName = geometry->getEntryPointName();
|
||||
}
|
||||
if(gfxInfo.fragmentShader != nullptr)
|
||||
{
|
||||
PFragmentShader fragment = gfxInfo.fragmentShader.cast<FragmentShader>();
|
||||
|
||||
VkPipelineShaderStageCreateInfo& fragmentInfo = stageInfos[createInfo.stageCount++];
|
||||
fragmentInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
fragmentInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
fragmentInfo.module = fragment->getModuleHandle();
|
||||
fragmentInfo.pName = fragment->getEntryPointName();
|
||||
}
|
||||
VkPipelineVertexInputStateCreateInfo vertexInput =
|
||||
init::PipelineVertexInputStateCreateInfo();
|
||||
Gfx::PVertexDeclaration vertexDecl = gfxInfo.vertexDeclaration;
|
||||
auto vertexStreams = vertexDecl->getVertexStreams();
|
||||
Array<VkVertexInputBindingDescription> bindingDesc(vertexStreams.size());
|
||||
Array<VkVertexInputAttributeDescription> attribDesc;
|
||||
uint32 bindingNum = 0;
|
||||
for(auto vertexBinding : vertexStreams)
|
||||
{
|
||||
uint32 stride = vertexBinding.getVertexBuffer()->getVertexSize();
|
||||
for(auto vertexAttrib : vertexBinding.getVertexDescriptions())
|
||||
{
|
||||
auto attrib = attribDesc.add();
|
||||
attrib.binding = bindingNum;
|
||||
attrib.format = cast(vertexAttrib.vertexFormat);
|
||||
attrib.location = vertexAttrib.location;
|
||||
attrib.offset = vertexAttrib.offset;
|
||||
}
|
||||
bindingDesc[bindingNum].binding = bindingNum;
|
||||
bindingDesc[bindingNum].stride = stride;
|
||||
bindingDesc[bindingNum].inputRate = vertexBinding.isInstanced() ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
bindingNum++;
|
||||
}
|
||||
vertexInput.pVertexBindingDescriptions = bindingDesc.data();
|
||||
vertexInput.vertexBindingDescriptionCount = bindingDesc.size();
|
||||
vertexInput.pVertexAttributeDescriptions = attribDesc.data();
|
||||
vertexInput.vertexAttributeDescriptionCount = attribDesc.size();
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo assemblyInfo =
|
||||
init::PipelineInputAssemblyStateCreateInfo(
|
||||
cast(gfxInfo.topology),
|
||||
0,
|
||||
false
|
||||
);
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportInfo =
|
||||
init::PipelineViewportStateCreateInfo(
|
||||
1,
|
||||
1,
|
||||
0
|
||||
);
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationState =
|
||||
init::PipelineRasterizationStateCreateInfo(
|
||||
cast(gfxInfo.rasterizationState.polygonMode),
|
||||
gfxInfo.rasterizationState.cullMode,
|
||||
(VkFrontFace)gfxInfo.rasterizationState.frontFace,
|
||||
0
|
||||
);
|
||||
rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable;
|
||||
rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp;
|
||||
rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBoasConstantFactor;
|
||||
rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor;
|
||||
rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable;
|
||||
rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth;
|
||||
rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable;
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisampleState =
|
||||
init::PipelineMultisampleStateCreateInfo((VkSampleCountFlagBits)gfxInfo.multisampleState.samples, 0);
|
||||
multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable;
|
||||
multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable;
|
||||
multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading;
|
||||
multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable;
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilState =
|
||||
init::PipelineDepthStencilStateCreateInfo(
|
||||
gfxInfo.depthStencilState.depthTestEnable,
|
||||
gfxInfo.depthStencilState.depthWriteEnable,
|
||||
cast(gfxInfo.depthStencilState.depthCompareOp)
|
||||
);
|
||||
|
||||
const auto colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments;
|
||||
Array<VkPipelineColorBlendAttachmentState> blendAttachments(colorAttachments.size());
|
||||
for(uint32 i = 0; i < colorAttachments.size(); ++i)
|
||||
{
|
||||
const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i];
|
||||
VkPipelineColorBlendAttachmentState& blendAttachment = blendAttachments[i];
|
||||
blendAttachment.alphaBlendOp = (VkBlendOp)attachment.alphaBlendOp;
|
||||
blendAttachment.blendEnable = attachment.blendEnable;
|
||||
blendAttachment.colorBlendOp = (VkBlendOp)attachment.colorBlendOp;
|
||||
blendAttachment.colorWriteMask = attachment.colorWriteMask;
|
||||
blendAttachment.dstAlphaBlendFactor = (VkBlendFactor)attachment.dstAlphaBlendFactor;
|
||||
blendAttachment.srcAlphaBlendFactor = (VkBlendFactor)attachment.srcAlphaBlendFactor;
|
||||
blendAttachment.dstColorBlendFactor = (VkBlendFactor)attachment.dstColorBlendFactor;
|
||||
blendAttachment.srcColorBlendFactor = (VkBlendFactor)attachment.srcColorBlendFactor;
|
||||
}
|
||||
VkPipelineColorBlendStateCreateInfo blendState =
|
||||
init::PipelineColorBlendStateCreateInfo(
|
||||
blendAttachments.size(),
|
||||
blendAttachments.data()
|
||||
);
|
||||
blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable;
|
||||
blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp;
|
||||
std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(float)*4);
|
||||
|
||||
uint32 numDynamicEnabled = 0;
|
||||
StaticArray<VkDynamicState, VK_DYNAMIC_STATE_RANGE_SIZE> dynamicEnabled;
|
||||
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT;
|
||||
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR;
|
||||
|
||||
VkPipelineDynamicStateCreateInfo dynamicState =
|
||||
init::PipelineDynamicStateCreateInfo(
|
||||
dynamicEnabled.data(),
|
||||
numDynamicEnabled,
|
||||
0
|
||||
);
|
||||
|
||||
createInfo.pStages = stageInfos;
|
||||
createInfo.pVertexInputState = &vertexInput;
|
||||
createInfo.pInputAssemblyState = &assemblyInfo;
|
||||
createInfo.pTessellationState = &tessInfo;
|
||||
createInfo.pViewportState = &viewportInfo;
|
||||
createInfo.pRasterizationState = &rasterizationState;
|
||||
createInfo.pMultisampleState = &multisampleState;
|
||||
createInfo.pDepthStencilState = &depthStencilState;
|
||||
createInfo.pColorBlendState = &blendState;
|
||||
createInfo.pDynamicState = &dynamicState;
|
||||
createInfo.renderPass = gfxInfo.renderPass.cast<RenderPass>()->getHandle();
|
||||
createInfo.layout = gfxInfo.pipelineLayout.cast<PipelineLayout>()->getHandle();
|
||||
createInfo.subpass = 0;
|
||||
|
||||
VkPipeline pipelineHandle;
|
||||
auto beginTime = std::chrono::high_resolution_clock::now();
|
||||
VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
int64 delta = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - beginTime).count();
|
||||
std::cout << "Gfx creation time: " << delta << std::endl;
|
||||
|
||||
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, gfxInfo.pipelineLayout.cast<PipelineLayout>(), gfxInfo);
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "VulkanPipeline.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
class PipelineCache
|
||||
{
|
||||
public:
|
||||
PipelineCache(PGraphics graphics, const std::string& cacheFilePath);
|
||||
~PipelineCache();
|
||||
PGraphicsPipeline createPipeline(const GraphicsPipelineCreateInfo& createInfo);
|
||||
private:
|
||||
VkPipelineCache cache;
|
||||
PGraphics graphics;
|
||||
std::string cacheFile;
|
||||
};
|
||||
DEFINE_REF(PipelineCache);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -9,22 +9,19 @@ using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
Queue::Queue(PGraphics graphics, Gfx::QueueType queueType, uint32 familyIndex, uint32 queueIndex)
|
||||
: familyIndex(familyIndex)
|
||||
, graphics(graphics)
|
||||
, queueType(queueType)
|
||||
{
|
||||
: familyIndex(familyIndex), graphics(graphics), queueType(queueType)
|
||||
{
|
||||
vkGetDeviceQueue(graphics->getDevice(), familyIndex, queueIndex, &queue);
|
||||
}
|
||||
|
||||
Queue::~Queue()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore* signalSemaphores)
|
||||
void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore *signalSemaphores)
|
||||
{
|
||||
assert(cmdBuffer->state == CmdBuffer::State::Ended);
|
||||
|
||||
|
||||
PFence fence = cmdBuffer->fence;
|
||||
assert(!fence->isSignaled());
|
||||
|
||||
@@ -38,9 +35,9 @@ void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores
|
||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||
|
||||
Array<VkSemaphore> waitSemaphores;
|
||||
if(cmdBuffer->waitSemaphores.size() > 0)
|
||||
if (cmdBuffer->waitSemaphores.size() > 0)
|
||||
{
|
||||
for(PSemaphore semaphore : cmdBuffer->waitSemaphores)
|
||||
for (PSemaphore semaphore : cmdBuffer->waitSemaphores)
|
||||
{
|
||||
waitSemaphores.add(semaphore->getHandle());
|
||||
}
|
||||
@@ -55,7 +52,7 @@ void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores
|
||||
cmdBuffer->waitFlags.clear();
|
||||
cmdBuffer->waitSemaphores.clear();
|
||||
|
||||
if(Gfx::waitIdleOnSubmit)
|
||||
if (Gfx::waitIdleOnSubmit)
|
||||
{
|
||||
fence->wait(200 * 1000ull);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
RenderPass::RenderPass(PGraphics graphics, Gfx::PRenderTargetLayout layout)
|
||||
: layout(layout), graphics(graphics)
|
||||
: Gfx::RenderPass(layout)
|
||||
, graphics(graphics)
|
||||
{
|
||||
Array<VkAttachmentDescription> attachments;
|
||||
Array<VkAttachmentReference> inputRefs;
|
||||
@@ -108,17 +109,17 @@ uint32 RenderPass::getFramebufferHash()
|
||||
{
|
||||
FramebufferDescription description;
|
||||
std::memset(&description, 0, sizeof(FramebufferDescription));
|
||||
for(auto inputAttachment : layout->inputAttachments)
|
||||
for (auto inputAttachment : layout->inputAttachments)
|
||||
{
|
||||
PTexture2D tex = inputAttachment->getTexture().cast<Texture2D>();
|
||||
description.inputAttachments[description.numInputAttachments++] = tex->getView();
|
||||
}
|
||||
for(auto colorAttachment : layout->colorAttachments)
|
||||
for (auto colorAttachment : layout->colorAttachments)
|
||||
{
|
||||
PTexture2D tex = colorAttachment->getTexture().cast<Texture2D>();
|
||||
description.colorAttachments[description.numColorAttachments++] = tex->getView();
|
||||
description.colorAttachments[description.numColorAttachments++] = tex->getView();
|
||||
}
|
||||
if(layout->depthAttachment != nullptr)
|
||||
if (layout->depthAttachment != nullptr)
|
||||
{
|
||||
PTexture2D tex = layout->depthAttachment->getTexture().cast<Texture2D>();
|
||||
description.depthAttachment = tex->getView();
|
||||
|
||||
@@ -30,13 +30,8 @@ public:
|
||||
{
|
||||
return subpassContents;
|
||||
}
|
||||
inline Gfx::PRenderTargetLayout getLayout()
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Gfx::PRenderTargetLayout layout;
|
||||
VkRenderPass renderPass;
|
||||
Array<VkClearValue> clearValues;
|
||||
VkRect2D renderArea;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "VulkanShader.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
Shader(PGraphics graphics, ShaderType shaderType, VkShaderStageFlags stage);
|
||||
virtual ~Shader();
|
||||
|
||||
VkShaderModule getModuleHandle() const
|
||||
{
|
||||
return module;
|
||||
}
|
||||
const char* getEntryPointName() const
|
||||
{
|
||||
return entryPointName.c_str();
|
||||
}
|
||||
private:
|
||||
VkShaderModule module;
|
||||
std::string entryPointName;
|
||||
};
|
||||
DEFINE_REF(Shader);
|
||||
|
||||
template <typename Base, ShaderType shaderType, VkShaderStageFlags stage>
|
||||
class ShaderBase : public Base, public Shader
|
||||
{
|
||||
public:
|
||||
ShaderBase(PGraphics graphics)
|
||||
: Shader(graphics, shaderType, stage)
|
||||
{
|
||||
}
|
||||
virtual ~ShaderBase()
|
||||
{
|
||||
}
|
||||
};
|
||||
typedef ShaderBase<Gfx::VertexShader, ShaderType::VERTEX, VK_SHADER_STAGE_VERTEX_BIT> VertexShader;
|
||||
typedef ShaderBase<Gfx::ControlShader, ShaderType::CONTROL, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT> ControlShader;
|
||||
typedef ShaderBase<Gfx::EvaluationShader, ShaderType::EVALUATION, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT> EvaluationShader;
|
||||
typedef ShaderBase<Gfx::GeometryShader, ShaderType::GEOMETRY, VK_SHADER_STAGE_GEOMETRY_BIT> GeometryShader;
|
||||
typedef ShaderBase<Gfx::FragmentShader, ShaderType::FRAGMENT, VK_SHADER_STAGE_FRAGMENT_BIT> FragmentShader;
|
||||
typedef ShaderBase<Gfx::ComputeShader, ShaderType::COMPUTE, VK_SHADER_STAGE_COMPUTE_BIT> ComputeShader;
|
||||
|
||||
DEFINE_REF(VertexShader);
|
||||
DEFINE_REF(ControlShader);
|
||||
DEFINE_REF(EvaluationShader);
|
||||
DEFINE_REF(GeometryShader);
|
||||
DEFINE_REF(FragmentShader);
|
||||
DEFINE_REF(ComputeShader);
|
||||
|
||||
} // namespace Vulkan
|
||||
}
|
||||
@@ -32,7 +32,7 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format)
|
||||
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
|
||||
bool bArray, uint32 arraySize, uint32 mipLevel,
|
||||
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner, VkImage existingImage)
|
||||
: QueueOwnedResource(graphics, owner), graphics(graphics), sizeX(sizeX), sizeY(sizeY), sizeZ(sizeZ), mipLevels(mipLevel), format(format), samples(samples), usage(usage), arrayCount(bArray ? arraySize : 1), aspect(getAspectFromFormat(format))
|
||||
: QueueOwnedResource(graphics, owner), graphics(graphics), sizeX(sizeX), sizeY(sizeY), sizeZ(sizeZ), mipLevels(mipLevel), format(format), samples(samples), usage(usage), arrayCount(bArray ? arraySize : 1), aspect(getAspectFromFormat(format)), image(existingImage), layout(VK_IMAGE_LAYOUT_UNDEFINED)
|
||||
{
|
||||
if (existingImage == VK_NULL_HANDLE)
|
||||
{
|
||||
@@ -105,8 +105,13 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, uint3
|
||||
|
||||
TextureHandle::~TextureHandle()
|
||||
{
|
||||
vkDestroyImageView(graphics->getDevice(), defaultView, nullptr);
|
||||
vkDestroyImage(graphics->getDevice(), image, nullptr);
|
||||
auto &deletionQueue = graphics->getDeletionQueue();
|
||||
auto fence = getCommands()->getCommands()->getFence();
|
||||
VkDevice device = graphics->getDevice();
|
||||
VkImageView view = defaultView;
|
||||
VkImage img = image;
|
||||
deletionQueue.addPendingDelete(fence, [device, view]() { vkDestroyImageView(device, view, nullptr); });
|
||||
deletionQueue.addPendingDelete(fence, [device, img]() { vkDestroyImage(device, img, nullptr); });
|
||||
}
|
||||
|
||||
void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
@@ -145,7 +150,7 @@ void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
dstManager = graphics->getTransferCommands();
|
||||
}
|
||||
else if(currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
|
||||
else if (currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
|
||||
{
|
||||
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
|
||||
@@ -9,7 +9,7 @@ using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
|
||||
: Gfx::Window(createInfo), graphics(graphics), instance(graphics->getInstance())
|
||||
: Gfx::Window(createInfo), graphics(graphics), instance(graphics->getInstance()), swapchain(VK_NULL_HANDLE)
|
||||
{
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow *handle = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, createInfo.bFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr);
|
||||
@@ -19,7 +19,28 @@ Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
|
||||
|
||||
glfwCreateWindowSurface(instance, handle, nullptr, &surface);
|
||||
|
||||
createSwapchain();
|
||||
uint32_t numQueueFamilies = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(graphics->getPhysicalDevice(), &numQueueFamilies, nullptr);
|
||||
Array<VkQueueFamilyProperties> queueProperties(numQueueFamilies);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(graphics->getPhysicalDevice(), &numQueueFamilies, queueProperties.data());
|
||||
|
||||
bool viableDevice = false;
|
||||
for (uint32 i = 0; i < numQueueFamilies; ++i)
|
||||
{
|
||||
VkBool32 supportsPresent;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(graphics->getPhysicalDevice(), i, surface, &supportsPresent);
|
||||
if (supportsPresent)
|
||||
{
|
||||
viableDevice = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!viableDevice)
|
||||
{
|
||||
std::cerr << "Device not suitable for presenting to surface " << surface << ", use a different one" << std::endl;
|
||||
}
|
||||
|
||||
recreateSwapchain(createInfo);
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
@@ -30,6 +51,7 @@ Window::~Window()
|
||||
|
||||
void Window::beginFrame()
|
||||
{
|
||||
glfwPollEvents();
|
||||
advanceBackBuffer();
|
||||
}
|
||||
|
||||
@@ -75,16 +97,9 @@ void Window::advanceBackBuffer()
|
||||
imageAcquiredSemaphore = imageAcquired[semaphoreIndex];
|
||||
currentImageIndex = imageIndex;
|
||||
|
||||
VkImageMemoryBarrier barrier =
|
||||
init::ImageMemoryBarrier(
|
||||
backBufferImages[currentImageIndex]->getHandle(),
|
||||
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
backBufferImages[currentImageIndex]->changeLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
|
||||
vkCmdPipelineBarrier(cmdBuffer->getHandle(),
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
cmdBuffer->addWaitSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
|
||||
graphics->getGraphicsCommands()->getCommands()->addWaitSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
|
||||
graphics->getGraphicsCommands()->submitCommands();
|
||||
}
|
||||
|
||||
@@ -187,7 +202,10 @@ void Window::createSwapchain()
|
||||
|
||||
void Window::destroySwapchain()
|
||||
{
|
||||
vkDestroySwapchainKHR(graphics->getDevice(), swapchain, nullptr);
|
||||
if (swapchain != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroySwapchainKHR(graphics->getDevice(), swapchain, nullptr);
|
||||
}
|
||||
for (uint32 i = 0; i < Gfx::numFramesBuffered; ++i)
|
||||
{
|
||||
imageAcquired[i] = nullptr;
|
||||
|
||||
@@ -7,7 +7,6 @@ Seele::Window::Window(Gfx::PWindow handle)
|
||||
|
||||
Seele::Window::~Window()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Seele::Window::addView(PView view)
|
||||
@@ -18,7 +17,7 @@ void Seele::Window::addView(PView view)
|
||||
void Seele::Window::beginFrame()
|
||||
{
|
||||
gfxHandle->beginFrame();
|
||||
for(auto view : viewports)
|
||||
for (auto view : viewports)
|
||||
{
|
||||
view->beginFrame();
|
||||
}
|
||||
@@ -26,7 +25,7 @@ void Seele::Window::beginFrame()
|
||||
|
||||
void Seele::Window::render()
|
||||
{
|
||||
for(auto view : viewports)
|
||||
for (auto view : viewports)
|
||||
{
|
||||
view->render();
|
||||
}
|
||||
@@ -35,7 +34,7 @@ void Seele::Window::render()
|
||||
void Seele::Window::endFrame()
|
||||
{
|
||||
gfxHandle->endFrame();
|
||||
for(auto view : viewports)
|
||||
for (auto view : viewports)
|
||||
{
|
||||
view->endFrame();
|
||||
}
|
||||
|
||||
@@ -15,9 +15,10 @@ public:
|
||||
void render();
|
||||
void endFrame();
|
||||
Gfx::PWindow getGfxHandle();
|
||||
|
||||
private:
|
||||
Array<PView> viewports;
|
||||
Gfx::PWindow gfxHandle;
|
||||
};
|
||||
DEFINE_REF(Window);
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -24,10 +24,12 @@ Seele::WindowManager::~WindowManager()
|
||||
{
|
||||
}
|
||||
|
||||
void Seele::WindowManager::addWindow(const WindowCreateInfo &createInfo)
|
||||
PWindow Seele::WindowManager::addWindow(const WindowCreateInfo &createInfo)
|
||||
{
|
||||
Gfx::PWindow window = graphics->createWindow(createInfo);
|
||||
Gfx::PWindow handle = graphics->createWindow(createInfo);
|
||||
PWindow window = new Window(handle);
|
||||
windows.add(window);
|
||||
return window;
|
||||
}
|
||||
|
||||
void Seele::WindowManager::beginFrame()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "GraphicsResources.h"
|
||||
#include "Graphics.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Window.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -10,16 +11,20 @@ class WindowManager
|
||||
public:
|
||||
WindowManager();
|
||||
~WindowManager();
|
||||
void addWindow(const WindowCreateInfo &createInfo);
|
||||
PWindow addWindow(const WindowCreateInfo &createInfo);
|
||||
void beginFrame();
|
||||
void endFrame();
|
||||
Gfx::PGraphics getGraphics()
|
||||
{
|
||||
return graphics;
|
||||
}
|
||||
inline bool isActive() const
|
||||
{
|
||||
return windows.size();
|
||||
}
|
||||
|
||||
private:
|
||||
Array<Gfx::PWindow> windows;
|
||||
Array<PWindow> windows;
|
||||
Gfx::PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(WindowManager);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
target_sources(SeeleEngine
|
||||
PRIVATE
|
||||
Material.h
|
||||
Material.cpp
|
||||
MaterialInstance.h
|
||||
MaterialInstance.cpp)
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "Material.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace Seele;
|
||||
using json = nlohmann::json;
|
||||
|
||||
Material::Material()
|
||||
{
|
||||
}
|
||||
|
||||
Material::Material(const std::string& directory, const std::string& name)
|
||||
: FileAsset(directory, name)
|
||||
{
|
||||
}
|
||||
|
||||
Material::Material(const std::string& fullPath)
|
||||
: FileAsset(fullPath)
|
||||
{
|
||||
}
|
||||
|
||||
Material::~Material()
|
||||
{
|
||||
}
|
||||
|
||||
void Material::compile()
|
||||
{
|
||||
auto& stream = getReadStream();
|
||||
stream.seekg(0);
|
||||
json j;
|
||||
stream >> j;
|
||||
std::cout << j["test"] << std::endl;
|
||||
}
|
||||
|
||||
Gfx::PGraphicsPipeline Material::getPipeline()
|
||||
{
|
||||
return pipeline;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Asset/FileAsset.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
struct FloatExpression
|
||||
{
|
||||
float data;
|
||||
std::string name;
|
||||
uint32 location;
|
||||
};
|
||||
struct VectorExpression
|
||||
{
|
||||
Vector data;
|
||||
std::string name;
|
||||
uint32 location;
|
||||
};
|
||||
struct TextureExpression
|
||||
{
|
||||
Gfx::PTexture texture;
|
||||
std::string name;
|
||||
uint32 location;
|
||||
};
|
||||
DECLARE_NAME_REF(Gfx, GraphicsPipeline);
|
||||
DECLARE_NAME_REF(Gfx, PipelineLayout);
|
||||
class Material : public FileAsset
|
||||
{
|
||||
public:
|
||||
Material();
|
||||
Material(const std::string &directory, const std::string &name);
|
||||
Material(const std::string &fullPath);
|
||||
~Material();
|
||||
void compile();
|
||||
Gfx::PGraphicsPipeline getPipeline();
|
||||
|
||||
private:
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
Gfx::PPipelineLayout pipelineLayout;
|
||||
};
|
||||
DEFINE_REF(Material);
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "MaterialInstance.h"
|
||||
#include "Material.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
MaterialInstance::MaterialInstance()
|
||||
{
|
||||
}
|
||||
|
||||
MaterialInstance::MaterialInstance(const std::string& directory, const std::string& name)
|
||||
: FileAsset(directory, name)
|
||||
{
|
||||
}
|
||||
|
||||
MaterialInstance::MaterialInstance(const std::string& fullPath)
|
||||
: FileAsset(fullPath)
|
||||
{
|
||||
}
|
||||
|
||||
MaterialInstance::~MaterialInstance()
|
||||
{
|
||||
}
|
||||
|
||||
PMaterial MaterialInstance::getBaseMaterial() const
|
||||
{
|
||||
return baseMaterial;
|
||||
}
|
||||
|
||||
Gfx::PDescriptorSet MaterialInstance::getDescriptor()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "Asset/FileAsset.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_NAME_REF(Gfx, DescriptorSet);
|
||||
DECLARE_REF(Material);
|
||||
class MaterialInstance : public FileAsset
|
||||
{
|
||||
public:
|
||||
MaterialInstance();
|
||||
MaterialInstance(const std::string& directory, const std::string& name);
|
||||
MaterialInstance(const std::string& fullPath);
|
||||
~MaterialInstance();
|
||||
PMaterial getBaseMaterial() const;
|
||||
Gfx::PDescriptorSet getDescriptor();
|
||||
private:
|
||||
PMaterial baseMaterial;
|
||||
};
|
||||
DEFINE_REF(MaterialInstance);
|
||||
} // namespace Seele
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "Vector.h"
|
||||
#include "Matrix.h"
|
||||
#include "EngineTypes.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -24,6 +25,28 @@ struct Rect
|
||||
Vector2 size;
|
||||
Vector2 offset;
|
||||
};
|
||||
//Unsigned int
|
||||
struct URect
|
||||
{
|
||||
URect()
|
||||
: size(0, 0), offset(0, 0)
|
||||
{
|
||||
}
|
||||
URect(uint32 sizeX, uint32 sizeY, uint32 offsetX, uint32 offsetY)
|
||||
: size(sizeX, sizeY), offset(offsetX, offsetY)
|
||||
{
|
||||
}
|
||||
URect(UVector2 size, UVector2 offset)
|
||||
: size(size), offset(offset)
|
||||
{
|
||||
}
|
||||
bool isEmpty() const
|
||||
{
|
||||
return size.x == 0 || size.y == 0;
|
||||
}
|
||||
UVector2 size;
|
||||
UVector2 offset;
|
||||
};
|
||||
struct Rect3D
|
||||
{
|
||||
Vector size;
|
||||
|
||||
@@ -7,6 +7,19 @@ Transform::Transform()
|
||||
{
|
||||
}
|
||||
|
||||
Transform::Transform(Transform &&other)
|
||||
: position(other.position), rotation(other.rotation), scale(scale)
|
||||
{
|
||||
other.position = Vector4(0, 0, 0, 0);
|
||||
other.rotation = Quaternion(0, 0, 0, 0);
|
||||
other.scale = Vector4(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
Transform::Transform(const Transform &other)
|
||||
: position(other.position), rotation(other.rotation), scale(scale)
|
||||
{
|
||||
}
|
||||
|
||||
Transform::Transform(Vector position)
|
||||
: position(Vector4(position, 0)), rotation(Quaternion(0, 0, 0, 0)), scale(Vector4(1, 1, 1, 0))
|
||||
{
|
||||
@@ -26,12 +39,61 @@ Transform::Transform(Quaternion rotation, Vector scale)
|
||||
Transform::~Transform()
|
||||
{
|
||||
}
|
||||
Vector Transform::inverseTransformPosition(const Vector& v) const
|
||||
Vector Transform::inverseTransformPosition(const Vector &v) const
|
||||
{
|
||||
return (unrotateVector(rotation, v - Vector(position))) * getSafeScaleReciprocal(scale);
|
||||
}
|
||||
Matrix4 Transform::toMatrix()
|
||||
{
|
||||
Matrix4 mat;
|
||||
|
||||
Vector Transform::getSafeScaleReciprocal(const Vector4& inScale, float tolerance)
|
||||
mat[3][0] = position.x;
|
||||
mat[3][1] = position.y;
|
||||
mat[3][2] = position.z;
|
||||
|
||||
const float x2 = rotation.x + rotation.x;
|
||||
const float y2 = rotation.y + rotation.y;
|
||||
const float z2 = rotation.z + rotation.z;
|
||||
{
|
||||
const float xx2 = rotation.x * x2;
|
||||
const float yy2 = rotation.y * y2;
|
||||
const float zz2 = rotation.z * z2;
|
||||
|
||||
mat[0][0] = (1.0f - (yy2 + zz2)) * scale.x;
|
||||
mat[1][1] = (1.0f - (xx2 + zz2)) * scale.y;
|
||||
mat[2][2] = (1.0f - (xx2 + yy2)) * scale.z;
|
||||
}
|
||||
|
||||
{
|
||||
const float yz2 = rotation.y * z2;
|
||||
const float wx2 = rotation.w * x2;
|
||||
|
||||
mat[2][1] = (yz2 - wx2) * scale.z;
|
||||
mat[1][2] = (yz2 + wx2) * scale.y;
|
||||
}
|
||||
{
|
||||
const float xy2 = rotation.x * y2;
|
||||
const float wz2 = rotation.w * z2;
|
||||
|
||||
mat[1][0] = (xy2 - wz2) * scale.y;
|
||||
mat[0][1] = (xy2 + wz2) * scale.x;
|
||||
}
|
||||
{
|
||||
const float xz2 = rotation.x * z2;
|
||||
const float wy2 = rotation.w * y2;
|
||||
|
||||
mat[2][0] = (xz2 + wy2) * scale.z;
|
||||
mat[0][2] = (xz2 - wy2) * scale.x;
|
||||
}
|
||||
|
||||
mat[0][3] = 0.0f;
|
||||
mat[1][3] = 0.0f;
|
||||
mat[2][3] = 0.0f;
|
||||
mat[3][3] = 1.0f;
|
||||
|
||||
return mat;
|
||||
}
|
||||
Vector Transform::getSafeScaleReciprocal(const Vector4 &inScale, float tolerance)
|
||||
{
|
||||
Vector safeReciprocalScale;
|
||||
if (abs(inScale.x) <= tolerance)
|
||||
@@ -61,24 +123,67 @@ Vector Transform::getSafeScaleReciprocal(const Vector4& inScale, float tolerance
|
||||
return safeReciprocalScale;
|
||||
}
|
||||
|
||||
inline Vector Transform::getPosition() const
|
||||
Vector Transform::getPosition() const
|
||||
{
|
||||
return Vector(position);
|
||||
}
|
||||
|
||||
inline Quaternion Transform::getRotation() const
|
||||
Quaternion Transform::getRotation() const
|
||||
{
|
||||
return rotation;
|
||||
}
|
||||
|
||||
inline Vector Transform::getScale() const
|
||||
Vector Transform::getScale() const
|
||||
{
|
||||
return Vector(scale);
|
||||
}
|
||||
|
||||
inline void Transform::multiply(Transform* outTransform, const Transform* a, const Transform* b)
|
||||
bool Transform::equals(const Transform &other, float tolerance)
|
||||
{
|
||||
if (abs(position - other.position).length() > tolerance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (abs(rotation.x - other.rotation.x) <= tolerance && abs(rotation.y - other.rotation.y) <= tolerance && abs(rotation.z - other.rotation.z) <= tolerance && abs(rotation.w - other.rotation.w) <= tolerance || abs(rotation.x + other.rotation.x) <= tolerance && abs(rotation.y + other.rotation.y) <= tolerance && abs(rotation.z + other.rotation.z) <= tolerance && abs(rotation.w - other.rotation.w) <= tolerance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (abs(scale - other.scale).length() > tolerance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Transform::multiply(Transform *outTransform, const Transform *a, const Transform *b)
|
||||
{
|
||||
outTransform->rotation = b->rotation * a->rotation;
|
||||
outTransform->position = b->position * (b->scale * a->position) + b->position;
|
||||
outTransform->scale = b->scale * a->scale;
|
||||
}
|
||||
|
||||
Transform &Transform::operator=(const Transform &other)
|
||||
{
|
||||
position = other.position;
|
||||
rotation = other.rotation;
|
||||
scale = other.scale;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Transform &Transform::operator=(Transform &&other)
|
||||
{
|
||||
position = other.position;
|
||||
rotation = other.rotation;
|
||||
scale = other.scale;
|
||||
other.position = Vector4(0, 0, 0, 0);
|
||||
other.rotation = Quaternion(0, 0, 0, 0);
|
||||
other.scale = Vector4(0, 0, 0, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Transform &Transform::operator*(const Transform &other) const
|
||||
{
|
||||
Transform outTransform;
|
||||
multiply(&outTransform, this, &other);
|
||||
return outTransform;
|
||||
}
|
||||
|
||||
+13
-11
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "Vector.h"
|
||||
#include "Matrix.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -7,26 +8,27 @@ class Transform
|
||||
{
|
||||
public:
|
||||
Transform();
|
||||
Transform(const Transform &other);
|
||||
Transform(Transform &&other);
|
||||
Transform(Vector position);
|
||||
Transform(Vector position, Quaternion rotation);
|
||||
Transform(Vector position, Quaternion rotation, Vector scale);
|
||||
Transform(Quaternion rotation, Vector scale);
|
||||
~Transform();
|
||||
Vector inverseTransformPosition(const Vector &v) const;
|
||||
static Vector getSafeScaleReciprocal(const Vector4 &inScale, float tolerance = 0.00001f);
|
||||
Matrix4 toMatrix();
|
||||
static Vector getSafeScaleReciprocal(const Vector4 &inScale, float tolerance = 0.000000001f);
|
||||
|
||||
inline Vector getPosition() const;
|
||||
inline Quaternion getRotation() const;
|
||||
inline Vector getScale() const;
|
||||
Vector getPosition() const;
|
||||
Quaternion getRotation() const;
|
||||
Vector getScale() const;
|
||||
|
||||
inline static void multiply(Transform* outTransform, const Transform* a, const Transform* b);
|
||||
bool equals(const Transform &other, float tolerance = 0.000000001f);
|
||||
static void multiply(Transform *outTransform, const Transform *a, const Transform *b);
|
||||
|
||||
Transform& operator*(const Transform& other) const
|
||||
{
|
||||
Transform outTransform;
|
||||
multiply(&outTransform, this, &other);
|
||||
return outTransform;
|
||||
}
|
||||
Transform &operator=(const Transform &other);
|
||||
Transform &operator=(Transform &&other);
|
||||
Transform &operator*(const Transform &other) const;
|
||||
|
||||
private:
|
||||
Vector4 position;
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#pragma warning(disable : 4201)
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#pragma warning(default : 4201)
|
||||
namespace Seele
|
||||
{
|
||||
typedef glm::vec2 Vector2;
|
||||
@@ -21,7 +24,7 @@ typedef glm::quat Quaternion;
|
||||
|
||||
static inline float square(float x)
|
||||
{
|
||||
return x * x;
|
||||
return x * x;
|
||||
}
|
||||
|
||||
static inline Vector unrotateVector(Quaternion quaternion, Vector v)
|
||||
@@ -32,10 +35,9 @@ static inline Vector unrotateVector(Quaternion quaternion, Vector v)
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool equalsQuaternion(const Quaternion& right, const Quaternion& left, float tolerance)
|
||||
static inline bool equalsQuaternion(const Quaternion &right, const Quaternion &left, float tolerance)
|
||||
{
|
||||
return (abs(right.x - left.x) <= tolerance && abs(right.y - left.y) <= tolerance && abs(right.z - left.z) <= tolerance && abs(right.w - left.w) <= tolerance)
|
||||
|| (abs(right.x + left.x) <= tolerance && abs(right.y + left.y) <= tolerance && abs(right.z + left.z) <= tolerance && abs(right.w + left.w) <= tolerance);
|
||||
return (abs(right.x - left.x) <= tolerance && abs(right.y - left.y) <= tolerance && abs(right.z - left.z) <= tolerance && abs(right.w - left.w) <= tolerance) || (abs(right.x + left.x) <= tolerance && abs(right.y + left.y) <= tolerance && abs(right.z + left.z) <= tolerance && abs(right.w + left.w) <= tolerance);
|
||||
}
|
||||
|
||||
static inline float clampRotatorAxis(float angle)
|
||||
@@ -58,7 +60,7 @@ static inline float normalizeRotatorAxis(float angle)
|
||||
return angle;
|
||||
}
|
||||
|
||||
static inline Quaternion toQuaternion(const Vector& other)
|
||||
static inline Quaternion toQuaternion(const Vector &other)
|
||||
{
|
||||
Quaternion result;
|
||||
const float DEG_TO_RAD = glm::pi<float>() / (180.f);
|
||||
@@ -71,7 +73,7 @@ static inline Quaternion toQuaternion(const Vector& other)
|
||||
const float SP = sin(PitchNoWinding * RADS_DIVIDED_BY_2);
|
||||
const float SY = sin(YawNoWinding * RADS_DIVIDED_BY_2);
|
||||
const float SR = sin(RollNoWinding * RADS_DIVIDED_BY_2);
|
||||
|
||||
|
||||
const float CP = cos(PitchNoWinding * RADS_DIVIDED_BY_2);
|
||||
const float CY = cos(YawNoWinding * RADS_DIVIDED_BY_2);
|
||||
const float CR = cos(RollNoWinding * RADS_DIVIDED_BY_2);
|
||||
@@ -83,12 +85,12 @@ static inline Quaternion toQuaternion(const Vector& other)
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline Vector toRotator(const Quaternion& other)
|
||||
static inline Vector toRotator(const Quaternion &other)
|
||||
{
|
||||
const float singularityTest = other.z * other.x - other.w * other.y;
|
||||
const float yawY = 2.f * (other.w * other.z + other.x * other.y);
|
||||
const float yawX = (1.f - 2.f * (square(other.y) + square(other.z)));
|
||||
|
||||
|
||||
const float SINGULARITY_THRESHOLD = 0.4999995f;
|
||||
const float RAD_TO_DEG = (180.f) / glm::pi<float>();
|
||||
Vector rotatorFromQuat;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#include "MinimalEngine.h"
|
||||
|
||||
Seele::Map<void*, void*> registeredObjects;
|
||||
Seele::Map<void *, void *> registeredObjects;
|
||||
|
||||
+288
-268
@@ -8,302 +8,322 @@
|
||||
#include "EngineTypes.h"
|
||||
#include "Math/Math.h"
|
||||
|
||||
#define DEFINE_REF(x) typedef RefPtr<x> P##x; \
|
||||
typedef UniquePtr<x> UP##x; \
|
||||
typedef WeakPtr<x> W##x;
|
||||
#define DEFINE_REF(x) \
|
||||
typedef RefPtr<x> P##x; \
|
||||
typedef UniquePtr<x> UP##x; \
|
||||
typedef WeakPtr<x> W##x;
|
||||
|
||||
#define DECLARE_REF(x) class x; \
|
||||
typedef RefPtr<x> P##x; \
|
||||
typedef UniquePtr<x> UP##x; \
|
||||
typedef WeakPtr<x> W##x;
|
||||
#define DECLARE_REF(x) \
|
||||
class x; \
|
||||
typedef RefPtr<x> P##x; \
|
||||
typedef UniquePtr<x> UP##x; \
|
||||
typedef WeakPtr<x> W##x;
|
||||
|
||||
extern Seele::Map<void*, void*> registeredObjects;
|
||||
|
||||
#define DECLARE_NAME_REF(nmsp, x) \
|
||||
namespace nmsp \
|
||||
{ \
|
||||
class x; \
|
||||
typedef RefPtr<x> P##x; \
|
||||
typedef UniquePtr<x> UP##x; \
|
||||
typedef WeakPtr<x> W##x; \
|
||||
}
|
||||
|
||||
extern Seele::Map<void *, void *> registeredObjects;
|
||||
namespace Seele
|
||||
{
|
||||
template<typename T>
|
||||
class RefObject
|
||||
template <typename T>
|
||||
class RefObject
|
||||
{
|
||||
public:
|
||||
RefObject(T *ptr)
|
||||
: handle(ptr), refCount(1)
|
||||
{
|
||||
public:
|
||||
RefObject(T* ptr)
|
||||
: handle(ptr)
|
||||
, refCount(1)
|
||||
{
|
||||
registeredObjects[ptr] = this;
|
||||
}
|
||||
RefObject(const RefObject& rhs)
|
||||
: handle(rhs.handle)
|
||||
, refCount(rhs.refCount)
|
||||
{
|
||||
}
|
||||
RefObject(RefObject&& rhs)
|
||||
: handle(std::move(rhs.handle))
|
||||
, refCount(std::move(rhs.refCount))
|
||||
{}
|
||||
~RefObject()
|
||||
{
|
||||
registeredObjects.erase(handle);
|
||||
delete handle;
|
||||
}
|
||||
RefObject& operator=(const RefObject& rhs)
|
||||
{
|
||||
if(*this != rhs)
|
||||
{
|
||||
handle = rhs.handle;
|
||||
refCount = rhs.refCount;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
RefObject& operator=(RefObject&& rhs)
|
||||
{
|
||||
if(*this != rhs)
|
||||
{
|
||||
handle = std::move(rhs.handle);
|
||||
refCount = std::move(rhs.refCount);
|
||||
rhs.handle = nullptr;
|
||||
rhs.refCount = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const RefObject& other) const
|
||||
{
|
||||
return handle == other.handle;
|
||||
}
|
||||
bool operator!=(const RefObject& other) const
|
||||
{
|
||||
return handle != other.handle;
|
||||
}
|
||||
bool operator<(const RefObject& other) const
|
||||
{
|
||||
return handle < other.handle;
|
||||
}
|
||||
void addRef()
|
||||
{
|
||||
refCount++;
|
||||
}
|
||||
void removeRef()
|
||||
{
|
||||
refCount--;
|
||||
if (refCount.load() == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
inline T* getHandle() const
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
private:
|
||||
T* handle;
|
||||
std::atomic_uint64_t refCount;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class RefPtr
|
||||
registeredObjects[ptr] = this;
|
||||
}
|
||||
RefObject(const RefObject &rhs)
|
||||
: handle(rhs.handle), refCount(rhs.refCount)
|
||||
{
|
||||
public:
|
||||
RefPtr()
|
||||
}
|
||||
RefObject(RefObject &&rhs)
|
||||
: handle(std::move(rhs.handle)), refCount(std::move(rhs.refCount))
|
||||
{
|
||||
}
|
||||
~RefObject()
|
||||
{
|
||||
registeredObjects.erase(handle);
|
||||
delete handle;
|
||||
}
|
||||
RefObject &operator=(const RefObject &rhs)
|
||||
{
|
||||
if (*this != rhs)
|
||||
{
|
||||
object = nullptr;
|
||||
handle = rhs.handle;
|
||||
refCount = rhs.refCount;
|
||||
}
|
||||
RefPtr(nullptr_t)
|
||||
return *this;
|
||||
}
|
||||
RefObject &operator=(RefObject &&rhs)
|
||||
{
|
||||
if (*this != rhs)
|
||||
{
|
||||
object = nullptr;
|
||||
handle = std::move(rhs.handle);
|
||||
refCount = std::move(rhs.refCount);
|
||||
rhs.handle = nullptr;
|
||||
rhs.refCount = 0;
|
||||
}
|
||||
RefPtr(T* ptr)
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const RefObject &other) const
|
||||
{
|
||||
return handle == other.handle;
|
||||
}
|
||||
bool operator!=(const RefObject &other) const
|
||||
{
|
||||
return handle != other.handle;
|
||||
}
|
||||
bool operator<(const RefObject &other) const
|
||||
{
|
||||
return handle < other.handle;
|
||||
}
|
||||
void addRef()
|
||||
{
|
||||
refCount++;
|
||||
}
|
||||
void removeRef()
|
||||
{
|
||||
refCount--;
|
||||
if (refCount.load() == 0)
|
||||
{
|
||||
auto registeredObj = registeredObjects.find(ptr);
|
||||
if(registeredObj == registeredObjects.end())
|
||||
{
|
||||
object = new RefObject<T>(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
object = (RefObject<T>*)registeredObj->value;
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
explicit RefPtr(RefObject<T>* other)
|
||||
: object(other)
|
||||
}
|
||||
inline T *getHandle() const
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
|
||||
private:
|
||||
T *handle;
|
||||
std::atomic_uint64_t refCount;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class RefPtr
|
||||
{
|
||||
public:
|
||||
RefPtr()
|
||||
{
|
||||
object = nullptr;
|
||||
}
|
||||
RefPtr(nullptr_t)
|
||||
{
|
||||
object = nullptr;
|
||||
}
|
||||
RefPtr(T *ptr)
|
||||
{
|
||||
auto registeredObj = registeredObjects.find(ptr);
|
||||
if (registeredObj == registeredObjects.end())
|
||||
{
|
||||
object = new RefObject<T>(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
object = (RefObject<T> *)registeredObj->value;
|
||||
}
|
||||
}
|
||||
explicit RefPtr(RefObject<T> *other)
|
||||
: object(other)
|
||||
{
|
||||
object->addRef();
|
||||
}
|
||||
RefPtr(const RefPtr &other)
|
||||
: object(other.object)
|
||||
{
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->addRef();
|
||||
}
|
||||
RefPtr(const RefPtr& other)
|
||||
: object(other.object)
|
||||
}
|
||||
RefPtr(RefPtr &&rhs)
|
||||
: object(std::move(rhs.object))
|
||||
{
|
||||
rhs.object = nullptr;
|
||||
//Dont change references, they stay the same
|
||||
}
|
||||
template <typename F>
|
||||
RefPtr(const RefPtr<F> &other)
|
||||
{
|
||||
F *f = other.getObject()->getHandle();
|
||||
static_cast<T *>(f);
|
||||
object = (RefObject<T> *)other.getObject();
|
||||
object->addRef();
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
RefPtr<F> cast()
|
||||
{
|
||||
T *t = object->getHandle();
|
||||
F *f = dynamic_cast<F *>(t);
|
||||
if (f == nullptr)
|
||||
{
|
||||
if(object != nullptr)
|
||||
return nullptr;
|
||||
}
|
||||
RefObject<F> *newObject = (RefObject<F> *)object;
|
||||
return RefPtr<F>(newObject);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
const RefPtr<F> cast() const
|
||||
{
|
||||
T *t = object->getHandle();
|
||||
F *f = dynamic_cast<F *>(t);
|
||||
if (f == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
RefObject<F> *newObject = (RefObject<F> *)object;
|
||||
return RefPtr<F>(newObject);
|
||||
}
|
||||
|
||||
RefPtr &operator=(const RefPtr &other)
|
||||
{
|
||||
if (*this != other)
|
||||
{
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->removeRef();
|
||||
}
|
||||
object = other.object;
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->addRef();
|
||||
}
|
||||
}
|
||||
RefPtr(RefPtr&& rhs)
|
||||
: object(std::move(rhs.object))
|
||||
return *this;
|
||||
}
|
||||
RefPtr &operator=(RefPtr &&rhs)
|
||||
{
|
||||
if (*this != rhs)
|
||||
{
|
||||
rhs.object = nullptr;
|
||||
//Dont change references, they stay the same
|
||||
}
|
||||
template<typename F>
|
||||
RefPtr(const RefPtr<F>& other)
|
||||
{
|
||||
F* f = other.getObject()->getHandle();
|
||||
static_cast<T*>(f);
|
||||
object = (RefObject<T>*)other.getObject();
|
||||
object->addRef();
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
RefPtr<F> cast()
|
||||
{
|
||||
T* t = object->getHandle();
|
||||
F* f = dynamic_cast<F*>(t);
|
||||
if (f == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
RefObject<F>* newObject = (RefObject<F>*)object;
|
||||
return RefPtr<F>(newObject);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
const RefPtr<F> cast() const
|
||||
{
|
||||
T* t = object->getHandle();
|
||||
F* f = dynamic_cast<F*>(t);
|
||||
if (f == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
RefObject<F>* newObject = (RefObject<F>*)object;
|
||||
return RefPtr<F>(newObject);
|
||||
}
|
||||
|
||||
RefPtr& operator=(const RefPtr& other)
|
||||
{
|
||||
if (*this != other)
|
||||
{
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->removeRef();
|
||||
}
|
||||
object = other.object;
|
||||
if(object != nullptr)
|
||||
{
|
||||
object->addRef();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(RefPtr&& rhs)
|
||||
{
|
||||
if(*this != rhs)
|
||||
{
|
||||
if(object != nullptr)
|
||||
{
|
||||
object->removeRef();
|
||||
}
|
||||
object = std::move(rhs.object);
|
||||
rhs.object = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
~RefPtr()
|
||||
{
|
||||
if(object != nullptr)
|
||||
if (object != nullptr)
|
||||
{
|
||||
object->removeRef();
|
||||
}
|
||||
object = std::move(rhs.object);
|
||||
rhs.object = nullptr;
|
||||
}
|
||||
bool operator==(const RefPtr& other) const
|
||||
{
|
||||
return object == other.object;
|
||||
}
|
||||
bool operator!=(const RefPtr& other) const
|
||||
{
|
||||
return object != other.object;
|
||||
}
|
||||
T* operator->()
|
||||
{
|
||||
assert(object != nullptr);
|
||||
return object->getHandle();
|
||||
}
|
||||
const T* operator->() const
|
||||
{
|
||||
assert(object != nullptr);
|
||||
return object->getHandle();
|
||||
}
|
||||
RefObject<T>* getObject() const
|
||||
{
|
||||
return object;
|
||||
}
|
||||
T* getHandle()
|
||||
{
|
||||
return object->getHandle();
|
||||
}
|
||||
const T* getHandle() const
|
||||
{
|
||||
return object->getHandle();
|
||||
}
|
||||
private:
|
||||
RefObject<T>* object;
|
||||
};
|
||||
//A weak pointer has no ownership over an object and thus cant delete it
|
||||
template<typename T>
|
||||
class WeakPtr
|
||||
return *this;
|
||||
}
|
||||
~RefPtr()
|
||||
{
|
||||
public:
|
||||
WeakPtr()
|
||||
: pointer(nullptr)
|
||||
{}
|
||||
WeakPtr(RefPtr<T>& sharedPtr)
|
||||
: pointer(sharedPtr)
|
||||
{}
|
||||
WeakPtr& operator=(WeakPtr<T>& weakPtr)
|
||||
if (object != nullptr)
|
||||
{
|
||||
pointer = weakPtr.pointer;
|
||||
return *this;
|
||||
object->removeRef();
|
||||
}
|
||||
WeakPtr& operator=(RefPtr<T>& sharedPtr)
|
||||
{
|
||||
pointer = sharedPtr;
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
RefPtr<T> pointer;
|
||||
};
|
||||
template<typename T>
|
||||
class UniquePtr
|
||||
}
|
||||
bool operator==(const RefPtr &other) const
|
||||
{
|
||||
public:
|
||||
UniquePtr(T* ptr)
|
||||
: handle(ptr)
|
||||
{}
|
||||
UniquePtr(const UniquePtr& rhs) = delete;
|
||||
UniquePtr(UniquePtr&& rhs) noexcept
|
||||
: handle(rhs.handle)
|
||||
{
|
||||
rhs.handle = nullptr;
|
||||
}
|
||||
UniquePtr& operator=(const UniquePtr& rhs) = delete;
|
||||
UniquePtr& operator=(UniquePtr&& rhs)
|
||||
{
|
||||
handle = rhs.handle;
|
||||
rhs.handle = nullptr;
|
||||
return *this;
|
||||
}
|
||||
~UniquePtr()
|
||||
{
|
||||
delete handle;
|
||||
}
|
||||
T* operator->()
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
bool isValid()
|
||||
{
|
||||
return handle != nullptr;
|
||||
}
|
||||
private:
|
||||
T* handle;
|
||||
};
|
||||
}
|
||||
return object == other.object;
|
||||
}
|
||||
bool operator!=(const RefPtr &other) const
|
||||
{
|
||||
return object != other.object;
|
||||
}
|
||||
bool operator<(const RefPtr &other) const
|
||||
{
|
||||
return object < other.object;
|
||||
}
|
||||
T *operator->()
|
||||
{
|
||||
assert(object != nullptr);
|
||||
return object->getHandle();
|
||||
}
|
||||
const T *operator->() const
|
||||
{
|
||||
assert(object != nullptr);
|
||||
return object->getHandle();
|
||||
}
|
||||
RefObject<T> *getObject() const
|
||||
{
|
||||
return object;
|
||||
}
|
||||
T *getHandle()
|
||||
{
|
||||
return object->getHandle();
|
||||
}
|
||||
const T *getHandle() const
|
||||
{
|
||||
return object->getHandle();
|
||||
}
|
||||
|
||||
private:
|
||||
RefObject<T> *object;
|
||||
};
|
||||
//A weak pointer has no ownership over an object and thus cant delete it
|
||||
template <typename T>
|
||||
class WeakPtr
|
||||
{
|
||||
public:
|
||||
WeakPtr()
|
||||
: pointer(nullptr)
|
||||
{
|
||||
}
|
||||
WeakPtr(RefPtr<T> &sharedPtr)
|
||||
: pointer(sharedPtr)
|
||||
{
|
||||
}
|
||||
WeakPtr &operator=(WeakPtr<T> &weakPtr)
|
||||
{
|
||||
pointer = weakPtr.pointer;
|
||||
return *this;
|
||||
}
|
||||
WeakPtr &operator=(RefPtr<T> &sharedPtr)
|
||||
{
|
||||
pointer = sharedPtr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<T> pointer;
|
||||
};
|
||||
template <typename T>
|
||||
class UniquePtr
|
||||
{
|
||||
public:
|
||||
UniquePtr(T *ptr)
|
||||
: handle(ptr)
|
||||
{
|
||||
}
|
||||
UniquePtr(const UniquePtr &rhs) = delete;
|
||||
UniquePtr(UniquePtr &&rhs) noexcept
|
||||
: handle(rhs.handle)
|
||||
{
|
||||
rhs.handle = nullptr;
|
||||
}
|
||||
UniquePtr &operator=(const UniquePtr &rhs) = delete;
|
||||
UniquePtr &operator=(UniquePtr &&rhs)
|
||||
{
|
||||
handle = rhs.handle;
|
||||
rhs.handle = nullptr;
|
||||
return *this;
|
||||
}
|
||||
~UniquePtr()
|
||||
{
|
||||
delete handle;
|
||||
}
|
||||
T *operator->()
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
bool isValid()
|
||||
{
|
||||
return handle != nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
T *handle;
|
||||
};
|
||||
} // namespace Seele
|
||||
|
||||
using namespace Seele;
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "Actor.h"
|
||||
#include "Component.h"
|
||||
#include "Scene/Components/Component.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -11,6 +12,25 @@ Actor::~Actor()
|
||||
{
|
||||
|
||||
}
|
||||
void Actor::tick(float deltaTime)
|
||||
{
|
||||
rootComponent->tick(deltaTime);
|
||||
for(auto child : children)
|
||||
{
|
||||
child->tick(deltaTime);
|
||||
}
|
||||
}
|
||||
void Actor::notifySceneAttach(PScene scene)
|
||||
{
|
||||
owningScene = scene;
|
||||
rootComponent->notifySceneAttach(scene);
|
||||
}
|
||||
|
||||
PScene Actor::getScene()
|
||||
{
|
||||
return owningScene;
|
||||
}
|
||||
|
||||
void Actor::setParent(PActor newParent)
|
||||
{
|
||||
parent = newParent;
|
||||
@@ -18,10 +38,14 @@ void Actor::setParent(PActor newParent)
|
||||
void Actor::addChild(PActor child)
|
||||
{
|
||||
children.add(child);
|
||||
child->setParent(this);
|
||||
child->notifySceneAttach(owningScene);
|
||||
}
|
||||
void Actor::detachChild(PActor child)
|
||||
{
|
||||
children.remove(children.find(child), false);
|
||||
child->setParent(nullptr);
|
||||
child->notifySceneAttach(nullptr);
|
||||
}
|
||||
void Actor::setWorldLocation(Vector location)
|
||||
{
|
||||
@@ -55,15 +79,16 @@ void Actor::addWorldRotation(Vector4 rotation)
|
||||
{
|
||||
rootComponent->addWorldRotation(rotation);
|
||||
}
|
||||
void Actor::addWorldScale(Vector scale)
|
||||
{
|
||||
rootComponent->addWorldScale(scale);
|
||||
}
|
||||
PComponent Actor::getRootComponent()
|
||||
{
|
||||
return rootComponent;
|
||||
}
|
||||
void Actor::setRootComponent(PComponent newRoot)
|
||||
{
|
||||
if(rootComponent != nullptr)
|
||||
{
|
||||
rootComponent->owner = nullptr;
|
||||
}
|
||||
rootComponent = newRoot;
|
||||
rootComponent->owner = this;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Transform.h"
|
||||
#include "Math/Transform.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Actor);
|
||||
DECLARE_REF(Component);
|
||||
DECLARE_REF(Scene);
|
||||
class Actor
|
||||
{
|
||||
public:
|
||||
Actor();
|
||||
virtual ~Actor();
|
||||
void setParent(PActor parent);
|
||||
|
||||
void tick(float deltaTime);
|
||||
void notifySceneAttach(PScene scene);
|
||||
PScene getScene();
|
||||
|
||||
PActor getParent();
|
||||
void addChild(PActor child);
|
||||
void detachChild(PActor child);
|
||||
@@ -23,18 +28,20 @@ public:
|
||||
void setRelativeLocation(Vector location);
|
||||
void setRelativeRotation(Vector4 rotation);
|
||||
void setRelativeScale(Vector scale);
|
||||
|
||||
|
||||
void addWorldTranslation(Vector translation);
|
||||
void addWorldRotation(Vector4 rotation);
|
||||
void addWorldScale(Vector scale);
|
||||
|
||||
|
||||
PComponent getRootComponent();
|
||||
void setRootComponent(PComponent newRoot);
|
||||
|
||||
private:
|
||||
void setParent(PActor parent);
|
||||
PScene owningScene;
|
||||
PActor parent;
|
||||
Array<PActor> children;
|
||||
PComponent rootComponent;
|
||||
Transform transform;
|
||||
};
|
||||
DEFINE_REF(Actor);
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "Component.h"
|
||||
#include "Scene/Actor/Actor.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -8,58 +10,123 @@ Component::Component()
|
||||
Component::~Component()
|
||||
{
|
||||
}
|
||||
void Component::tick(float deltaTime)
|
||||
{
|
||||
for (auto child : children)
|
||||
{
|
||||
child->tick(deltaTime);
|
||||
}
|
||||
}
|
||||
PComponent Component::getParent()
|
||||
{
|
||||
|
||||
return parent;
|
||||
}
|
||||
PActor Component::getOwner()
|
||||
{
|
||||
if (owner != nullptr)
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
if (parent != nullptr)
|
||||
{
|
||||
return parent->getOwner();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Component::notifySceneAttach(PScene scene)
|
||||
{
|
||||
owningScene = scene;
|
||||
for (auto child : children)
|
||||
{
|
||||
child->notifySceneAttach(scene);
|
||||
}
|
||||
}
|
||||
void Component::setWorldLocation(Vector location)
|
||||
{
|
||||
Vector newRelLocation = location;
|
||||
if (parent != nullptr)
|
||||
{
|
||||
Transform parentToWorld = getParent()->getTransform();
|
||||
newRelLocation = parentToWorld.inverseTransformPosition(location);
|
||||
}
|
||||
setRelativeLocation(newRelLocation);
|
||||
}
|
||||
void Component::setWorldRotation(Vector rotation)
|
||||
{
|
||||
Vector newRelRotator = rotation;
|
||||
if (parent == nullptr)
|
||||
{
|
||||
setRelativeRotation(rotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
setWorldRotation(toQuaternion(newRelRotator));
|
||||
}
|
||||
}
|
||||
void Component::setWorldRotation(Quaternion rotation)
|
||||
{
|
||||
Quaternion newRelRotation = getRelativeWorldRotation(rotation);
|
||||
setRelativeRotation(newRelRotation);
|
||||
}
|
||||
void Component::setWorldScale(Vector scale)
|
||||
{
|
||||
Vector newRelScale = scale;
|
||||
if (parent != nullptr)
|
||||
{
|
||||
Transform parentToWorld = parent->getTransform();
|
||||
newRelScale = scale * parentToWorld.getSafeScaleReciprocal(Vector4(parentToWorld.getScale(), 0));
|
||||
}
|
||||
setRelativeScale(newRelScale);
|
||||
}
|
||||
void Component::setRelativeLocation(Vector location)
|
||||
{
|
||||
setRelativeLocationAndRotation(location, relativeRotation);
|
||||
}
|
||||
void Component::setRelativeRotation(Vector rotation)
|
||||
{
|
||||
setRelativeLocationAndRotation(relativeLocation, toQuaternion(rotation));
|
||||
}
|
||||
void Component::setRelativeRotation(Quaternion rotation)
|
||||
{
|
||||
setRelativeLocationAndRotation(relativeLocation, rotation);
|
||||
}
|
||||
void Component::setRelativeScale(Vector scale)
|
||||
{
|
||||
if (scale != relativeScale)
|
||||
{
|
||||
relativeScale = scale;
|
||||
updateComponentTransform(relativeRotation);
|
||||
}
|
||||
}
|
||||
void Component::addWorldTranslation(Vector translation)
|
||||
{
|
||||
const Vector newWorldLocation = translation + transform.getPosition();
|
||||
setWorldLocation(newWorldLocation);
|
||||
}
|
||||
void Component::addWorldRotation(Vector rotation)
|
||||
{
|
||||
const Quaternion newWorldRotation = toQuaternion(rotation) * transform.getRotation();
|
||||
setWorldRotation(newWorldRotation);
|
||||
}
|
||||
void Component::addWorldRotation(Quaternion rotation)
|
||||
{
|
||||
}
|
||||
void Component::addWorldScale(Vector scale)
|
||||
{
|
||||
const Quaternion newWorldRotation = rotation * transform.getRotation();
|
||||
setWorldRotation(newWorldRotation);
|
||||
}
|
||||
Transform Component::getTransform() const
|
||||
{
|
||||
return transform;
|
||||
}
|
||||
|
||||
void Component::setParent(PComponent newParent)
|
||||
{
|
||||
parent = newParent;
|
||||
}
|
||||
|
||||
void Component::internalSetTransform(Vector newLocation, Quaternion newRotation)
|
||||
{
|
||||
if(parent != nullptr)
|
||||
if (parent != nullptr)
|
||||
{
|
||||
Transform parentTransform = parent->getTransform();
|
||||
newLocation = parentTransform.inverseTransformPosition(newLocation);
|
||||
@@ -67,7 +134,7 @@ void Component::internalSetTransform(Vector newLocation, Quaternion newRotation)
|
||||
}
|
||||
|
||||
const Vector newRelRotation = toRotator(newRotation);
|
||||
if(newLocation != relativeLocation || newRelRotation != relativeLocation)
|
||||
if (newLocation != relativeLocation || newRelRotation != relativeLocation)
|
||||
{
|
||||
relativeLocation = newLocation;
|
||||
relativeRotation = newRelRotation;
|
||||
@@ -75,24 +142,21 @@ void Component::internalSetTransform(Vector newLocation, Quaternion newRotation)
|
||||
}
|
||||
}
|
||||
|
||||
void Component::propagateTransformUpdate()
|
||||
void Component::propagateTransformUpdate()
|
||||
{
|
||||
for(auto child : children)
|
||||
for (auto child : children)
|
||||
{
|
||||
if(child != nullptr)
|
||||
{
|
||||
child->updateComponentTransform(child->relativeRotation);
|
||||
}
|
||||
child->updateComponentTransform(child->relativeRotation);
|
||||
}
|
||||
}
|
||||
|
||||
void Component::updateComponentTransform(Quaternion relativeRotationQuat)
|
||||
void Component::updateComponentTransform(Quaternion relativeRotationQuat)
|
||||
{
|
||||
if(parent != nullptr && !parent->bComponentTransformClean)
|
||||
if (parent != nullptr && !parent->bComponentTransformClean)
|
||||
{
|
||||
parent->updateComponentTransform(parent->relativeRotation);
|
||||
|
||||
if(bComponentTransformClean)
|
||||
if (bComponentTransformClean)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -100,9 +164,41 @@ void Component::updateComponentTransform(Quaternion relativeRotationQuat)
|
||||
bComponentTransformClean = true;
|
||||
Transform newTransform;
|
||||
const Transform relTransform(relativeLocation, relativeRotationQuat, relativeScale);
|
||||
if(parent != nullptr)
|
||||
if (parent != nullptr)
|
||||
{
|
||||
newTransform = parent->getTransform() * relTransform;
|
||||
}
|
||||
|
||||
bool bHasChanged = !getTransform().equals(newTransform);
|
||||
if (bHasChanged)
|
||||
{
|
||||
transform = newTransform;
|
||||
propagateTransformUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
Quaternion Component::getRelativeWorldRotation(Quaternion worldRotation)
|
||||
{
|
||||
Quaternion newRelRotation = worldRotation;
|
||||
if (parent != nullptr)
|
||||
{
|
||||
const Transform parentToWorld = parent->getTransform();
|
||||
|
||||
const Quaternion parentToWorldQuat = parentToWorld.getRotation();
|
||||
const Quaternion newRelQuat = glm::inverse(parentToWorldQuat) * worldRotation;
|
||||
newRelRotation = newRelQuat;
|
||||
}
|
||||
return newRelRotation;
|
||||
}
|
||||
|
||||
void Component::setRelativeLocationAndRotation(Vector newLocation, Quaternion newRotation)
|
||||
{
|
||||
if (!bComponentTransformClean)
|
||||
{
|
||||
updateComponentTransform(toQuaternion(relativeRotation));
|
||||
}
|
||||
|
||||
const Transform desiredRelTransform(newLocation, newRotation);
|
||||
const Transform desiredWorldTransform = parent->getTransform() * desiredRelTransform;
|
||||
|
||||
internalSetTransform(desiredWorldTransform.getPosition(), desiredWorldTransform.getRotation());
|
||||
}
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Transform.h"
|
||||
#include "Math/Transform.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Actor);
|
||||
DECLARE_REF(Scene);
|
||||
DECLARE_REF(Component);
|
||||
class Component
|
||||
{
|
||||
public:
|
||||
Component();
|
||||
virtual ~Component();
|
||||
void tick(float deltaTime);
|
||||
PComponent getParent();
|
||||
void setParent(PComponent parent);
|
||||
PActor getOwner();
|
||||
void setOwner(PActor owner);
|
||||
virtual void notifySceneAttach(PScene scene);
|
||||
|
||||
void setWorldLocation(Vector location);
|
||||
void setWorldRotation(Vector rotation);
|
||||
@@ -24,25 +26,30 @@ public:
|
||||
void setRelativeRotation(Vector rotation);
|
||||
void setRelativeRotation(Quaternion rotation);
|
||||
void setRelativeScale(Vector scale);
|
||||
|
||||
|
||||
void addWorldTranslation(Vector translation);
|
||||
void addWorldRotation(Vector rotation);
|
||||
void addWorldRotation(Quaternion rotation);
|
||||
void addWorldScale(Vector scale);
|
||||
|
||||
Transform getTransform() const;
|
||||
|
||||
private:
|
||||
void setParent(PComponent parent);
|
||||
void internalSetTransform(Vector newLocation, Quaternion newRotation);
|
||||
void propagateTransformUpdate();
|
||||
void updateComponentTransform(Quaternion relativeRotationQuat);
|
||||
uint8 bComponentTransformClean:1;
|
||||
Quaternion getRelativeWorldRotation(Quaternion worldRotation);
|
||||
void setRelativeLocationAndRotation(Vector newLocation, Quaternion newRotation);
|
||||
uint8 bComponentTransformClean : 1;
|
||||
Vector relativeLocation;
|
||||
Vector relativeRotation;
|
||||
Vector relativeScale;
|
||||
Transform transform;
|
||||
PScene owningScene;
|
||||
PActor owner;
|
||||
PComponent parent;
|
||||
Array<PComponent> children;
|
||||
friend class Actor;
|
||||
};
|
||||
DEFINE_REF(Component)
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "PrimitiveComponent.h"
|
||||
#include "Scene/Scene.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
PrimitiveComponent::PrimitiveComponent()
|
||||
{
|
||||
}
|
||||
|
||||
PrimitiveComponent::~PrimitiveComponent()
|
||||
{
|
||||
}
|
||||
|
||||
void PrimitiveComponent::notifySceneAttach(PScene scene)
|
||||
{
|
||||
scene->addPrimitiveComponent(this);
|
||||
}
|
||||
|
||||
Matrix4 PrimitiveComponent::getRenderMatrix()
|
||||
{
|
||||
return getTransform().toMatrix();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
#pragma once
|
||||
#include "Component.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class PrimitiveComponent : public Component
|
||||
{
|
||||
public:
|
||||
private:
|
||||
PrimitiveComponent();
|
||||
~PrimitiveComponent();
|
||||
virtual void notifySceneAttach(PScene scene) override;
|
||||
Matrix4 getRenderMatrix();
|
||||
|
||||
private:
|
||||
PMaterialInstance instance;
|
||||
Gfx::PVertexBuffer vertexBuffer;
|
||||
Gfx::PIndexBuffer indexBuffer;
|
||||
friend class Scene;
|
||||
};
|
||||
}
|
||||
DEFINE_REF(PrimitiveComponent);
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "Scene.h"
|
||||
#include "Components/PrimitiveComponent.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Material/Material.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Scene::Scene()
|
||||
{
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
}
|
||||
|
||||
void Scene::tick(float deltaTime)
|
||||
{
|
||||
for (auto actor : rootActors)
|
||||
{
|
||||
actor->tick(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::addActor(PActor actor)
|
||||
{
|
||||
rootActors.add(actor);
|
||||
actor->notifySceneAttach(this);
|
||||
}
|
||||
|
||||
void Scene::addPrimitiveComponent(PPrimitiveComponent comp)
|
||||
{
|
||||
primitives.add(comp);
|
||||
}
|
||||
|
||||
Map<PMaterial, DrawState> Scene::getMeshBatches()
|
||||
{
|
||||
meshBatches.clear();
|
||||
for (auto primitive : primitives)
|
||||
{
|
||||
PMaterialInstance matInstance = primitive->instance;
|
||||
PMaterial mat = matInstance->getBaseMaterial();
|
||||
DrawInstance inst;
|
||||
inst.instance = primitive->instance;
|
||||
inst.vertexBuffer = primitive->vertexBuffer;
|
||||
inst.indexBuffer = primitive->indexBuffer;
|
||||
inst.modelMatrix = primitive->getRenderMatrix();
|
||||
|
||||
if (meshBatches.find(mat) != meshBatches.end())
|
||||
{
|
||||
DrawState &state = meshBatches[mat];
|
||||
state.instances.add(inst);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawState state;
|
||||
state.instances.add(inst);
|
||||
meshBatches[mat] = state;
|
||||
}
|
||||
}
|
||||
return meshBatches;
|
||||
}
|
||||
@@ -1,14 +1,28 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Actor/Actor.h"
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Components/PrimitiveComponent.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Material);
|
||||
|
||||
class Scene
|
||||
{
|
||||
public:
|
||||
Scene();
|
||||
~Scene();
|
||||
void tick(float deltaTime);
|
||||
void addActor(PActor actor);
|
||||
void addPrimitiveComponent(PPrimitiveComponent comp);
|
||||
|
||||
private:
|
||||
Map<PMaterial, DrawState> meshBatches;
|
||||
Array<PActor> rootActors;
|
||||
Array<PPrimitiveComponent> primitives;
|
||||
|
||||
public:
|
||||
Map<PMaterial, DrawState> getMeshBatches();
|
||||
};
|
||||
}
|
||||
} // namespace Seele
|
||||
Reference in New Issue
Block a user