Memory leak, but otherwise working
This commit is contained in:
+57
-57
@@ -13,72 +13,72 @@ struct SkyboxData
|
||||
layout(set=1)
|
||||
ParameterBlock<SkyboxData> pSkyboxData;
|
||||
|
||||
float3 vertices[] = {
|
||||
// Back
|
||||
float3(-512, -512, 512),
|
||||
float3(-512, 512, 512),
|
||||
float3( 512, -512, 512),
|
||||
|
||||
float3( 512, -512, 512),
|
||||
float3(-512, 512, 512),
|
||||
float3( 512, 512, 512),
|
||||
|
||||
// Front
|
||||
float3( 512, -512, -512),
|
||||
float3( 512, 512, -512),
|
||||
float3(-512, -512, -512),
|
||||
|
||||
float3(-512, -512, -512),
|
||||
float3( 512, 512, -512),
|
||||
float3(-512, 512, -512),
|
||||
|
||||
// Top
|
||||
float3(-512, -512, -512),
|
||||
float3(-512, -512, 512),
|
||||
float3( 512, -512, -512),
|
||||
|
||||
float3( 512, -512, -512),
|
||||
float3(-512, -512, 512),
|
||||
float3( 512, -512, 512),
|
||||
|
||||
// Bottom
|
||||
float3(-512, 512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3( 512, 512, 512),
|
||||
|
||||
float3( 512, 512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3( 512, 512, -512),
|
||||
|
||||
// Left
|
||||
float3(-512, -512, -512),
|
||||
float3(-512, 512, -512),
|
||||
float3(-512, -512, 512),
|
||||
|
||||
float3(-512, -512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3(-512, 512, 512),
|
||||
|
||||
// Right
|
||||
float3( 512, -512, 512),
|
||||
float3( 512, 512, 512),
|
||||
float3( 512, -512, -512),
|
||||
|
||||
float3( 512, -512, -512),
|
||||
float3( 512, 512, 512),
|
||||
float3( 512, 512, -512),
|
||||
};
|
||||
|
||||
[shader("vertex")]
|
||||
VertexShaderOutput vertexMain(
|
||||
uint vertexIndex : SV_VertexId)
|
||||
{
|
||||
const float3 vertices[] = {
|
||||
// Back
|
||||
float3(-512, -512, 512),
|
||||
float3(-512, 512, 512),
|
||||
float3( 512, -512, 512),
|
||||
|
||||
float3( 512, -512, 512),
|
||||
float3(-512, 512, 512),
|
||||
float3( 512, 512, 512),
|
||||
|
||||
// Front
|
||||
float3( 512, -512, -512),
|
||||
float3( 512, 512, -512),
|
||||
float3(-512, -512, -512),
|
||||
|
||||
float3(-512, -512, -512),
|
||||
float3( 512, 512, -512),
|
||||
float3(-512, 512, -512),
|
||||
|
||||
// Top
|
||||
float3(-512, -512, -512),
|
||||
float3(-512, -512, 512),
|
||||
float3( 512, -512, -512),
|
||||
|
||||
float3( 512, -512, -512),
|
||||
float3(-512, -512, 512),
|
||||
float3( 512, -512, 512),
|
||||
|
||||
// Bottom
|
||||
float3(-512, 512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3( 512, 512, 512),
|
||||
|
||||
float3( 512, 512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3( 512, 512, -512),
|
||||
|
||||
// Left
|
||||
float3(-512, -512, -512),
|
||||
float3(-512, 512, -512),
|
||||
float3(-512, -512, 512),
|
||||
|
||||
float3(-512, -512, 512),
|
||||
float3(-512, 512, -512),
|
||||
float3(-512, 512, 512),
|
||||
|
||||
// Right
|
||||
float3( 512, -512, 512),
|
||||
float3( 512, 512, 512),
|
||||
float3( 512, -512, -512),
|
||||
|
||||
float3( 512, -512, -512),
|
||||
float3( 512, 512, 512),
|
||||
float3( 512, 512, -512),
|
||||
};
|
||||
|
||||
VertexShaderOutput output;
|
||||
float3x3 cameraRotation = float3x3(pViewParams.viewMatrix);
|
||||
float4 worldPos = float4(mul(cameraRotation, vertices[vertexIndex]), 1.0f);
|
||||
//clip(dot(worldPos, clipPlane));
|
||||
output.clipPos = mul(pViewParams.projectionMatrix, worldPos);
|
||||
output.texCoords = normalize(input.position);
|
||||
output.texCoords = normalize(vertices[vertexIndex]);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -216,9 +216,8 @@ int main()
|
||||
mainWindowInfo.title = "SeeleEngine";
|
||||
mainWindowInfo.width = 1280;
|
||||
mainWindowInfo.height = 720;
|
||||
mainWindowInfo.bFullscreen = false;
|
||||
mainWindowInfo.numSamples = 1;
|
||||
mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
|
||||
mainWindowInfo.preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_SRGB;
|
||||
auto window = windowManager->addWindow(graphics, mainWindowInfo);
|
||||
ViewportCreateInfo sceneViewInfo;
|
||||
sceneViewInfo.dimensions.size.x = 1280;
|
||||
|
||||
@@ -746,12 +746,14 @@ public:
|
||||
}
|
||||
StaticArray(std::initializer_list<T> init)
|
||||
{
|
||||
assert(init.size() == N);
|
||||
auto beg = init.begin();
|
||||
for (size_t i = 0; i < N; ++i)
|
||||
{
|
||||
_data[i] = *beg;
|
||||
beg++;
|
||||
if (init.size() == N)
|
||||
{
|
||||
beg++;
|
||||
}
|
||||
}
|
||||
}
|
||||
~StaticArray()
|
||||
|
||||
@@ -179,7 +179,6 @@ public:
|
||||
, _size(std::move(other._size))
|
||||
, allocator(std::move(other.allocator))
|
||||
{
|
||||
other.clear();
|
||||
}
|
||||
List(List&& other, const Allocator& alloc)
|
||||
: root(std::move(other.root))
|
||||
|
||||
@@ -260,18 +260,6 @@ public:
|
||||
markIteratorsDirty();
|
||||
return getNode(root)->pair.value;
|
||||
}
|
||||
constexpr mapped_type& operator[](key_type&& key)
|
||||
{
|
||||
root = splay(root, std::move(key));
|
||||
if (!isValid(root) || !equal(getNode(root)->pair.key, key))
|
||||
{
|
||||
root = insert(root, std::move(key));
|
||||
_size++;
|
||||
}
|
||||
markIteratorsDirty();
|
||||
return getNode(root)->pair.value;
|
||||
}
|
||||
|
||||
constexpr const mapped_type& operator[](const key_type& key) const
|
||||
{
|
||||
size_t it = root;
|
||||
@@ -288,23 +276,6 @@ public:
|
||||
}
|
||||
return getNode(it)->pair.value;
|
||||
}
|
||||
constexpr const mapped_type& operator[](key_type&& key) const
|
||||
{
|
||||
size_t it = root;
|
||||
while (!equal(getNode(it)->pair.key, key))
|
||||
{
|
||||
if (comp(key, getNode(it)->pair.key))
|
||||
{
|
||||
it = getNode(it)->leftChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
it = getNode(it)->rightChild;
|
||||
}
|
||||
}
|
||||
return getNode(it)->pair.value;
|
||||
}
|
||||
|
||||
constexpr mapped_type& at(const key_type& key)
|
||||
{
|
||||
root = splay(root, key);
|
||||
@@ -361,6 +332,7 @@ public:
|
||||
{
|
||||
root = remove(root, key);
|
||||
refreshIterators();
|
||||
assert(root != SIZE_MAX || _size == 0);
|
||||
return iterator(root, &nodeContainer);
|
||||
}
|
||||
constexpr iterator erase(key_type&& key)
|
||||
@@ -528,7 +500,6 @@ private:
|
||||
endIndex = getNode(endIndex)->rightChild;
|
||||
}
|
||||
return Iterator(endIndex, &nodeContainer, std::move(endTraversal));
|
||||
|
||||
}
|
||||
Array<Node, NodeAlloc> nodeContainer = Array<Node, NodeAlloc>();
|
||||
size_t root;
|
||||
|
||||
@@ -28,7 +28,9 @@ target_sources(Engine
|
||||
Texture.h
|
||||
Texture.cpp
|
||||
VertexData.h
|
||||
VertexData.cpp)
|
||||
VertexData.cpp
|
||||
Window.h
|
||||
Window.cpp)
|
||||
|
||||
target_sources(Engine
|
||||
PUBLIC FILE_SET HEADERS
|
||||
@@ -47,7 +49,8 @@ target_sources(Engine
|
||||
Shader.h
|
||||
StaticMeshVertexData.h
|
||||
Texture.h
|
||||
VertexData.h)
|
||||
VertexData.h
|
||||
Window.h)
|
||||
|
||||
add_subdirectory(RenderPass/)
|
||||
add_subdirectory(Vulkan/)
|
||||
@@ -8,12 +8,12 @@ LegacyPipelineCreateInfo::LegacyPipelineCreateInfo()
|
||||
: topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
|
||||
, multisampleState(MultisampleState{
|
||||
.samples = 1,
|
||||
})
|
||||
})
|
||||
, rasterizationState(RasterizationState{
|
||||
.polygonMode = Gfx::SE_POLYGON_MODE_FILL,
|
||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||
.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||
})
|
||||
})
|
||||
, depthStencilState(DepthStencilState{
|
||||
.depthTestEnable = true,
|
||||
.depthWriteEnable = true,
|
||||
@@ -21,7 +21,7 @@ LegacyPipelineCreateInfo::LegacyPipelineCreateInfo()
|
||||
.stencilTestEnable = false,
|
||||
.minDepthBounds = 0.0f,
|
||||
.maxDepthBounds = 1.0f,
|
||||
})
|
||||
})
|
||||
, colorBlend(ColorBlendState{
|
||||
.logicOpEnable = false,
|
||||
.attachmentCount = 0,
|
||||
@@ -40,7 +40,7 @@ LegacyPipelineCreateInfo::LegacyPipelineCreateInfo()
|
||||
1.0f,
|
||||
1.0f,
|
||||
},
|
||||
})
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -36,9 +36,8 @@ struct WindowCreateInfo
|
||||
int32 width;
|
||||
int32 height;
|
||||
const char *title;
|
||||
bool bFullscreen;
|
||||
Gfx::SeSampleCountFlags numSamples;
|
||||
Gfx::SeFormat pixelFormat;
|
||||
Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_MAX_ENUM;
|
||||
void *windowHandle;
|
||||
};
|
||||
struct ViewportCreateInfo
|
||||
|
||||
@@ -48,9 +48,6 @@ void BasePass::beginFrame(const Component::Camera& cam)
|
||||
RenderPass::beginFrame(cam);
|
||||
|
||||
lightCullingLayout->reset();
|
||||
descriptorSets[INDEX_VIEW_PARAMS] = viewParamsSet;
|
||||
descriptorSets[INDEX_LIGHT_ENV] = scene->getLightEnvironment()->getDescriptorSet();
|
||||
descriptorSets[INDEX_LIGHT_CULLING] = lightCullingLayout->allocateDescriptorSet();
|
||||
}
|
||||
|
||||
void BasePass::render()
|
||||
@@ -68,6 +65,10 @@ void BasePass::render()
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
descriptorSets[INDEX_VIEW_PARAMS] = viewParamsSet;
|
||||
descriptorSets[INDEX_LIGHT_ENV] = scene->getLightEnvironment()->getDescriptorSet();
|
||||
descriptorSets[INDEX_LIGHT_CULLING] = lightCullingLayout->allocateDescriptorSet();
|
||||
|
||||
descriptorSets[INDEX_LIGHT_CULLING]->updateBuffer(0, oLightIndexList);
|
||||
descriptorSets[INDEX_LIGHT_CULLING]->updateBuffer(1, tLightIndexList);
|
||||
descriptorSets[INDEX_LIGHT_CULLING]->updateTexture(2, oLightGrid);
|
||||
|
||||
@@ -145,8 +145,8 @@ void DepthPrepass::publishOutputs()
|
||||
// still match the size of the whole image or their coordinate systems go out of sync
|
||||
TextureCreateInfo depthBufferInfo = {
|
||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||
.width = viewport->getOwner()->getWidth(),
|
||||
.height = viewport->getOwner()->getHeight(),
|
||||
.width = viewport->getOwner()->getFramebufferWidth(),
|
||||
.height = viewport->getOwner()->getFramebufferHeight(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
};
|
||||
depthBuffer = graphics->createTexture2D(depthBufferInfo);
|
||||
|
||||
@@ -51,7 +51,6 @@ void SkyboxRenderPass::render()
|
||||
renderCommand->setViewport(viewport);
|
||||
renderCommand->bindPipeline(pipeline);
|
||||
renderCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
|
||||
renderCommand->bindVertexBuffer({ cubeBuffer });
|
||||
renderCommand->draw(36, 1, 0, 0);
|
||||
graphics->executeCommands(Array{ renderCommand });
|
||||
graphics->endRenderPass();
|
||||
|
||||
@@ -3,40 +3,6 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
Window::Window(const WindowCreateInfo& createInfo)
|
||||
: windowState(createInfo)
|
||||
{
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
}
|
||||
|
||||
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
||||
: sizeX(std::min(owner->getWidth(), viewportInfo.dimensions.size.x))
|
||||
, sizeY(std::min(owner->getHeight(), viewportInfo.dimensions.size.y))
|
||||
, offsetX(viewportInfo.dimensions.offset.x)
|
||||
, offsetY(viewportInfo.dimensions.offset.y)
|
||||
, fieldOfView(viewportInfo.fieldOfView)
|
||||
, owner(owner)
|
||||
{
|
||||
}
|
||||
|
||||
Viewport::~Viewport()
|
||||
{
|
||||
}
|
||||
|
||||
Matrix4 Viewport::getProjectionMatrix() const
|
||||
{
|
||||
if (fieldOfView > 0.0f)
|
||||
{
|
||||
return glm::perspective(fieldOfView, sizeX / static_cast<float>(sizeY), 0.1f, 1000.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f);
|
||||
}
|
||||
}
|
||||
RenderTargetAttachment::RenderTargetAttachment(PTexture2D texture,
|
||||
SeAttachmentLoadOp loadOp,
|
||||
SeAttachmentStoreOp storeOp,
|
||||
|
||||
@@ -1,71 +1,12 @@
|
||||
#pragma once
|
||||
#include "Resources.h"
|
||||
#include "Texture.h"
|
||||
#include "Window.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
Window(const WindowCreateInfo &createInfo);
|
||||
virtual ~Window();
|
||||
virtual void beginFrame() = 0;
|
||||
virtual void endFrame() = 0;
|
||||
virtual void onWindowCloseEvent() = 0;
|
||||
virtual PTexture2D getBackBuffer() = 0;
|
||||
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) = 0;
|
||||
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) = 0;
|
||||
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) = 0;
|
||||
virtual void setScrollCallback(std::function<void(double, double)> callback) = 0;
|
||||
virtual void setFileCallback(std::function<void(int, const char**)> callback) = 0;
|
||||
virtual void setCloseCallback(std::function<void()> callback) = 0;
|
||||
constexpr SeFormat getSwapchainFormat() const
|
||||
{
|
||||
return windowState.pixelFormat;
|
||||
}
|
||||
constexpr SeSampleCountFlags getNumSamples() const
|
||||
{
|
||||
return windowState.numSamples;
|
||||
}
|
||||
constexpr uint32 getWidth() const
|
||||
{
|
||||
return windowState.width;
|
||||
}
|
||||
constexpr uint32 getHeight() const
|
||||
{
|
||||
return windowState.height;
|
||||
}
|
||||
|
||||
protected:
|
||||
WindowCreateInfo windowState;
|
||||
};
|
||||
DEFINE_REF(Window)
|
||||
|
||||
class Viewport
|
||||
{
|
||||
public:
|
||||
Viewport(PWindow owner, const ViewportCreateInfo &createInfo);
|
||||
virtual ~Viewport();
|
||||
virtual void resize(uint32 newX, uint32 newY) = 0;
|
||||
virtual void move(uint32 newOffsetX, uint32 newOffsetY) = 0;
|
||||
constexpr PWindow getOwner() const {return owner;}
|
||||
constexpr uint32 getWidth() const {return sizeX;}
|
||||
constexpr uint32 getHeight() const {return sizeY;}
|
||||
constexpr uint32 getOffsetX() const {return offsetX;}
|
||||
constexpr uint32 getOffsetY() const {return offsetY;}
|
||||
Matrix4 getProjectionMatrix() const;
|
||||
protected:
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
uint32 offsetX;
|
||||
uint32 offsetY;
|
||||
float fieldOfView;
|
||||
PWindow owner;
|
||||
};
|
||||
DEFINE_REF(Viewport)
|
||||
|
||||
class RenderTargetAttachment
|
||||
{
|
||||
public:
|
||||
@@ -133,11 +74,11 @@ public:
|
||||
}
|
||||
virtual uint32 getWidth() const
|
||||
{
|
||||
return owner->getWidth();
|
||||
return owner->getFramebufferWidth();
|
||||
}
|
||||
virtual uint32 getHeight() const
|
||||
{
|
||||
return owner->getHeight();
|
||||
return owner->getFramebufferHeight();
|
||||
}
|
||||
private:
|
||||
PWindow owner;
|
||||
|
||||
@@ -44,8 +44,9 @@ Allocation::Allocation(PGraphics graphics, PAllocator pool, VkDeviceSize size, u
|
||||
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
|
||||
: device(graphics->getDevice())
|
||||
, pool(pool)
|
||||
, bytesAllocated(0)
|
||||
, bytesAllocated(size)
|
||||
, bytesUsed(0)
|
||||
, mappedPointer(nullptr)
|
||||
, canMap((properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
|
||||
, isMapped(false)
|
||||
, properties(properties)
|
||||
@@ -59,9 +60,7 @@ Allocation::Allocation(PGraphics graphics, PAllocator pool, VkDeviceSize size, u
|
||||
};
|
||||
isDedicated = dedicatedInfo != nullptr;
|
||||
VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory));
|
||||
bytesAllocated = size;
|
||||
freeRanges[0] = size;
|
||||
|
||||
}
|
||||
|
||||
Allocation::~Allocation()
|
||||
@@ -95,6 +94,7 @@ OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
|
||||
VkDeviceSize allocatedSize = requestedSize + (alignedOffset - lower);
|
||||
if (size >= allocatedSize)
|
||||
{
|
||||
//std::cout << "Allocating " << lower << "-" << lower + allocatedSize << std::endl;
|
||||
VkDeviceSize newSize = size - allocatedSize;
|
||||
VkDeviceSize newLower = lower + allocatedSize;
|
||||
OSubAllocation alloc = new SubAllocation(this, requestedSize, lower, allocatedSize, alignedOffset);
|
||||
@@ -113,6 +113,7 @@ OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
|
||||
|
||||
void Allocation::markFree(PSubAllocation allocation)
|
||||
{
|
||||
//std::cout << "Freeing " << allocation->allocatedOffset << "-" << allocation->allocatedOffset + allocation->allocatedSize << std::endl;
|
||||
assert(activeAllocations.find(allocation) != activeAllocations.end());
|
||||
VkDeviceSize lowerBound = allocation->allocatedOffset;
|
||||
VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize;
|
||||
@@ -121,7 +122,7 @@ void Allocation::markFree(PSubAllocation allocation)
|
||||
{
|
||||
if (lower + size == lowerBound)
|
||||
{
|
||||
freeRanges[lower] = upperBound;
|
||||
freeRanges[lower] = size + allocation->allocatedSize;
|
||||
freeRanges.erase(lowerBound);
|
||||
lowerBound = lower;
|
||||
break;
|
||||
@@ -134,10 +135,6 @@ void Allocation::markFree(PSubAllocation allocation)
|
||||
}
|
||||
activeAllocations.remove(allocation, false);
|
||||
bytesUsed -= allocation->allocatedSize;
|
||||
if (bytesUsed == 0)
|
||||
{
|
||||
pool->free(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Allocation::flushMemory()
|
||||
@@ -205,7 +202,7 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
|
||||
{
|
||||
OAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
|
||||
heaps[heapIndex].inUse += newAllocation->bytesAllocated;
|
||||
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
|
||||
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
|
||||
heaps[heapIndex].allocations.add(std::move(newAllocation));
|
||||
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
|
||||
}
|
||||
@@ -225,7 +222,7 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
|
||||
// no suitable allocations found, allocate new block
|
||||
OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > DEFAULT_ALLOCATION) ? requirements.size : DEFAULT_ALLOCATION, memoryTypeIndex, properties, nullptr);
|
||||
heaps[heapIndex].inUse += newAllocation->bytesAllocated;
|
||||
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
|
||||
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
|
||||
heaps[heapIndex].allocations.add(std::move(newAllocation));
|
||||
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
|
||||
}
|
||||
@@ -240,7 +237,7 @@ void Allocator::free(PAllocation allocation)
|
||||
if (heaps[heapIndex].allocations[alloc] == allocation)
|
||||
{
|
||||
heaps[heapIndex].inUse -= allocation->bytesAllocated;
|
||||
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
|
||||
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
|
||||
heaps[heapIndex].allocations.removeAt(alloc, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ target_sources(Engine
|
||||
Queue.cpp
|
||||
RenderPass.h
|
||||
RenderPass.cpp
|
||||
RenderTarget.h
|
||||
RenderTarget.cpp
|
||||
Resources.h
|
||||
Resources.cpp
|
||||
Shader.h
|
||||
Shader.cpp
|
||||
Texture.h
|
||||
Texture.cpp)
|
||||
Texture.cpp
|
||||
Window.h
|
||||
Window.cpp)
|
||||
|
||||
target_sources(Engine
|
||||
PUBLIC FILE_SET HEADERS
|
||||
@@ -48,8 +48,8 @@ target_sources(Engine
|
||||
PipelineCache.h
|
||||
Queue.h
|
||||
RenderPass.h
|
||||
RenderTarget.h
|
||||
Resources.h
|
||||
Shader.h
|
||||
Texture.h)
|
||||
Texture.h
|
||||
Window.h)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "RenderPass.h"
|
||||
#include "Pipeline.h"
|
||||
#include "Descriptor.h"
|
||||
#include "RenderTarget.h"
|
||||
#include "Window.h"
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace Seele;
|
||||
@@ -58,7 +58,8 @@ void Command::end()
|
||||
void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
|
||||
{
|
||||
assert(state == State::Begin);
|
||||
|
||||
boundRenderPass = renderPass;
|
||||
boundFramebuffer = framebuffer;
|
||||
VkRenderPassBeginInfo beginInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -74,6 +75,8 @@ void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
|
||||
|
||||
void Command::endRenderPass()
|
||||
{
|
||||
boundRenderPass = nullptr;
|
||||
boundFramebuffer = nullptr;
|
||||
vkCmdEndRenderPass(handle);
|
||||
state = State::Begin;
|
||||
}
|
||||
@@ -148,6 +151,7 @@ void Command::checkFence()
|
||||
for(auto& descriptor : boundDescriptors)
|
||||
{
|
||||
descriptor->unbind();
|
||||
//std::cout << "Unbinding descriptor " << descriptor.cast<DescriptorSet>()->getHandle() << " to cmd " << handle << std::endl;
|
||||
}
|
||||
boundDescriptors.clear();
|
||||
graphics->getDestructionManager()->notifyCmdComplete(this);
|
||||
@@ -282,6 +286,7 @@ void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorS
|
||||
assert(descriptorSet->writeDescriptors.size() == 0);
|
||||
descriptorSet->bind();
|
||||
|
||||
//std::cout << "Binding descriptor " << descriptorSet->getHandle() << " to cmd " << handle << std::endl;
|
||||
boundDescriptors.add(descriptorSet.getHandle());
|
||||
sets[descriptorSet->getSetIndex()] = descriptorSet->getHandle();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "PipelineCache.h"
|
||||
#include "Command.h"
|
||||
#include "Descriptor.h"
|
||||
#include "RenderTarget.h"
|
||||
#include "Window.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "Shader.h"
|
||||
|
||||
@@ -23,8 +23,7 @@ void Queue::submitCommandBuffer(PCommand command, uint32 numSignalSemaphores, Vk
|
||||
std::unique_lock lock(queueLock);
|
||||
assert(command->state == Command::State::End);
|
||||
|
||||
PFence fence = command->fence;
|
||||
assert(!fence->isSignaled());
|
||||
assert(!(command->fence->isSignaled()));
|
||||
|
||||
VkCommandBuffer cmdHandle = command->handle;
|
||||
|
||||
@@ -49,15 +48,15 @@ void Queue::submitCommandBuffer(PCommand command, uint32 numSignalSemaphores, Vk
|
||||
.pSignalSemaphores = signalSemaphores,
|
||||
};
|
||||
|
||||
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, fence->getHandle()));
|
||||
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, command->fence->getHandle()));
|
||||
command->state = Command::State::Submit;
|
||||
command->waitFlags.clear();
|
||||
command->waitSemaphores.clear();
|
||||
|
||||
if (Gfx::waitIdleOnSubmit)
|
||||
{
|
||||
fence->wait(200 * 1000ull);
|
||||
command->fence->wait(200 * 1000ull);
|
||||
}
|
||||
|
||||
command->checkFence();
|
||||
command->checkFence();
|
||||
}
|
||||
@@ -121,7 +121,15 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::ORenderTargetLayout _layout, Gfx
|
||||
};
|
||||
|
||||
VK_CHECK(vkCreateRenderPass(graphics->getDevice(), &info, nullptr, &renderPass));
|
||||
}
|
||||
|
||||
RenderPass::~RenderPass()
|
||||
{
|
||||
vkDestroyRenderPass(graphics->getDevice(), renderPass, nullptr);
|
||||
}
|
||||
|
||||
uint32 RenderPass::getFramebufferHash()
|
||||
{
|
||||
FramebufferDescription description;
|
||||
std::memset(&description, 0, sizeof(FramebufferDescription));
|
||||
for (auto& inputAttachment : layout->inputAttachments)
|
||||
@@ -139,11 +147,5 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::ORenderTargetLayout _layout, Gfx
|
||||
PTexture2D tex = layout->depthAttachment->getTexture().cast<Texture2D>();
|
||||
description.depthAttachment = tex->getView();
|
||||
}
|
||||
framebufferHash = CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
|
||||
return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
|
||||
}
|
||||
|
||||
RenderPass::~RenderPass()
|
||||
{
|
||||
vkDestroyRenderPass(graphics->getDevice(), renderPass, nullptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,7 @@ class RenderPass : public Gfx::RenderPass
|
||||
public:
|
||||
RenderPass(PGraphics graphics, Gfx::ORenderTargetLayout layout, Gfx::PViewport viewport);
|
||||
virtual ~RenderPass();
|
||||
constexpr uint32 getFramebufferHash() const
|
||||
{
|
||||
return framebufferHash;
|
||||
}
|
||||
uint32 getFramebufferHash();
|
||||
constexpr VkRenderPass getHandle() const
|
||||
{
|
||||
return renderPass;
|
||||
|
||||
@@ -1,412 +0,0 @@
|
||||
#include "RenderTarget.h"
|
||||
#include "Resources.h"
|
||||
#include "Graphics.h"
|
||||
#include "Enums.h"
|
||||
#include "Command.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
double currentFrameDelta = 0;
|
||||
double Gfx::getCurrentFrameDelta()
|
||||
{
|
||||
return currentFrameDelta;
|
||||
}
|
||||
|
||||
void glfwKeyCallback(GLFWwindow* handle, int key, int, int action, int modifier)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->keyCallback((KeyCode)key, (InputAction)action, (KeyModifier)modifier);
|
||||
}
|
||||
|
||||
void glfwMouseMoveCallback(GLFWwindow* handle, double xpos, double ypos)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->mouseMoveCallback(xpos, ypos);
|
||||
}
|
||||
|
||||
void glfwMouseButtonCallback(GLFWwindow* handle, int button, int action, int modifier)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->mouseButtonCallback((MouseButton)button, (InputAction)action, (KeyModifier)modifier);
|
||||
}
|
||||
|
||||
void glfwScrollCallback(GLFWwindow* handle, double xoffset, double yoffset)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->scrollCallback(xoffset, yoffset);
|
||||
}
|
||||
|
||||
void glfwFileCallback(GLFWwindow* handle, int count, const char** paths)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
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)
|
||||
, instance(graphics->getInstance())
|
||||
, swapchain(VK_NULL_HANDLE)
|
||||
, numSamples(createInfo.numSamples)
|
||||
{
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow *handle = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, createInfo.bFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr);
|
||||
windowHandle = handle;
|
||||
glfwSetWindowUserPointer(handle, this);
|
||||
glfwGetWindowSize(handle, &windowState.width, &windowState.height);
|
||||
|
||||
glfwSetKeyCallback(handle, &glfwKeyCallback);
|
||||
glfwSetCursorPosCallback(handle, &glfwMouseMoveCallback);
|
||||
glfwSetMouseButtonCallback(handle, &glfwMouseButtonCallback);
|
||||
glfwSetScrollCallback(handle, &glfwScrollCallback);
|
||||
glfwSetDropCallback(handle, &glfwFileCallback);
|
||||
glfwSetWindowCloseCallback(handle, &glfwCloseCallback);
|
||||
|
||||
glfwCreateWindowSurface(instance, handle, nullptr, &surface);
|
||||
|
||||
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(windowState);
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
vkDestroySwapchainKHR(graphics->getDevice(), swapchain, nullptr);
|
||||
vkDestroySurfaceKHR(instance, surface, nullptr);
|
||||
glfwDestroyWindow(static_cast<GLFWwindow *>(windowHandle));
|
||||
}
|
||||
|
||||
void Window::beginFrame()
|
||||
{
|
||||
glfwPollEvents();
|
||||
advanceBackBuffer();
|
||||
}
|
||||
|
||||
void Window::endFrame()
|
||||
{
|
||||
present();
|
||||
}
|
||||
|
||||
void Window::onWindowCloseEvent()
|
||||
{
|
||||
}
|
||||
|
||||
Gfx::PTexture2D Window::getBackBuffer()
|
||||
{
|
||||
return PTexture2D(backBufferImages[currentImageIndex]);
|
||||
}
|
||||
|
||||
void Window::setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback)
|
||||
{
|
||||
keyCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setMouseMoveCallback(std::function<void(double, double)> callback)
|
||||
{
|
||||
mouseMoveCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback)
|
||||
{
|
||||
mouseButtonCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setScrollCallback(std::function<void(double, double)> callback)
|
||||
{
|
||||
scrollCallback = callback;
|
||||
}
|
||||
|
||||
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;
|
||||
uint32 imageIndex = 0;
|
||||
const int32 prevSemaphoreIndex = semaphoreIndex;
|
||||
semaphoreIndex = (semaphoreIndex + 1) % Gfx::numFramesBuffered;
|
||||
|
||||
while (res != VK_SUCCESS)
|
||||
{
|
||||
res = vkAcquireNextImageKHR(
|
||||
graphics->getDevice(),
|
||||
swapchain,
|
||||
UINT64_MAX,
|
||||
imageAcquired[semaphoreIndex]->getHandle(),
|
||||
VK_NULL_HANDLE,
|
||||
&imageIndex);
|
||||
if (res == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
{
|
||||
semaphoreIndex = prevSemaphoreIndex;
|
||||
}
|
||||
if (res == VK_ERROR_SURFACE_LOST_KHR)
|
||||
{
|
||||
semaphoreIndex = prevSemaphoreIndex;
|
||||
}
|
||||
}
|
||||
imageAcquiredSemaphore = imageAcquired[semaphoreIndex];
|
||||
currentImageIndex = imageIndex;
|
||||
|
||||
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
VkClearColorValue clearColor = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
PCommand command = graphics->getGraphicsCommands()->getCommands();
|
||||
VkImageSubresourceRange range = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
};
|
||||
vkCmdClearColorImage(
|
||||
command->getHandle(),
|
||||
backBufferHandles[currentImageIndex],
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
&clearColor,
|
||||
1,
|
||||
&range);
|
||||
|
||||
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
|
||||
graphics->getGraphicsCommands()->submitCommands();
|
||||
}
|
||||
|
||||
void Window::recreateSwapchain(const WindowCreateInfo &windowInfo)
|
||||
{
|
||||
destroySwapchain();
|
||||
windowState = windowInfo;
|
||||
uint32_t numFormats;
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(graphics->getPhysicalDevice(), surface, &numFormats, nullptr));
|
||||
Array<VkSurfaceFormatKHR> formats(numFormats);
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(graphics->getPhysicalDevice(), surface, &numFormats, formats.data()));
|
||||
|
||||
uint32_t numPresentModes;
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(graphics->getPhysicalDevice(), surface, &numPresentModes, nullptr));
|
||||
Array<VkPresentModeKHR> modes(numPresentModes);
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(graphics->getPhysicalDevice(), surface, &numPresentModes, modes.data()));
|
||||
|
||||
chooseSurfaceFormat(formats, windowInfo.pixelFormat);
|
||||
choosePresentMode(modes);
|
||||
createSwapchain();
|
||||
}
|
||||
|
||||
static uint32_t currentFrameIndex = 0;
|
||||
|
||||
void Window::present()
|
||||
{
|
||||
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
graphics->getGraphicsCommands()->submitCommands(renderFinished[currentImageIndex]);
|
||||
VkSemaphore renderFinishedHandle = renderFinished[currentImageIndex]->getHandle();
|
||||
VkPresentInfoKHR info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.pNext = nullptr,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &renderFinishedHandle,
|
||||
.swapchainCount = 1,
|
||||
.pSwapchains = &swapchain,
|
||||
.pImageIndices = (uint32*)¤tImageIndex,
|
||||
.pResults = 0,
|
||||
};
|
||||
VkResult presentResult = VK_ERROR_OUT_OF_DATE_KHR;
|
||||
// Trial and error
|
||||
while (presentResult != VK_SUCCESS)
|
||||
{
|
||||
presentResult = vkQueuePresentKHR(graphics->getGraphicsCommands()->getQueue()->getHandle(), &info);
|
||||
}
|
||||
currentFrameIndex = (currentFrameIndex + 1) % Gfx::numFramesBuffered;
|
||||
static double lastFrameTime = 0.f;
|
||||
double currentTime = glfwGetTime();
|
||||
double currentDelta = currentTime - lastFrameTime;
|
||||
currentFrameDelta = currentDelta;
|
||||
lastFrameTime = currentTime;
|
||||
}
|
||||
|
||||
void Window::createSwapchain()
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR surfProperties;
|
||||
VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(graphics->getPhysicalDevice(), surface, &surfProperties));
|
||||
|
||||
uint32 desiredNumBuffers = Gfx::numFramesBuffered;
|
||||
if (desiredNumBuffers < surfProperties.minImageCount)
|
||||
{
|
||||
throw new std::logic_error("Trying to buffer less than the minimal number of frames");
|
||||
}
|
||||
if (desiredNumBuffers > surfProperties.maxImageCount)
|
||||
{
|
||||
throw new std::logic_error("Trying to buffer more than the maximum number of frames");
|
||||
}
|
||||
|
||||
VkSwapchainCreateInfoKHR swapchainInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.surface = surface,
|
||||
.minImageCount = desiredNumBuffers,
|
||||
.imageFormat = surfaceFormat.format,
|
||||
.imageColorSpace = surfaceFormat.colorSpace,
|
||||
.imageExtent = {
|
||||
.width = getWidth(),
|
||||
.height = getHeight(),
|
||||
},
|
||||
.imageArrayLayers = 1,
|
||||
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
|
||||
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
||||
.presentMode = presentMode,
|
||||
.clipped = VK_TRUE,
|
||||
};
|
||||
VK_CHECK(vkCreateSwapchainKHR(graphics->getDevice(), &swapchainInfo, nullptr, &swapchain));
|
||||
|
||||
uint32 numSwapchainImages;
|
||||
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, nullptr));
|
||||
Array<VkImage> swapchainImages(numSwapchainImages);
|
||||
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, swapchainImages.data()));
|
||||
|
||||
|
||||
TextureCreateInfo backBufferCreateInfo = {
|
||||
.sourceData = {
|
||||
.owner = Gfx::QueueType::GRAPHICS,
|
||||
},
|
||||
.format = cast(surfaceFormat.format),
|
||||
.width = getWidth(),
|
||||
.height = getHeight(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
};
|
||||
for (uint32 i = 0; i < numSwapchainImages; ++i)
|
||||
{
|
||||
imageAcquired[i] = new Semaphore(graphics);
|
||||
renderFinished[i] = new Semaphore(graphics);
|
||||
backBufferImages[i] = new Texture2D(graphics, backBufferCreateInfo, swapchainImages[i]);
|
||||
backBufferHandles[i] = swapchainImages[i];
|
||||
|
||||
VkClearColorValue clearColor;
|
||||
std::memset(&clearColor, 0, sizeof(VkClearColorValue));
|
||||
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
VkImageSubresourceRange range = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
};
|
||||
PCommand command = graphics->getGraphicsCommands()->getCommands();
|
||||
vkCmdClearColorImage(command->getHandle(), backBufferHandles[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
|
||||
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
graphics->getGraphicsCommands()->submitCommands();
|
||||
currentImageIndex = -1;
|
||||
}
|
||||
|
||||
void Window::destroySwapchain()
|
||||
{
|
||||
if (swapchain != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroySwapchainKHR(graphics->getDevice(), swapchain, nullptr);
|
||||
}
|
||||
for (uint32 i = 0; i < Gfx::numFramesBuffered; ++i)
|
||||
{
|
||||
imageAcquired[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Window::chooseSurfaceFormat(const Array<VkSurfaceFormatKHR> &available, Gfx::SeFormat preferred)
|
||||
{
|
||||
VkFormat preferredFormat = cast(preferred);
|
||||
for (auto availabeFormat : available)
|
||||
{
|
||||
if (availabeFormat.format == preferredFormat)
|
||||
{
|
||||
surfaceFormat = availabeFormat;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (available.size() == 1 && available[0].format == VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
surfaceFormat = {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
|
||||
return;
|
||||
}
|
||||
for (const auto &availableFormat : available)
|
||||
{
|
||||
if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
||||
{
|
||||
surfaceFormat = availableFormat;
|
||||
return;
|
||||
}
|
||||
}
|
||||
surfaceFormat = available[0];
|
||||
}
|
||||
void Window::choosePresentMode(const Array<VkPresentModeKHR> &modes)
|
||||
{
|
||||
for (auto mode : modes)
|
||||
{
|
||||
if (mode == VK_PRESENT_MODE_MAILBOX_KHR)
|
||||
{
|
||||
presentMode = mode;
|
||||
return;
|
||||
}
|
||||
}
|
||||
presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||
}
|
||||
|
||||
Viewport::Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &viewportInfo)
|
||||
: Gfx::Viewport(owner, viewportInfo), graphics(graphics)
|
||||
{
|
||||
handle.width = static_cast<float>(sizeX);
|
||||
handle.height = static_cast<float>(sizeY);
|
||||
handle.x = static_cast<float>(offsetX);
|
||||
handle.y = static_cast<float>(offsetY) + handle.height;
|
||||
handle.height = -handle.height;
|
||||
handle.minDepth = 0.f;
|
||||
handle.maxDepth = 1.f;
|
||||
}
|
||||
|
||||
Viewport::~Viewport()
|
||||
{
|
||||
}
|
||||
|
||||
void Viewport::resize(uint32 newX, uint32 newY)
|
||||
{
|
||||
sizeX = newX;
|
||||
sizeY = newY;
|
||||
handle.width = static_cast<float>(sizeX);
|
||||
handle.y = static_cast<float>(sizeY + offsetX);
|
||||
handle.height = -static_cast<float>(sizeY);
|
||||
}
|
||||
|
||||
void Viewport::move(uint32 newOffsetX, uint32 newOffsetY)
|
||||
{
|
||||
offsetX = newOffsetX;
|
||||
offsetY = newOffsetY;
|
||||
handle.x = static_cast<float>(offsetX);
|
||||
handle.y = static_cast<float>(offsetY + sizeY);
|
||||
}
|
||||
@@ -197,7 +197,9 @@ void TextureBase::changeLayout(Gfx::SeImageLayout newLayout)
|
||||
.image = image,
|
||||
.subresourceRange = {
|
||||
.aspectMask = aspect,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = layerCount,
|
||||
},
|
||||
};
|
||||
@@ -328,6 +330,10 @@ void TextureBase::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStag
|
||||
.image = image,
|
||||
.subresourceRange = {
|
||||
.aspectMask = aspect,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
};
|
||||
PCommand command = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
#include "Window.h"
|
||||
#include "Resources.h"
|
||||
#include "Graphics.h"
|
||||
#include "Enums.h"
|
||||
#include "Command.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
double currentFrameDelta = 0;
|
||||
double Gfx::getCurrentFrameDelta()
|
||||
{
|
||||
return currentFrameDelta;
|
||||
}
|
||||
|
||||
void glfwKeyCallback(GLFWwindow* handle, int key, int, int action, int modifier)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->keyCallback((KeyCode)key, (InputAction)action, (KeyModifier)modifier);
|
||||
}
|
||||
|
||||
void glfwMouseMoveCallback(GLFWwindow* handle, double xpos, double ypos)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->mouseMoveCallback(xpos, ypos);
|
||||
}
|
||||
|
||||
void glfwMouseButtonCallback(GLFWwindow* handle, int button, int action, int modifier)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->mouseButtonCallback((MouseButton)button, (InputAction)action, (KeyModifier)modifier);
|
||||
}
|
||||
|
||||
void glfwScrollCallback(GLFWwindow* handle, double xoffset, double yoffset)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->scrollCallback(xoffset, yoffset);
|
||||
}
|
||||
|
||||
void glfwFileCallback(GLFWwindow* handle, int count, const char** paths)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->fileCallback(count, paths);
|
||||
}
|
||||
|
||||
void glfwCloseCallback(GLFWwindow* handle)
|
||||
{
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->closeCallback();
|
||||
}
|
||||
|
||||
Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
|
||||
: graphics(graphics)
|
||||
, preferences(createInfo)
|
||||
, instance(graphics->getInstance())
|
||||
, swapchain(VK_NULL_HANDLE)
|
||||
, numSamples(createInfo.numSamples)
|
||||
{
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow *handle = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, nullptr, nullptr);
|
||||
windowHandle = handle;
|
||||
glfwSetWindowUserPointer(handle, this);
|
||||
|
||||
glfwSetKeyCallback(handle, &glfwKeyCallback);
|
||||
glfwSetCursorPosCallback(handle, &glfwMouseMoveCallback);
|
||||
glfwSetMouseButtonCallback(handle, &glfwMouseButtonCallback);
|
||||
glfwSetScrollCallback(handle, &glfwScrollCallback);
|
||||
glfwSetDropCallback(handle, &glfwFileCallback);
|
||||
glfwSetWindowCloseCallback(handle, &glfwCloseCallback);
|
||||
|
||||
glfwCreateWindowSurface(instance, handle, nullptr, &surface);
|
||||
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(graphics->getPhysicalDevice(), surface, &capabilities);
|
||||
|
||||
uint32 numFormats;
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(graphics->getPhysicalDevice(), surface, &numFormats, nullptr);
|
||||
supportedFormats.resize(numFormats);
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(graphics->getPhysicalDevice(), surface, &numFormats, supportedFormats.data());
|
||||
|
||||
uint32 numPresentModes;
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(graphics->getPhysicalDevice(), surface, &numPresentModes, nullptr);
|
||||
supportedPresentModes.resize(numFormats);
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(graphics->getPhysicalDevice(), surface, &numPresentModes, supportedPresentModes.data());
|
||||
chooseSwapSurfaceFormat();
|
||||
framebufferFormat = cast(format.format);
|
||||
chooseSwapPresentMode();
|
||||
chooseSwapExtent();
|
||||
framebufferWidth = extent.width;
|
||||
framebufferHeight = extent.height;
|
||||
sampleFlags = createInfo.numSamples;
|
||||
createSwapChain();
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
vkDestroySwapchainKHR(graphics->getDevice(), swapchain, nullptr);
|
||||
vkDestroySurfaceKHR(instance, surface, nullptr);
|
||||
glfwDestroyWindow(static_cast<GLFWwindow *>(windowHandle));
|
||||
}
|
||||
|
||||
void Window::beginFrame()
|
||||
{
|
||||
glfwPollEvents();
|
||||
vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits<uint64>::max(), imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(), VK_NULL_HANDLE, ¤tImageIndex);
|
||||
swapChainTextures[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, imageAvailableSemaphores[currentSemaphoreIndex]);
|
||||
}
|
||||
|
||||
void Window::endFrame()
|
||||
{
|
||||
swapChainTextures[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||
graphics->getGraphicsCommands()->submitCommands(renderingDoneSemaphores[currentSemaphoreIndex]);
|
||||
VkSemaphore renderDoneHandle = renderingDoneSemaphores[currentSemaphoreIndex]->getHandle();
|
||||
VkPresentInfoKHR presentInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.pNext = nullptr,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &renderDoneHandle,
|
||||
.swapchainCount = 1,
|
||||
.pSwapchains = &swapchain,
|
||||
.pImageIndices = ¤tImageIndex,
|
||||
.pResults = nullptr,
|
||||
};
|
||||
VkResult r = vkQueuePresentKHR(graphics->getGraphicsCommands()->getQueue()->getHandle(), &presentInfo);
|
||||
if(r == VK_SUCCESS)
|
||||
{ }
|
||||
else if (r == VK_ERROR_OUT_OF_DATE_KHR || r == VK_SUBOPTIMAL_KHR)
|
||||
{
|
||||
createSwapChain();
|
||||
}
|
||||
else
|
||||
{
|
||||
VK_CHECK(r);
|
||||
}
|
||||
currentSemaphoreIndex = (currentSemaphoreIndex + 1) % Gfx::numFramesBuffered;
|
||||
}
|
||||
|
||||
void Window::onWindowCloseEvent()
|
||||
{
|
||||
}
|
||||
|
||||
Gfx::PTexture2D Window::getBackBuffer()
|
||||
{
|
||||
return PTexture2D(swapChainTextures[currentImageIndex]);
|
||||
}
|
||||
|
||||
void Window::setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback)
|
||||
{
|
||||
keyCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setMouseMoveCallback(std::function<void(double, double)> callback)
|
||||
{
|
||||
mouseMoveCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback)
|
||||
{
|
||||
mouseButtonCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setScrollCallback(std::function<void(double, double)> callback)
|
||||
{
|
||||
scrollCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setFileCallback(std::function<void(int, const char**)> callback)
|
||||
{
|
||||
fileCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setCloseCallback(std::function<void()> callback)
|
||||
{
|
||||
closeCallback = callback;
|
||||
}
|
||||
|
||||
void Window::chooseSwapSurfaceFormat()
|
||||
{
|
||||
for (const auto& supportedFormat : supportedFormats)
|
||||
{
|
||||
if (supportedFormat.format == cast(preferences.preferredFormat))
|
||||
{
|
||||
format = supportedFormat;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const auto& supportedFormat : supportedFormats)
|
||||
{
|
||||
if (supportedFormat.format == VK_FORMAT_R8G8B8A8_SRGB && supportedFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
||||
{
|
||||
format = supportedFormat;
|
||||
return;
|
||||
}
|
||||
}
|
||||
format = supportedFormats[0];
|
||||
}
|
||||
|
||||
void Window::chooseSwapPresentMode()
|
||||
{
|
||||
for (const auto& supportedPresentMode : supportedPresentModes)
|
||||
{
|
||||
if (supportedPresentMode == VK_PRESENT_MODE_MAILBOX_KHR)
|
||||
{
|
||||
presentMode = supportedPresentMode;
|
||||
return;
|
||||
}
|
||||
}
|
||||
presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
}
|
||||
|
||||
void Window::chooseSwapExtent()
|
||||
{
|
||||
if (capabilities.currentExtent.width != std::numeric_limits<uint32>::max()) {
|
||||
extent = capabilities.currentExtent;
|
||||
return;
|
||||
}
|
||||
int width, height;
|
||||
glfwGetFramebufferSize(static_cast<GLFWwindow*>(windowHandle), &width, &height);
|
||||
|
||||
extent = {
|
||||
static_cast<uint32>(width),
|
||||
static_cast<uint32>(height),
|
||||
};
|
||||
extent.width = std::clamp(extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
|
||||
extent.height = std::clamp(extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
|
||||
}
|
||||
|
||||
void Window::createSwapChain()
|
||||
{
|
||||
uint32 imageCount = Gfx::numFramesBuffered;
|
||||
VkSwapchainCreateInfoKHR createInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
||||
.pNext = nullptr,
|
||||
.surface = surface,
|
||||
.minImageCount = Gfx::numFramesBuffered,
|
||||
.imageFormat = format.format,
|
||||
.imageColorSpace = format.colorSpace,
|
||||
.imageExtent = extent,
|
||||
.imageArrayLayers = 1,
|
||||
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.preTransform = capabilities.currentTransform,
|
||||
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
||||
.presentMode = presentMode,
|
||||
.clipped = VK_TRUE,
|
||||
.oldSwapchain = swapchain,
|
||||
};
|
||||
VK_CHECK(vkCreateSwapchainKHR(graphics->getDevice(), &createInfo, nullptr, &swapchain));
|
||||
|
||||
uint32 numImages;
|
||||
vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numImages, swapChainImages.data());
|
||||
|
||||
assert(numImages == Gfx::numFramesBuffered);
|
||||
for (uint32 i = 0; i < numImages; ++i)
|
||||
{
|
||||
swapChainTextures[i] = new Texture2D(graphics, TextureCreateInfo{
|
||||
.format = cast(format.format),
|
||||
.width = extent.width,
|
||||
.height = extent.height,
|
||||
.depth = 1,
|
||||
.mipLevels = 1,
|
||||
.layers = 1,
|
||||
.elements = 1,
|
||||
.samples = 1,
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
}, swapChainImages[i]);
|
||||
imageAvailableSemaphores[i] = new Semaphore(graphics);
|
||||
renderingDoneSemaphores[i] = new Semaphore(graphics);
|
||||
}
|
||||
}
|
||||
|
||||
Viewport::Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &viewportInfo)
|
||||
: Gfx::Viewport(owner, viewportInfo), graphics(graphics)
|
||||
{
|
||||
handle.width = static_cast<float>(sizeX);
|
||||
handle.height = static_cast<float>(sizeY);
|
||||
handle.x = static_cast<float>(offsetX);
|
||||
handle.y = static_cast<float>(offsetY) + handle.height;
|
||||
handle.height = -handle.height;
|
||||
handle.minDepth = 0.f;
|
||||
handle.maxDepth = 1.f;
|
||||
}
|
||||
|
||||
Viewport::~Viewport()
|
||||
{
|
||||
}
|
||||
|
||||
void Viewport::resize(uint32 newX, uint32 newY)
|
||||
{
|
||||
sizeX = newX;
|
||||
sizeY = newY;
|
||||
handle.width = static_cast<float>(sizeX);
|
||||
handle.y = static_cast<float>(sizeY + offsetX);
|
||||
handle.height = -static_cast<float>(sizeY);
|
||||
}
|
||||
|
||||
void Viewport::move(uint32 newOffsetX, uint32 newOffsetY)
|
||||
{
|
||||
offsetX = newOffsetX;
|
||||
offsetY = newOffsetY;
|
||||
handle.x = static_cast<float>(offsetX);
|
||||
handle.y = static_cast<float>(offsetY + sizeY);
|
||||
}
|
||||
@@ -24,11 +24,6 @@ public:
|
||||
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
|
||||
virtual void setCloseCallback(std::function<void()> callback);
|
||||
|
||||
VkFormat getPixelFormat() const
|
||||
{
|
||||
return cast(windowState.pixelFormat);
|
||||
}
|
||||
|
||||
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
|
||||
std::function<void(double, double)> mouseMoveCallback;
|
||||
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
|
||||
@@ -36,32 +31,30 @@ public:
|
||||
std::function<void(int, const char**)> fileCallback;
|
||||
std::function<void()> closeCallback;
|
||||
protected:
|
||||
void advanceBackBuffer();
|
||||
void recreateSwapchain(const WindowCreateInfo &createInfo);
|
||||
void present();
|
||||
void destroySwapchain();
|
||||
void createSwapchain();
|
||||
void chooseSurfaceFormat(const Array<VkSurfaceFormatKHR> &available, Gfx::SeFormat preferred);
|
||||
void choosePresentMode(const Array<VkPresentModeKHR> &modes);
|
||||
|
||||
OTexture2D backBufferImages[Gfx::numFramesBuffered];
|
||||
VkImage backBufferHandles[Gfx::numFramesBuffered];
|
||||
OSemaphore renderFinished[Gfx::numFramesBuffered];
|
||||
OSemaphore imageAcquired[Gfx::numFramesBuffered];
|
||||
PSemaphore imageAcquiredSemaphore;
|
||||
|
||||
void chooseSwapSurfaceFormat();
|
||||
void chooseSwapPresentMode();
|
||||
void chooseSwapExtent();
|
||||
void createSwapChain();
|
||||
PGraphics graphics;
|
||||
WindowCreateInfo preferences;
|
||||
VkInstance instance;
|
||||
VkSwapchainKHR swapchain;
|
||||
VkSampleCountFlags numSamples;
|
||||
VkPresentModeKHR presentMode;
|
||||
VkSurfaceKHR surface;
|
||||
VkSurfaceFormatKHR surfaceFormat;
|
||||
VkSurfaceCapabilitiesKHR capabilities;
|
||||
Array<VkSurfaceFormatKHR> supportedFormats;
|
||||
Array<VkPresentModeKHR> supportedPresentModes;
|
||||
// the values used for the current swapchain
|
||||
VkSurfaceFormatKHR format;
|
||||
VkPresentModeKHR presentMode;
|
||||
VkExtent2D extent;
|
||||
void *windowHandle;
|
||||
int32 currentImageIndex;
|
||||
int32 acquiredImageIndex;
|
||||
int32 preAcquiredImageIndex;
|
||||
int32 semaphoreIndex;
|
||||
StaticArray<VkImage, Gfx::numFramesBuffered> swapChainImages;
|
||||
StaticArray<OTexture2D, Gfx::numFramesBuffered> swapChainTextures;
|
||||
StaticArray<OSemaphore, Gfx::numFramesBuffered> imageAvailableSemaphores;
|
||||
StaticArray<OSemaphore, Gfx::numFramesBuffered> renderingDoneSemaphores;
|
||||
uint32 currentImageIndex = 0;
|
||||
uint32 currentSemaphoreIndex = 0;
|
||||
};
|
||||
DEFINE_REF(Window)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "Window.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
|
||||
Window::Window()
|
||||
{
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
}
|
||||
|
||||
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
|
||||
: sizeX(std::min(owner->getFramebufferWidth(), viewportInfo.dimensions.size.x))
|
||||
, sizeY(std::min(owner->getFramebufferHeight(), viewportInfo.dimensions.size.y))
|
||||
, offsetX(viewportInfo.dimensions.offset.x)
|
||||
, offsetY(viewportInfo.dimensions.offset.y)
|
||||
, fieldOfView(viewportInfo.fieldOfView)
|
||||
, owner(owner)
|
||||
{
|
||||
}
|
||||
|
||||
Viewport::~Viewport()
|
||||
{
|
||||
}
|
||||
|
||||
Matrix4 Viewport::getProjectionMatrix() const
|
||||
{
|
||||
if (fieldOfView > 0.0f)
|
||||
{
|
||||
return glm::perspective(fieldOfView, sizeX / static_cast<float>(sizeY), 0.1f, 1000.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
#include "Initializer.h"
|
||||
#include "Texture.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
Window();
|
||||
virtual ~Window();
|
||||
virtual void beginFrame() = 0;
|
||||
virtual void endFrame() = 0;
|
||||
virtual void onWindowCloseEvent() = 0;
|
||||
virtual PTexture2D getBackBuffer() = 0;
|
||||
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) = 0;
|
||||
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) = 0;
|
||||
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) = 0;
|
||||
virtual void setScrollCallback(std::function<void(double, double)> callback) = 0;
|
||||
virtual void setFileCallback(std::function<void(int, const char**)> callback) = 0;
|
||||
virtual void setCloseCallback(std::function<void()> callback) = 0;
|
||||
constexpr SeFormat getSwapchainFormat() const
|
||||
{
|
||||
return framebufferFormat;
|
||||
}
|
||||
constexpr SeSampleCountFlags getNumSamples() const
|
||||
{
|
||||
return sampleFlags;
|
||||
}
|
||||
constexpr uint32 getFramebufferWidth() const
|
||||
{
|
||||
return framebufferWidth;
|
||||
}
|
||||
constexpr uint32 getFramebufferHeight() const
|
||||
{
|
||||
return framebufferHeight;
|
||||
}
|
||||
|
||||
protected:
|
||||
SeFormat framebufferFormat;
|
||||
SeSampleCountFlags sampleFlags;
|
||||
uint32 framebufferWidth;
|
||||
uint32 framebufferHeight;
|
||||
};
|
||||
DEFINE_REF(Window)
|
||||
|
||||
class Viewport
|
||||
{
|
||||
public:
|
||||
Viewport(PWindow owner, const ViewportCreateInfo& createInfo);
|
||||
virtual ~Viewport();
|
||||
virtual void resize(uint32 newX, uint32 newY) = 0;
|
||||
virtual void move(uint32 newOffsetX, uint32 newOffsetY) = 0;
|
||||
constexpr PWindow getOwner() const { return owner; }
|
||||
constexpr uint32 getWidth() const { return sizeX; }
|
||||
constexpr uint32 getHeight() const { return sizeY; }
|
||||
constexpr uint32 getOffsetX() const { return offsetX; }
|
||||
constexpr uint32 getOffsetY() const { return offsetY; }
|
||||
Matrix4 getProjectionMatrix() const;
|
||||
protected:
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
uint32 offsetX;
|
||||
uint32 offsetY;
|
||||
float fieldOfView;
|
||||
PWindow owner;
|
||||
};
|
||||
DEFINE_REF(Viewport)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ void Window::render()
|
||||
view->render();
|
||||
}
|
||||
gfxHandle->endFrame();
|
||||
std::cout << "Render" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user