Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/andrejnau/FlyCube

Graphics API wrapper is written in C++ on top of DirectX 12, Vulkan and Metal. Provides main features including ray tracing.
https://github.com/andrejnau/FlyCube

d3d12 direct3d directx directx-12 directx12 dxr gamedev graphics-api graphics-engine graphics-library graphics-programming metal ray-tracing raytracing renderer rendering rtx vulkan vulkan-api

Last synced: 2 months ago
JSON representation

Graphics API wrapper is written in C++ on top of DirectX 12, Vulkan and Metal. Provides main features including ray tracing.

Lists

README

        

# FlyCube
FlyCube is a low-level graphics API is written in C++ on top of `DirectX 12`, `Vulkan` and `Metal`.

### The low-level graphics API features
* Ray tracing
* Mesh shading
* Variable rate shading
* Bindless resource binding
* HLSL as a shader language for all backends
* Compilation in DXIL, SPIRV or MSL depend on selected backend

### Supported platforms

| | DirectX 12 | Vulkan | Metal |
|----------------|--------------------------|-------------------------------|--------------------------|
| Windows | :heavy_check_mark: | :heavy_check_mark: | :heavy_multiplication_x: |
| macOS/iOS/tvOS | :heavy_multiplication_x: | :heavy_check_mark: (MoltenVK) | :heavy_check_mark: |
| Linux | :heavy_multiplication_x: | :heavy_check_mark: | :heavy_multiplication_x: |

### Cloning repository
```
git clone --recursive https://github.com/andrejnau/FlyCube.git
```

