aasdasdasdasd

This commit is contained in:
Joshua Ashton 2022-08-13 20:41:19 +00:00
parent ac52336049
commit 0b84e8b027
15 changed files with 220 additions and 47 deletions

3
.gitmodules vendored
View File

@ -4,3 +4,6 @@
[submodule "thirdparty/miniz"]
path = subprojects/miniz
url = https://github.com/richgel999/miniz
[submodule "subprojects/libspng"]
path = subprojects/libspng
url = https://github.com/randy408/libspng

View File

@ -13,4 +13,15 @@ namespace orange
{
return HashString(s, count);
}
inline size_t& hashCombine(size_t& seed) { (void)seed; return seed; }
template <typename T, typename... Rest>
inline size_t& hashCombine(size_t& seed, const T& v, Rest... rest)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
hashCombine(seed, rest...);
return seed;
}
}

View File

@ -6,6 +6,18 @@
namespace orange
{
//#define USE_32BIT_INDICES
#ifdef USE_32BIT_INDICES
using IndexType = uint32_t;
static constexpr VkIndexType VulkanIndexType = VK_INDEX_TYPE_UINT32;
static constexpr size_t MaxMeshIndex = UINT32_MAX;
#else
using IndexType = uint16_t;
static constexpr VkIndexType VulkanIndexType = VK_INDEX_TYPE_UINT16;
static constexpr size_t MaxMeshIndex = UINT16_MAX;
#endif
struct MeshVertexData
{
MeshVertexData(MeshVertexType type)
@ -64,9 +76,9 @@ namespace orange
MeshData(MeshVertexType type)
: vertexData{ type } {}
MeshVertexData vertexData;
Vector<uint16_t> indices;
AABB bounds;
MeshVertexData vertexData;
Vector<IndexType> indices;
AABB bounds;
};
Result<MeshData> ParseOBJ(StringView buffer);

View File

@ -14,6 +14,7 @@ namespace orange
VkBuffer buffer;
VkDeviceSize offset;
VkDeviceSize size;
void* ptr;
};
struct GPUMemoryBuffer
@ -33,7 +34,8 @@ namespace orange
Result<BufferSlice> AllocSlice(VkDeviceSize size, VkDeviceSize alignment = 1u)
{
uint32_t offset = Align(m_offset, alignment);
BufferSlice slice{ m_buffer.buffer, offset, size };
BufferSlice slice{ m_buffer.buffer, offset, size,
m_buffer.ptr ? reinterpret_cast<uint8_t*>(m_buffer.ptr) + offset : nullptr };
if (offset + size > m_buffer.size)
return Result<BufferSlice>::Error();
@ -80,7 +82,8 @@ namespace orange
VulkanResult<VoidResult> BeginCommandBuffer(VkCommandBuffer buffer);
VulkanResult<VoidResult> EndCommandBuffer(VkCommandBuffer buffer);
VulkanResult<GPUMemoryBuffer> CreateBuffer(VkDeviceSize size);
VulkanResult<VkImage> CreateImage(MemoryPool& pool, uint32_t width, uint32_t height, VkFormat format);
VulkanResult<VkImage> CreateImage(MemoryPool& pool, uint32_t width, uint32_t height, VkFormat format, VkImageUsageFlags usage);
VulkanResult<VkImageView> CreateImageView(VkImage image, VkFormat format, VkImageAspectFlagBits aspect);
VulkanResult<VkShaderModule> CreateShader(Span<const uint32_t> code);

View File

@ -25,6 +25,8 @@ namespace orange
bool Update(Input::InputHandler& handler);
void EnableRelativeMouse(bool relative);
void SetTitle(const char* title);
protected:
friend Result<Window>;
Window(SDL_Window* window);

View File

@ -21,4 +21,15 @@ orange_include = include_directories(['include', 'subprojects'])
sdl2_dep = dependency('SDL2')
vulkan_dep = dependency('vulkan') # get rid of me!
miniz_proj = subproject('miniz', default_options: [
'default_library=static',
])
miniz_dep = miniz_proj.get_variable('miniz_dep')
spng_proj = subproject('libspng', default_options: [
'default_library=static',
'use_miniz=True',
])
spng_dep = spng_proj.get_variable('spng_dep')
subdir('src')

View File

@ -18,9 +18,12 @@
#include <vs_Mesh.h>
#include <vs_Fullscreen.h>
#include <fs_DebugVertColor.h>
#include <fs_Mesh.h>
#include <fs_SkyGradient.h>
#include <fs_Red.h>
#include <spng.h>
using namespace orange;
struct MiniPipelineInfo
@ -103,7 +106,7 @@ static VulkanResult<VkPipeline> CreateGraphicsPipeline(VkDevice device, const Mi
VkPipelineRasterizationStateCreateInfo rasterizationInfo =
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.cullMode = VK_CULL_MODE_NONE, //VK_CULL_MODE_BACK_BIT,
.cullMode = VK_CULL_MODE_BACK_BIT,
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
.lineWidth = 1.0f,
};
@ -191,6 +194,7 @@ int main(int argc, char** argv)
if (!r_swapchain)
return 1;
//auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/gman.obj");
auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/chair.obj");
//auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/cube.obj");
if (!r_objData)
@ -198,11 +202,16 @@ int main(int argc, char** argv)
auto r_mesh = ParseOBJ(*r_objData);
auto r_buffer = r_renderContext->CreateBuffer(256 * 1024 * 1024);
if (!r_buffer)
return 1;
auto pooler = MemoryPool{ *r_buffer };
auto r_vsMesh = r_renderContext->CreateShader(vs_Mesh);
if (!r_vsMesh) return 1;
auto r_vsFullscreen = r_renderContext->CreateShader(vs_Fullscreen);
if (!r_vsFullscreen) return 1;
auto r_fsMesh = r_renderContext->CreateShader(fs_DebugVertColor);
auto r_fsMesh = r_renderContext->CreateShader(fs_Mesh);
if (!r_fsMesh) return 1;
auto r_fsRed = r_renderContext->CreateShader(fs_Red);
if (!r_fsRed) return 1;
@ -354,10 +363,58 @@ int main(int argc, char** argv)
.vertexAttributes = Span<const VkVertexInputAttributeDescription>(nullptr, 0),
});
auto r_buffer = r_renderContext->CreateBuffer(256 * 1024 * 1024);
if (!r_buffer)
struct ImageUpload
{
BufferSlice from;
VkImage to;
VkExtent3D extent;
};
Vector<ImageUpload> imageUploads;
auto r_pngData = fs::OpenFileIntoBuffer("/home/joshua/chair_color.png");
if (!r_pngData)
return 1;
spng_ctx *ctx = spng_ctx_new(0);
spng_set_png_buffer(ctx, r_pngData->data, r_pngData->size);
size_t pngOutSize = 0zu;
spng_decoded_image_size(ctx, SPNG_FMT_RGBA8, &pngOutSize);
auto pngLinearSlice = *pooler.AllocSlice(pngOutSize, 16);
spng_decode_image(ctx, pngLinearSlice.ptr, pngOutSize, SPNG_FMT_RGBA8, 0);
struct spng_ihdr ihdr;
spng_get_ihdr(ctx, &ihdr);
spng_ctx_free(ctx);
auto r_texture = r_renderContext->CreateImage(pooler, ihdr.width, ihdr.height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_USAGE_SAMPLED_BIT);
auto r_textureView = r_renderContext->CreateImageView(*r_texture, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
VkDescriptorImageInfo descriptorImageInfo =
{
.imageView = *r_textureView,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkWriteDescriptorSet writeImageDescriptorSet[] =
{
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = descriptorSet,
.dstBinding = 2,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.pImageInfo = &descriptorImageInfo,
},
};
vkUpdateDescriptorSets(r_renderContext->Device(), Size(writeImageDescriptorSet), writeImageDescriptorSet, 0, nullptr);
imageUploads.PushBack(ImageUpload
{
.from = pngLinearSlice,
.to = *r_texture,
.extent = VkExtent3D{ ihdr.width, ihdr.height, 1u },
});
struct UniformData
{
mat4 projection;
@ -377,25 +434,12 @@ int main(int argc, char** argv)
.view = camera.view(),
};
auto pooler = MemoryPool{ *r_buffer };
auto meshData = r_mesh->vertexData.View();
auto vertexSlice = *pooler.AllocSlice(meshData.size, 16);
auto indexSlice = *pooler.AllocSlice(r_mesh->indices.Size() * sizeof(uint16_t), 16);
auto indexSlice = *pooler.AllocSlice(r_mesh->indices.Size() * sizeof(IndexType), 16);
auto uniformSlice = *pooler.AllocSlice(sizeof(UniformData), 16);
auto r_depthImage = r_renderContext->CreateImage(pooler, 1280, 720, depthFormat);
VkImageViewCreateInfo depthImageViewInfo =
{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = *r_depthImage,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = depthFormat,
.subresourceRange = FirstDepthMipSubresourceRange,
};
VkImageView depthImageView = VK_NULL_HANDLE;
if (vkCreateImageView(r_renderContext->Device(), &depthImageViewInfo, nullptr, &depthImageView) != VK_SUCCESS)
return 1;
auto r_depthImage = r_renderContext->CreateImage(pooler, 1280, 720, depthFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
auto depthImageView = *r_renderContext->CreateImageView(*r_depthImage, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
VkDescriptorBufferInfo bufferInfo =
{
@ -430,9 +474,14 @@ int main(int argc, char** argv)
while (r_window->Update(handler))
{
const auto t2 = Time::now();
const float dt = Seconds(t2 - t1).count();
auto delta = t2 - t1;
const float dt = Seconds(delta).count();
t1 = t2;
//char title[64];
//stbsp_snprintf(title, sizeof(title), "CubeTest - %gfps", 1.0f / dt);
//r_window->SetTitle(title);
{
auto mouseDelta = handler.getMouseMotionDelta();
auto scrollDelta = handler.getMouseScrollDelta();
@ -477,6 +526,24 @@ int main(int argc, char** argv)
VkCommandBuffer cmdBuf = r_swapchain->CommandBuffer();
r_renderContext->BeginCommandBuffer(cmdBuf);
{
for (auto& upload : imageUploads)
{
VkBufferImageCopy region =
{
.bufferOffset = upload.from.offset,
.imageSubresource =
{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0u,
.baseArrayLayer = 0u,
.layerCount = 1u,
},
.imageExtent = upload.extent,
};
vkCmdCopyBufferToImage(cmdBuf, upload.from.buffer, upload.to, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1, &region);
}
imageUploads.Clear();
VkViewport viewport =
{
.x = 0.0f,
@ -498,7 +565,7 @@ int main(int argc, char** argv)
vkCmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
vkCmdBindVertexBuffers2(cmdBuf, 0, 1, &vertexSlice.buffer, &vertexSlice.offset, &vertexSlice.size, nullptr);
vkCmdBindIndexBuffer(cmdBuf, r_buffer->buffer, indexSlice.offset, VK_INDEX_TYPE_UINT16);
vkCmdBindIndexBuffer(cmdBuf, r_buffer->buffer, indexSlice.offset, VulkanIndexType);
const VkImageMemoryBarrier undefinedToColorBarrier =
{

View File

@ -1,4 +1,4 @@
executable('CubeTest', 'CubeTest.cpp', orange_src, orange_shaders,
dependencies : [ sdl2_dep, vulkan_dep ],
dependencies : [ sdl2_dep, vulkan_dep, spng_dep, miniz_dep ],
include_directories : [ orange_include ]
)

View File

@ -3,9 +3,22 @@
#include <Orange/Graphics/Mesh.h>
#include <Orange/Core/Parse.h>
#include <Orange/Core/Hash.h>
#include <unordered_map>
namespace orange
{
struct StaticVertexHash
{
size_t operator() (const StaticVertex& key) const
{
size_t hash = 0;
return hashCombine(hash, key.pos.x, key.pos.y, key.pos.z, key.uv.x, key.uv.y, key.normal.x, key.normal.y, key.normal.z);
}
};
Result<MeshData> ParseOBJ(StringView buffer)
{
MeshData data{ MeshVertexType::Static };
@ -14,6 +27,8 @@ namespace orange
Vector<vec2> uvs;
Vector<vec3> normals;
std::unordered_map<StaticVertex, IndexType, StaticVertexHash> indexTracker;
const char* obj = buffer.data;
const char* end = buffer.data + buffer.size;
while (obj != end)
@ -32,9 +47,9 @@ namespace orange
}
if (element == "v")
positions.EmplaceBack(vtx[0], vtx[1], vtx[2]);
positions.EmplaceBack(vtx[0], -vtx[2], vtx[1]); // TODO remove hack and make this customizable
else if (element == "vt")
uvs.EmplaceBack(vtx[0], vtx[1]);
uvs.EmplaceBack(vtx[0], 1.0f - vtx[1]); // Fix the space from gl -> vk/dx
else if (element == "vn")
normals.EmplaceBack(vtx[0], vtx[1], vtx[2]);
}
@ -69,7 +84,9 @@ namespace orange
}
}
for (int i = 0; i < 3; i++)
// Do backwards so we can have front faces
// be CCW.
for (int i = 2; i >= 0; i--)
{
StaticVertex vertex =
{
@ -80,15 +97,19 @@ namespace orange
auto& vertices = data.vertexData.GetStaticVertices();
size_t vertexIdx = vertices.FindIdx(vertex);
if (vertexIdx == vertices.InvalidIdx)
auto iter = indexTracker.find(vertex);
size_t vertexIdx;
if (iter == indexTracker.end())
{
data.bounds.Extend(vertex.pos);
vertexIdx = vertices.PushBack(vertex);
indexTracker.emplace(vertex, vertexIdx);
}
else
vertexIdx = iter->second;
Assert(vertexIdx < UINT16_MAX);
data.indices.PushBack(uint16_t(vertexIdx));
Assert(vertexIdx < MaxMeshIndex);
data.indices.PushBack(IndexType(vertexIdx));
}
}
else if (!element.Empty())

View File

@ -113,7 +113,7 @@ namespace orange
return VulkanResult<GPUMemoryBuffer>::Success(memory, buffer, size, data);
}
VulkanResult<VkImage> RenderContext::CreateImage(MemoryPool& pool, uint32_t width, uint32_t height, VkFormat format)
VulkanResult<VkImage> RenderContext::CreateImage(MemoryPool& pool, uint32_t width, uint32_t height, VkFormat format, VkImageUsageFlags usage)
{
VkImageCreateInfo imageInfo =
{
@ -125,7 +125,7 @@ namespace orange
.arrayLayers = 1u,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
.usage = usage,
};
VkImage image = VK_NULL_HANDLE;
@ -142,4 +142,30 @@ namespace orange
return VulkanResult<VkImage>::Success(image);
}
VulkanResult<VkImageView> RenderContext::CreateImageView(VkImage image, VkFormat format, VkImageAspectFlagBits aspect)
{
VkImageViewCreateInfo imageViewInfo =
{
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = image,
.viewType = VK_IMAGE_VIEW_TYPE_2D,
.format = format,
.subresourceRange =
{
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
};
VkImageView imageView = VK_NULL_HANDLE;
VkResult res = VK_SUCCESS;
if ((res = vkCreateImageView(m_device, &imageViewInfo, nullptr, &imageView)) != VK_SUCCESS)
return VulkanResult<VkImageView>::Error(res);
return VulkanResult<VkImageView>::Success(imageView);
}
}

View File

@ -0,0 +1,15 @@
#version 450
#extension GL_EXT_nonuniform_qualifier : enable
layout(set = 0, binding = 1) uniform sampler s_sampler;
layout(set = 0, binding = 2) uniform texture2D s_images[];
layout(location = 0) in flat int id;
layout(location = 1) in vec2 uv;
layout(location = 0) out vec4 outColor;
void main()
{
outColor = texture(sampler2D(s_images[nonuniformEXT(id)], s_sampler), uv);
}

View File

@ -1,4 +1,5 @@
#version 450
#extension GL_ARB_shader_draw_parameters : enable
layout(binding = 0) uniform UniformData {
mat4 projection;
@ -9,18 +10,12 @@ layout(location = 0) in vec3 i_pos;
layout(location = 1) in vec2 i_uv;
layout(location = 2) in vec3 i_normal;
layout(location = 0) out vec4 o_color;
vec3 k_colors[3] = vec3[]
(
vec3(1.0, 0.0, 0.0),
vec3(0.0, 1.0, 0.0),
vec3(0.0, 0.0, 1.0)
);
layout(location = 0) out flat int o_id;
layout(location = 1) out vec2 o_uv;
void main()
{
gl_Position = u_data.projection * u_data.view * vec4(i_pos, 1.0);
//o_color = vec4(k_colors[gl_VertexIndex % 3], 1.0);
o_color = vec4(i_uv, 0.0f, 1.0);
o_id = gl_DrawIDARB;
o_uv = i_uv;
}

View File

@ -117,4 +117,9 @@ namespace orange
SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE);
SDL_ShowCursor(m_hasFocus && relative ? SDL_FALSE : SDL_TRUE);
}
void Window::SetTitle(const char* title)
{
SDL_SetWindowTitle(m_window, title);
}
}

View File

@ -1,5 +1,6 @@
orange_shaders = glsl_generator.process([
'Render/Shaders/fs_DebugVertColor.frag',
'Render/Shaders/fs_Mesh.frag',
'Render/Shaders/fs_Red.frag',
'Render/Shaders/fs_SkyGradient.frag',
'Render/Shaders/vs_Fullscreen.vert',

1
subprojects/libspng Submodule

@ -0,0 +1 @@
Subproject commit c4126ad8ce0513ec16aa2e4180eb6545548710a0