Polymorphic Map and threadpool
This commit is contained in:
+3
-1
@@ -21,7 +21,9 @@ set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
|
||||
|
||||
set(Boost_USE_STATIC_LIBS OFF)
|
||||
set(Boost_LIB_PREFIX lib)
|
||||
if(WIN32)
|
||||
set(Boost_LIB_PREFIX lib)
|
||||
endif()
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE})
|
||||
#Workaround for vs, because it places artifacts into an additional subfolder
|
||||
|
||||
@@ -3,18 +3,18 @@ import Common;
|
||||
|
||||
struct ComputeShaderInput
|
||||
{
|
||||
uint3 groupID : SV_GroupID;
|
||||
uint3 groupThreadID : SV_GroupThreadID;
|
||||
uint3 dispatchThreadID : SV_DispatchThreadID;
|
||||
uint groupIndex : SV_GroupIndex;
|
||||
uint3 groupID : SV_GroupID;
|
||||
uint3 groupThreadID : SV_GroupThreadID;
|
||||
uint3 dispatchThreadID : SV_DispatchThreadID;
|
||||
uint groupIndex : SV_GroupIndex;
|
||||
};
|
||||
layout(set = INDEX_VIEW_PARAMS, binding = 1)
|
||||
cbuffer DispatchParams
|
||||
{
|
||||
uint3 numThreadGroups;
|
||||
uint pad0;
|
||||
uint3 numThreads;
|
||||
uint pad1;
|
||||
uint3 numThreadGroups;
|
||||
uint pad0;
|
||||
uint3 numThreads;
|
||||
uint pad1;
|
||||
}
|
||||
|
||||
layout(set = INDEX_VIEW_PARAMS, binding = 2)
|
||||
@@ -52,90 +52,90 @@ groupshared uint tLightList[1024];
|
||||
|
||||
void oAppendLight(uint lightIndex)
|
||||
{
|
||||
uint index;
|
||||
InterlockedAdd(oLightCount, 1, index);
|
||||
if(index < 1024)
|
||||
{
|
||||
oLightList[index] = lightIndex;
|
||||
}
|
||||
uint index;
|
||||
InterlockedAdd(oLightCount, 1, index);
|
||||
if(index < 1024)
|
||||
{
|
||||
oLightList[index] = lightIndex;
|
||||
}
|
||||
}
|
||||
|
||||
void tAppendLight(uint lightIndex)
|
||||
{
|
||||
uint index;
|
||||
InterlockedAdd(tLightCount, 1, index);
|
||||
if(index < 1024)
|
||||
{
|
||||
tLightList[index] = lightIndex;
|
||||
}
|
||||
uint index;
|
||||
InterlockedAdd(tLightCount, 1, index);
|
||||
if(index < 1024)
|
||||
{
|
||||
tLightList[index] = lightIndex;
|
||||
}
|
||||
}
|
||||
|
||||
[numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)]
|
||||
[shader("compute")]
|
||||
void cullLights(ComputeShaderInput in)
|
||||
{
|
||||
int3 texCoord = int3(in.dispatchThreadID.xy, 0);
|
||||
float fDepth = depthTextureVS.Load(texCoord).r;
|
||||
int3 texCoord = int3(in.dispatchThreadID.xy, 0);
|
||||
float fDepth = depthTextureVS.Load(texCoord).r;
|
||||
|
||||
uint uDepth = asuint(fDepth);
|
||||
if(in.groupIndex == 0)
|
||||
{
|
||||
uMinDepth = 0xffffffff;
|
||||
uMaxDepth = 0x0;
|
||||
oLightCount = 0;
|
||||
tLightCount = 0;
|
||||
uint uDepth = asuint(fDepth);
|
||||
if(in.groupIndex == 0)
|
||||
{
|
||||
uMinDepth = 0xffffffff;
|
||||
uMaxDepth = 0x0;
|
||||
oLightCount = 0;
|
||||
tLightCount = 0;
|
||||
groupFrustum = frustums[in.groupID.x + (in.groupID.y * numThreadGroups.x)];
|
||||
}
|
||||
}
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
InterlockedMin(uMinDepth, uDepth);
|
||||
InterlockedMax(uMaxDepth, uDepth);
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
InterlockedMin(uMinDepth, uDepth);
|
||||
InterlockedMax(uMaxDepth, uDepth);
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
float fMinDepth = asfloat(uMinDepth);
|
||||
float fMaxDepth = asfloat(uMaxDepth);
|
||||
float fMinDepth = asfloat(uMinDepth);
|
||||
float fMaxDepth = asfloat(uMaxDepth);
|
||||
|
||||
float minDepthVS = clipToView(float4(0, 0, fMinDepth, 1)).z;
|
||||
float maxDepthVS = clipToView(float4(0, 0, fMaxDepth, 1)).z;
|
||||
float nearClipVS = clipToView(float4(0, 0, 0, 1.0f)).z;
|
||||
float minDepthVS = clipToView(float4(0, 0, fMinDepth, 1)).z;
|
||||
float maxDepthVS = clipToView(float4(0, 0, fMaxDepth, 1)).z;
|
||||
float nearClipVS = clipToView(float4(0, 0, 0, 1.0f)).z;
|
||||
|
||||
Plane minPlane = {float3(0, 0, -1), -minDepthVS};
|
||||
Plane minPlane = {float3(0, 0, -1), -minDepthVS};
|
||||
|
||||
for ( uint i = in.groupIndex; i < numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
|
||||
{
|
||||
{
|
||||
PointLight light = pointLights[i];
|
||||
//TODO: why doesn't this check go through?
|
||||
//if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
|
||||
{
|
||||
tAppendLight(i);
|
||||
//TODO: why doesn't this check go through?
|
||||
//if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
|
||||
{
|
||||
tAppendLight(i);
|
||||
if(!light.insidePlane(minPlane))
|
||||
{
|
||||
oAppendLight(i);
|
||||
}
|
||||
}
|
||||
{
|
||||
oAppendLight(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
if(in.groupIndex == 0)
|
||||
{
|
||||
InterlockedAdd(oLightIndexCounter[0], (uint)oLightCount, oLightIndexStartOffset);
|
||||
oLightGrid[in.groupID.xy] = uint2(oLightIndexStartOffset, oLightCount);
|
||||
|
||||
InterlockedAdd(tLightIndexCounter[0], (uint)tLightCount, tLightIndexStartOffset);
|
||||
tLightGrid[in.groupID.xy] = uint2(tLightIndexStartOffset, tLightCount);
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
for (uint j = in.groupIndex; j < (uint)oLightCount; j += BLOCK_SIZE * BLOCK_SIZE)
|
||||
{
|
||||
oLightIndexList[oLightIndexStartOffset + j] = oLightList[j];
|
||||
}
|
||||
|
||||
// For transparent geometry.
|
||||
for ( uint k = in.groupIndex; k < (uint)tLightCount; k += BLOCK_SIZE * BLOCK_SIZE )
|
||||
{
|
||||
tLightIndexList[tLightIndexStartOffset + k] = tLightList[k];
|
||||
}
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
if(in.groupIndex == 0)
|
||||
{
|
||||
InterlockedAdd(oLightIndexCounter[0], (uint)oLightCount, oLightIndexStartOffset);
|
||||
oLightGrid[in.groupID.xy] = uint2(oLightIndexStartOffset, oLightCount);
|
||||
|
||||
InterlockedAdd(tLightIndexCounter[0], (uint)tLightCount, tLightIndexStartOffset);
|
||||
tLightGrid[in.groupID.xy] = uint2(tLightIndexStartOffset, tLightCount);
|
||||
}
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
for (uint j = in.groupIndex; j < (uint)oLightCount; j += BLOCK_SIZE * BLOCK_SIZE)
|
||||
{
|
||||
oLightIndexList[oLightIndexStartOffset + j] = oLightList[j];
|
||||
}
|
||||
|
||||
// For transparent geometry.
|
||||
for ( uint k = in.groupIndex; k < (uint)tLightCount; k += BLOCK_SIZE * BLOCK_SIZE )
|
||||
{
|
||||
tLightIndexList[tLightIndexStartOffset + k] = tLightList[k];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ void TextureAsset::load()
|
||||
setStatus(Status::Loading);
|
||||
ktxTexture2* kTexture;
|
||||
// TODO: consider return
|
||||
std::cout << "Loading texture " << getFullPath() << std::endl;
|
||||
ktxTexture2_CreateFromNamedFile(getFullPath().c_str(),
|
||||
KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT,
|
||||
&kTexture);
|
||||
|
||||
@@ -28,7 +28,6 @@ void TextureLoader::importAsset(const std::filesystem::path& filePath)
|
||||
PTextureAsset asset = new TextureAsset(assetFileName.replace_extension("asset").filename().generic_string());
|
||||
asset->setStatus(Asset::Status::Loading);
|
||||
asset->setTexture(placeholderAsset->getTexture());
|
||||
std::cout << "Loading texture " << asset->getFileName() << std::endl;
|
||||
AssetRegistry::get().registerTexture(asset);
|
||||
futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable {
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace Seele
|
||||
assert(_data != nullptr);
|
||||
markIteratorDirty();
|
||||
}
|
||||
constexpr Array(size_type size, const T& value, const allocator_type& alloc = allocator_type())
|
||||
constexpr Array(size_type size, const value_type& value, const allocator_type& alloc = allocator_type())
|
||||
: arraySize(size)
|
||||
, allocated(size)
|
||||
, allocator(alloc)
|
||||
@@ -169,21 +169,16 @@ namespace Seele
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value
|
||||
&& !std::allocator_traits<allocator_type>::is_always_equal::value)
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value )
|
||||
{
|
||||
if(allocator != other.allocator)
|
||||
if (!std::allocator_traits<allocator_type>::is_always_equal::value
|
||||
&& allocator != other.allocator)
|
||||
{
|
||||
deallocateArray(_data, allocated);
|
||||
_data = nullptr;
|
||||
}
|
||||
}
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value)
|
||||
{
|
||||
allocator = other.allocator;
|
||||
}
|
||||
else
|
||||
{}
|
||||
if(other.arraySize > allocated)
|
||||
{
|
||||
if(_data != nullptr)
|
||||
@@ -203,17 +198,14 @@ namespace Seele
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value
|
||||
&& !std::allocator_traits<allocator_type>::is_always_equal::value)
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
|
||||
{
|
||||
if(allocator != other.allocator)
|
||||
if (!std::allocator_traits<allocator_type>::is_always_equal::value
|
||||
&& allocator != other.allocator)
|
||||
{
|
||||
deallocateArray(_data, allocated);
|
||||
_data = nullptr;
|
||||
}
|
||||
}
|
||||
if constexpr (std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value)
|
||||
{
|
||||
allocator = std::move(other.allocator);
|
||||
}
|
||||
if (_data != nullptr)
|
||||
@@ -248,59 +240,59 @@ namespace Seele
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
constexpr Iterator find(const T &item)
|
||||
constexpr iterator find(const value_type &item)
|
||||
{
|
||||
for (uint32 i = 0; i < arraySize; ++i)
|
||||
{
|
||||
if (_data[i] == item)
|
||||
{
|
||||
return Iterator(&_data[i]);
|
||||
return iterator(&_data[i]);
|
||||
}
|
||||
}
|
||||
return endIt;
|
||||
}
|
||||
constexpr Iterator find(T&& item)
|
||||
constexpr iterator find(value_type&& item)
|
||||
{
|
||||
for (uint32 i = 0; i < arraySize; ++i)
|
||||
{
|
||||
if (_data[i] == item)
|
||||
{
|
||||
return Iterator(&_data[i]);
|
||||
return iterator(&_data[i]);
|
||||
}
|
||||
}
|
||||
return endIt;
|
||||
}
|
||||
constexpr Allocator get_allocator() const
|
||||
constexpr allocator_type get_allocator() const
|
||||
{
|
||||
return allocator;
|
||||
}
|
||||
constexpr Iterator begin() const
|
||||
constexpr iterator begin() const
|
||||
{
|
||||
return beginIt;
|
||||
}
|
||||
constexpr Iterator end() const
|
||||
constexpr iterator end() const
|
||||
{
|
||||
return endIt;
|
||||
}
|
||||
constexpr ConstIterator cbegin() const
|
||||
constexpr const_iterator cbegin() const
|
||||
{
|
||||
return beginIt;
|
||||
}
|
||||
constexpr ConstIterator cend() const
|
||||
constexpr const_iterator cend() const
|
||||
{
|
||||
return endIt;
|
||||
}
|
||||
constexpr T &add(const T &item = T())
|
||||
constexpr reference add(const value_type &item = value_type())
|
||||
{
|
||||
return addInternal(item);
|
||||
}
|
||||
constexpr T &add(T&& item)
|
||||
constexpr reference add(value_type&& item)
|
||||
{
|
||||
return addInternal(std::forward<T>(item));
|
||||
}
|
||||
constexpr T &addUnique(const T &item = T())
|
||||
constexpr reference addUnique(const value_type &item = value_type())
|
||||
{
|
||||
Iterator it;
|
||||
iterator it;
|
||||
if((it = std::move(find(item))) != endIt)
|
||||
{
|
||||
return *it;
|
||||
@@ -308,7 +300,7 @@ namespace Seele
|
||||
return addInternal(item);
|
||||
}
|
||||
template<typename... args>
|
||||
constexpr T &emplace(args... arguments)
|
||||
constexpr reference emplace(args... arguments)
|
||||
{
|
||||
if (arraySize == allocated)
|
||||
{
|
||||
@@ -316,10 +308,8 @@ namespace Seele
|
||||
allocated = calculateGrowth(newSize);
|
||||
T *tempArray = allocateArray(allocated);
|
||||
assert(tempArray != nullptr);
|
||||
for (size_type i = 0; i < arraySize; ++i)
|
||||
{
|
||||
tempArray[i] = std::move(_data[i]);
|
||||
}
|
||||
|
||||
std::uninitialized_move(begin(), end(), Iterator(tempArray));
|
||||
deallocateArray(_data, arraySize);
|
||||
_data = tempArray;
|
||||
}
|
||||
@@ -327,7 +317,7 @@ namespace Seele
|
||||
markIteratorDirty();
|
||||
return _data[arraySize - 1];
|
||||
}
|
||||
constexpr void remove(Iterator it, bool keepOrder = true)
|
||||
constexpr void remove(iterator it, bool keepOrder = true)
|
||||
{
|
||||
remove(it - beginIt, keepOrder);
|
||||
}
|
||||
@@ -351,7 +341,7 @@ namespace Seele
|
||||
{
|
||||
resizeInternal(newSize, std::move(T()));
|
||||
}
|
||||
constexpr void resize(size_type newSize, const T& value)
|
||||
constexpr void resize(size_type newSize, const value_type& value)
|
||||
{
|
||||
resizeInternal(newSize, value);
|
||||
}
|
||||
@@ -367,11 +357,11 @@ namespace Seele
|
||||
allocated = 0;
|
||||
markIteratorDirty();
|
||||
}
|
||||
inline size_type indexOf(Iterator iterator)
|
||||
inline size_type indexOf(iterator iterator)
|
||||
{
|
||||
return iterator - beginIt;
|
||||
}
|
||||
inline size_type indexOf(ConstIterator iterator) const
|
||||
inline size_type indexOf(const_iterator iterator) const
|
||||
{
|
||||
return iterator.p - beginIt.p;
|
||||
}
|
||||
@@ -395,12 +385,18 @@ namespace Seele
|
||||
{
|
||||
return allocated;
|
||||
}
|
||||
inline T *data() const
|
||||
inline pointer data() const
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
inline T &back() const
|
||||
inline reference front() const
|
||||
{
|
||||
assert(arraySize > 0);
|
||||
return _data[0];
|
||||
}
|
||||
inline reference back() const
|
||||
{
|
||||
assert(arraySize > 0);
|
||||
return _data[arraySize - 1];
|
||||
}
|
||||
void pop()
|
||||
@@ -408,12 +404,12 @@ namespace Seele
|
||||
arraySize--;
|
||||
markIteratorDirty();
|
||||
}
|
||||
constexpr inline T &operator[](size_type index)
|
||||
constexpr inline reference operator[](size_type index)
|
||||
{
|
||||
assert(index < arraySize);
|
||||
return _data[index];
|
||||
}
|
||||
constexpr inline const T &operator[](size_type index) const
|
||||
constexpr inline const reference operator[](size_type index) const
|
||||
{
|
||||
assert(index < arraySize);
|
||||
return _data[index];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include <xmemory>
|
||||
#include <memory_resource>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -187,11 +187,11 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
T &front()
|
||||
reference front()
|
||||
{
|
||||
return root->data;
|
||||
}
|
||||
T &back()
|
||||
reference back()
|
||||
{
|
||||
return tail->prev->data;
|
||||
}
|
||||
@@ -218,7 +218,7 @@ public:
|
||||
root = allocateNode();
|
||||
tail = root;
|
||||
}
|
||||
tail->data = value;
|
||||
initializeNode(tail, value);
|
||||
Node *newTail = allocateNode();
|
||||
newTail->prev = tail;
|
||||
newTail->next = nullptr;
|
||||
@@ -236,7 +236,7 @@ public:
|
||||
root = allocateNode();
|
||||
tail = root;
|
||||
}
|
||||
tail->data = std::move(value);
|
||||
initializeNode(tail, std::move(value));
|
||||
Node *newTail = allocateNode();
|
||||
newTail->prev = tail;
|
||||
newTail->next = nullptr;
|
||||
@@ -247,6 +247,13 @@ public:
|
||||
_size++;
|
||||
return insertedElement;
|
||||
}
|
||||
// front + popFront
|
||||
value_type&& retrieve()
|
||||
{
|
||||
auto&& temp = std::move(root->data);
|
||||
popFront();
|
||||
return std::move(temp);
|
||||
}
|
||||
iterator remove(iterator pos)
|
||||
{
|
||||
_size--;
|
||||
@@ -299,7 +306,7 @@ public:
|
||||
}
|
||||
Node *tmp = pos.node->prev;
|
||||
Node *newNode = allocateNode();
|
||||
newNode->data = value;
|
||||
initializeNode(newNode, value);
|
||||
tmp->next = newNode;
|
||||
newNode->prev = tmp;
|
||||
newNode->next = pos.node;
|
||||
@@ -346,10 +353,20 @@ private:
|
||||
Node* allocateNode()
|
||||
{
|
||||
Node* node = allocator.allocate(1);
|
||||
std::memset(node, 0, sizeof(Node));
|
||||
assert(node != nullptr);
|
||||
node->prev = nullptr;
|
||||
node->next = nullptr;
|
||||
return node;
|
||||
}
|
||||
template<typename Type>
|
||||
void initializeNode(Node* node, Type&& data)
|
||||
{
|
||||
std::allocator_traits<NodeAllocator>::construct(allocator,
|
||||
node,
|
||||
node->prev,
|
||||
node->next,
|
||||
std::forward<Type>(data));
|
||||
}
|
||||
void deallocateNode(Node* node)
|
||||
{
|
||||
allocator.deallocate(node, 1);
|
||||
|
||||
+514
-521
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -370,12 +370,14 @@ public:
|
||||
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) override;
|
||||
virtual void setScrollCallback(std::function<void(double, double)> callback) override;
|
||||
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
|
||||
virtual void setCloseCallback(std::function<void()> callback);
|
||||
|
||||
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
|
||||
std::function<void(double, double)> mouseMoveCallback;
|
||||
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
|
||||
std::function<void(double, double)> scrollCallback;
|
||||
std::function<void(int, const char**)> fileCallback;
|
||||
std::function<void()> closeCallback;
|
||||
protected:
|
||||
void advanceBackBuffer();
|
||||
void recreateSwapchain(const WindowCreateInfo &createInfo);
|
||||
|
||||
@@ -38,6 +38,12 @@ void glfwFileCallback(GLFWwindow* handle, int count, const char** paths)
|
||||
window->fileCallback(count, paths);
|
||||
}
|
||||
|
||||
void glfwCloseCallback(GLFWwindow* handle)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->closeCallback();
|
||||
}
|
||||
|
||||
Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
|
||||
: Gfx::Window(createInfo)
|
||||
, graphics(graphics)
|
||||
@@ -56,6 +62,7 @@ Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
|
||||
glfwSetMouseButtonCallback(handle, &glfwMouseButtonCallback);
|
||||
glfwSetScrollCallback(handle, &glfwScrollCallback);
|
||||
glfwSetDropCallback(handle, &glfwFileCallback);
|
||||
glfwSetWindowCloseCallback(handle, &glfwCloseCallback);
|
||||
|
||||
glfwCreateWindowSurface(instance, handle, nullptr, &surface);
|
||||
|
||||
@@ -134,6 +141,11 @@ void Window::setFileCallback(std::function<void(int, const char**)> callback)
|
||||
fileCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setCloseCallback(std::function<void()> callback)
|
||||
{
|
||||
closeCallback = callback;
|
||||
}
|
||||
|
||||
void Window::advanceBackBuffer()
|
||||
{
|
||||
VkResult res = VK_ERROR_OUT_OF_DATE_KHR;
|
||||
|
||||
@@ -54,9 +54,9 @@ public:
|
||||
std::unique_lock lock(registeredObjectsLock);
|
||||
registeredObjects.erase(handle);
|
||||
}
|
||||
#pragma warning( disable: 4150)
|
||||
// #pragma warning( disable: 4150)
|
||||
delete handle;
|
||||
#pragma warning( default: 4150)
|
||||
// #pragma warning( default: 4150)
|
||||
}
|
||||
RefObject &operator=(const RefObject &rhs)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ Scene::Scene(Gfx::PGraphics graphics)
|
||||
lightEnv.directionalLights[0].color = Vector4(1, 1, 1, 1);
|
||||
lightEnv.directionalLights[0].direction = Vector4(1, 1, 0, 1);
|
||||
lightEnv.directionalLights[0].intensity = Vector4(1, 1, 1, 1);
|
||||
lightEnv.numDirectionalLights = 0;
|
||||
lightEnv.numDirectionalLights = 1;
|
||||
srand((unsigned int)time(NULL));
|
||||
for(uint32 i = 0; i < 16; ++i)
|
||||
{
|
||||
|
||||
@@ -2,20 +2,38 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Event::Event()
|
||||
: flag(new std::atomic_bool())
|
||||
{}
|
||||
|
||||
void Event::await_suspend(std::coroutine_handle<JobPromise> h)
|
||||
Event::Event(const std::string& name)
|
||||
: name(name)
|
||||
, flag(new std::atomic_bool())
|
||||
{}
|
||||
|
||||
void Event::raise()
|
||||
{
|
||||
getGlobalThreadPool().addJob(Job(h));
|
||||
flag->store(1);
|
||||
getGlobalThreadPool().notify(this);
|
||||
}
|
||||
void Event::reset()
|
||||
{
|
||||
flag->store(0);
|
||||
}
|
||||
|
||||
Job JobPromise::get_return_object() noexcept {
|
||||
return Job { std::coroutine_handle<JobPromise>::from_promise(*this) };
|
||||
bool Event::await_ready()
|
||||
{
|
||||
return flag->load();
|
||||
}
|
||||
|
||||
ThreadPool::ThreadPool(uint32 threadCount)
|
||||
: workers(threadCount)
|
||||
{
|
||||
|
||||
running.store(true);
|
||||
for(uint32 i = 0; i < threadCount; ++i)
|
||||
{
|
||||
workers[i] = std::thread(&ThreadPool::threadLoop, this, i == 0);
|
||||
}
|
||||
}
|
||||
|
||||
ThreadPool::~ThreadPool()
|
||||
@@ -25,6 +43,63 @@ ThreadPool::~ThreadPool()
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
void ThreadPool::addJob(Job&& job)
|
||||
{
|
||||
std::unique_lock lock(jobQueueLock);
|
||||
jobQueue.add(job);
|
||||
}
|
||||
void ThreadPool::addJob(MainJob&& job)
|
||||
{
|
||||
std::unique_lock lock(mainJobLock);
|
||||
mainJobs.add(job);
|
||||
}
|
||||
void ThreadPool::enqueueWaiting(Event* event, Job&& job)
|
||||
{
|
||||
std::unique_lock lock(waitingLock);
|
||||
waitingJobs[event].add(std::move(job));
|
||||
}
|
||||
void ThreadPool::enqueueWaiting(Event* event, MainJob&& job)
|
||||
{
|
||||
std::unique_lock lock(waitingMainLock);
|
||||
waitingMainJobs[event].add(std::move(job));
|
||||
}
|
||||
void ThreadPool::notify(Event* event)
|
||||
{
|
||||
{
|
||||
std::unique_lock lock(jobQueueLock);
|
||||
std::unique_lock lock2(waitingLock);
|
||||
for(auto&& job : waitingJobs[event])
|
||||
{
|
||||
jobQueue.add(job);
|
||||
}
|
||||
waitingJobs[event].clear();
|
||||
}
|
||||
{
|
||||
std::unique_lock lock(mainJobLock);
|
||||
std::unique_lock lock2(waitingMainLock);
|
||||
for(auto&& job : waitingMainJobs[event])
|
||||
{
|
||||
mainJobs.add(job);
|
||||
}
|
||||
waitingMainJobs[event].clear();
|
||||
}
|
||||
event->reset();
|
||||
}
|
||||
void ThreadPool::threadLoop(const bool mainThread)
|
||||
{
|
||||
while(running.load())
|
||||
{
|
||||
if(mainThread)
|
||||
{
|
||||
std::unique_lock lock(mainJobLock);
|
||||
if(!mainJobs.empty())
|
||||
{
|
||||
MainJob&& job = mainJobs.retrieve();
|
||||
job.resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ThreadPool& Seele::getGlobalThreadPool()
|
||||
{
|
||||
|
||||
+88
-37
@@ -1,35 +1,20 @@
|
||||
#pragma once
|
||||
#include <thread>
|
||||
#include <coroutine>
|
||||
#include "Containers/List.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
struct JobPromise;
|
||||
struct Event
|
||||
{
|
||||
public:
|
||||
void raise()
|
||||
{
|
||||
flag.test_and_set();
|
||||
flag.notify_all();
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
flag.clear();
|
||||
}
|
||||
bool await_ready() { return flag.test(); }
|
||||
void await_suspend(std::coroutine_handle<JobPromise> h);
|
||||
void await_resume() {}
|
||||
private:
|
||||
std::atomic_flag flag;
|
||||
};
|
||||
struct [[nodiscard]] Job;
|
||||
struct JobPromise
|
||||
{
|
||||
Job get_return_object() noexcept;
|
||||
extern class ThreadPool& getGlobalThreadPool();
|
||||
|
||||
std::suspend_always initial_suspend() const noexcept { return {}; }
|
||||
template<bool MainJob>
|
||||
struct JobBase;
|
||||
|
||||
template<bool MainJob>
|
||||
struct JobPromiseBase
|
||||
{
|
||||
JobBase<MainJob> get_return_object() noexcept;
|
||||
|
||||
inline auto initial_suspend() const noexcept;
|
||||
std::suspend_never final_suspend() const noexcept { return {}; }
|
||||
|
||||
void return_void() noexcept {}
|
||||
@@ -38,23 +23,47 @@ struct JobPromise
|
||||
exit(1);
|
||||
};
|
||||
};
|
||||
struct [[nodiscard]] Job
|
||||
template<bool MainJob>
|
||||
struct JobBase
|
||||
{
|
||||
public:
|
||||
using promise_type = JobPromise;
|
||||
using promise_type = JobPromiseBase<MainJob>;
|
||||
|
||||
explicit Job(std::coroutine_handle<JobPromise> handle)
|
||||
explicit JobBase(std::coroutine_handle<promise_type> handle)
|
||||
: handle(handle)
|
||||
{}
|
||||
~Job()
|
||||
~JobBase()
|
||||
{
|
||||
if(handle)
|
||||
{
|
||||
handle.destroy();
|
||||
}
|
||||
}
|
||||
void resume()
|
||||
{
|
||||
handle.resume();
|
||||
}
|
||||
private:
|
||||
std::coroutine_handle<JobPromise> handle;
|
||||
std::coroutine_handle<promise_type> handle;
|
||||
};
|
||||
|
||||
using MainJob = JobBase<true>;
|
||||
using Job = JobBase<false>;
|
||||
|
||||
struct Event
|
||||
{
|
||||
public:
|
||||
Event();
|
||||
Event(const std::string& name);
|
||||
void raise();
|
||||
void reset();
|
||||
bool await_ready();
|
||||
template<bool MainJob>
|
||||
constexpr void await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h);
|
||||
constexpr void await_resume() {}
|
||||
private:
|
||||
std::string name;
|
||||
RefPtr<std::atomic_bool> flag;
|
||||
};
|
||||
|
||||
class ThreadPool
|
||||
@@ -62,14 +71,56 @@ class ThreadPool
|
||||
public:
|
||||
ThreadPool(uint32 threadCount = std::thread::hardware_concurrency());
|
||||
virtual ~ThreadPool();
|
||||
void addJob(Job&& job)
|
||||
{
|
||||
jobs.add(std::move(job));
|
||||
}
|
||||
void addJob(Job&& job);
|
||||
void addJob(MainJob&& job);
|
||||
void enqueueWaiting(Event* event, Job&& job);
|
||||
void enqueueWaiting(Event* event, MainJob&& job);
|
||||
void notify(Event* event);
|
||||
private:
|
||||
std::atomic_bool running;
|
||||
std::thread* mainThread;
|
||||
std::vector<std::thread> workers;
|
||||
List<Job> jobs;
|
||||
void threadLoop();
|
||||
|
||||
List<MainJob> mainJobs;
|
||||
std::mutex mainJobLock;
|
||||
|
||||
List<Job> jobQueue;
|
||||
std::mutex jobQueueLock;
|
||||
|
||||
Map<Event*, List<Job>> waitingJobs;
|
||||
std::mutex waitingLock;
|
||||
|
||||
Map<Event*, List<MainJob>> waitingMainJobs;
|
||||
std::mutex waitingMainLock;
|
||||
|
||||
void threadLoop(const bool isMainThread);
|
||||
};
|
||||
extern ThreadPool& getGlobalThreadPool();
|
||||
|
||||
|
||||
template<bool MainJob>
|
||||
inline JobBase<MainJob> JobPromiseBase<MainJob>::get_return_object() noexcept {
|
||||
return JobBase<MainJob> { std::coroutine_handle<JobPromiseBase<MainJob>>::from_promise(*this) };
|
||||
}
|
||||
|
||||
template<bool MainJob>
|
||||
inline auto JobPromiseBase<MainJob>::initial_suspend() const noexcept
|
||||
{
|
||||
struct JobAwaitable
|
||||
{
|
||||
constexpr bool await_ready() { return false; }
|
||||
constexpr void await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h)
|
||||
{
|
||||
getGlobalThreadPool().addJob(JobBase<MainJob>(h));
|
||||
}
|
||||
constexpr void await_resume() {}
|
||||
};
|
||||
return JobAwaitable{};
|
||||
}
|
||||
|
||||
template<bool MainJob>
|
||||
inline constexpr void Event::await_suspend(std::coroutine_handle<JobPromiseBase<MainJob>> h)
|
||||
{
|
||||
getGlobalThreadPool().enqueueWaiting(this, JobBase<MainJob>(h));
|
||||
}
|
||||
|
||||
} // namespace Seele
|
||||
|
||||
@@ -8,49 +8,49 @@
|
||||
using namespace Seele;
|
||||
|
||||
Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo)
|
||||
: View(graphics, owner, createInfo)
|
||||
, activeCamera(new CameraActor())
|
||||
, depthPrepass(DepthPrepass(graphics, viewport, activeCamera))
|
||||
, lightCullingPass(LightCullingPass(graphics, viewport, activeCamera))
|
||||
, basePass(BasePass(graphics, viewport, activeCamera))
|
||||
: View(graphics, owner, createInfo)
|
||||
, activeCamera(new CameraActor())
|
||||
, depthPrepass(DepthPrepass(graphics, viewport, activeCamera))
|
||||
, lightCullingPass(LightCullingPass(graphics, viewport, activeCamera))
|
||||
, basePass(BasePass(graphics, viewport, activeCamera))
|
||||
{
|
||||
scene = new Scene(graphics);
|
||||
scene->addActor(activeCamera);
|
||||
/*AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Hair_Diffuse.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Hair_Lightmap.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Tex_FaceLightmap.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Ayaka.fbx");
|
||||
PPrimitiveComponent ayaka = new PrimitiveComponent(AssetRegistry::findMesh("Ayaka"));
|
||||
ayaka->addWorldTranslation(Vector(0, 0, 100));
|
||||
ayaka->setWorldScale(Vector(0.1f, 0.1f, 0.1f));
|
||||
scene->addPrimitiveComponent(ayaka);*/
|
||||
scene = new Scene(graphics);
|
||||
scene->addActor(activeCamera);
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Hair_Diffuse.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Sword_Ayaka_Tex_Hair_Lightmap.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Avatar_Girl_Tex_FaceLightmap.png");
|
||||
AssetRegistry::importFile("/home/dynamitos/Assets/Ayaka/Ayaka.fbx");
|
||||
PPrimitiveComponent ayaka = new PrimitiveComponent(AssetRegistry::findMesh("Ayaka"));
|
||||
ayaka->addWorldTranslation(Vector(0, 0, 0));
|
||||
ayaka->setWorldScale(Vector(10, 10, 10));
|
||||
scene->addPrimitiveComponent(ayaka);
|
||||
|
||||
AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Ely\\Ely.fbx");
|
||||
AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Cube\\cube.obj");
|
||||
AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Plane\\plane.fbx");
|
||||
PPrimitiveComponent plane = new PrimitiveComponent(AssetRegistry::findMesh("plane"));
|
||||
plane->setWorldScale(Vector(100, 100, 100));
|
||||
PPrimitiveComponent arissa = new PrimitiveComponent(AssetRegistry::findMesh("Ely"));
|
||||
arissa->addWorldTranslation(Vector(0, 0, 100));
|
||||
arissa->setWorldScale(Vector(0.1f, 0.1f, 0.1f));
|
||||
scene->addPrimitiveComponent(plane);
|
||||
scene->addPrimitiveComponent(arissa);
|
||||
/*AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Ely\\Ely.fbx");
|
||||
AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Cube\\cube.obj");
|
||||
AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Plane\\plane.fbx");
|
||||
PPrimitiveComponent plane = new PrimitiveComponent(AssetRegistry::findMesh("plane"));
|
||||
plane->setWorldScale(Vector(100, 100, 100));
|
||||
PPrimitiveComponent arissa = new PrimitiveComponent(AssetRegistry::findMesh("Ely"));
|
||||
arissa->addWorldTranslation(Vector(0, 0, 100));
|
||||
arissa->setWorldScale(Vector(0.1f, 0.1f, 0.1f));
|
||||
scene->addPrimitiveComponent(plane);
|
||||
scene->addPrimitiveComponent(arissa);*/
|
||||
|
||||
PRenderGraphResources resources = new RenderGraphResources();
|
||||
depthPrepass.setResources(resources);
|
||||
lightCullingPass.setResources(resources);
|
||||
basePass.setResources(resources);
|
||||
PRenderGraphResources resources = new RenderGraphResources();
|
||||
depthPrepass.setResources(resources);
|
||||
lightCullingPass.setResources(resources);
|
||||
basePass.setResources(resources);
|
||||
|
||||
depthPrepass.publishOutputs();
|
||||
lightCullingPass.publishOutputs();
|
||||
basePass.publishOutputs();
|
||||
depthPrepass.publishOutputs();
|
||||
lightCullingPass.publishOutputs();
|
||||
basePass.publishOutputs();
|
||||
|
||||
depthPrepass.createRenderPass();
|
||||
lightCullingPass.createRenderPass();
|
||||
basePass.createRenderPass();
|
||||
depthPrepass.createRenderPass();
|
||||
lightCullingPass.createRenderPass();
|
||||
basePass.createRenderPass();
|
||||
}
|
||||
|
||||
Seele::SceneView::~SceneView()
|
||||
@@ -59,8 +59,8 @@ Seele::SceneView::~SceneView()
|
||||
|
||||
void SceneView::beginUpdate()
|
||||
{
|
||||
View::beginUpdate();
|
||||
scene->tick(Gfx::currentFrameDelta);
|
||||
View::beginUpdate();
|
||||
scene->tick(Gfx::currentFrameDelta);
|
||||
}
|
||||
|
||||
void SceneView::update()
|
||||
@@ -69,81 +69,81 @@ void SceneView::update()
|
||||
|
||||
void SceneView::commitUpdate()
|
||||
{
|
||||
depthPrepassData.staticDrawList = scene->getStaticMeshes();
|
||||
lightCullingPassData.lightEnv = scene->getLightBuffer();
|
||||
basePassData.staticDrawList = scene->getStaticMeshes();
|
||||
depthPrepassData.staticDrawList = scene->getStaticMeshes();
|
||||
lightCullingPassData.lightEnv = scene->getLightBuffer();
|
||||
basePassData.staticDrawList = scene->getStaticMeshes();
|
||||
}
|
||||
|
||||
void SceneView::prepareRender()
|
||||
{
|
||||
depthPrepass.updateViewFrame(depthPrepassData);
|
||||
lightCullingPass.updateViewFrame(lightCullingPassData);
|
||||
basePass.updateViewFrame(basePassData);
|
||||
depthPrepass.updateViewFrame(depthPrepassData);
|
||||
lightCullingPass.updateViewFrame(lightCullingPassData);
|
||||
basePass.updateViewFrame(basePassData);
|
||||
}
|
||||
|
||||
void SceneView::render()
|
||||
{
|
||||
depthPrepass.beginFrame();
|
||||
lightCullingPass.beginFrame();
|
||||
basePass.beginFrame();
|
||||
depthPrepass.beginFrame();
|
||||
lightCullingPass.beginFrame();
|
||||
basePass.beginFrame();
|
||||
|
||||
depthPrepass.render();
|
||||
lightCullingPass.render();
|
||||
basePass.render();
|
||||
depthPrepass.render();
|
||||
lightCullingPass.render();
|
||||
basePass.render();
|
||||
|
||||
depthPrepass.endFrame();
|
||||
lightCullingPass.endFrame();
|
||||
basePass.endFrame();
|
||||
depthPrepass.endFrame();
|
||||
lightCullingPass.endFrame();
|
||||
basePass.endFrame();
|
||||
}
|
||||
|
||||
void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier)
|
||||
{
|
||||
if(action != InputAction::RELEASE)
|
||||
{
|
||||
if(code == KeyCode::KEY_W)
|
||||
{
|
||||
activeCamera->getCameraComponent()->moveOrigin(1);
|
||||
}
|
||||
if(code == KeyCode::KEY_S)
|
||||
{
|
||||
activeCamera->getCameraComponent()->moveOrigin(-1);
|
||||
}
|
||||
}
|
||||
if(action != InputAction::RELEASE)
|
||||
{
|
||||
if(code == KeyCode::KEY_W)
|
||||
{
|
||||
activeCamera->getCameraComponent()->moveOrigin(1);
|
||||
}
|
||||
if(code == KeyCode::KEY_S)
|
||||
{
|
||||
activeCamera->getCameraComponent()->moveOrigin(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool mouseDown = false;
|
||||
|
||||
void SceneView::mouseMoveCallback(double xPos, double yPos)
|
||||
{
|
||||
static double prevXPos = 0.0f, prevYPos = 0.0f;
|
||||
double deltaX = prevXPos - xPos;
|
||||
double deltaY = prevYPos - yPos;
|
||||
prevXPos = xPos;
|
||||
prevYPos = yPos;
|
||||
if(mouseDown)
|
||||
{
|
||||
activeCamera->getCameraComponent()->mouseMove((float)deltaX, (float)deltaY);
|
||||
}
|
||||
static double prevXPos = 0.0f, prevYPos = 0.0f;
|
||||
double deltaX = prevXPos - xPos;
|
||||
double deltaY = prevYPos - yPos;
|
||||
prevXPos = xPos;
|
||||
prevYPos = yPos;
|
||||
if(mouseDown)
|
||||
{
|
||||
activeCamera->getCameraComponent()->mouseMove((float)deltaX, (float)deltaY);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneView::mouseButtonCallback(MouseButton button, InputAction action, KeyModifier)
|
||||
{
|
||||
if(button == MouseButton::MOUSE_BUTTON_1 && action != InputAction::RELEASE)
|
||||
{
|
||||
mouseDown = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseDown = false;
|
||||
}
|
||||
if(button == MouseButton::MOUSE_BUTTON_1 && action != InputAction::RELEASE)
|
||||
{
|
||||
mouseDown = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseDown = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneView::scrollCallback(double, double yOffset)
|
||||
{
|
||||
activeCamera->getCameraComponent()->mouseScroll(yOffset);
|
||||
activeCamera->getCameraComponent()->mouseScroll(yOffset);
|
||||
}
|
||||
|
||||
void SceneView::fileCallback(int, const char**)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "Window.h"
|
||||
#include "WindowManager.h"
|
||||
#include <functional>
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Window::Window(Gfx::PWindow handle)
|
||||
: gfxHandle(handle)
|
||||
Window::Window(PWindowManager owner, Gfx::PWindow handle)
|
||||
: owner(owner)
|
||||
, gfxHandle(handle)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -20,23 +22,17 @@ void Window::addView(PView view)
|
||||
views.add(windowView);
|
||||
}
|
||||
|
||||
void Window::render()
|
||||
MainJob Window::render()
|
||||
{
|
||||
gfxHandle->beginFrame();
|
||||
for(auto& windowView : views)
|
||||
{
|
||||
windowView->view->beginUpdate();
|
||||
windowView->view->update();
|
||||
{
|
||||
std::unique_lock lock(windowView->workerMutex);
|
||||
windowView->view->commitUpdate();
|
||||
}
|
||||
windowView->updateFinished.raise();
|
||||
{
|
||||
viewWorker(windowView);
|
||||
co_await windowView->updateFinished;
|
||||
{
|
||||
std::unique_lock lock(windowView->workerMutex);
|
||||
windowView->view->prepareRender();
|
||||
}
|
||||
windowView->updateFinished.reset();
|
||||
windowView->view->render();
|
||||
}
|
||||
gfxHandle->endFrame();
|
||||
@@ -59,12 +55,22 @@ void Window::setFocused(PView view)
|
||||
gfxHandle->setMouseButtonCallback(mouseButtonFunction);
|
||||
gfxHandle->setScrollCallback(scrollFunction);
|
||||
gfxHandle->setFileCallback(fileFunction);
|
||||
gfxHandle->setCloseCallback([this](){
|
||||
owner->notifyWindowClosed(this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void Window::viewWorker(WindowView* windowView)
|
||||
Job Window::viewWorker(WindowView* windowView)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
windowView->view->beginUpdate();
|
||||
windowView->view->update();
|
||||
{
|
||||
std::unique_lock lock(windowView->workerMutex);
|
||||
windowView->view->commitUpdate();
|
||||
}
|
||||
windowView->updateFinished.raise();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,26 +9,27 @@ struct WindowView
|
||||
{
|
||||
PView view;
|
||||
Event updateFinished;
|
||||
std::thread worker;
|
||||
std::mutex workerMutex;
|
||||
};
|
||||
DEFINE_REF(WindowView)
|
||||
DECLARE_REF(WindowManager)
|
||||
// The logical window, with the graphics proxy
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
Window(Gfx::PWindow handle);
|
||||
Window(PWindowManager owner, Gfx::PWindow handle);
|
||||
~Window();
|
||||
void addView(PView view);
|
||||
void render();
|
||||
MainJob render();
|
||||
Gfx::PWindow getGfxHandle();
|
||||
void setFocused(PView view);
|
||||
|
||||
protected:
|
||||
PWindowManager owner;
|
||||
Array<WindowView*> views;
|
||||
Gfx::PWindow gfxHandle;
|
||||
|
||||
void viewWorker(WindowView* view);
|
||||
Job viewWorker(WindowView* view);
|
||||
};
|
||||
DEFINE_REF(Window)
|
||||
} // namespace Seele
|
||||
@@ -7,21 +7,21 @@ Gfx::PGraphics WindowManager::graphics;
|
||||
|
||||
WindowManager::WindowManager()
|
||||
{
|
||||
graphics = new Vulkan::Graphics();
|
||||
GraphicsInitializer initializer;
|
||||
graphics->init(initializer);
|
||||
TextureCreateInfo info;
|
||||
info.width = 4096;
|
||||
info.height = 4096;
|
||||
Gfx::PTexture2D testTexture = graphics->createTexture2D(info);
|
||||
UniformBufferCreateInfo uniformInitializer;
|
||||
uniformInitializer.resourceData.size = 4096;
|
||||
uniformInitializer.resourceData.data = new uint8[4096];
|
||||
for (int i = 0; i < 4096; ++i)
|
||||
{
|
||||
uniformInitializer.resourceData.data[i] = (uint8)i;
|
||||
}
|
||||
Gfx::PUniformBuffer testUniform = graphics->createUniformBuffer(uniformInitializer);
|
||||
graphics = new Vulkan::Graphics();
|
||||
GraphicsInitializer initializer;
|
||||
graphics->init(initializer);
|
||||
TextureCreateInfo info;
|
||||
info.width = 4096;
|
||||
info.height = 4096;
|
||||
Gfx::PTexture2D testTexture = graphics->createTexture2D(info);
|
||||
UniformBufferCreateInfo uniformInitializer;
|
||||
uniformInitializer.resourceData.size = 4096;
|
||||
uniformInitializer.resourceData.data = new uint8[4096];
|
||||
for (int i = 0; i < 4096; ++i)
|
||||
{
|
||||
uniformInitializer.resourceData.data[i] = (uint8)i;
|
||||
}
|
||||
Gfx::PUniformBuffer testUniform = graphics->createUniformBuffer(uniformInitializer);
|
||||
}
|
||||
|
||||
WindowManager::~WindowManager()
|
||||
@@ -30,8 +30,13 @@ WindowManager::~WindowManager()
|
||||
|
||||
PWindow WindowManager::addWindow(const WindowCreateInfo &createInfo)
|
||||
{
|
||||
Gfx::PWindow handle = graphics->createWindow(createInfo);
|
||||
PWindow window = new Window(handle);
|
||||
windows.add(window);
|
||||
return window;
|
||||
Gfx::PWindow handle = graphics->createWindow(createInfo);
|
||||
PWindow window = new Window(this, handle);
|
||||
windows.add(window);
|
||||
return window;
|
||||
}
|
||||
|
||||
void WindowManager::notifyWindowClosed(PWindow window)
|
||||
{
|
||||
windows.remove(windows.find(window));
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ public:
|
||||
WindowManager();
|
||||
~WindowManager();
|
||||
PWindow addWindow(const WindowCreateInfo &createInfo);
|
||||
void notifyWindowClosed(PWindow window);
|
||||
static Gfx::PGraphics getGraphics()
|
||||
{
|
||||
return graphics;
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ using namespace Seele;
|
||||
int main()
|
||||
{
|
||||
PWindowManager windowManager = new WindowManager();
|
||||
AssetRegistry::init("D:\\Private\\Programming\\C++\\TestSeeleProject\\");
|
||||
AssetRegistry::init("/home/dynamitos/TestSeeleProject");
|
||||
WindowCreateInfo mainWindowInfo;
|
||||
mainWindowInfo.title = "SeeleEngine";
|
||||
mainWindowInfo.width = 1280;
|
||||
@@ -34,7 +34,7 @@ int main()
|
||||
PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo);
|
||||
window->addView(inspectorView);
|
||||
sceneView->setFocused();
|
||||
while(true)
|
||||
while(windowManager->isActive())
|
||||
{
|
||||
window->render();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user