Compare commits
10 Commits
021e552f74
...
0cc5570098
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cc5570098 | ||
|
|
7f80ef96e1 | ||
|
|
33a6592d41 | ||
|
|
2808defc94 | ||
|
|
32834878b5 | ||
|
|
23b94fabba | ||
|
|
fe54cba61b | ||
|
|
903919d6d2 | ||
|
|
089deb520f | ||
|
|
06d49043d3 |
5
.github/workflows/c-cpp.yml
vendored
5
.github/workflows/c-cpp.yml
vendored
@@ -11,7 +11,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Prepare Vulkan SDK
|
||||
uses: humbletim/setup-vulkan-sdk@v1.2.0
|
||||
with:
|
||||
|
||||
150
.vims
150
.vims
@@ -14,7 +14,7 @@ else
|
||||
set shortmess=aoO
|
||||
endif
|
||||
badd +693 src/graphics/vulkan_tutorial.cpp
|
||||
badd +316 src/inferno.cpp
|
||||
badd +317 src/inferno.cpp
|
||||
badd +45 src/scene/mesh.hpp
|
||||
badd +75 src/scene/mesh.cpp
|
||||
badd +33 src/graphics/pipeline.cpp
|
||||
@@ -28,7 +28,7 @@ badd +13 src/graphics/swapchain.hpp
|
||||
badd +56 src/inferno.hpp
|
||||
badd +1 src/main.cpp
|
||||
badd +1 ~/dprog/active/inferno-hart/src/graphics/descriptor.cpp
|
||||
badd +53 src/graphics/vkrenderer.hpp
|
||||
badd +11 src/graphics/vkrenderer.hpp
|
||||
badd +42 src/renderer/renderer.hpp
|
||||
badd +28 src/scene/scene.cpp
|
||||
badd +173 src/graphics/buffer.cpp
|
||||
@@ -47,20 +47,20 @@ badd +43 src/gui/gui.hpp
|
||||
badd +130 src/window.cpp
|
||||
badd +111 src/thirdparty/imgui/imgui_impl_vulkan.cpp
|
||||
badd +66 ~/dprog/active/inferno-hart/src/thirdparty/imgui/imgui_impl_vulkan.h
|
||||
badd +38 src/preview_renderer/renderer.hpp
|
||||
badd +59 src/preview_renderer/renderer.cpp
|
||||
badd +1 src/preview_renderer/renderer.hpp
|
||||
badd +1 src/preview_renderer/renderer.cpp
|
||||
badd +49 src/raytracing/renderer.cpp
|
||||
badd +0 src/graphics/rendertarget.cpp
|
||||
badd +1 src/graphics/rendertarget.hpp
|
||||
argglobal
|
||||
%argdel
|
||||
edit src/inferno.cpp
|
||||
edit src/raytracing/renderer.cpp
|
||||
let s:save_splitbelow = &splitbelow
|
||||
let s:save_splitright = &splitright
|
||||
set splitbelow splitright
|
||||
wincmd _ | wincmd |
|
||||
vsplit
|
||||
wincmd _ | wincmd |
|
||||
vsplit
|
||||
2wincmd h
|
||||
wincmd w
|
||||
1wincmd h
|
||||
wincmd w
|
||||
wincmd _ | wincmd |
|
||||
split
|
||||
@@ -75,8 +75,58 @@ set winminheight=0
|
||||
set winheight=1
|
||||
set winminwidth=0
|
||||
set winwidth=1
|
||||
wincmd =
|
||||
exe 'vert 1resize ' . ((&columns * 120 + 132) / 265)
|
||||
exe '2resize ' . ((&lines * 44 + 45) / 91)
|
||||
exe 'vert 2resize ' . ((&columns * 144 + 132) / 265)
|
||||
exe '3resize ' . ((&lines * 43 + 45) / 91)
|
||||
exe 'vert 3resize ' . ((&columns * 144 + 132) / 265)
|
||||
argglobal
|
||||
balt src/inferno.cpp
|
||||
setlocal fdm=manual
|
||||
setlocal fde=0
|
||||
setlocal fmr={{{,}}}
|
||||
setlocal fdi=#
|
||||
setlocal fdl=0
|
||||
setlocal fml=1
|
||||
setlocal fdn=20
|
||||
setlocal fen
|
||||
silent! normal! zE
|
||||
let &fdl = &fdl
|
||||
let s:l = 93 - ((29 * winheight(0) + 44) / 88)
|
||||
if s:l < 1 | let s:l = 1 | endif
|
||||
keepjumps exe s:l
|
||||
normal! zt
|
||||
keepjumps 93
|
||||
normal! 0
|
||||
wincmd w
|
||||
argglobal
|
||||
if bufexists(fnamemodify("src/graphics/rendertarget.hpp", ":p")) | buffer src/graphics/rendertarget.hpp | else | edit src/graphics/rendertarget.hpp | endif
|
||||
if &buftype ==# 'terminal'
|
||||
silent file src/graphics/rendertarget.hpp
|
||||
endif
|
||||
balt src/graphics/vkrenderer.hpp
|
||||
setlocal fdm=manual
|
||||
setlocal fde=0
|
||||
setlocal fmr={{{,}}}
|
||||
setlocal fdi=#
|
||||
setlocal fdl=0
|
||||
setlocal fml=1
|
||||
setlocal fdn=20
|
||||
setlocal fen
|
||||
silent! normal! zE
|
||||
let &fdl = &fdl
|
||||
let s:l = 1 - ((0 * winheight(0) + 22) / 44)
|
||||
if s:l < 1 | let s:l = 1 | endif
|
||||
keepjumps exe s:l
|
||||
normal! zt
|
||||
keepjumps 1
|
||||
normal! 0
|
||||
wincmd w
|
||||
argglobal
|
||||
if bufexists(fnamemodify("src/graphics/rendertarget.cpp", ":p")) | buffer src/graphics/rendertarget.cpp | else | edit src/graphics/rendertarget.cpp | endif
|
||||
if &buftype ==# 'terminal'
|
||||
silent file src/graphics/rendertarget.cpp
|
||||
endif
|
||||
balt src/preview_renderer/renderer.hpp
|
||||
setlocal fdm=manual
|
||||
setlocal fde=0
|
||||
@@ -88,83 +138,19 @@ setlocal fdn=20
|
||||
setlocal fen
|
||||
silent! normal! zE
|
||||
let &fdl = &fdl
|
||||
let s:l = 317 - ((60 * winheight(0) + 43) / 86)
|
||||
if s:l < 1 | let s:l = 1 | endif
|
||||
keepjumps exe s:l
|
||||
normal! zt
|
||||
keepjumps 317
|
||||
normal! 050|
|
||||
wincmd w
|
||||
argglobal
|
||||
if bufexists(fnamemodify("src/preview_renderer/renderer.cpp", ":p")) | buffer src/preview_renderer/renderer.cpp | else | edit src/preview_renderer/renderer.cpp | endif
|
||||
if &buftype ==# 'terminal'
|
||||
silent file src/preview_renderer/renderer.cpp
|
||||
endif
|
||||
balt src/graphics/vkrenderer.cpp
|
||||
setlocal fdm=manual
|
||||
setlocal fde=0
|
||||
setlocal fmr={{{,}}}
|
||||
setlocal fdi=#
|
||||
setlocal fdl=0
|
||||
setlocal fml=1
|
||||
setlocal fdn=20
|
||||
setlocal fen
|
||||
silent! normal! zE
|
||||
let &fdl = &fdl
|
||||
let s:l = 59 - ((56 * winheight(0) + 43) / 86)
|
||||
if s:l < 1 | let s:l = 1 | endif
|
||||
keepjumps exe s:l
|
||||
normal! zt
|
||||
keepjumps 59
|
||||
normal! 015|
|
||||
wincmd w
|
||||
argglobal
|
||||
if bufexists(fnamemodify("src/graphics/vkrenderer.hpp", ":p")) | buffer src/graphics/vkrenderer.hpp | else | edit src/graphics/vkrenderer.hpp | endif
|
||||
if &buftype ==# 'terminal'
|
||||
silent file src/graphics/vkrenderer.hpp
|
||||
endif
|
||||
balt src/graphics/vkrenderer.cpp
|
||||
setlocal fdm=manual
|
||||
setlocal fde=0
|
||||
setlocal fmr={{{,}}}
|
||||
setlocal fdi=#
|
||||
setlocal fdl=0
|
||||
setlocal fml=1
|
||||
setlocal fdn=20
|
||||
setlocal fen
|
||||
silent! normal! zE
|
||||
let &fdl = &fdl
|
||||
let s:l = 10 - ((4 * winheight(0) + 24) / 49)
|
||||
if s:l < 1 | let s:l = 1 | endif
|
||||
keepjumps exe s:l
|
||||
normal! zt
|
||||
keepjumps 10
|
||||
normal! 0
|
||||
wincmd w
|
||||
argglobal
|
||||
if bufexists(fnamemodify("src/preview_renderer/renderer.hpp", ":p")) | buffer src/preview_renderer/renderer.hpp | else | edit src/preview_renderer/renderer.hpp | endif
|
||||
if &buftype ==# 'terminal'
|
||||
silent file src/preview_renderer/renderer.hpp
|
||||
endif
|
||||
balt src/graphics/pipeline.hpp
|
||||
setlocal fdm=manual
|
||||
setlocal fde=0
|
||||
setlocal fmr={{{,}}}
|
||||
setlocal fdi=#
|
||||
setlocal fdl=0
|
||||
setlocal fml=1
|
||||
setlocal fdn=20
|
||||
setlocal fen
|
||||
silent! normal! zE
|
||||
let &fdl = &fdl
|
||||
let s:l = 1 - ((0 * winheight(0) + 18) / 36)
|
||||
let s:l = 1 - ((0 * winheight(0) + 21) / 43)
|
||||
if s:l < 1 | let s:l = 1 | endif
|
||||
keepjumps exe s:l
|
||||
normal! zt
|
||||
keepjumps 1
|
||||
normal! 08|
|
||||
normal! 0
|
||||
wincmd w
|
||||
wincmd =
|
||||
2wincmd w
|
||||
exe 'vert 1resize ' . ((&columns * 120 + 132) / 265)
|
||||
exe '2resize ' . ((&lines * 44 + 45) / 91)
|
||||
exe 'vert 2resize ' . ((&columns * 144 + 132) / 265)
|
||||
exe '3resize ' . ((&lines * 43 + 45) / 91)
|
||||
exe 'vert 3resize ' . ((&columns * 144 + 132) / 265)
|
||||
tabnext 1
|
||||
if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'
|
||||
silent exe 'bwipe ' . s:wipebuf
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(inferno)
|
||||
|
||||
set(CMAKE_COMPILE_WARNING_AS_ERROR OFF)
|
||||
|
||||
# file(GLOB SRC "src/*.cpp" "src/graphics/*.cpp" "src/preview_renderer/*.cpp" "src/scene/*.cpp" "src/thirdparty/imgui/*.cpp" "src/preview_renderer/*.cpp")
|
||||
file(GLOB_RECURSE SRC "src/*.cpp")
|
||||
|
||||
@@ -31,11 +33,18 @@ else()
|
||||
target_compile_options(inferno PRIVATE -std=c++20)
|
||||
target_compile_options(inferno PRIVATE -m64)
|
||||
if (CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
target_compile_options(inferno PRIVATE -O1)
|
||||
target_compile_options(inferno PRIVATE -O0)
|
||||
target_compile_options(inferno PRIVATE -Wall)
|
||||
target_compile_options(inferno PRIVATE -g)
|
||||
target_compile_options(inferno PRIVATE -D_GLIBCXX_DEBUG)
|
||||
endif()
|
||||
if (CMAKE_BUILD_TYPE MATCHES "Release")
|
||||
target_compile_options(inferno PRIVATE -O3)
|
||||
target_compile_options(inferno PRIVATE -march=native)
|
||||
target_compile_options(inferno PRIVATE -DNDEBUG)
|
||||
# allow warnings
|
||||
target_compile_options(inferno PRIVATE -Wall)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Compile shaders first..
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
35
imgui.ini
Normal file
35
imgui.ini
Normal file
@@ -0,0 +1,35 @@
|
||||
[Window][main]
|
||||
Pos=0,0
|
||||
Size=1920,1080
|
||||
Collapsed=0
|
||||
|
||||
[Window][Inferno HART]
|
||||
Pos=840,26
|
||||
Size=1076,304
|
||||
Collapsed=0
|
||||
DockId=0x00000003,0
|
||||
|
||||
[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Preview]
|
||||
Pos=840,332
|
||||
Size=1076,745
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Window][Render]
|
||||
Pos=4,26
|
||||
Size=834,1051
|
||||
Collapsed=0
|
||||
DockId=0x00000001,0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x9498A894 Window=0xBF28CD64 Pos=4,26 Size=1912,1051 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x9498A894 SizeRef=834,1051 CentralNode=1 Selected=0x81AED595
|
||||
DockNode ID=0x00000002 Parent=0x9498A894 SizeRef=1076,1051 Split=Y Selected=0x83AD8318
|
||||
DockNode ID=0x00000003 Parent=0x00000002 SizeRef=1076,286 Selected=0x83AD8318
|
||||
DockNode ID=0x00000004 Parent=0x00000002 SizeRef=1076,700 Selected=0x382916D5
|
||||
|
||||
3
libhart/thirdparty/yolo/yolo.hpp
vendored
3
libhart/thirdparty/yolo/yolo.hpp
vendored
@@ -117,3 +117,6 @@ inline uint8_t registerModule(std::string name, std::string ANSI)
|
||||
|
||||
}
|
||||
|
||||
// alias yolo to yo for less typing
|
||||
namespace yo = yolo;
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#version 450 core
|
||||
|
||||
layout (location = 0) in vec3 vFragPos;
|
||||
layout (location = 1) in vec3 vColour;
|
||||
|
||||
layout(location = 0) out vec4 outColour;
|
||||
|
||||
void main()
|
||||
{
|
||||
outColour = vec4(1., 0., 0., 1.0);
|
||||
outColour = vec4(vColour, 1.0);
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,7 @@
|
||||
#version 450 core
|
||||
|
||||
layout (location = 0) in vec3 position;
|
||||
layout (location = 1) in vec3 colour;
|
||||
|
||||
layout (binding = 0) uniform SceneUniformBufferObject {
|
||||
mat4 proj;
|
||||
@@ -11,9 +12,11 @@ layout (binding = 0) uniform SceneUniformBufferObject {
|
||||
|
||||
// mat4 model;
|
||||
|
||||
layout (location = 1) out vec3 vFragPos;
|
||||
layout (location = 0) out vec3 vFragPos;
|
||||
layout (location = 1) out vec3 vColour;
|
||||
|
||||
void main() {
|
||||
vFragPos = vec3(vec4(position, 1.0));
|
||||
vColour = colour;
|
||||
gl_Position = ubo.proj * ubo.view * vec4(position, 1.0);
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -3,6 +3,8 @@
|
||||
#include "graphics.hpp"
|
||||
#include "window.hpp"
|
||||
|
||||
#include "vkrenderer.hpp"
|
||||
|
||||
#include "yolo/yolo.hpp"
|
||||
|
||||
#include <map>
|
||||
@@ -180,6 +182,7 @@ bool device_evaluate(GraphicsDevice* g, VkPhysicalDevice device)
|
||||
|
||||
// does the device support the extensions we need?
|
||||
if (!device_evaluate_extensions(device, DEVICE_EXTENSIONS)) {
|
||||
yolo::error("Device {} does not support required extensions", deviceProperties.deviceName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -219,6 +222,11 @@ void device_cleanup(GraphicsDevice* device)
|
||||
vkDestroyInstance(device->VulkanInstance, nullptr);
|
||||
}
|
||||
|
||||
void device_add_context(GraphicsDevice* device, VulkanRenderer* context)
|
||||
{
|
||||
device->RenderContext = context;
|
||||
}
|
||||
|
||||
void device_create_vulkan_instance(GraphicsDevice* device)
|
||||
{
|
||||
|
||||
@@ -312,7 +320,13 @@ void device_create_vulkan_physical_device(GraphicsDevice* device)
|
||||
// established the device with the best score, or the only one in the system.
|
||||
device->VulkanPhysicalDevice = candidates.rbegin()->second;
|
||||
} else {
|
||||
yolo::error("failed to find a suitable GPU!");
|
||||
// log all devices and their scores
|
||||
for (const auto& device_candidate : candidates) {
|
||||
VkPhysicalDeviceProperties deviceProperties;
|
||||
vkGetPhysicalDeviceProperties(device_candidate.second, &deviceProperties);
|
||||
yolo::error("Device {} scored {}", deviceProperties.deviceName, device_candidate.first);
|
||||
}
|
||||
yolo::error("Failed to find a suitable GPU!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,18 +6,22 @@
|
||||
|
||||
namespace inferno::graphics {
|
||||
|
||||
// #define VALIDATION_LAYERS_ENABLED 1
|
||||
#define VALIDATION_LAYERS_ENABLED 1
|
||||
#ifdef VALIDATION_LAYERS_ENABLED
|
||||
const std::vector<const char*> VALIDATION_LAYERS = {
|
||||
"VK_LAYER_KHRONOS_validation",
|
||||
// "VK_LAYER_KHRONOS_validation",
|
||||
// "VK_LAYER_RENDERDOC_Capture",
|
||||
};
|
||||
#endif
|
||||
|
||||
const std::vector<const char*> DEVICE_EXTENSIONS = {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||
VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME,
|
||||
// VK_EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME,
|
||||
};
|
||||
|
||||
struct VulkanRenderer;
|
||||
|
||||
typedef struct GraphicsDevice {
|
||||
VkInstance VulkanInstance;
|
||||
VkDebugUtilsMessengerEXT VulkanDebugMessenger;
|
||||
@@ -28,6 +32,9 @@ typedef struct GraphicsDevice {
|
||||
VkQueue VulkanPresentQueue;
|
||||
VkCommandPool VulkanCommandPool;
|
||||
|
||||
// FIXME: There is no way in hell this should be here
|
||||
VulkanRenderer* RenderContext;
|
||||
|
||||
glm::ivec2 SurfaceSize;
|
||||
bool Resized = false;
|
||||
} GraphicsDevice;
|
||||
@@ -46,6 +53,8 @@ struct QueueFamilyIndices {
|
||||
GraphicsDevice* device_create();
|
||||
void device_cleanup(GraphicsDevice* device);
|
||||
|
||||
void device_add_context(GraphicsDevice* device, VulkanRenderer* context);
|
||||
|
||||
void device_create_vulkan_instance(GraphicsDevice* device);
|
||||
void device_vulkan_debugger(GraphicsDevice* device);
|
||||
void device_create_vulkan_physical_device(GraphicsDevice* device);
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#include "graphics/image.hpp"
|
||||
|
||||
#include "device.hpp"
|
||||
#include "vkrenderer.hpp"
|
||||
|
||||
#include "yolo/yolo.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace inferno::graphics {
|
||||
|
||||
void create_image(GraphicsDevice* device, uint32_t width, uint32_t height,
|
||||
@@ -69,6 +72,36 @@ VkImageView create_image_view(GraphicsDevice* device, VkImage image, VkFormat fo
|
||||
return imageView;
|
||||
}
|
||||
|
||||
void transition_image_layout(GraphicsDevice* device, VkImage image, VkFormat format,
|
||||
VkImageLayout oldLayout, VkImageLayout newLayout)
|
||||
{
|
||||
// This all goes in a standard callback to go to the renderer as a one time command
|
||||
// buffer execution
|
||||
std::function<void(VulkanRenderer*, VkCommandBuffer*)> callback
|
||||
= [&](VulkanRenderer* renderer, VkCommandBuffer* commandBuffer) {
|
||||
VkImageMemoryBarrier barrier {};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.oldLayout = oldLayout;
|
||||
barrier.newLayout = newLayout;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = image;
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
barrier.subresourceRange.baseMipLevel = 0;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
barrier.srcAccessMask = 0; // TODO
|
||||
barrier.dstAccessMask = 0; // TODO
|
||||
|
||||
vkCmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1,
|
||||
&barrier);
|
||||
};
|
||||
|
||||
graphics::renderer_submit_now(device->RenderContext, callback);
|
||||
}
|
||||
|
||||
VkFormat find_format(GraphicsDevice* device, const std::vector<VkFormat>& candidates,
|
||||
VkImageTiling tiling, VkFormatFeatureFlags features)
|
||||
{
|
||||
@@ -92,10 +125,9 @@ VkFormat find_depth_format(GraphicsDevice* device)
|
||||
{
|
||||
return VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
return find_format(device,
|
||||
{ VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT },
|
||||
{ VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT,
|
||||
VK_FORMAT_D24_UNORM_S8_UINT },
|
||||
VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ void create_image(GraphicsDevice* device, uint32_t width, uint32_t height,
|
||||
VkImageView create_image_view(GraphicsDevice* device, VkImage image, VkFormat format,
|
||||
VkImageAspectFlags aspectFlags);
|
||||
|
||||
void transition_image_layout(GraphicsDevice* device, VkImage image, VkFormat format,
|
||||
VkImageLayout oldLayout, VkImageLayout newLayout);
|
||||
// void copy_buffer_to_image(GraphicsDevice* device, VkBuffer buffer, VkImage image,
|
||||
// uint32_t width, uint32_t height);
|
||||
|
||||
VkFormat find_format(GraphicsDevice* device, const std::vector<VkFormat>& candidates,
|
||||
VkImageTiling tiling, VkFormatFeatureFlags features);
|
||||
VkFormat find_depth_format(GraphicsDevice* device);
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#include "rendertarget.hpp"
|
||||
|
||||
#include "buffer.hpp"
|
||||
#include "device.hpp"
|
||||
#include "graphics.hpp"
|
||||
#include "image.hpp"
|
||||
#include "vkrenderer.hpp"
|
||||
|
||||
#include "yolo/yolo.hpp"
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace inferno::graphics {
|
||||
|
||||
@@ -13,8 +16,8 @@ RenderTarget* rendertarget_create(
|
||||
{
|
||||
RenderTarget* target = new RenderTarget();
|
||||
target->Device = device;
|
||||
target->Format = format;
|
||||
target->Extent = extent;
|
||||
target->Format = format;
|
||||
|
||||
VkSamplerCreateInfo samplerInfo {};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
@@ -39,16 +42,26 @@ RenderTarget* rendertarget_create(
|
||||
yolo::error("failed to create texture sampler!");
|
||||
}
|
||||
|
||||
target->TargetImage = new ImageAttachment();
|
||||
|
||||
create_image(device, extent.width, extent.height, format, VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->Image, target->Memory);
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
|
||||
| VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->TargetImage->Image,
|
||||
target->TargetImage->Memory);
|
||||
|
||||
target->TargetImage->ImageView = create_image_view(
|
||||
device, target->TargetImage->Image, format, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
target->ImageView
|
||||
= create_image_view(device, target->Image, format, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
target->DescriptorSet = ImGui_ImplVulkan_AddTexture(target->Sampler,
|
||||
target->TargetImage->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
target->DescriptorSet = ImGui_ImplVulkan_AddTexture(
|
||||
target->Sampler, target->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
// wait for the image to be ready
|
||||
graphics::renderer_submit_now(
|
||||
device->RenderContext, [&](VulkanRenderer* re, VkCommandBuffer* cmd) {
|
||||
transition_image_layout(re->Device, target->TargetImage->Image, format,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
});
|
||||
|
||||
if (depth) {
|
||||
rendertarget_create_depth(target);
|
||||
@@ -59,9 +72,10 @@ RenderTarget* rendertarget_create(
|
||||
|
||||
void rendertarget_cleanup(RenderTarget* target)
|
||||
{
|
||||
vkDestroyImageView(target->Device->VulkanDevice, target->ImageView, nullptr);
|
||||
vkDestroyImage(target->Device->VulkanDevice, target->Image, nullptr);
|
||||
vkFreeMemory(target->Device->VulkanDevice, target->Memory, nullptr);
|
||||
vkDestroyImageView(
|
||||
target->Device->VulkanDevice, target->TargetImage->ImageView, nullptr);
|
||||
vkDestroyImage(target->Device->VulkanDevice, target->TargetImage->Image, nullptr);
|
||||
vkFreeMemory(target->Device->VulkanDevice, target->TargetImage->Memory, nullptr);
|
||||
|
||||
rendertarget_destroy_depth(target);
|
||||
|
||||
@@ -80,8 +94,8 @@ void rendertarget_create_depth(RenderTarget* target)
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->TargetDepth->Image,
|
||||
target->TargetDepth->Memory);
|
||||
|
||||
target->TargetDepth->ImageView = create_image_view(target->Device, target->TargetDepth->Image,
|
||||
depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
target->TargetDepth->ImageView = create_image_view(target->Device,
|
||||
target->TargetDepth->Image, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
}
|
||||
|
||||
void rendertarget_destroy_depth(RenderTarget* target)
|
||||
@@ -100,15 +114,214 @@ void rendertarget_recreate(RenderTarget* target, VkExtent2D extent, VkFormat for
|
||||
|
||||
bool doDepth = target->TargetDepth != nullptr;
|
||||
|
||||
rendertarget_cleanup(target);
|
||||
vkDestroyImageView(
|
||||
target->Device->VulkanDevice, target->TargetImage->ImageView, nullptr);
|
||||
vkDestroyImage(target->Device->VulkanDevice, target->TargetImage->Image, nullptr);
|
||||
vkFreeMemory(target->Device->VulkanDevice, target->TargetImage->Memory, nullptr);
|
||||
|
||||
if (doDepth) {
|
||||
vkDestroyImageView(
|
||||
target->Device->VulkanDevice, target->TargetDepth->ImageView, nullptr);
|
||||
vkDestroyImage(target->Device->VulkanDevice, target->TargetDepth->Image, nullptr);
|
||||
vkFreeMemory(target->Device->VulkanDevice, target->TargetDepth->Memory, nullptr);
|
||||
}
|
||||
|
||||
target->Extent = extent;
|
||||
target->Format = format;
|
||||
|
||||
rendertarget_create(target->Device, extent, format, doDepth);
|
||||
target->TargetImage = new ImageAttachment();
|
||||
|
||||
// if (doDepth)
|
||||
// rendertarget_create_depth(target);
|
||||
create_image(target->Device, extent.width, extent.height, format,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
|
||||
| VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->TargetImage->Image,
|
||||
target->TargetImage->Memory);
|
||||
|
||||
target->TargetImage->ImageView = create_image_view(
|
||||
target->Device, target->TargetImage->Image, format, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
target->DescriptorSet = ImGui_ImplVulkan_AddTexture(target->Sampler,
|
||||
target->TargetImage->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
// wait for the image to be ready
|
||||
graphics::renderer_submit_now(
|
||||
target->Device->RenderContext, [&](VulkanRenderer* re, VkCommandBuffer* cmd) {
|
||||
transition_image_layout(re->Device, target->TargetImage->Image, format,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
});
|
||||
|
||||
if (doDepth) {
|
||||
rendertarget_create_depth(target);
|
||||
}
|
||||
}
|
||||
|
||||
DynamicCPUTarget* dynamic_rendertarget_create(
|
||||
GraphicsDevice* device, VkExtent2D extent, VkFormat format)
|
||||
{
|
||||
DynamicCPUTarget* target = new DynamicCPUTarget();
|
||||
target->Format = format;
|
||||
target->Extent = extent;
|
||||
target->Device = device;
|
||||
|
||||
VkSamplerCreateInfo samplerInfo {};
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.anisotropyEnable = VK_FALSE;
|
||||
samplerInfo.maxAnisotropy = 0.0f;
|
||||
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||
samplerInfo.unnormalizedCoordinates = VK_FALSE;
|
||||
samplerInfo.compareEnable = VK_FALSE;
|
||||
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
|
||||
if (vkCreateSampler(device->VulkanDevice, &samplerInfo, nullptr, &target->Sampler)
|
||||
!= VK_SUCCESS) {
|
||||
yolo::error("failed to create texture sampler!");
|
||||
}
|
||||
|
||||
// Create VkImage with Undefined
|
||||
create_image(device, extent.width, extent.height, format, VK_IMAGE_TILING_LINEAR,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
|
||||
| VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->Image, target->Memory);
|
||||
|
||||
target->ImageView
|
||||
= create_image_view(device, target->Image, format, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
target->DescriptorSet = ImGui_ImplVulkan_AddTexture(
|
||||
target->Sampler, target->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
// NOTE: This assumes that the image is in the UNDEFINED LAYOUT
|
||||
// And also assumes that the cpu layout is floating point (4 bytes) and the image is
|
||||
// RGBA
|
||||
target->StagingBuffer = generic_buffer_create(device, 0,
|
||||
extent.width * extent.height * 4, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
void dynamic_rendertarget_cleanup(DynamicCPUTarget* target)
|
||||
{
|
||||
vkDestroyImageView(target->Device->VulkanDevice, target->ImageView, nullptr);
|
||||
vkDestroyImage(target->Device->VulkanDevice, target->Image, nullptr);
|
||||
vkFreeMemory(target->Device->VulkanDevice, target->Memory, nullptr);
|
||||
vkDestroySampler(target->Device->VulkanDevice, target->Sampler, nullptr);
|
||||
delete target;
|
||||
}
|
||||
|
||||
// TODO: We should do this with a double buffer but whatever
|
||||
void dynamic_rendertarget_update(DynamicCPUTarget* target, void* data, VkExtent2D size)
|
||||
{
|
||||
if (size.width != target->Extent.width || size.height != target->Extent.height) {
|
||||
yolo::error("Dynamic CPU Target size mismatch");
|
||||
return;
|
||||
}
|
||||
|
||||
// Traansition to General
|
||||
transition_image_layout(target->Device, target->Image, target->Format,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
// Sync with Fence
|
||||
// we need a fence here because we need to wait for the image to be ready
|
||||
// before we can copy to it
|
||||
VkFenceCreateInfo fenceInfo {};
|
||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fenceInfo.flags = 0;
|
||||
|
||||
VkFence fence;
|
||||
if (vkCreateFence(target->Device->VulkanDevice, &fenceInfo, nullptr, &fence)
|
||||
!= VK_SUCCESS) {
|
||||
yolo::error("failed to create fence!");
|
||||
}
|
||||
|
||||
VkSubmitInfo submitInfo {};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.pNext = nullptr;
|
||||
submitInfo.waitSemaphoreCount = 0;
|
||||
submitInfo.pWaitSemaphores = nullptr;
|
||||
submitInfo.pWaitDstStageMask = nullptr;
|
||||
submitInfo.commandBufferCount = 0;
|
||||
submitInfo.pCommandBuffers = nullptr;
|
||||
submitInfo.signalSemaphoreCount = 0;
|
||||
submitInfo.pSignalSemaphores = nullptr;
|
||||
|
||||
if (vkQueueSubmit(target->Device->VulkanGraphicsQueue, 1, &submitInfo, fence)
|
||||
!= VK_SUCCESS) {
|
||||
yolo::error("failed to submit queue!");
|
||||
}
|
||||
|
||||
vkWaitForFences(target->Device->VulkanDevice, 1, &fence, VK_TRUE, UINT64_MAX);
|
||||
|
||||
// Map Memory
|
||||
void* mappedData;
|
||||
vkMapMemory(target->Device->VulkanDevice, target->StagingBuffer->DeviceData, 0,
|
||||
target->StagingBuffer->Size, 0, &mappedData);
|
||||
memcpy(mappedData, data, target->StagingBuffer->Size);
|
||||
vkUnmapMemory(target->Device->VulkanDevice, target->StagingBuffer->DeviceData);
|
||||
|
||||
transition_image_layout(target->Device, target->Image, target->Format,
|
||||
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
// No we have the data in the buffer, let's move it to the image
|
||||
graphics::renderer_submit_now(
|
||||
target->Device->RenderContext, [&](VulkanRenderer* re, VkCommandBuffer* cmd) {
|
||||
VkBufferImageCopy region {};
|
||||
region.bufferOffset = 0;
|
||||
region.bufferRowLength = size.width;
|
||||
region.bufferImageHeight = size.height;
|
||||
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.mipLevel = 0;
|
||||
region.imageSubresource.baseArrayLayer = 0;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
|
||||
region.imageOffset = { 0, 0, 0 };
|
||||
region.imageExtent = { size.width, size.height, 1 };
|
||||
|
||||
vkCmdCopyBufferToImage(*cmd, target->StagingBuffer->Handle, target->Image,
|
||||
VK_IMAGE_LAYOUT_GENERAL, 1, ®ion);
|
||||
});
|
||||
|
||||
// Sync with Fence
|
||||
vkResetFences(target->Device->VulkanDevice, 1, &fence);
|
||||
vkDestroyFence(target->Device->VulkanDevice, fence, nullptr);
|
||||
|
||||
// Transition to whatever we need
|
||||
transition_image_layout(target->Device, target->Image, target->Format,
|
||||
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
}
|
||||
|
||||
void dynamic_rendertarget_recreate(DynamicCPUTarget* target, VkExtent2D extent)
|
||||
{
|
||||
vkDestroyImageView(target->Device->VulkanDevice, target->ImageView, nullptr);
|
||||
vkDestroyImage(target->Device->VulkanDevice, target->Image, nullptr);
|
||||
vkFreeMemory(target->Device->VulkanDevice, target->Memory, nullptr);
|
||||
|
||||
target->Extent = extent;
|
||||
|
||||
// Create VkImage with Undefined
|
||||
create_image(target->Device, extent.width, extent.height, target->Format, VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
|
||||
| VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->Image, target->Memory);
|
||||
|
||||
target->ImageView
|
||||
= create_image_view(target->Device, target->Image, target->Format, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
target->DescriptorSet = ImGui_ImplVulkan_AddTexture(
|
||||
target->Sampler, target->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
// NOTE: This assumes that the image is in the UNDEFINED LAYOUT
|
||||
// And also assumes that the cpu layout is floating point (4 bytes) and the image is
|
||||
// RGBA
|
||||
target->StagingBuffer = generic_buffer_create(target->Device, 0,
|
||||
extent.width * extent.height * 4, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,14 +3,16 @@
|
||||
#include "graphics.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace inferno::graphics {
|
||||
|
||||
struct GraphicsDevice;
|
||||
struct GenBuffer;
|
||||
|
||||
// TODO: Should probably be "ImageAttachment" and then the
|
||||
// target will abstract which sort of attachment it is
|
||||
typedef struct DepthAttachment {
|
||||
typedef struct ImageAttachment {
|
||||
VkImage Image;
|
||||
VkDeviceMemory Memory;
|
||||
VkImageView ImageView;
|
||||
@@ -19,14 +21,11 @@ typedef struct DepthAttachment {
|
||||
|
||||
// TODO: What about the present mode?
|
||||
typedef struct RenderTarget {
|
||||
VkImage Image;
|
||||
VkDeviceMemory Memory;
|
||||
VkImageView ImageView;
|
||||
ImageAttachment* TargetImage = nullptr;
|
||||
ImageAttachment* TargetDepth = nullptr;
|
||||
|
||||
VkFormat Format;
|
||||
VkExtent2D Extent;
|
||||
|
||||
DepthAttachment* TargetDepth = nullptr;
|
||||
VkFormat Format;
|
||||
|
||||
// NOTE: This is for the ImGui renderer.. it needs a descriptor set of a sampler of an
|
||||
// image
|
||||
@@ -45,4 +44,29 @@ void rendertarget_destroy_depth(RenderTarget* target);
|
||||
|
||||
void rendertarget_recreate(RenderTarget* target, VkExtent2D extent, VkFormat format);
|
||||
|
||||
typedef struct DynamicCPUTarget {
|
||||
VkImage Image;
|
||||
VkDeviceMemory Memory;
|
||||
VkImageView ImageView;
|
||||
|
||||
VkFormat Format;
|
||||
VkExtent2D Extent;
|
||||
|
||||
GenBuffer* StagingBuffer;
|
||||
|
||||
// This is being given to ImGUI so we need a Sampler and a DescriptorSet
|
||||
VkSampler Sampler;
|
||||
VkDescriptorSet DescriptorSet;
|
||||
|
||||
GraphicsDevice* Device;
|
||||
} DynamicCPUTarget;
|
||||
|
||||
DynamicCPUTarget* dynamic_rendertarget_create(
|
||||
GraphicsDevice* device, VkExtent2D extent, VkFormat format);
|
||||
void dynamic_rendertarget_cleanup(DynamicCPUTarget* target);
|
||||
|
||||
void dynamic_rendertarget_update(DynamicCPUTarget* target, void* data, VkExtent2D size);
|
||||
|
||||
void dynamic_rendertarget_recreate(DynamicCPUTarget* target, VkExtent2D extent);
|
||||
|
||||
}
|
||||
|
||||
@@ -200,12 +200,17 @@ bool renderer_begin_frame(VulkanRenderer* renderer)
|
||||
void renderer_begin_pass(
|
||||
VulkanRenderer* renderer, RenderTarget* target, VkRect2D renderArea, bool clear)
|
||||
{
|
||||
// Validate that "Image" is valid
|
||||
if (target == nullptr || target->TargetImage == nullptr) {
|
||||
yolo::error("Target image is null");
|
||||
}
|
||||
|
||||
VkImageMemoryBarrier imageMemoryBarrier {};
|
||||
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
imageMemoryBarrier.image = target->Image;
|
||||
imageMemoryBarrier.image = target->TargetImage->Image;
|
||||
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
|
||||
imageMemoryBarrier.subresourceRange.layerCount = 1;
|
||||
@@ -223,7 +228,7 @@ void renderer_begin_pass(
|
||||
VkClearValue clearColor = { { { 0.0f, 0.0f, 0.0f, 1.0f } } };
|
||||
VkRenderingAttachmentInfo attachmentInfo {};
|
||||
attachmentInfo.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
|
||||
attachmentInfo.imageView = target->ImageView;
|
||||
attachmentInfo.imageView = target->TargetImage->ImageView;
|
||||
attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR;
|
||||
attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
|
||||
@@ -90,6 +90,7 @@ InfernoApp* inferno_create()
|
||||
app->Input = new InfernoInput;
|
||||
app->Scene = scene::scene_create();
|
||||
app->MainTimer = inferno_timer_create();
|
||||
app->FrameCount = 0;
|
||||
|
||||
graphics::camera_set_position(app->Scene->Camera, { 0.0f, 1.0f, 3.1f });
|
||||
|
||||
@@ -97,6 +98,8 @@ InfernoApp* inferno_create()
|
||||
graphics::window_create("Inferno v" INFERNO_VERSION, 1920, 1080);
|
||||
app->Device = graphics::device_create();
|
||||
app->Renderer = graphics::renderer_create(app->Device);
|
||||
// FIXME: FUCKING CHANGE THIS
|
||||
graphics::device_add_context(app->Device, app->Renderer);
|
||||
|
||||
graphics::renderer_configure_gui(app->Renderer);
|
||||
graphics::renderer_configure_command_buffer(app->Renderer);
|
||||
@@ -126,15 +129,13 @@ InfernoApp* inferno_create()
|
||||
// scene::scene_object_load(object, "res/sponza.obj");
|
||||
scene::scene_object_load(object, "res/cornell-box.obj");
|
||||
scene::scene_add_object(app->Scene, object);
|
||||
//
|
||||
// scene::SceneObject* lucy = scene::scene_object_create(app->Device);
|
||||
// scene::scene_object_load(lucy, "res/lucy.obj");
|
||||
// scene::scene_object_optimize(lucy);
|
||||
// scene::scene_add_object(app->Scene, lucy);
|
||||
|
||||
scene::SceneObject* lucy = scene::scene_object_create(app->Device);
|
||||
scene::scene_object_load(lucy, "res/lucy.obj");
|
||||
scene::scene_object_optimize(lucy);
|
||||
scene::scene_add_object(app->Scene, lucy);
|
||||
// app->PreviewRenderer = graphics::preview_create();
|
||||
// graphics::preview_set_viewport(app->PreviewRenderer, app->Scene->Camera);
|
||||
// app->RayRenderer = graphics::rayr_create(app->Scene);
|
||||
// graphics::rayr_set_viewport(app->RayRenderer, app->Scene->Camera);
|
||||
app->RayRenderer = graphics::rayr_create(app->Renderer, app->Scene);
|
||||
|
||||
return app;
|
||||
}
|
||||
@@ -248,30 +249,24 @@ void inferno_end(InfernoApp* app)
|
||||
|
||||
int inferno_run(InfernoApp* app)
|
||||
{
|
||||
|
||||
// we weant to outline Lucy in lines
|
||||
graphics::renderer_submit_repeat(
|
||||
app->Renderer,
|
||||
[&](graphics::VulkanRenderer* renderer, VkCommandBuffer* commandBuffer) {
|
||||
const auto lucy = app->Scene->Objects[0];
|
||||
for (auto& mesh : scene::scene_object_get_meshs(lucy)) {
|
||||
for (int i = 0; i < mesh->Indicies.size() - 1; i += 3) {
|
||||
graphics::debug_draw_line(
|
||||
mesh->Verticies[mesh->Indicies[i]].Position,
|
||||
mesh->Verticies[mesh->Indicies[i + 1]].Position,
|
||||
{ 1, 0, 0 });
|
||||
graphics::debug_draw_line(
|
||||
mesh->Verticies[mesh->Indicies[i + 1]].Position,
|
||||
mesh->Verticies[mesh->Indicies[i + 2]].Position,
|
||||
{ 1, 0, 0 });
|
||||
graphics::debug_draw_line(
|
||||
mesh->Verticies[mesh->Indicies[i + 2]].Position,
|
||||
mesh->Verticies[mesh->Indicies[i]].Position,
|
||||
{ 1, 0, 0 });
|
||||
}
|
||||
}
|
||||
},
|
||||
false);
|
||||
// graphics::renderer_submit_repeat(
|
||||
// app->Renderer,
|
||||
// [&](graphics::VulkanRenderer* renderer, VkCommandBuffer* commandBuffer) {
|
||||
// const auto lucy = app->Scene->Objects[0];
|
||||
// for (auto& mesh : scene::scene_object_get_meshs(lucy)) {
|
||||
// for (int i = 0; i < mesh->Indicies.size() - 1; i += 3) {
|
||||
// graphics::debug_draw_line(mesh->Verticies[mesh->Indicies[i]].Position,
|
||||
// mesh->Verticies[mesh->Indicies[i + 1]].Position, { 0, 0, 1 });
|
||||
// graphics::debug_draw_line(
|
||||
// mesh->Verticies[mesh->Indicies[i + 1]].Position,
|
||||
// mesh->Verticies[mesh->Indicies[i + 2]].Position, { 0, 0, 1 });
|
||||
// graphics::debug_draw_line(
|
||||
// mesh->Verticies[mesh->Indicies[i + 2]].Position,
|
||||
// mesh->Verticies[mesh->Indicies[i]].Position, { 0, 0, 1 });
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// false);
|
||||
|
||||
while (graphics::window_new_frame()) {
|
||||
if (!inferno_pre(app))
|
||||
@@ -358,13 +353,22 @@ int inferno_run(InfernoApp* app)
|
||||
}
|
||||
|
||||
if (ImGui::Begin("Render")) {
|
||||
// graphics::rayr_draw(app->RayRenderer);
|
||||
// static ImVec2 lastViewport = { 0, 0 };
|
||||
// ImVec2 currentViewport = ImGui::GetWindowSize();
|
||||
// if (lastViewport.x != currentViewport.x
|
||||
// || lastViewport.y != currentViewport.y) {
|
||||
// graphics::camera_ray_set_viewport(scene::scene_get_camera(app->Scene),
|
||||
// { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y });
|
||||
// graphics::rayr_set_viewport(app->RayRenderer, app->Scene->Camera);
|
||||
// }
|
||||
// lastViewport = currentViewport;
|
||||
|
||||
// ImTextureID texture
|
||||
// = (ImTextureID)graphics::rayr_get_rendered_texture(app->RayRenderer);
|
||||
// ImGui::Image(texture, { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y
|
||||
// },
|
||||
// ImVec2(0, 1), ImVec2(1, 0));
|
||||
graphics::rayr_draw(app->RayRenderer);
|
||||
|
||||
ImTextureID texture
|
||||
= (ImTextureID)graphics::rayr_get_target(app->RayRenderer)->DescriptorSet;
|
||||
ImGui::Image(texture, { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y },
|
||||
ImVec2(0, 1), ImVec2(1, 0));
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
@@ -377,4 +381,4 @@ int inferno_run(InfernoApp* app)
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace infern
|
||||
} // name
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "scene/scene.hpp"
|
||||
// #include "scene/camera.hpp"
|
||||
#include "preview/renderer.hpp"
|
||||
#include "raytracing/renderer.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -59,7 +60,7 @@ typedef struct InfernoApp {
|
||||
graphics::VulkanRenderer* Renderer;
|
||||
|
||||
graphics::PreviewRenderer* PreviewRenderer;
|
||||
// graphics::RayRenderer* RayRenderer;
|
||||
graphics::RayRenderer* RayRenderer;
|
||||
|
||||
InfernoTimer* MainTimer;
|
||||
uint64_t FrameCount;
|
||||
|
||||
@@ -38,6 +38,7 @@ PreviewRenderer* preview_create(VulkanRenderer* vkrenderer)
|
||||
|
||||
renderer->PreviewRenderTarget = graphics::rendertarget_create(
|
||||
renderer->Renderer->Device, { 1920, 1080 }, VK_FORMAT_R8G8B8A8_UNORM, true);
|
||||
yolo::info("Created preview rendertarget");
|
||||
|
||||
// bind preview renderer to debugdraw
|
||||
debug_init(renderer);
|
||||
@@ -71,6 +72,7 @@ void preview_draw(PreviewRenderer* renderer, scene::Scene* scene)
|
||||
VkCommandBuffer commandBuffer = *renderer->Renderer->CommandBufferInFlight;
|
||||
// if changed
|
||||
if (renderer->HasViewportChanged) {
|
||||
yolo::info("Resizing preview");
|
||||
graphics::rendertarget_recreate(renderer->PreviewRenderTarget,
|
||||
renderer->Viewport.extent, VK_FORMAT_R8G8B8A8_UNORM);
|
||||
}
|
||||
|
||||
@@ -50,12 +50,12 @@ HitInfo* object_ray_collide(scene::SceneObject* object, Ray* ray)
|
||||
const uint32_t* ind;
|
||||
const float* verts;
|
||||
const float* norms;
|
||||
// mesh->getIndicies(&ind);
|
||||
// mesh->getVerticies(&verts, &norms);
|
||||
scene::mesh_get_indicies(mesh, &ind);
|
||||
scene::mesh_get_verticies(mesh, &verts, &norms);
|
||||
|
||||
float t = INFINITY;
|
||||
int i ;
|
||||
// for (int i = 0; i < mesh->getIndexCount(); i += 3) {
|
||||
int i;
|
||||
for (int i = 0; i < scene::mesh_get_index_count(mesh); i += 3) {
|
||||
uint32_t indexa = ind[i + 0];
|
||||
uint32_t indexb = ind[i + 1];
|
||||
uint32_t indexc = ind[i + 2];
|
||||
@@ -72,7 +72,7 @@ HitInfo* object_ray_collide(scene::SceneObject* object, Ray* ray)
|
||||
t = temp_t;
|
||||
info->Distance = t;
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -32,19 +32,21 @@ RayRenderer* rayr_create(VulkanRenderer* renderer, scene::Scene* scene)
|
||||
ray->Renderer = renderer;
|
||||
|
||||
auto camera = scene::scene_get_camera(scene);
|
||||
glm::ivec2 viewport = camera_ray_get_viewport(camera);
|
||||
ray->Viewport = { .extent
|
||||
= { static_cast<uint32_t>(viewport.x), static_cast<uint32_t>(viewport.y) } };
|
||||
ray->Viewport.offset.x = 0;
|
||||
ray->Viewport.offset.y = 0;
|
||||
ray->Viewport.extent.width = camera_ray_get_viewport(camera).x;
|
||||
ray->Viewport.extent.height = camera_ray_get_viewport(camera).y;
|
||||
ray->HasViewportChanged = true;
|
||||
|
||||
|
||||
ray->RenderData
|
||||
= new glm::fvec4[ray->Viewport.extent.width * ray->Viewport.extent.height];
|
||||
memset(ray->RenderData, 0,
|
||||
ray->Viewport.extent.width * ray->Viewport.extent.height * sizeof(glm::fvec4));
|
||||
|
||||
// TODO: We need to upload RenderData to the GPU / maybe do a quad pass ? I think
|
||||
// ImGui handels that
|
||||
|
||||
// ray->RayRenderTarget = graphics::rendertarget_create()
|
||||
ray->RayRenderTarget = graphics::dynamic_rendertarget_create(
|
||||
renderer->Device, ray->Viewport.extent, VK_FORMAT_R32G32B32A32_SFLOAT);
|
||||
rayr_set_viewport(ray, camera);
|
||||
|
||||
return ray;
|
||||
}
|
||||
@@ -61,11 +63,21 @@ void rayr_set_viewport(RayRenderer* renderer, Camera* camera)
|
||||
renderer->Viewport.extent.width = viewport.x;
|
||||
renderer->Viewport.extent.height = viewport.y;
|
||||
renderer->HasViewportChanged = true;
|
||||
|
||||
delete[] renderer->RenderData;
|
||||
renderer->RenderData
|
||||
= new glm::fvec4[renderer->Viewport.extent.width * renderer->Viewport.extent.height];
|
||||
memset(renderer->RenderData, 1,
|
||||
renderer->Viewport.extent.width * renderer->Viewport.extent.height * sizeof(glm::fvec4));
|
||||
|
||||
// Now resize the rendertarget
|
||||
graphics::dynamic_rendertarget_recreate(
|
||||
renderer->RayRenderTarget, renderer->Viewport.extent);
|
||||
}
|
||||
|
||||
GLuint rayr_get_rendered_texture(RayRenderer* renderer)
|
||||
DynamicCPUTarget* rayr_get_target(RayRenderer* renderer)
|
||||
{
|
||||
// return renderer->RenderTargetTexture;
|
||||
return renderer->RayRenderTarget;
|
||||
}
|
||||
|
||||
glm::fvec4* rayr_get_render_data(RayRenderer* renderer) { return renderer->RenderData; }
|
||||
@@ -73,7 +85,7 @@ glm::fvec4* rayr_get_render_data(RayRenderer* renderer) { return renderer->Rende
|
||||
void rayr_prepare(RayRenderer* renderer)
|
||||
{
|
||||
// TODO: This is TEMP
|
||||
memset(renderer->RenderData, 0,
|
||||
memset(renderer->RenderData, 1,
|
||||
renderer->Viewport.extent.width * renderer->Viewport.extent.height
|
||||
* sizeof(glm::fvec4));
|
||||
|
||||
@@ -94,11 +106,11 @@ void rayr_draw(RayRenderer* renderer)
|
||||
rays::ReferencedRayField startRays
|
||||
= rays::generate_initial_rays(scene::scene_get_camera(renderer->Scene), true);
|
||||
|
||||
// debug_draw_line({ 0, 0, 0 }, { 0, 0, 1 }, { 1, 0, 0 });
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int x = 0; x < renderer->Viewport.extent.width; x++) {
|
||||
for (int y = 0; y < renderer->Viewport.extent.height; y++) {
|
||||
// renderer->RenderData[y * renderer->Viewport.extent.width + x]
|
||||
// = { 1.0, 1.0, 1.0, 1.0 };
|
||||
rays::Ray* ray = startRays.Field[x * renderer->Viewport.extent.height + y];
|
||||
rays::HitInfo* closest_hit = nullptr;
|
||||
|
||||
@@ -127,6 +139,9 @@ void rayr_draw(RayRenderer* renderer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
graphics::dynamic_rendertarget_update(renderer->RayRenderTarget,
|
||||
(void*)renderer->RenderData, renderer->Viewport.extent);
|
||||
}
|
||||
//
|
||||
// void RayRenderer::computeHit(HitInfo* info)
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace inferno::scene {
|
||||
namespace inferno::graphics {
|
||||
|
||||
class VulkanRenderer;
|
||||
class RenderTarget;
|
||||
class DynamicCPUTarget;
|
||||
|
||||
class Camera;
|
||||
class HitInfo;
|
||||
@@ -27,7 +27,7 @@ typedef struct RayRenderer {
|
||||
// TODO: Can this be direct to GPU?
|
||||
// NOTE: Probably not
|
||||
glm::fvec4* RenderData = nullptr;
|
||||
RenderTarget* RayRenderTarget;
|
||||
DynamicCPUTarget* RayRenderTarget;
|
||||
|
||||
scene::Scene* Scene = nullptr;
|
||||
|
||||
@@ -42,7 +42,7 @@ void rayr_cleanup(RayRenderer* renderer);
|
||||
void rayr_draw_ui(RayRenderer* renderer);
|
||||
void rayr_set_viewport(RayRenderer* renderer, Camera* camera);
|
||||
|
||||
// rayr_get_rendered_texture(RayRenderer* renderer);
|
||||
DynamicCPUTarget* rayr_get_target(RayRenderer* renderer);
|
||||
glm::fvec4* rayr_get_render_data(RayRenderer* renderer);
|
||||
|
||||
void rayr_prepare(RayRenderer* renderer);
|
||||
|
||||
@@ -62,6 +62,8 @@ void mesh_process(Mesh* out, aiMesh* mesh)
|
||||
= glm::vec3(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z),
|
||||
};
|
||||
|
||||
out->Positions.push_back(vertex.Position);
|
||||
out->Normals.push_back(vertex.Normal);
|
||||
out->Verticies.push_back(vertex);
|
||||
}
|
||||
|
||||
@@ -91,9 +93,10 @@ void mesh_ready(Mesh* mesh)
|
||||
yolo::debug("Mesh for preview ready...");
|
||||
}
|
||||
|
||||
// TODO: Extract vertex and normal data from internal mesh
|
||||
uint32_t mesh_get_verticies(Mesh* mesh, const float** v, const float** n)
|
||||
{
|
||||
*v = (float*)mesh->Positions.data();
|
||||
*n = (float*)mesh->Normals.data();
|
||||
return mesh->Verticies.size();
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@ typedef struct Mesh {
|
||||
glm::mat4 ModelMatrix;
|
||||
|
||||
std::vector<Vert> Verticies;
|
||||
|
||||
std::vector<glm::vec3> Positions;
|
||||
std::vector<glm::vec3> Normals;
|
||||
|
||||
std::vector<uint32_t> Indicies;
|
||||
|
||||
graphics::Buffer* VertexBuffer;
|
||||
|
||||
Reference in New Issue
Block a user