### An example of the low-level graphics API usage
```cpp
std::shared_ptr instance = CreateInstance(settings.api_type);
std::shared_ptr adapter = std::move(instance->EnumerateAdapters()[settings.required_gpu_index]);
std::shared_ptr device = adapter->CreateDevice();
std::shared_ptr command_queue = device->GetCommandQueue(CommandListType::kGraphics);
constexpr uint32_t frame_count = 3;
std::shared_ptr swapchain =
device->CreateSwapchain(app.GetNativeWindow(), rect.width, rect.height, frame_count, settings.vsync);
uint64_t fence_value = 0;
std::shared_ptr fence = device->CreateFence(fence_value);

std::vector index_data = { 0, 1, 2 };
std::shared_ptr index_buffer =
device->CreateBuffer(BindFlag::kIndexBuffer | BindFlag::kCopyDest, sizeof(uint32_t) * index_data.size());
index_buffer->CommitMemory(MemoryType::kUpload);
index_buffer->UpdateUploadBuffer(0, index_data.data(), sizeof(index_data.front()) * index_data.size());

std::vector vertex_data = {
glm::vec3(-0.5, -0.5, 0.0),
glm::vec3(0.0, 0.5, 0.0),
glm::vec3(0.5, -0.5, 0.0),
};
std::shared_ptr vertex_buffer = device->CreateBuffer(BindFlag::kVertexBuffer | BindFlag::kCopyDest,
sizeof(vertex_data.front()) * vertex_data.size());
vertex_buffer->CommitMemory(MemoryType::kUpload);
vertex_buffer->UpdateUploadBuffer(0, vertex_data.data(), sizeof(vertex_data.front()) * vertex_data.size());

glm::vec4 constant_data = glm::vec4(1, 0, 0, 1);
std::shared_ptr constant_buffer =
device->CreateBuffer(BindFlag::kConstantBuffer | BindFlag::kCopyDest, sizeof(constant_data));
constant_buffer->CommitMemory(MemoryType::kUpload);
constant_buffer->UpdateUploadBuffer(0, &constant_data, sizeof(constant_data));

std::shared_ptr vertex_shader = device->CompileShader(
{ ASSETS_PATH "shaders/CoreTriangle/VertexShader.hlsl", "main", ShaderType::kVertex, "6_0" });
std::shared_ptr pixel_shader = device->CompileShader(
{ ASSETS_PATH "shaders/CoreTriangle/PixelShader.hlsl", "main", ShaderType::kPixel, "6_0" });
std::shared_ptr program = device->CreateProgram({ vertex_shader, pixel_shader });

ViewDesc constant_view_desc = {};
constant_view_desc.view_type = ViewType::kConstantBuffer;
constant_view_desc.dimension = ViewDimension::kBuffer;
std::shared_ptr constant_view = device->CreateView(constant_buffer, constant_view_desc);
BindKey settings_key = { ShaderType::kPixel, ViewType::kConstantBuffer, 0, 0, 1 };
std::shared_ptr layout = device->CreateBindingSetLayout({ settings_key });
std::shared_ptr binding_set = device->CreateBindingSet(layout);
binding_set->WriteBindings({ { settings_key, constant_view } });

RenderPassDesc render_pass_desc = {
{ { swapchain->GetFormat(), RenderPassLoadOp::kClear, RenderPassStoreOp::kStore } },
};
std::shared_ptr render_pass = device->CreateRenderPass(render_pass_desc);
ClearDesc clear_desc = { { { 0.0, 0.2, 0.4, 1.0 } } };
GraphicsPipelineDesc pipeline_desc = {
program,
layout,
{ { 0, "POSITION", gli::FORMAT_RGB32_SFLOAT_PACK32, sizeof(vertex_data.front()) } },
render_pass,
};
std::shared_ptr pipeline = device->CreateGraphicsPipeline(pipeline_desc);

std::array fence_values = {};
std::vector> command_lists;
std::vector> framebuffers;
for (uint32_t i = 0; i < frame_count; ++i) {
ViewDesc back_buffer_view_desc = {};
back_buffer_view_desc.view_type = ViewType::kRenderTarget;
back_buffer_view_desc.dimension = ViewDimension::kTexture2D;
std::shared_ptr back_buffer = swapchain->GetBackBuffer(i);
std::shared_ptr back_buffer_view = device->CreateView(back_buffer, back_buffer_view_desc);
FramebufferDesc framebuffer_desc = {};
framebuffer_desc.render_pass = render_pass;
framebuffer_desc.width = rect.width;
framebuffer_desc.height = rect.height;
framebuffer_desc.colors = { back_buffer_view };
std::shared_ptr framebuffer =
framebuffers.emplace_back(device->CreateFramebuffer(framebuffer_desc));
std::shared_ptr command_list =
command_lists.emplace_back(device->CreateCommandList(CommandListType::kGraphics));
command_list->BindPipeline(pipeline);
command_list->BindBindingSet(binding_set);
command_list->SetViewport(0, 0, rect.width, rect.height);
command_list->SetScissorRect(0, 0, rect.width, rect.height);
command_list->IASetIndexBuffer(index_buffer, gli::format::FORMAT_R32_UINT_PACK32);
command_list->IASetVertexBuffer(0, vertex_buffer);
command_list->ResourceBarrier({ { back_buffer, ResourceState::kPresent, ResourceState::kRenderTarget } });
command_list->BeginRenderPass(render_pass, framebuffer, clear_desc);
command_list->DrawIndexed(3, 1, 0, 0, 0);
command_list->EndRenderPass();
command_list->ResourceBarrier({ { back_buffer, ResourceState::kRenderTarget, ResourceState::kPresent } });
command_list->Close();
}

while (!app.PollEvents()) {
uint32_t frame_index = swapchain->NextImage(fence, ++fence_value);
command_queue->Wait(fence, fence_value);
fence->Wait(fence_values[frame_index]);
command_queue->ExecuteCommandLists({ command_lists[frame_index] });
command_queue->Signal(fence, fence_values[frame_index] = ++fence_value);
swapchain->Present(fence, fence_values[frame_index]);
}
command_queue->Signal(fence, ++fence_value);
fence->Wait(fence_value);
```

### Advanced sample
[SponzaPbr](https://github.com/andrejnau/SponzaPbr) was originally part of the repository. This is my sandbox for rendering techniques.
* Features
* Deferred rendering
* Physically based rendering
* Image based lighting
* Ambient occlusion
* Raytracing
* Screen space
* Normal mapping
* Point shadow mapping
* Skeletal animation
* Multisample anti-aliasing
* Tone mapping
* Simple imgui based UI settings

![sponza.png](screenshots/sponza.png)